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.
42 #include <limits.h> /* UINT_MAX */
56 /* Pixel storage modes */
59 GLint pack_row_length
;
61 GLint pack_skip_pixels
;
63 GLint pack_swap_bytes
;
64 GLint pack_skip_images
;
65 GLint pack_image_height
;
67 GLint unpack_alignment
;
68 GLint unpack_row_length
;
69 GLint unpack_skip_rows
;
70 GLint unpack_skip_pixels
;
71 GLint unpack_lsb_first
;
72 GLint unpack_swap_bytes
;
73 GLint unpack_skip_images
;
74 GLint unpack_image_height
;
77 static int gluBuild1DMipmapLevelsCore(GLenum
, GLint
,
80 GLenum
, GLenum
, GLint
, GLint
, GLint
,
82 static int gluBuild2DMipmapLevelsCore(GLenum
, GLint
,
85 GLenum
, GLenum
, GLint
, GLint
, GLint
,
87 static int gluBuild3DMipmapLevelsCore(GLenum
, GLint
,
88 GLsizei
, GLsizei
, GLsizei
,
89 GLsizei
, GLsizei
, GLsizei
,
90 GLenum
, GLenum
, GLint
, GLint
, GLint
,
94 * internal function declarations
96 static GLfloat
bytes_per_element(GLenum type
);
97 static GLint
elements_per_group(GLenum format
, GLenum type
);
98 static GLint
is_index(GLenum format
);
99 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
);
100 static void fill_image(const PixelStorageModes
*,
101 GLint width
, GLint height
, GLenum format
,
102 GLenum type
, GLboolean index_format
,
103 const void *userdata
, GLushort
*newimage
);
104 static void empty_image(const PixelStorageModes
*,
105 GLint width
, GLint height
, GLenum format
,
106 GLenum type
, GLboolean index_format
,
107 const GLushort
*oldimage
, void *userdata
);
108 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
109 const GLushort
*datain
,
110 GLint widthout
, GLint heightout
,
113 static void scale_internal_ubyte(GLint components
, GLint widthin
,
114 GLint heightin
, const GLubyte
*datain
,
115 GLint widthout
, GLint heightout
,
116 GLubyte
*dataout
, GLint element_size
,
117 GLint ysize
, GLint group_size
);
118 static void scale_internal_byte(GLint components
, GLint widthin
,
119 GLint heightin
, const GLbyte
*datain
,
120 GLint widthout
, GLint heightout
,
121 GLbyte
*dataout
, GLint element_size
,
122 GLint ysize
, GLint group_size
);
123 static void scale_internal_ushort(GLint components
, GLint widthin
,
124 GLint heightin
, const GLushort
*datain
,
125 GLint widthout
, GLint heightout
,
126 GLushort
*dataout
, GLint element_size
,
127 GLint ysize
, GLint group_size
,
129 static void scale_internal_short(GLint components
, GLint widthin
,
130 GLint heightin
, const GLshort
*datain
,
131 GLint widthout
, GLint heightout
,
132 GLshort
*dataout
, GLint element_size
,
133 GLint ysize
, GLint group_size
,
135 static void scale_internal_uint(GLint components
, GLint widthin
,
136 GLint heightin
, const GLuint
*datain
,
137 GLint widthout
, GLint heightout
,
138 GLuint
*dataout
, GLint element_size
,
139 GLint ysize
, GLint group_size
,
141 static void scale_internal_int(GLint components
, GLint widthin
,
142 GLint heightin
, const GLint
*datain
,
143 GLint widthout
, GLint heightout
,
144 GLint
*dataout
, GLint element_size
,
145 GLint ysize
, GLint group_size
,
147 static void scale_internal_float(GLint components
, GLint widthin
,
148 GLint heightin
, const GLfloat
*datain
,
149 GLint widthout
, GLint heightout
,
150 GLfloat
*dataout
, GLint element_size
,
151 GLint ysize
, GLint group_size
,
154 static int checkMipmapArgs(GLenum
, GLenum
, GLenum
);
155 static GLboolean
legalFormat(GLenum
);
156 static GLboolean
legalType(GLenum
);
157 static GLboolean
isTypePackedPixel(GLenum
);
158 static GLboolean
isLegalFormatForPackedPixelType(GLenum
, GLenum
);
159 static GLboolean
isLegalLevels(GLint
, GLint
, GLint
, GLint
);
160 static void closestFit(GLenum
, GLint
, GLint
, GLint
, GLenum
, GLenum
,
163 /* all extract/shove routines must return double to handle unsigned ints */
164 static GLdouble
extractUbyte(int, const void *);
165 static void shoveUbyte(GLdouble
, int, void *);
166 static GLdouble
extractSbyte(int, const void *);
167 static void shoveSbyte(GLdouble
, int, void *);
168 static GLdouble
extractUshort(int, const void *);
169 static void shoveUshort(GLdouble
, int, void *);
170 static GLdouble
extractSshort(int, const void *);
171 static void shoveSshort(GLdouble
, int, void *);
172 static GLdouble
extractUint(int, const void *);
173 static void shoveUint(GLdouble
, int, void *);
174 static GLdouble
extractSint(int, const void *);
175 static void shoveSint(GLdouble
, int, void *);
176 static GLdouble
extractFloat(int, const void *);
177 static void shoveFloat(GLdouble
, int, void *);
178 static void halveImageSlice(int, GLdouble (*)(int, const void *),
179 void (*)(GLdouble
, int, void *),
181 const void *, void *,
182 GLint
, GLint
, GLint
, GLint
, GLint
);
183 static void halveImage3D(int, GLdouble (*)(int, const void *),
184 void (*)(GLdouble
, int, void *),
186 const void *, void *,
187 GLint
, GLint
, GLint
, GLint
, GLint
);
189 /* packedpixel type scale routines */
190 static void extract332(int,const void *, GLfloat
[]);
191 static void shove332(const GLfloat
[],int ,void *);
192 static void extract233rev(int,const void *, GLfloat
[]);
193 static void shove233rev(const GLfloat
[],int ,void *);
194 static void extract565(int,const void *, GLfloat
[]);
195 static void shove565(const GLfloat
[],int ,void *);
196 static void extract565rev(int,const void *, GLfloat
[]);
197 static void shove565rev(const GLfloat
[],int ,void *);
198 static void extract4444(int,const void *, GLfloat
[]);
199 static void shove4444(const GLfloat
[],int ,void *);
200 static void extract4444rev(int,const void *, GLfloat
[]);
201 static void shove4444rev(const GLfloat
[],int ,void *);
202 static void extract5551(int,const void *, GLfloat
[]);
203 static void shove5551(const GLfloat
[],int ,void *);
204 static void extract1555rev(int,const void *, GLfloat
[]);
205 static void shove1555rev(const GLfloat
[],int ,void *);
206 static void extract8888(int,const void *, GLfloat
[]);
207 static void shove8888(const GLfloat
[],int ,void *);
208 static void extract8888rev(int,const void *, GLfloat
[]);
209 static void shove8888rev(const GLfloat
[],int ,void *);
210 static void extract1010102(int,const void *, GLfloat
[]);
211 static void shove1010102(const GLfloat
[],int ,void *);
212 static void extract2101010rev(int,const void *, GLfloat
[]);
213 static void shove2101010rev(const GLfloat
[],int ,void *);
214 static void scaleInternalPackedPixel(int,
215 void (*)(int, const void *,GLfloat
[]),
216 void (*)(const GLfloat
[],int, void *),
217 GLint
,GLint
, const void *,
218 GLint
,GLint
,void *,GLint
,GLint
,GLint
);
219 static void halveImagePackedPixel(int,
220 void (*)(int, const void *,GLfloat
[]),
221 void (*)(const GLfloat
[],int, void *),
222 GLint
, GLint
, const void *,
223 void *, GLint
, GLint
, GLint
);
224 static void halve1DimagePackedPixel(int,
225 void (*)(int, const void *,GLfloat
[]),
226 void (*)(const GLfloat
[],int, void *),
227 GLint
, GLint
, const void *,
228 void *, GLint
, GLint
, GLint
);
230 static void halve1Dimage_ubyte(GLint
, GLuint
, GLuint
,const GLubyte
*,
231 GLubyte
*, GLint
, GLint
, GLint
);
232 static void halve1Dimage_byte(GLint
, GLuint
, GLuint
,const GLbyte
*, GLbyte
*,
233 GLint
, GLint
, GLint
);
234 static void halve1Dimage_ushort(GLint
, GLuint
, GLuint
, const GLushort
*,
235 GLushort
*, GLint
, GLint
, GLint
, GLint
);
236 static void halve1Dimage_short(GLint
, GLuint
, GLuint
,const GLshort
*, GLshort
*,
237 GLint
, GLint
, GLint
, GLint
);
238 static void halve1Dimage_uint(GLint
, GLuint
, GLuint
, const GLuint
*, GLuint
*,
239 GLint
, GLint
, GLint
, GLint
);
240 static void halve1Dimage_int(GLint
, GLuint
, GLuint
, const GLint
*, GLint
*,
241 GLint
, GLint
, GLint
, GLint
);
242 static void halve1Dimage_float(GLint
, GLuint
, GLuint
, const GLfloat
*, GLfloat
*,
243 GLint
, GLint
, GLint
, GLint
);
245 static GLint
imageSize3D(GLint
, GLint
, GLint
, GLenum
,GLenum
);
246 static void fillImage3D(const PixelStorageModes
*, GLint
, GLint
, GLint
,GLenum
,
247 GLenum
, GLboolean
, const void *, GLushort
*);
248 static void emptyImage3D(const PixelStorageModes
*,
249 GLint
, GLint
, GLint
, GLenum
,
251 const GLushort
*, void *);
252 static void scaleInternal3D(GLint
, GLint
, GLint
, GLint
, const GLushort
*,
253 GLint
, GLint
, GLint
, GLushort
*);
255 static void retrieveStoreModes(PixelStorageModes
*psm
)
257 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
258 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
259 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
260 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
261 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
262 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
264 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
265 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
266 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
267 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
268 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
269 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
272 static void retrieveStoreModes3D(PixelStorageModes
*psm
)
274 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
275 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
276 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
277 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
278 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
279 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
280 glGetIntegerv(GL_UNPACK_SKIP_IMAGES
, &psm
->unpack_skip_images
);
281 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT
, &psm
->unpack_image_height
);
283 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
284 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
285 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
286 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
287 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
288 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
289 glGetIntegerv(GL_PACK_SKIP_IMAGES
, &psm
->pack_skip_images
);
290 glGetIntegerv(GL_PACK_IMAGE_HEIGHT
, &psm
->pack_image_height
);
293 static int computeLog(GLuint value
)
300 if (value
== 0) return -1;
305 if (value
!= 1) return -1;
314 ** Compute the nearest power of 2 number. This algorithm is a little
315 ** strange, but it works quite well.
317 static int nearestPower(GLuint value
)
324 if (value
== 0) return -1;
329 } else if (value
== 3) {
337 #define __GLU_SWAP_2_BYTES(s)\
338 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
340 #define __GLU_SWAP_4_BYTES(s)\
341 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
342 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
343 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
345 static void halveImage(GLint components
, GLuint width
, GLuint height
,
346 const GLushort
*datain
, GLushort
*dataout
)
349 int newwidth
, newheight
;
354 newwidth
= width
/ 2;
355 newheight
= height
/ 2;
356 delta
= width
* components
;
361 for (i
= 0; i
< newheight
; i
++) {
362 for (j
= 0; j
< newwidth
; j
++) {
363 for (k
= 0; k
< components
; k
++) {
364 s
[0] = (t
[0] + t
[components
] + t
[delta
] +
365 t
[delta
+components
] + 2) / 4;
374 static void halveImage_ubyte(GLint components
, GLuint width
, GLuint height
,
375 const GLubyte
*datain
, GLubyte
*dataout
,
376 GLint element_size
, GLint ysize
, GLint group_size
)
379 int newwidth
, newheight
;
383 /* handle case where there is only 1 column/row */
384 if (width
== 1 || height
== 1) {
385 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
386 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
387 element_size
,ysize
,group_size
);
391 newwidth
= width
/ 2;
392 newheight
= height
/ 2;
394 t
= (const char *)datain
;
397 for (i
= 0; i
< newheight
; i
++) {
398 for (j
= 0; j
< newwidth
; j
++) {
399 for (k
= 0; k
< components
; k
++) {
400 s
[0] = (*(const GLubyte
*)t
+
401 *(const GLubyte
*)(t
+group_size
) +
402 *(const GLubyte
*)(t
+ysize
) +
403 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
404 s
++; t
+= element_size
;
413 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
414 const GLubyte
*dataIn
, GLubyte
*dataOut
,
415 GLint element_size
, GLint ysize
,
418 GLint halfWidth
= width
/ 2;
419 GLint halfHeight
= height
/ 2;
420 const char *src
= (const char *) dataIn
;
421 GLubyte
*dest
= dataOut
;
424 assert(width
== 1 || height
== 1); /* must be 1D */
425 assert(width
!= height
); /* can't be square */
427 if (height
== 1) { /* 1 row */
428 assert(width
!= 1); /* widthxheight can't be 1x1 */
431 for (jj
= 0; jj
< halfWidth
; jj
++) {
433 for (kk
= 0; kk
< components
; kk
++) {
434 *dest
= (*(const GLubyte
*)src
+
435 *(const GLubyte
*)(src
+group_size
)) / 2;
440 src
+= group_size
; /* skip to next 2 */
443 int padBytes
= ysize
- (width
*group_size
);
444 src
+= padBytes
; /* for assertion only */
447 else if (width
== 1) { /* 1 column */
448 int padBytes
= ysize
- (width
* group_size
);
449 assert(height
!= 1); /* widthxheight can't be 1x1 */
451 /* one vertical column with possible pad bytes per row */
452 /* average two at a time */
454 for (jj
= 0; jj
< halfHeight
; jj
++) {
456 for (kk
= 0; kk
< components
; kk
++) {
457 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
462 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
467 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
468 assert((char *)dest
== &((char *)dataOut
)
469 [components
* element_size
* halfWidth
* halfHeight
]);
470 } /* halve1Dimage_ubyte() */
472 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
473 const GLbyte
*datain
, GLbyte
*dataout
,
475 GLint ysize
, GLint group_size
)
478 int newwidth
, newheight
;
482 /* handle case where there is only 1 column/row */
483 if (width
== 1 || height
== 1) {
484 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
485 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
486 element_size
,ysize
,group_size
);
490 newwidth
= width
/ 2;
491 newheight
= height
/ 2;
493 t
= (const char *)datain
;
496 for (i
= 0; i
< newheight
; i
++) {
497 for (j
= 0; j
< newwidth
; j
++) {
498 for (k
= 0; k
< components
; k
++) {
499 s
[0] = (*(const GLbyte
*)t
+
500 *(const GLbyte
*)(t
+group_size
) +
501 *(const GLbyte
*)(t
+ysize
) +
502 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
503 s
++; t
+= element_size
;
511 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
512 const GLbyte
*dataIn
, GLbyte
*dataOut
,
513 GLint element_size
,GLint ysize
, GLint group_size
)
515 GLint halfWidth
= width
/ 2;
516 GLint halfHeight
= height
/ 2;
517 const char *src
= (const char *) dataIn
;
518 GLbyte
*dest
= dataOut
;
521 assert(width
== 1 || height
== 1); /* must be 1D */
522 assert(width
!= height
); /* can't be square */
524 if (height
== 1) { /* 1 row */
525 assert(width
!= 1); /* widthxheight can't be 1x1 */
528 for (jj
= 0; jj
< halfWidth
; jj
++) {
530 for (kk
= 0; kk
< components
; kk
++) {
531 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
536 src
+= group_size
; /* skip to next 2 */
539 int padBytes
= ysize
- (width
*group_size
);
540 src
+= padBytes
; /* for assertion only */
543 else if (width
== 1) { /* 1 column */
544 int padBytes
= ysize
- (width
* group_size
);
545 assert(height
!= 1); /* widthxheight can't be 1x1 */
547 /* one vertical column with possible pad bytes per row */
548 /* average two at a time */
550 for (jj
= 0; jj
< halfHeight
; jj
++) {
552 for (kk
= 0; kk
< components
; kk
++) {
553 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
558 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
562 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
565 assert((char *)dest
== &((char *)dataOut
)
566 [components
* element_size
* halfWidth
* halfHeight
]);
567 } /* halve1Dimage_byte() */
569 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
570 const GLushort
*datain
, GLushort
*dataout
,
571 GLint element_size
, GLint ysize
, GLint group_size
,
575 int newwidth
, newheight
;
579 /* handle case where there is only 1 column/row */
580 if (width
== 1 || height
== 1) {
581 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
582 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
583 element_size
,ysize
,group_size
, myswap_bytes
);
587 newwidth
= width
/ 2;
588 newheight
= height
/ 2;
590 t
= (const char *)datain
;
594 for (i
= 0; i
< newheight
; i
++) {
595 for (j
= 0; j
< newwidth
; j
++) {
596 for (k
= 0; k
< components
; k
++) {
597 s
[0] = (*(const GLushort
*)t
+
598 *(const GLushort
*)(t
+group_size
) +
599 *(const GLushort
*)(t
+ysize
) +
600 *(const GLushort
*)(t
+ysize
+group_size
) + 2) / 4;
601 s
++; t
+= element_size
;
608 for (i
= 0; i
< newheight
; i
++) {
609 for (j
= 0; j
< newwidth
; j
++) {
610 for (k
= 0; k
< components
; k
++) {
611 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
612 __GLU_SWAP_2_BYTES(t
+group_size
) +
613 __GLU_SWAP_2_BYTES(t
+ysize
) +
614 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
615 s
++; t
+= element_size
;
623 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
624 const GLushort
*dataIn
, GLushort
*dataOut
,
625 GLint element_size
, GLint ysize
,
626 GLint group_size
, GLint myswap_bytes
)
628 GLint halfWidth
= width
/ 2;
629 GLint halfHeight
= height
/ 2;
630 const char *src
= (const char *) dataIn
;
631 GLushort
*dest
= dataOut
;
634 assert(width
== 1 || height
== 1); /* must be 1D */
635 assert(width
!= height
); /* can't be square */
637 if (height
== 1) { /* 1 row */
638 assert(width
!= 1); /* widthxheight can't be 1x1 */
641 for (jj
= 0; jj
< halfWidth
; jj
++) {
643 for (kk
= 0; kk
< components
; kk
++) {
645 GLushort ushort
[BOX2
];
647 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
648 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
651 ushort
[0]= *(const GLushort
*)src
;
652 ushort
[1]= *(const GLushort
*)(src
+group_size
);
655 *dest
= (ushort
[0] + ushort
[1]) / 2;
659 src
+= group_size
; /* skip to next 2 */
662 int padBytes
= ysize
- (width
*group_size
);
663 src
+= padBytes
; /* for assertion only */
666 else if (width
== 1) { /* 1 column */
667 int padBytes
= ysize
- (width
* group_size
);
668 assert(height
!= 1); /* widthxheight can't be 1x1 */
670 /* one vertical column with possible pad bytes per row */
671 /* average two at a time */
673 for (jj
= 0; jj
< halfHeight
; jj
++) {
675 for (kk
= 0; kk
< components
; kk
++) {
677 GLushort ushort
[BOX2
];
679 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
680 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
683 ushort
[0]= *(const GLushort
*)src
;
684 ushort
[1]= *(const GLushort
*)(src
+ysize
);
686 *dest
= (ushort
[0] + ushort
[1]) / 2;
691 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
695 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
698 assert((char *)dest
== &((char *)dataOut
)
699 [components
* element_size
* halfWidth
* halfHeight
]);
701 } /* halve1Dimage_ushort() */
704 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
705 const GLshort
*datain
, GLshort
*dataout
,
706 GLint element_size
, GLint ysize
, GLint group_size
,
710 int newwidth
, newheight
;
714 /* handle case where there is only 1 column/row */
715 if (width
== 1 || height
== 1) {
716 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
717 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
718 element_size
,ysize
,group_size
, myswap_bytes
);
722 newwidth
= width
/ 2;
723 newheight
= height
/ 2;
725 t
= (const char *)datain
;
729 for (i
= 0; i
< newheight
; i
++) {
730 for (j
= 0; j
< newwidth
; j
++) {
731 for (k
= 0; k
< components
; k
++) {
732 s
[0] = (*(const GLshort
*)t
+
733 *(const GLshort
*)(t
+group_size
) +
734 *(const GLshort
*)(t
+ysize
) +
735 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
736 s
++; t
+= element_size
;
743 for (i
= 0; i
< newheight
; i
++) {
744 for (j
= 0; j
< newwidth
; j
++) {
745 for (k
= 0; k
< components
; k
++) {
748 b
= __GLU_SWAP_2_BYTES(t
);
749 buf
= *(const GLshort
*)&b
;
750 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
751 buf
+= *(const GLshort
*)&b
;
752 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
753 buf
+= *(const GLshort
*)&b
;
754 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
755 buf
+= *(const GLshort
*)&b
;
756 s
[0] = (GLshort
)((buf
+2)/4);
757 s
++; t
+= element_size
;
765 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
766 const GLshort
*dataIn
, GLshort
*dataOut
,
767 GLint element_size
, GLint ysize
,
768 GLint group_size
, GLint myswap_bytes
)
770 GLint halfWidth
= width
/ 2;
771 GLint halfHeight
= height
/ 2;
772 const char *src
= (const char *) dataIn
;
773 GLshort
*dest
= dataOut
;
776 assert(width
== 1 || height
== 1); /* must be 1D */
777 assert(width
!= height
); /* can't be square */
779 if (height
== 1) { /* 1 row */
780 assert(width
!= 1); /* widthxheight can't be 1x1 */
783 for (jj
= 0; jj
< halfWidth
; jj
++) {
785 for (kk
= 0; kk
< components
; kk
++) {
787 GLshort sshort
[BOX2
];
789 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
790 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
793 sshort
[0]= *(const GLshort
*)src
;
794 sshort
[1]= *(const GLshort
*)(src
+group_size
);
797 *dest
= (sshort
[0] + sshort
[1]) / 2;
801 src
+= group_size
; /* skip to next 2 */
804 int padBytes
= ysize
- (width
*group_size
);
805 src
+= padBytes
; /* for assertion only */
808 else if (width
== 1) { /* 1 column */
809 int padBytes
= ysize
- (width
* group_size
);
810 assert(height
!= 1); /* widthxheight can't be 1x1 */
812 /* one vertical column with possible pad bytes per row */
813 /* average two at a time */
815 for (jj
= 0; jj
< halfHeight
; jj
++) {
817 for (kk
= 0; kk
< components
; kk
++) {
819 GLshort sshort
[BOX2
];
821 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
822 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
825 sshort
[0]= *(const GLshort
*)src
;
826 sshort
[1]= *(const GLshort
*)(src
+ysize
);
828 *dest
= (sshort
[0] + sshort
[1]) / 2;
833 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
837 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
840 assert((char *)dest
== &((char *)dataOut
)
841 [components
* element_size
* halfWidth
* halfHeight
]);
843 } /* halve1Dimage_short() */
846 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
847 const GLuint
*datain
, GLuint
*dataout
,
848 GLint element_size
, GLint ysize
, GLint group_size
,
852 int newwidth
, newheight
;
856 /* handle case where there is only 1 column/row */
857 if (width
== 1 || height
== 1) {
858 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
859 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
860 element_size
,ysize
,group_size
, myswap_bytes
);
864 newwidth
= width
/ 2;
865 newheight
= height
/ 2;
867 t
= (const char *)datain
;
871 for (i
= 0; i
< newheight
; i
++) {
872 for (j
= 0; j
< newwidth
; j
++) {
873 for (k
= 0; k
< components
; k
++) {
874 /* need to cast to double to hold large unsigned ints */
875 s
[0] = ((double)*(const GLuint
*)t
+
876 (double)*(const GLuint
*)(t
+group_size
) +
877 (double)*(const GLuint
*)(t
+ysize
) +
878 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
879 s
++; t
+= element_size
;
887 for (i
= 0; i
< newheight
; i
++) {
888 for (j
= 0; j
< newwidth
; j
++) {
889 for (k
= 0; k
< components
; k
++) {
890 /* need to cast to double to hold large unsigned ints */
892 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
893 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
894 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
895 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
896 s
[0] = (GLuint
)(buf
/4 + 0.5);
898 s
++; t
+= element_size
;
907 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
908 const GLuint
*dataIn
, GLuint
*dataOut
,
909 GLint element_size
, GLint ysize
,
910 GLint group_size
, GLint myswap_bytes
)
912 GLint halfWidth
= width
/ 2;
913 GLint halfHeight
= height
/ 2;
914 const char *src
= (const char *) dataIn
;
915 GLuint
*dest
= dataOut
;
918 assert(width
== 1 || height
== 1); /* must be 1D */
919 assert(width
!= height
); /* can't be square */
921 if (height
== 1) { /* 1 row */
922 assert(width
!= 1); /* widthxheight can't be 1x1 */
925 for (jj
= 0; jj
< halfWidth
; jj
++) {
927 for (kk
= 0; kk
< components
; kk
++) {
931 uint
[0]= __GLU_SWAP_4_BYTES(src
);
932 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
935 uint
[0]= *(const GLuint
*)src
;
936 uint
[1]= *(const GLuint
*)(src
+group_size
);
938 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
943 src
+= group_size
; /* skip to next 2 */
946 int padBytes
= ysize
- (width
*group_size
);
947 src
+= padBytes
; /* for assertion only */
950 else if (width
== 1) { /* 1 column */
951 int padBytes
= ysize
- (width
* group_size
);
952 assert(height
!= 1); /* widthxheight can't be 1x1 */
954 /* one vertical column with possible pad bytes per row */
955 /* average two at a time */
957 for (jj
= 0; jj
< halfHeight
; jj
++) {
959 for (kk
= 0; kk
< components
; kk
++) {
963 uint
[0]= __GLU_SWAP_4_BYTES(src
);
964 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
967 uint
[0]= *(const GLuint
*)src
;
968 uint
[1]= *(const GLuint
*)(src
+ysize
);
970 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
975 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
979 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
982 assert((char *)dest
== &((char *)dataOut
)
983 [components
* element_size
* halfWidth
* halfHeight
]);
985 } /* halve1Dimage_uint() */
987 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
988 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
989 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
992 int newwidth
, newheight
;
996 /* handle case where there is only 1 column/row */
997 if (width
== 1 || height
== 1) {
998 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
999 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1000 element_size
,ysize
,group_size
, myswap_bytes
);
1004 newwidth
= width
/ 2;
1005 newheight
= height
/ 2;
1007 t
= (const char *)datain
;
1009 /* Piece o' cake! */
1011 for (i
= 0; i
< newheight
; i
++) {
1012 for (j
= 0; j
< newwidth
; j
++) {
1013 for (k
= 0; k
< components
; k
++) {
1014 s
[0] = ((float)*(const GLint
*)t
+
1015 (float)*(const GLint
*)(t
+group_size
) +
1016 (float)*(const GLint
*)(t
+ysize
) +
1017 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1018 s
++; t
+= element_size
;
1025 for (i
= 0; i
< newheight
; i
++) {
1026 for (j
= 0; j
< newwidth
; j
++) {
1027 for (k
= 0; k
< components
; k
++) {
1030 b
= __GLU_SWAP_4_BYTES(t
);
1032 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1034 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1036 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1038 s
[0] = (GLint
)(buf
/4 + 0.5);
1040 s
++; t
+= element_size
;
1049 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1050 const GLint
*dataIn
, GLint
*dataOut
,
1051 GLint element_size
, GLint ysize
,
1052 GLint group_size
, GLint myswap_bytes
)
1054 GLint halfWidth
= width
/ 2;
1055 GLint halfHeight
= height
/ 2;
1056 const char *src
= (const char *) dataIn
;
1057 GLint
*dest
= dataOut
;
1060 assert(width
== 1 || height
== 1); /* must be 1D */
1061 assert(width
!= height
); /* can't be square */
1063 if (height
== 1) { /* 1 row */
1064 assert(width
!= 1); /* widthxheight can't be 1x1 */
1067 for (jj
= 0; jj
< halfWidth
; jj
++) {
1069 for (kk
= 0; kk
< components
; kk
++) {
1073 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1074 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1077 uint
[0]= *(const GLuint
*)src
;
1078 uint
[1]= *(const GLuint
*)(src
+group_size
);
1080 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1085 src
+= group_size
; /* skip to next 2 */
1088 int padBytes
= ysize
- (width
*group_size
);
1089 src
+= padBytes
; /* for assertion only */
1092 else if (width
== 1) { /* 1 column */
1093 int padBytes
= ysize
- (width
* group_size
);
1094 assert(height
!= 1); /* widthxheight can't be 1x1 */
1096 /* one vertical column with possible pad bytes per row */
1097 /* average two at a time */
1099 for (jj
= 0; jj
< halfHeight
; jj
++) {
1101 for (kk
= 0; kk
< components
; kk
++) {
1105 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1106 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1109 uint
[0]= *(const GLuint
*)src
;
1110 uint
[1]= *(const GLuint
*)(src
+ysize
);
1112 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1117 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1121 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1124 assert((char *)dest
== &((char *)dataOut
)
1125 [components
* element_size
* halfWidth
* halfHeight
]);
1127 } /* halve1Dimage_int() */
1130 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1131 const GLfloat
*datain
, GLfloat
*dataout
,
1132 GLint element_size
, GLint ysize
, GLint group_size
,
1136 int newwidth
, newheight
;
1140 /* handle case where there is only 1 column/row */
1141 if (width
== 1 || height
== 1) {
1142 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1143 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1144 element_size
,ysize
,group_size
, myswap_bytes
);
1148 newwidth
= width
/ 2;
1149 newheight
= height
/ 2;
1151 t
= (const char *)datain
;
1153 /* Piece o' cake! */
1155 for (i
= 0; i
< newheight
; i
++) {
1156 for (j
= 0; j
< newwidth
; j
++) {
1157 for (k
= 0; k
< components
; k
++) {
1158 s
[0] = (*(const GLfloat
*)t
+
1159 *(const GLfloat
*)(t
+group_size
) +
1160 *(const GLfloat
*)(t
+ysize
) +
1161 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1162 s
++; t
+= element_size
;
1169 for (i
= 0; i
< newheight
; i
++) {
1170 for (j
= 0; j
< newwidth
; j
++) {
1171 for (k
= 0; k
< components
; k
++) {
1172 union { GLuint b
; GLfloat f
; } swapbuf
;
1173 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
);
1175 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1177 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1179 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1182 s
++; t
+= element_size
;
1191 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1192 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1193 GLint element_size
, GLint ysize
,
1194 GLint group_size
, GLint myswap_bytes
)
1196 GLint halfWidth
= width
/ 2;
1197 GLint halfHeight
= height
/ 2;
1198 const char *src
= (const char *) dataIn
;
1199 GLfloat
*dest
= dataOut
;
1202 assert(width
== 1 || height
== 1); /* must be 1D */
1203 assert(width
!= height
); /* can't be square */
1205 if (height
== 1) { /* 1 row */
1206 assert(width
!= 1); /* widthxheight can't be 1x1 */
1209 for (jj
= 0; jj
< halfWidth
; jj
++) {
1211 for (kk
= 0; kk
< components
; kk
++) {
1213 GLfloat sfloat
[BOX2
];
1215 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1216 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1219 sfloat
[0]= *(const GLfloat
*)src
;
1220 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1223 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1227 src
+= group_size
; /* skip to next 2 */
1230 int padBytes
= ysize
- (width
*group_size
);
1231 src
+= padBytes
; /* for assertion only */
1234 else if (width
== 1) { /* 1 column */
1235 int padBytes
= ysize
- (width
* group_size
);
1236 assert(height
!= 1); /* widthxheight can't be 1x1 */
1238 /* one vertical column with possible pad bytes per row */
1239 /* average two at a time */
1241 for (jj
= 0; jj
< halfHeight
; jj
++) {
1243 for (kk
= 0; kk
< components
; kk
++) {
1245 GLfloat sfloat
[BOX2
];
1247 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1248 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1251 sfloat
[0]= *(const GLfloat
*)src
;
1252 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1254 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1259 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1260 src
+= ysize
; /* skip to odd row */
1264 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1265 assert((char *)dest
== &((char *)dataOut
)
1266 [components
* element_size
* halfWidth
* halfHeight
]);
1267 } /* halve1Dimage_float() */
1269 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1270 const GLushort
*datain
,
1271 GLint widthout
, GLint heightout
,
1274 float x
, lowx
, highx
, convx
, halfconvx
;
1275 float y
, lowy
, highy
, convy
, halfconvy
;
1276 float xpercent
,ypercent
;
1278 /* Max components in a format is 4, so... */
1281 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1284 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1285 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1288 convy
= (float) heightin
/heightout
;
1289 convx
= (float) widthin
/widthout
;
1290 halfconvx
= convx
/2;
1291 halfconvy
= convy
/2;
1292 for (i
= 0; i
< heightout
; i
++) {
1293 y
= convy
* (i
+0.5);
1294 if (heightin
> heightout
) {
1295 highy
= y
+ halfconvy
;
1296 lowy
= y
- halfconvy
;
1301 for (j
= 0; j
< widthout
; j
++) {
1302 x
= convx
* (j
+0.5);
1303 if (widthin
> widthout
) {
1304 highx
= x
+ halfconvx
;
1305 lowx
= x
- halfconvx
;
1312 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1313 ** to (highx, highy) on input data into this pixel on output
1316 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1322 yindex
= (yint
+ heightin
) % heightin
;
1323 if (highy
< yint
+1) {
1324 ypercent
= highy
- y
;
1326 ypercent
= yint
+1 - y
;
1333 xindex
= (xint
+ widthin
) % widthin
;
1334 if (highx
< xint
+1) {
1335 xpercent
= highx
- x
;
1337 xpercent
= xint
+1 - x
;
1340 percent
= xpercent
* ypercent
;
1342 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1343 for (k
= 0; k
< components
; k
++) {
1344 totals
[k
] += datain
[temp
+ k
] * percent
;
1354 temp
= (j
+ (i
* widthout
)) * components
;
1355 for (k
= 0; k
< components
; k
++) {
1356 /* totals[] should be rounded in the case of enlarging an RGB
1357 * ramp when the type is 332 or 4444
1359 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1365 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1366 GLint heightin
, const GLubyte
*datain
,
1367 GLint widthout
, GLint heightout
,
1368 GLubyte
*dataout
, GLint element_size
,
1369 GLint ysize
, GLint group_size
)
1374 /* Max components in a format is 4, so... */
1379 const char *temp
, *temp0
;
1380 const char *temp_index
;
1383 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1384 float x_percent
, y_percent
;
1385 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1386 float convy_float
, convx_float
;
1387 int convy_int
, convx_int
;
1389 const char *left
, *right
;
1391 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1392 halveImage_ubyte(components
, widthin
, heightin
,
1393 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1394 element_size
, ysize
, group_size
);
1397 convy
= (float) heightin
/heightout
;
1398 convx
= (float) widthin
/widthout
;
1399 convy_int
= floor(convy
);
1400 convy_float
= convy
- convy_int
;
1401 convx_int
= floor(convx
);
1402 convx_float
= convx
- convx_int
;
1404 area
= convx
* convy
;
1408 highy_int
= convy_int
;
1409 highy_float
= convy_float
;
1411 for (i
= 0; i
< heightout
; i
++) {
1412 /* Clamp here to be sure we don't read beyond input buffer. */
1413 if (highy_int
>= heightin
)
1414 highy_int
= heightin
- 1;
1417 highx_int
= convx_int
;
1418 highx_float
= convx_float
;
1420 for (j
= 0; j
< widthout
; j
++) {
1423 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1424 ** to (highx, highy) on input data into this pixel on output
1427 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1429 /* calculate the value for pixels in the 1st row */
1430 xindex
= lowx_int
*group_size
;
1431 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1433 y_percent
= 1-lowy_float
;
1434 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1435 percent
= y_percent
* (1-lowx_float
);
1436 for (k
= 0, temp_index
= temp
; k
< components
;
1437 k
++, temp_index
+= element_size
) {
1438 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1441 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1443 for (k
= 0, temp_index
= temp
; k
< components
;
1444 k
++, temp_index
+= element_size
) {
1445 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1450 percent
= y_percent
* highx_float
;
1451 for (k
= 0, temp_index
= temp
; k
< components
;
1452 k
++, temp_index
+= element_size
) {
1453 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1456 /* calculate the value for pixels in the last row */
1457 y_percent
= highy_float
;
1458 percent
= y_percent
* (1-lowx_float
);
1459 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1460 for (k
= 0, temp_index
= temp
; k
< components
;
1461 k
++, temp_index
+= element_size
) {
1462 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1464 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1466 for (k
= 0, temp_index
= temp
; k
< components
;
1467 k
++, temp_index
+= element_size
) {
1468 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1472 percent
= y_percent
* highx_float
;
1473 for (k
= 0, temp_index
= temp
; k
< components
;
1474 k
++, temp_index
+= element_size
) {
1475 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1479 /* calculate the value for pixels in the 1st and last column */
1480 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1483 for (k
= 0; k
< components
;
1484 k
++, left
+= element_size
, right
+= element_size
) {
1485 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1486 +(GLubyte
)(*(right
))*highx_float
;
1489 } else if (highy_int
> lowy_int
) {
1490 x_percent
= highx_float
- lowx_float
;
1491 percent
= (1-lowy_float
)*x_percent
;
1492 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1493 for (k
= 0, temp_index
= temp
; k
< components
;
1494 k
++, temp_index
+= element_size
) {
1495 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1497 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1499 for (k
= 0, temp_index
= temp
; k
< components
;
1500 k
++, temp_index
+= element_size
) {
1501 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1504 percent
= x_percent
* highy_float
;
1506 for (k
= 0, temp_index
= temp
; k
< components
;
1507 k
++, temp_index
+= element_size
) {
1508 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1510 } else if (highx_int
> lowx_int
) {
1511 y_percent
= highy_float
- lowy_float
;
1512 percent
= (1-lowx_float
)*y_percent
;
1513 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1514 for (k
= 0, temp_index
= temp
; k
< components
;
1515 k
++, temp_index
+= element_size
) {
1516 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1518 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1520 for (k
= 0, temp_index
= temp
; k
< components
;
1521 k
++, temp_index
+= element_size
) {
1522 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1526 percent
= y_percent
* highx_float
;
1527 for (k
= 0, temp_index
= temp
; k
< components
;
1528 k
++, temp_index
+= element_size
) {
1529 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1532 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1533 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1534 for (k
= 0, temp_index
= temp
; k
< components
;
1535 k
++, temp_index
+= element_size
) {
1536 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1542 /* this is for the pixels in the body */
1543 temp0
= (const char *)datain
+ xindex
+ group_size
+
1545 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1547 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1548 for (k
= 0, temp_index
= temp
; k
< components
;
1549 k
++, temp_index
+= element_size
) {
1550 totals
[k
] += (GLubyte
)(*(temp_index
));
1557 outindex
= (j
+ (i
* widthout
)) * components
;
1558 for (k
= 0; k
< components
; k
++) {
1559 dataout
[outindex
+ k
] = totals
[k
]/area
;
1560 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1562 lowx_int
= highx_int
;
1563 lowx_float
= highx_float
;
1564 highx_int
+= convx_int
;
1565 highx_float
+= convx_float
;
1566 if(highx_float
> 1) {
1571 lowy_int
= highy_int
;
1572 lowy_float
= highy_float
;
1573 highy_int
+= convy_int
;
1574 highy_float
+= convy_float
;
1575 if(highy_float
> 1) {
1582 static void scale_internal_byte(GLint components
, GLint widthin
,
1583 GLint heightin
, const GLbyte
*datain
,
1584 GLint widthout
, GLint heightout
,
1585 GLbyte
*dataout
, GLint element_size
,
1586 GLint ysize
, GLint group_size
)
1591 /* Max components in a format is 4, so... */
1596 const char *temp
, *temp0
;
1597 const char *temp_index
;
1600 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1601 float x_percent
, y_percent
;
1602 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1603 float convy_float
, convx_float
;
1604 int convy_int
, convx_int
;
1606 const char *left
, *right
;
1608 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1609 halveImage_byte(components
, widthin
, heightin
,
1610 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1611 element_size
, ysize
, group_size
);
1614 convy
= (float) heightin
/heightout
;
1615 convx
= (float) widthin
/widthout
;
1616 convy_int
= floor(convy
);
1617 convy_float
= convy
- convy_int
;
1618 convx_int
= floor(convx
);
1619 convx_float
= convx
- convx_int
;
1621 area
= convx
* convy
;
1625 highy_int
= convy_int
;
1626 highy_float
= convy_float
;
1628 for (i
= 0; i
< heightout
; i
++) {
1629 /* Clamp here to be sure we don't read beyond input buffer. */
1630 if (highy_int
>= heightin
)
1631 highy_int
= heightin
- 1;
1634 highx_int
= convx_int
;
1635 highx_float
= convx_float
;
1637 for (j
= 0; j
< widthout
; j
++) {
1640 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1641 ** to (highx, highy) on input data into this pixel on output
1644 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1646 /* calculate the value for pixels in the 1st row */
1647 xindex
= lowx_int
*group_size
;
1648 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1650 y_percent
= 1-lowy_float
;
1651 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1652 percent
= y_percent
* (1-lowx_float
);
1653 for (k
= 0, temp_index
= temp
; k
< components
;
1654 k
++, temp_index
+= element_size
) {
1655 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1658 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1660 for (k
= 0, temp_index
= temp
; k
< components
;
1661 k
++, temp_index
+= element_size
) {
1662 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1667 percent
= y_percent
* highx_float
;
1668 for (k
= 0, temp_index
= temp
; k
< components
;
1669 k
++, temp_index
+= element_size
) {
1670 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1673 /* calculate the value for pixels in the last row */
1674 y_percent
= highy_float
;
1675 percent
= y_percent
* (1-lowx_float
);
1676 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1677 for (k
= 0, temp_index
= temp
; k
< components
;
1678 k
++, temp_index
+= element_size
) {
1679 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1681 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1683 for (k
= 0, temp_index
= temp
; k
< components
;
1684 k
++, temp_index
+= element_size
) {
1685 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1689 percent
= y_percent
* highx_float
;
1690 for (k
= 0, temp_index
= temp
; k
< components
;
1691 k
++, temp_index
+= element_size
) {
1692 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1696 /* calculate the value for pixels in the 1st and last column */
1697 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1700 for (k
= 0; k
< components
;
1701 k
++, left
+= element_size
, right
+= element_size
) {
1702 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1703 +(GLbyte
)(*(right
))*highx_float
;
1706 } else if (highy_int
> lowy_int
) {
1707 x_percent
= highx_float
- lowx_float
;
1708 percent
= (1-lowy_float
)*x_percent
;
1709 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1710 for (k
= 0, temp_index
= temp
; k
< components
;
1711 k
++, temp_index
+= element_size
) {
1712 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1714 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1716 for (k
= 0, temp_index
= temp
; k
< components
;
1717 k
++, temp_index
+= element_size
) {
1718 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1721 percent
= x_percent
* highy_float
;
1723 for (k
= 0, temp_index
= temp
; k
< components
;
1724 k
++, temp_index
+= element_size
) {
1725 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1727 } else if (highx_int
> lowx_int
) {
1728 y_percent
= highy_float
- lowy_float
;
1729 percent
= (1-lowx_float
)*y_percent
;
1730 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1731 for (k
= 0, temp_index
= temp
; k
< components
;
1732 k
++, temp_index
+= element_size
) {
1733 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1735 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1737 for (k
= 0, temp_index
= temp
; k
< components
;
1738 k
++, temp_index
+= element_size
) {
1739 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1743 percent
= y_percent
* highx_float
;
1744 for (k
= 0, temp_index
= temp
; k
< components
;
1745 k
++, temp_index
+= element_size
) {
1746 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1749 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1750 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1751 for (k
= 0, temp_index
= temp
; k
< components
;
1752 k
++, temp_index
+= element_size
) {
1753 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1759 /* this is for the pixels in the body */
1760 temp0
= (const char *)datain
+ xindex
+ group_size
+
1762 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1764 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1765 for (k
= 0, temp_index
= temp
; k
< components
;
1766 k
++, temp_index
+= element_size
) {
1767 totals
[k
] += (GLbyte
)(*(temp_index
));
1774 outindex
= (j
+ (i
* widthout
)) * components
;
1775 for (k
= 0; k
< components
; k
++) {
1776 dataout
[outindex
+ k
] = totals
[k
]/area
;
1777 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1779 lowx_int
= highx_int
;
1780 lowx_float
= highx_float
;
1781 highx_int
+= convx_int
;
1782 highx_float
+= convx_float
;
1783 if(highx_float
> 1) {
1788 lowy_int
= highy_int
;
1789 lowy_float
= highy_float
;
1790 highy_int
+= convy_int
;
1791 highy_float
+= convy_float
;
1792 if(highy_float
> 1) {
1799 static void scale_internal_ushort(GLint components
, GLint widthin
,
1800 GLint heightin
, const GLushort
*datain
,
1801 GLint widthout
, GLint heightout
,
1802 GLushort
*dataout
, GLint element_size
,
1803 GLint ysize
, GLint group_size
,
1809 /* Max components in a format is 4, so... */
1814 const char *temp
, *temp0
;
1815 const char *temp_index
;
1818 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1819 float x_percent
, y_percent
;
1820 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1821 float convy_float
, convx_float
;
1822 int convy_int
, convx_int
;
1824 const char *left
, *right
;
1826 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1827 halveImage_ushort(components
, widthin
, heightin
,
1828 (const GLushort
*)datain
, (GLushort
*)dataout
,
1829 element_size
, ysize
, group_size
, myswap_bytes
);
1832 convy
= (float) heightin
/heightout
;
1833 convx
= (float) widthin
/widthout
;
1834 convy_int
= floor(convy
);
1835 convy_float
= convy
- convy_int
;
1836 convx_int
= floor(convx
);
1837 convx_float
= convx
- convx_int
;
1839 area
= convx
* convy
;
1843 highy_int
= convy_int
;
1844 highy_float
= convy_float
;
1846 for (i
= 0; i
< heightout
; i
++) {
1847 /* Clamp here to be sure we don't read beyond input buffer. */
1848 if (highy_int
>= heightin
)
1849 highy_int
= heightin
- 1;
1852 highx_int
= convx_int
;
1853 highx_float
= convx_float
;
1855 for (j
= 0; j
< widthout
; j
++) {
1857 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1858 ** to (highx, highy) on input data into this pixel on output
1861 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1863 /* calculate the value for pixels in the 1st row */
1864 xindex
= lowx_int
*group_size
;
1865 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1867 y_percent
= 1-lowy_float
;
1868 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1869 percent
= y_percent
* (1-lowx_float
);
1870 for (k
= 0, temp_index
= temp
; k
< components
;
1871 k
++, temp_index
+= element_size
) {
1873 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1875 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1879 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1881 for (k
= 0, temp_index
= temp
; k
< components
;
1882 k
++, temp_index
+= element_size
) {
1885 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1887 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1893 percent
= y_percent
* highx_float
;
1894 for (k
= 0, temp_index
= temp
; k
< components
;
1895 k
++, temp_index
+= element_size
) {
1897 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1899 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1903 /* calculate the value for pixels in the last row */
1904 y_percent
= highy_float
;
1905 percent
= y_percent
* (1-lowx_float
);
1906 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1907 for (k
= 0, temp_index
= temp
; k
< components
;
1908 k
++, temp_index
+= element_size
) {
1910 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1912 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1915 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1917 for (k
= 0, temp_index
= temp
; k
< components
;
1918 k
++, temp_index
+= element_size
) {
1921 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1923 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1928 percent
= y_percent
* highx_float
;
1929 for (k
= 0, temp_index
= temp
; k
< components
;
1930 k
++, temp_index
+= element_size
) {
1932 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1934 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1938 /* calculate the value for pixels in the 1st and last column */
1939 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1942 for (k
= 0; k
< components
;
1943 k
++, left
+= element_size
, right
+= element_size
) {
1946 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1947 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1949 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1950 + *(const GLushort
*)right
* highx_float
;
1954 } else if (highy_int
> lowy_int
) {
1955 x_percent
= highx_float
- lowx_float
;
1956 percent
= (1-lowy_float
)*x_percent
;
1957 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1958 for (k
= 0, temp_index
= temp
; k
< components
;
1959 k
++, temp_index
+= element_size
) {
1961 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1963 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1966 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1968 for (k
= 0, temp_index
= temp
; k
< components
;
1969 k
++, temp_index
+= element_size
) {
1972 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
1974 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
1978 percent
= x_percent
* highy_float
;
1980 for (k
= 0, temp_index
= temp
; k
< components
;
1981 k
++, temp_index
+= element_size
) {
1983 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1985 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1988 } else if (highx_int
> lowx_int
) {
1989 y_percent
= highy_float
- lowy_float
;
1990 percent
= (1-lowx_float
)*y_percent
;
1991 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1992 for (k
= 0, temp_index
= temp
; k
< components
;
1993 k
++, temp_index
+= element_size
) {
1995 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1997 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2000 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2002 for (k
= 0, temp_index
= temp
; k
< components
;
2003 k
++, temp_index
+= element_size
) {
2006 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2008 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2013 percent
= y_percent
* highx_float
;
2014 for (k
= 0, temp_index
= temp
; k
< components
;
2015 k
++, temp_index
+= element_size
) {
2017 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2019 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2023 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2024 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2025 for (k
= 0, temp_index
= temp
; k
< components
;
2026 k
++, temp_index
+= element_size
) {
2028 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2030 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2035 /* this is for the pixels in the body */
2036 temp0
= (const char *)datain
+ xindex
+ group_size
+
2038 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2040 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2041 for (k
= 0, temp_index
= temp
; k
< components
;
2042 k
++, temp_index
+= element_size
) {
2044 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2046 totals
[k
] += *(const GLushort
*)temp_index
;
2054 outindex
= (j
+ (i
* widthout
)) * components
;
2055 for (k
= 0; k
< components
; k
++) {
2056 dataout
[outindex
+ k
] = totals
[k
]/area
;
2057 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2059 lowx_int
= highx_int
;
2060 lowx_float
= highx_float
;
2061 highx_int
+= convx_int
;
2062 highx_float
+= convx_float
;
2063 if(highx_float
> 1) {
2068 lowy_int
= highy_int
;
2069 lowy_float
= highy_float
;
2070 highy_int
+= convy_int
;
2071 highy_float
+= convy_float
;
2072 if(highy_float
> 1) {
2079 static void scale_internal_short(GLint components
, GLint widthin
,
2080 GLint heightin
, const GLshort
*datain
,
2081 GLint widthout
, GLint heightout
,
2082 GLshort
*dataout
, GLint element_size
,
2083 GLint ysize
, GLint group_size
,
2089 /* Max components in a format is 4, so... */
2094 const char *temp
, *temp0
;
2095 const char *temp_index
;
2098 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2099 float x_percent
, y_percent
;
2100 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2101 float convy_float
, convx_float
;
2102 int convy_int
, convx_int
;
2104 const char *left
, *right
;
2106 GLushort swapbuf
; /* unsigned buffer */
2108 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2109 halveImage_short(components
, widthin
, heightin
,
2110 (const GLshort
*)datain
, (GLshort
*)dataout
,
2111 element_size
, ysize
, group_size
, myswap_bytes
);
2114 convy
= (float) heightin
/heightout
;
2115 convx
= (float) widthin
/widthout
;
2116 convy_int
= floor(convy
);
2117 convy_float
= convy
- convy_int
;
2118 convx_int
= floor(convx
);
2119 convx_float
= convx
- convx_int
;
2121 area
= convx
* convy
;
2125 highy_int
= convy_int
;
2126 highy_float
= convy_float
;
2128 for (i
= 0; i
< heightout
; i
++) {
2129 /* Clamp here to be sure we don't read beyond input buffer. */
2130 if (highy_int
>= heightin
)
2131 highy_int
= heightin
- 1;
2134 highx_int
= convx_int
;
2135 highx_float
= convx_float
;
2137 for (j
= 0; j
< widthout
; j
++) {
2139 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2140 ** to (highx, highy) on input data into this pixel on output
2143 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2145 /* calculate the value for pixels in the 1st row */
2146 xindex
= lowx_int
*group_size
;
2147 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2149 y_percent
= 1-lowy_float
;
2150 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2151 percent
= y_percent
* (1-lowx_float
);
2152 for (k
= 0, temp_index
= temp
; k
< components
;
2153 k
++, temp_index
+= element_size
) {
2155 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2156 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2158 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2162 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2164 for (k
= 0, temp_index
= temp
; k
< components
;
2165 k
++, temp_index
+= element_size
) {
2167 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2168 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2170 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2176 percent
= y_percent
* highx_float
;
2177 for (k
= 0, temp_index
= temp
; k
< components
;
2178 k
++, temp_index
+= element_size
) {
2180 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2181 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2183 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2187 /* calculate the value for pixels in the last row */
2188 y_percent
= highy_float
;
2189 percent
= y_percent
* (1-lowx_float
);
2190 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2191 for (k
= 0, temp_index
= temp
; k
< components
;
2192 k
++, temp_index
+= element_size
) {
2194 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2195 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2197 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2200 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2202 for (k
= 0, temp_index
= temp
; k
< components
;
2203 k
++, temp_index
+= element_size
) {
2205 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2206 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2208 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2213 percent
= y_percent
* highx_float
;
2214 for (k
= 0, temp_index
= temp
; k
< components
;
2215 k
++, temp_index
+= element_size
) {
2217 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2218 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2220 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2224 /* calculate the value for pixels in the 1st and last column */
2225 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2228 for (k
= 0; k
< components
;
2229 k
++, left
+= element_size
, right
+= element_size
) {
2231 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2232 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2233 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2234 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2236 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2237 + *(const GLshort
*)right
* highx_float
;
2241 } else if (highy_int
> lowy_int
) {
2242 x_percent
= highx_float
- lowx_float
;
2243 percent
= (1-lowy_float
)*x_percent
;
2244 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2245 for (k
= 0, temp_index
= temp
; k
< components
;
2246 k
++, temp_index
+= element_size
) {
2248 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2249 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2251 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2254 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2256 for (k
= 0, temp_index
= temp
; k
< components
;
2257 k
++, temp_index
+= element_size
) {
2259 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2260 totals
[k
] += *(const GLshort
*)&swapbuf
* x_percent
;
2262 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2266 percent
= x_percent
* highy_float
;
2268 for (k
= 0, temp_index
= temp
; k
< components
;
2269 k
++, temp_index
+= element_size
) {
2271 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2272 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2274 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2277 } else if (highx_int
> lowx_int
) {
2278 y_percent
= highy_float
- lowy_float
;
2279 percent
= (1-lowx_float
)*y_percent
;
2281 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2282 for (k
= 0, temp_index
= temp
; k
< components
;
2283 k
++, temp_index
+= element_size
) {
2285 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2286 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2288 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2291 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2293 for (k
= 0, temp_index
= temp
; k
< components
;
2294 k
++, temp_index
+= element_size
) {
2296 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2297 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2299 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2304 percent
= y_percent
* highx_float
;
2305 for (k
= 0, temp_index
= temp
; k
< components
;
2306 k
++, temp_index
+= element_size
) {
2308 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2309 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2311 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2315 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2316 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2317 for (k
= 0, temp_index
= temp
; k
< components
;
2318 k
++, temp_index
+= element_size
) {
2320 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2321 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2323 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2328 /* this is for the pixels in the body */
2329 temp0
= (const char *)datain
+ xindex
+ group_size
+
2331 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2333 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2334 for (k
= 0, temp_index
= temp
; k
< components
;
2335 k
++, temp_index
+= element_size
) {
2337 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2338 totals
[k
] += *(const GLshort
*)&swapbuf
;
2340 totals
[k
] += *(const GLshort
*)temp_index
;
2348 outindex
= (j
+ (i
* widthout
)) * components
;
2349 for (k
= 0; k
< components
; k
++) {
2350 dataout
[outindex
+ k
] = totals
[k
]/area
;
2351 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2353 lowx_int
= highx_int
;
2354 lowx_float
= highx_float
;
2355 highx_int
+= convx_int
;
2356 highx_float
+= convx_float
;
2357 if(highx_float
> 1) {
2362 lowy_int
= highy_int
;
2363 lowy_float
= highy_float
;
2364 highy_int
+= convy_int
;
2365 highy_float
+= convy_float
;
2366 if(highy_float
> 1) {
2373 static void scale_internal_uint(GLint components
, GLint widthin
,
2374 GLint heightin
, const GLuint
*datain
,
2375 GLint widthout
, GLint heightout
,
2376 GLuint
*dataout
, GLint element_size
,
2377 GLint ysize
, GLint group_size
,
2383 /* Max components in a format is 4, so... */
2388 const char *temp
, *temp0
;
2389 const char *temp_index
;
2392 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2393 float x_percent
, y_percent
;
2394 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2395 float convy_float
, convx_float
;
2396 int convy_int
, convx_int
;
2398 const char *left
, *right
;
2400 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2401 halveImage_uint(components
, widthin
, heightin
,
2402 (const GLuint
*)datain
, (GLuint
*)dataout
,
2403 element_size
, ysize
, group_size
, myswap_bytes
);
2406 convy
= (float) heightin
/heightout
;
2407 convx
= (float) widthin
/widthout
;
2408 convy_int
= floor(convy
);
2409 convy_float
= convy
- convy_int
;
2410 convx_int
= floor(convx
);
2411 convx_float
= convx
- convx_int
;
2413 area
= convx
* convy
;
2417 highy_int
= convy_int
;
2418 highy_float
= convy_float
;
2420 for (i
= 0; i
< heightout
; i
++) {
2421 /* Clamp here to be sure we don't read beyond input buffer. */
2422 if (highy_int
>= heightin
)
2423 highy_int
= heightin
- 1;
2426 highx_int
= convx_int
;
2427 highx_float
= convx_float
;
2429 for (j
= 0; j
< widthout
; j
++) {
2431 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2432 ** to (highx, highy) on input data into this pixel on output
2435 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2437 /* calculate the value for pixels in the 1st row */
2438 xindex
= lowx_int
*group_size
;
2439 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2441 y_percent
= 1-lowy_float
;
2442 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2443 percent
= y_percent
* (1-lowx_float
);
2444 for (k
= 0, temp_index
= temp
; k
< components
;
2445 k
++, temp_index
+= element_size
) {
2447 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2449 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2453 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2455 for (k
= 0, temp_index
= temp
; k
< components
;
2456 k
++, temp_index
+= element_size
) {
2459 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2461 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2467 percent
= y_percent
* highx_float
;
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
;
2477 /* calculate the value for pixels in the last row */
2478 y_percent
= highy_float
;
2479 percent
= y_percent
* (1-lowx_float
);
2480 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2481 for (k
= 0, temp_index
= temp
; k
< components
;
2482 k
++, temp_index
+= element_size
) {
2484 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2486 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2489 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2491 for (k
= 0, temp_index
= temp
; k
< components
;
2492 k
++, temp_index
+= element_size
) {
2495 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2497 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2502 percent
= y_percent
* highx_float
;
2503 for (k
= 0, temp_index
= temp
; k
< components
;
2504 k
++, temp_index
+= element_size
) {
2506 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2508 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2512 /* calculate the value for pixels in the 1st and last column */
2513 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2516 for (k
= 0; k
< components
;
2517 k
++, left
+= element_size
, right
+= element_size
) {
2520 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2521 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2523 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2524 + *(const GLuint
*)right
* highx_float
;
2528 } else if (highy_int
> lowy_int
) {
2529 x_percent
= highx_float
- lowx_float
;
2530 percent
= (1-lowy_float
)*x_percent
;
2531 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2532 for (k
= 0, temp_index
= temp
; k
< components
;
2533 k
++, temp_index
+= element_size
) {
2535 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2537 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2540 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2542 for (k
= 0, temp_index
= temp
; k
< components
;
2543 k
++, temp_index
+= element_size
) {
2546 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2548 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2552 percent
= x_percent
* highy_float
;
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 } else if (highx_int
> lowx_int
) {
2563 y_percent
= highy_float
- lowy_float
;
2564 percent
= (1-lowx_float
)*y_percent
;
2566 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2567 for (k
= 0, temp_index
= temp
; k
< components
;
2568 k
++, temp_index
+= element_size
) {
2570 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2572 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2575 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2577 for (k
= 0, temp_index
= temp
; k
< components
;
2578 k
++, temp_index
+= element_size
) {
2581 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2583 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2588 percent
= y_percent
* highx_float
;
2589 for (k
= 0, temp_index
= temp
; k
< components
;
2590 k
++, temp_index
+= element_size
) {
2592 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2594 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2598 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2599 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2600 for (k
= 0, temp_index
= temp
; k
< components
;
2601 k
++, temp_index
+= element_size
) {
2603 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2605 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2610 /* this is for the pixels in the body */
2611 temp0
= (const char *)datain
+ xindex
+ group_size
+
2613 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2615 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2616 for (k
= 0, temp_index
= temp
; k
< components
;
2617 k
++, temp_index
+= element_size
) {
2619 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2621 totals
[k
] += *(const GLuint
*)temp_index
;
2629 outindex
= (j
+ (i
* widthout
)) * components
;
2630 for (k
= 0; k
< components
; k
++) {
2631 /* clamp at UINT_MAX */
2632 float value
= totals
[k
]/area
;
2633 if (value
>= (float) UINT_MAX
) { /* need '=' */
2634 dataout
[outindex
+ k
] = UINT_MAX
;
2636 else dataout
[outindex
+ k
] = value
;
2638 lowx_int
= highx_int
;
2639 lowx_float
= highx_float
;
2640 highx_int
+= convx_int
;
2641 highx_float
+= convx_float
;
2642 if(highx_float
> 1) {
2647 lowy_int
= highy_int
;
2648 lowy_float
= highy_float
;
2649 highy_int
+= convy_int
;
2650 highy_float
+= convy_float
;
2651 if(highy_float
> 1) {
2660 static void scale_internal_int(GLint components
, GLint widthin
,
2661 GLint heightin
, const GLint
*datain
,
2662 GLint widthout
, GLint heightout
,
2663 GLint
*dataout
, GLint element_size
,
2664 GLint ysize
, GLint group_size
,
2670 /* Max components in a format is 4, so... */
2675 const char *temp
, *temp0
;
2676 const char *temp_index
;
2679 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2680 float x_percent
, y_percent
;
2681 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2682 float convy_float
, convx_float
;
2683 int convy_int
, convx_int
;
2685 const char *left
, *right
;
2687 GLuint swapbuf
; /* unsigned buffer */
2689 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2690 halveImage_int(components
, widthin
, heightin
,
2691 (const GLint
*)datain
, (GLint
*)dataout
,
2692 element_size
, ysize
, group_size
, myswap_bytes
);
2695 convy
= (float) heightin
/heightout
;
2696 convx
= (float) widthin
/widthout
;
2697 convy_int
= floor(convy
);
2698 convy_float
= convy
- convy_int
;
2699 convx_int
= floor(convx
);
2700 convx_float
= convx
- convx_int
;
2702 area
= convx
* convy
;
2706 highy_int
= convy_int
;
2707 highy_float
= convy_float
;
2709 for (i
= 0; i
< heightout
; i
++) {
2710 /* Clamp here to be sure we don't read beyond input buffer. */
2711 if (highy_int
>= heightin
)
2712 highy_int
= heightin
- 1;
2715 highx_int
= convx_int
;
2716 highx_float
= convx_float
;
2718 for (j
= 0; j
< widthout
; j
++) {
2720 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2721 ** to (highx, highy) on input data into this pixel on output
2724 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2726 /* calculate the value for pixels in the 1st row */
2727 xindex
= lowx_int
*group_size
;
2728 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2730 y_percent
= 1-lowy_float
;
2731 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2732 percent
= y_percent
* (1-lowx_float
);
2733 for (k
= 0, temp_index
= temp
; k
< components
;
2734 k
++, temp_index
+= element_size
) {
2736 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2737 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2739 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2743 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2745 for (k
= 0, temp_index
= temp
; k
< components
;
2746 k
++, temp_index
+= element_size
) {
2748 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2749 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2751 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2757 percent
= y_percent
* highx_float
;
2758 for (k
= 0, temp_index
= temp
; k
< components
;
2759 k
++, temp_index
+= element_size
) {
2761 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2762 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2764 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2768 /* calculate the value for pixels in the last row */
2769 y_percent
= highy_float
;
2770 percent
= y_percent
* (1-lowx_float
);
2771 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2772 for (k
= 0, temp_index
= temp
; k
< components
;
2773 k
++, temp_index
+= element_size
) {
2775 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2776 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2778 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2781 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2783 for (k
= 0, temp_index
= temp
; k
< components
;
2784 k
++, temp_index
+= element_size
) {
2786 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2787 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2789 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2794 percent
= y_percent
* highx_float
;
2795 for (k
= 0, temp_index
= temp
; k
< components
;
2796 k
++, temp_index
+= element_size
) {
2798 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2799 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2801 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2805 /* calculate the value for pixels in the 1st and last column */
2806 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2809 for (k
= 0; k
< components
;
2810 k
++, left
+= element_size
, right
+= element_size
) {
2812 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2813 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2814 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2815 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2817 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2818 + *(const GLint
*)right
* highx_float
;
2822 } else if (highy_int
> lowy_int
) {
2823 x_percent
= highx_float
- lowx_float
;
2824 percent
= (1-lowy_float
)*x_percent
;
2825 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2826 for (k
= 0, temp_index
= temp
; k
< components
;
2827 k
++, temp_index
+= element_size
) {
2829 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2830 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2832 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2835 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2837 for (k
= 0, temp_index
= temp
; k
< components
;
2838 k
++, temp_index
+= element_size
) {
2840 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2841 totals
[k
] += *(const GLint
*)&swapbuf
* x_percent
;
2843 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2847 percent
= x_percent
* highy_float
;
2849 for (k
= 0, temp_index
= temp
; k
< components
;
2850 k
++, temp_index
+= element_size
) {
2852 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2853 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2855 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2858 } else if (highx_int
> lowx_int
) {
2859 y_percent
= highy_float
- lowy_float
;
2860 percent
= (1-lowx_float
)*y_percent
;
2862 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2863 for (k
= 0, temp_index
= temp
; k
< components
;
2864 k
++, temp_index
+= element_size
) {
2866 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2867 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2869 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2872 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2874 for (k
= 0, temp_index
= temp
; k
< components
;
2875 k
++, temp_index
+= element_size
) {
2877 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2878 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2880 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2885 percent
= y_percent
* highx_float
;
2886 for (k
= 0, temp_index
= temp
; k
< components
;
2887 k
++, temp_index
+= element_size
) {
2889 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2890 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2892 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2896 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2897 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2898 for (k
= 0, temp_index
= temp
; k
< components
;
2899 k
++, temp_index
+= element_size
) {
2901 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2902 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2904 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2909 /* this is for the pixels in the body */
2910 temp0
= (const char *)datain
+ xindex
+ group_size
+
2912 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2914 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2915 for (k
= 0, temp_index
= temp
; k
< components
;
2916 k
++, temp_index
+= element_size
) {
2918 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2919 totals
[k
] += *(const GLint
*)&swapbuf
;
2921 totals
[k
] += *(const GLint
*)temp_index
;
2929 outindex
= (j
+ (i
* widthout
)) * components
;
2930 for (k
= 0; k
< components
; k
++) {
2931 dataout
[outindex
+ k
] = totals
[k
]/area
;
2932 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2934 lowx_int
= highx_int
;
2935 lowx_float
= highx_float
;
2936 highx_int
+= convx_int
;
2937 highx_float
+= convx_float
;
2938 if(highx_float
> 1) {
2943 lowy_int
= highy_int
;
2944 lowy_float
= highy_float
;
2945 highy_int
+= convy_int
;
2946 highy_float
+= convy_float
;
2947 if(highy_float
> 1) {
2956 static void scale_internal_float(GLint components
, GLint widthin
,
2957 GLint heightin
, const GLfloat
*datain
,
2958 GLint widthout
, GLint heightout
,
2959 GLfloat
*dataout
, GLint element_size
,
2960 GLint ysize
, GLint group_size
,
2966 /* Max components in a format is 4, so... */
2971 const char *temp
, *temp0
;
2972 const char *temp_index
;
2975 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2976 float x_percent
, y_percent
;
2977 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2978 float convy_float
, convx_float
;
2979 int convy_int
, convx_int
;
2981 const char *left
, *right
;
2983 union { GLuint b
; GLfloat f
; } swapbuf
;
2985 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2986 halveImage_float(components
, widthin
, heightin
,
2987 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
2988 element_size
, ysize
, group_size
, myswap_bytes
);
2991 convy
= (float) heightin
/heightout
;
2992 convx
= (float) widthin
/widthout
;
2993 convy_int
= floor(convy
);
2994 convy_float
= convy
- convy_int
;
2995 convx_int
= floor(convx
);
2996 convx_float
= convx
- convx_int
;
2998 area
= convx
* convy
;
3002 highy_int
= convy_int
;
3003 highy_float
= convy_float
;
3005 for (i
= 0; i
< heightout
; i
++) {
3006 /* Clamp here to be sure we don't read beyond input buffer. */
3007 if (highy_int
>= heightin
)
3008 highy_int
= heightin
- 1;
3011 highx_int
= convx_int
;
3012 highx_float
= convx_float
;
3014 for (j
= 0; j
< widthout
; j
++) {
3016 ** Ok, now apply box filter to box that goes from (lowx, lowy)
3017 ** to (highx, highy) on input data into this pixel on output
3020 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3022 /* calculate the value for pixels in the 1st row */
3023 xindex
= lowx_int
*group_size
;
3024 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3026 y_percent
= 1-lowy_float
;
3027 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3028 percent
= y_percent
* (1-lowx_float
);
3029 for (k
= 0, temp_index
= temp
; k
< components
;
3030 k
++, temp_index
+= element_size
) {
3032 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3033 totals
[k
] += swapbuf
.f
* percent
;
3035 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3039 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3041 for (k
= 0, temp_index
= temp
; k
< components
;
3042 k
++, temp_index
+= element_size
) {
3044 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3045 totals
[k
] += swapbuf
.f
* y_percent
;
3047 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3053 percent
= y_percent
* highx_float
;
3054 for (k
= 0, temp_index
= temp
; k
< components
;
3055 k
++, temp_index
+= element_size
) {
3057 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3058 totals
[k
] += swapbuf
.f
* percent
;
3060 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3064 /* calculate the value for pixels in the last row */
3065 y_percent
= highy_float
;
3066 percent
= y_percent
* (1-lowx_float
);
3067 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3068 for (k
= 0, temp_index
= temp
; k
< components
;
3069 k
++, temp_index
+= element_size
) {
3071 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3072 totals
[k
] += swapbuf
.f
* percent
;
3074 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3077 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3079 for (k
= 0, temp_index
= temp
; k
< components
;
3080 k
++, temp_index
+= element_size
) {
3082 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3083 totals
[k
] += swapbuf
.f
* y_percent
;
3085 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3090 percent
= y_percent
* highx_float
;
3091 for (k
= 0, temp_index
= temp
; k
< components
;
3092 k
++, temp_index
+= element_size
) {
3094 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3095 totals
[k
] += swapbuf
.f
* percent
;
3097 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3101 /* calculate the value for pixels in the 1st and last column */
3102 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3105 for (k
= 0; k
< components
;
3106 k
++, left
+= element_size
, right
+= element_size
) {
3108 swapbuf
.b
= __GLU_SWAP_4_BYTES(left
);
3109 totals
[k
] += swapbuf
.f
* (1-lowx_float
);
3110 swapbuf
.b
= __GLU_SWAP_4_BYTES(right
);
3111 totals
[k
] += swapbuf
.f
* highx_float
;
3113 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3114 + *(const GLfloat
*)right
* highx_float
;
3118 } else if (highy_int
> lowy_int
) {
3119 x_percent
= highx_float
- lowx_float
;
3120 percent
= (1-lowy_float
)*x_percent
;
3121 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3122 for (k
= 0, temp_index
= temp
; k
< components
;
3123 k
++, temp_index
+= element_size
) {
3125 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3126 totals
[k
] += swapbuf
.f
* percent
;
3128 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3131 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3133 for (k
= 0, temp_index
= temp
; k
< components
;
3134 k
++, temp_index
+= element_size
) {
3136 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3137 totals
[k
] += swapbuf
.f
* x_percent
;
3139 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3143 percent
= x_percent
* highy_float
;
3145 for (k
= 0, temp_index
= temp
; k
< components
;
3146 k
++, temp_index
+= element_size
) {
3148 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3149 totals
[k
] += swapbuf
.f
* percent
;
3151 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3154 } else if (highx_int
> lowx_int
) {
3155 y_percent
= highy_float
- lowy_float
;
3156 percent
= (1-lowx_float
)*y_percent
;
3158 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3159 for (k
= 0, temp_index
= temp
; k
< components
;
3160 k
++, temp_index
+= element_size
) {
3162 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3163 totals
[k
] += swapbuf
.f
* percent
;
3165 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3168 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3170 for (k
= 0, temp_index
= temp
; k
< components
;
3171 k
++, temp_index
+= element_size
) {
3173 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3174 totals
[k
] += swapbuf
.f
* y_percent
;
3176 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3181 percent
= y_percent
* highx_float
;
3182 for (k
= 0, temp_index
= temp
; k
< components
;
3183 k
++, temp_index
+= element_size
) {
3185 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3186 totals
[k
] += swapbuf
.f
* percent
;
3188 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3192 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3193 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3194 for (k
= 0, temp_index
= temp
; k
< components
;
3195 k
++, temp_index
+= element_size
) {
3197 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3198 totals
[k
] += swapbuf
.f
* percent
;
3200 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3205 /* this is for the pixels in the body */
3206 temp0
= (const char *)datain
+ xindex
+ group_size
+
3208 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3210 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3211 for (k
= 0, temp_index
= temp
; k
< components
;
3212 k
++, temp_index
+= element_size
) {
3214 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3215 totals
[k
] += swapbuf
.f
;
3217 totals
[k
] += *(const GLfloat
*)temp_index
;
3225 outindex
= (j
+ (i
* widthout
)) * components
;
3226 for (k
= 0; k
< components
; k
++) {
3227 dataout
[outindex
+ k
] = totals
[k
]/area
;
3228 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3230 lowx_int
= highx_int
;
3231 lowx_float
= highx_float
;
3232 highx_int
+= convx_int
;
3233 highx_float
+= convx_float
;
3234 if(highx_float
> 1) {
3239 lowy_int
= highy_int
;
3240 lowy_float
= highy_float
;
3241 highy_int
+= convy_int
;
3242 highy_float
+= convy_float
;
3243 if(highy_float
> 1) {
3250 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3252 if (!legalFormat(format
) || !legalType(type
)) {
3253 return GLU_INVALID_ENUM
;
3255 if (format
== GL_STENCIL_INDEX
) {
3256 return GLU_INVALID_ENUM
;
3259 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3260 return GLU_INVALID_OPERATION
;
3264 } /* checkMipmapArgs() */
3266 static GLboolean
legalFormat(GLenum format
)
3269 case GL_COLOR_INDEX
:
3270 case GL_STENCIL_INDEX
:
3271 case GL_DEPTH_COMPONENT
:
3279 case GL_LUMINANCE_ALPHA
:
3289 static GLboolean
legalType(GLenum type
)
3294 case GL_UNSIGNED_BYTE
:
3296 case GL_UNSIGNED_SHORT
:
3298 case GL_UNSIGNED_INT
:
3300 case GL_UNSIGNED_BYTE_3_3_2
:
3301 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3302 case GL_UNSIGNED_SHORT_5_6_5
:
3303 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3304 case GL_UNSIGNED_SHORT_4_4_4_4
:
3305 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3306 case GL_UNSIGNED_SHORT_5_5_5_1
:
3307 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3308 case GL_UNSIGNED_INT_8_8_8_8
:
3309 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3310 case GL_UNSIGNED_INT_10_10_10_2
:
3311 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3319 static GLboolean
isTypePackedPixel(GLenum type
)
3321 assert(legalType(type
));
3323 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3324 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3325 type
== GL_UNSIGNED_SHORT_5_6_5
||
3326 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3327 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3328 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3329 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3330 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3331 type
== GL_UNSIGNED_INT_8_8_8_8
||
3332 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3333 type
== GL_UNSIGNED_INT_10_10_10_2
||
3334 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3338 } /* isTypePackedPixel() */
3340 /* Determines if the packed pixel type is compatible with the format */
3341 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3343 /* if not a packed pixel type then return true */
3344 if (!isTypePackedPixel(type
)) {
3348 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3349 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3350 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3351 && format
!= GL_RGB
)
3354 /* 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 &
3355 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3357 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3358 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3359 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3360 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3361 type
== GL_UNSIGNED_INT_8_8_8_8
||
3362 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3363 type
== GL_UNSIGNED_INT_10_10_10_2
||
3364 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3365 (format
!= GL_RGBA
&&
3366 format
!= GL_BGRA
)) {
3371 } /* isLegalFormatForPackedPixelType() */
3373 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3376 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3377 totalLevels
< maxLevel
)
3379 else return GL_TRUE
;
3380 } /* isLegalLevels() */
3382 /* Given user requested texture size, determine if it fits. If it
3383 * doesn't then halve both sides and make the determination again
3384 * until it does fit (for IR only).
3385 * Note that proxy textures are not implemented in RE* even though
3386 * they advertise the texture extension.
3387 * Note that proxy textures are implemented but not according to spec in
3390 static void closestFit(GLenum target
, GLint width
, GLint height
,
3391 GLint internalFormat
, GLenum format
, GLenum type
,
3392 GLint
*newWidth
, GLint
*newHeight
)
3394 /* Use proxy textures if OpenGL version is >= 1.1 */
3395 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3397 GLint widthPowerOf2
= nearestPower(width
);
3398 GLint heightPowerOf2
= nearestPower(height
);
3402 /* compute level 1 width & height, clamping each at 1 */
3403 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3404 widthPowerOf2
>> 1 :
3406 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3407 heightPowerOf2
>> 1 :
3410 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3412 /* does width x height at level 1 & all their mipmaps fit? */
3413 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3414 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3415 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3417 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3419 #if defined(GL_ARB_texture_cube_map)
3420 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3421 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3422 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3423 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3424 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3425 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3426 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3427 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3429 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3431 #endif /* GL_ARB_texture_cube_map */
3433 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3434 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3435 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3436 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3438 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3439 /* does it fit??? */
3440 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3441 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3442 /* An 1x1 texture couldn't fit for some reason, so
3443 * break out. This should never happen. But things
3444 * happen. The disadvantage with this if-statement is
3445 * that we will never be aware of when this happens
3446 * since it will silently branch out.
3448 goto noProxyTextures
;
3450 widthPowerOf2
= widthAtLevelOne
;
3451 heightPowerOf2
= heightAtLevelOne
;
3453 /* else it does fit */
3454 } while (proxyWidth
== 0);
3455 /* loop must terminate! */
3457 /* return the width & height at level 0 that fits */
3458 *newWidth
= widthPowerOf2
;
3459 *newHeight
= heightPowerOf2
;
3460 /*printf("Proxy Textures\n");*/
3461 } /* if gluCheckExtension() */
3462 else { /* no texture extension, so do this instead */
3467 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3468 /* clamp user's texture sizes to maximum sizes, if necessary */
3469 *newWidth
= nearestPower(width
);
3470 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3471 *newHeight
= nearestPower(height
);
3472 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3473 /*printf("NO proxy textures\n");*/
3475 } /* closestFit() */
3478 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3479 GLenum typein
, const void *datain
,
3480 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3484 GLushort
*beforeImage
;
3485 GLushort
*afterImage
;
3486 PixelStorageModes psm
;
3488 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3491 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3492 return GLU_INVALID_VALUE
;
3494 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3495 return GLU_INVALID_ENUM
;
3497 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3498 return GLU_INVALID_OPERATION
;
3500 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3501 return GLU_INVALID_OPERATION
;
3504 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3506 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3507 if (beforeImage
== NULL
|| afterImage
== NULL
) {
3508 return GLU_OUT_OF_MEMORY
;
3511 retrieveStoreModes(&psm
);
3512 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3513 datain
, beforeImage
);
3514 components
= elements_per_group(format
, 0);
3515 scale_internal(components
, widthin
, heightin
, beforeImage
,
3516 widthout
, heightout
, afterImage
);
3517 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3518 is_index(format
), afterImage
, dataout
);
3519 free((GLbyte
*) beforeImage
);
3520 free((GLbyte
*) afterImage
);
3525 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3527 GLsizei widthPowerOf2
,
3528 GLenum format
, GLenum type
,
3529 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3533 GLint level
, levels
;
3535 GLint newImage_width
;
3536 GLushort
*otherImage
;
3537 GLushort
*imageTemp
;
3540 PixelStorageModes psm
;
3542 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3547 newwidth
= widthPowerOf2
;
3548 levels
= computeLog(newwidth
);
3552 retrieveStoreModes(&psm
);
3553 newImage
= (GLushort
*)
3554 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3555 newImage_width
= width
;
3556 if (newImage
== NULL
) {
3557 return GLU_OUT_OF_MEMORY
;
3559 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3561 cmpts
= elements_per_group(format
,type
);
3562 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3563 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3564 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3565 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3567 ** If swap_bytes was set, swapping occurred in fill_image.
3569 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3571 for (level
= userLevel
; level
<= levels
; level
++) {
3572 if (newImage_width
== newwidth
) {
3573 /* Use newImage for this level */
3574 if (baseLevel
<= level
&& level
<= maxLevel
) {
3575 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3576 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3579 if (otherImage
== NULL
) {
3580 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3581 otherImage
= (GLushort
*) malloc(memreq
);
3582 if (otherImage
== NULL
) {
3583 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3584 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3585 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3586 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3587 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3588 return GLU_OUT_OF_MEMORY
;
3591 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3592 newwidth
, 1, otherImage
);
3593 /* Swap newImage and otherImage */
3594 imageTemp
= otherImage
;
3595 otherImage
= newImage
;
3596 newImage
= imageTemp
;
3598 newImage_width
= newwidth
;
3599 if (baseLevel
<= level
&& level
<= maxLevel
) {
3600 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3601 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3604 if (newwidth
> 1) newwidth
/= 2;
3606 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3607 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3608 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3609 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3610 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3612 free((GLbyte
*) newImage
);
3614 free((GLbyte
*) otherImage
);
3620 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3622 GLenum format
, GLenum type
,
3623 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3628 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3629 if (rc
!= 0) return rc
;
3632 return GLU_INVALID_VALUE
;
3635 levels
= computeLog(width
);
3638 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3639 return GLU_INVALID_VALUE
;
3641 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3644 userLevel
, baseLevel
, maxLevel
,
3646 } /* gluBuild1DMipmapLevels() */
3649 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3650 GLenum format
, GLenum type
,
3653 GLint widthPowerOf2
;
3657 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3658 if (rc
!= 0) return rc
;
3661 return GLU_INVALID_VALUE
;
3664 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3665 levels
= computeLog(widthPowerOf2
);
3667 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3670 format
,type
,0,0,levels
,data
);
3673 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3674 GLint width
, GLint height
, GLenum format
,
3675 GLenum type
, const void *data
)
3677 GLint newwidth
, newheight
;
3678 GLint level
, levels
;
3680 GLint newImage_width
;
3681 GLint newImage_height
;
3682 GLushort
*otherImage
;
3683 GLushort
*imageTemp
;
3686 PixelStorageModes psm
;
3688 retrieveStoreModes(&psm
);
3691 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3692 newwidth
= nearestPower(width
);
3693 if (newwidth
> maxsize
) newwidth
= maxsize
;
3694 newheight
= nearestPower(height
);
3695 if (newheight
> maxsize
) newheight
= maxsize
;
3697 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3698 &newwidth
,&newheight
);
3700 levels
= computeLog(newwidth
);
3701 level
= computeLog(newheight
);
3702 if (level
> levels
) levels
=level
;
3705 newImage
= (GLushort
*)
3706 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3707 newImage_width
= width
;
3708 newImage_height
= height
;
3709 if (newImage
== NULL
) {
3710 return GLU_OUT_OF_MEMORY
;
3713 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3716 cmpts
= elements_per_group(format
,type
);
3717 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3718 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3719 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3720 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3722 ** If swap_bytes was set, swapping occurred in fill_image.
3724 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3726 for (level
= 0; level
<= levels
; level
++) {
3727 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3728 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3729 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3732 if (otherImage
== NULL
) {
3734 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3735 otherImage
= (GLushort
*) malloc(memreq
);
3736 if (otherImage
== NULL
) {
3737 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3738 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3739 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3740 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3741 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3742 return GLU_OUT_OF_MEMORY
;
3745 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3746 newwidth
, newheight
, otherImage
);
3747 /* Swap newImage and otherImage */
3748 imageTemp
= otherImage
;
3749 otherImage
= newImage
;
3750 newImage
= imageTemp
;
3752 newImage_width
= newwidth
;
3753 newImage_height
= newheight
;
3754 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3755 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3758 if (newwidth
> 1) newwidth
/= 2;
3759 if (newheight
> 1) newheight
/= 2;
3761 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3762 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3763 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3764 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3765 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3767 free((GLbyte
*) newImage
);
3769 free((GLbyte
*) otherImage
);
3774 /* To make swapping images less error prone */
3775 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3776 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3778 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3779 GLsizei width
, GLsizei height
,
3780 GLsizei widthPowerOf2
,
3781 GLsizei heightPowerOf2
,
3782 GLenum format
, GLenum type
,
3784 GLint baseLevel
,GLint maxLevel
,
3787 GLint newwidth
, newheight
;
3788 GLint level
, levels
;
3789 const void *usersImage
; /* passed from user. Don't touch! */
3790 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3791 __GLU_INIT_SWAP_IMAGE
;
3795 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3796 GLint rowsize
, padding
;
3797 PixelStorageModes psm
;
3799 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3800 assert(width
>= 1 && height
>= 1);
3802 if(type
== GL_BITMAP
) {
3803 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3804 format
, type
, data
);
3807 srcImage
= dstImage
= NULL
;
3809 newwidth
= widthPowerOf2
;
3810 newheight
= heightPowerOf2
;
3811 levels
= computeLog(newwidth
);
3812 level
= computeLog(newheight
);
3813 if (level
> levels
) levels
=level
;
3817 retrieveStoreModes(&psm
);
3818 myswap_bytes
= psm
.unpack_swap_bytes
;
3819 cmpts
= elements_per_group(format
,type
);
3820 if (psm
.unpack_row_length
> 0) {
3821 groups_per_line
= psm
.unpack_row_length
;
3823 groups_per_line
= width
;
3826 element_size
= bytes_per_element(type
);
3827 group_size
= element_size
* cmpts
;
3828 if (element_size
== 1) myswap_bytes
= 0;
3830 rowsize
= groups_per_line
* group_size
;
3831 padding
= (rowsize
% psm
.unpack_alignment
);
3833 rowsize
+= psm
.unpack_alignment
- padding
;
3835 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3836 psm
.unpack_skip_pixels
* group_size
;
3838 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3839 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3840 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3844 /* already power-of-two square */
3845 if (width
== newwidth
&& height
== newheight
) {
3846 /* Use usersImage for level userLevel */
3847 if (baseLevel
<= level
&& level
<= maxLevel
) {
3848 glTexImage2D(target
, level
, internalFormat
, width
,
3849 height
, 0, format
, type
,
3852 if(levels
== 0) { /* we're done. clean up and return */
3853 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3854 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3855 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3856 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3857 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3861 int nextWidth
= newwidth
/2;
3862 int nextHeight
= newheight
/2;
3865 if (nextWidth
< 1) nextWidth
= 1;
3866 if (nextHeight
< 1) nextHeight
= 1;
3867 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3871 case GL_UNSIGNED_BYTE
:
3872 dstImage
= (GLubyte
*)malloc(memreq
);
3875 dstImage
= (GLbyte
*)malloc(memreq
);
3877 case GL_UNSIGNED_SHORT
:
3878 dstImage
= (GLushort
*)malloc(memreq
);
3881 dstImage
= (GLshort
*)malloc(memreq
);
3883 case GL_UNSIGNED_INT
:
3884 dstImage
= (GLuint
*)malloc(memreq
);
3887 dstImage
= (GLint
*)malloc(memreq
);
3890 dstImage
= (GLfloat
*)malloc(memreq
);
3892 case GL_UNSIGNED_BYTE_3_3_2
:
3893 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3894 dstImage
= (GLubyte
*)malloc(memreq
);
3896 case GL_UNSIGNED_SHORT_5_6_5
:
3897 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3898 case GL_UNSIGNED_SHORT_4_4_4_4
:
3899 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3900 case GL_UNSIGNED_SHORT_5_5_5_1
:
3901 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3902 dstImage
= (GLushort
*)malloc(memreq
);
3904 case GL_UNSIGNED_INT_8_8_8_8
:
3905 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3906 case GL_UNSIGNED_INT_10_10_10_2
:
3907 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3908 dstImage
= (GLuint
*)malloc(memreq
);
3911 return GLU_INVALID_ENUM
;
3913 if (dstImage
== NULL
) {
3914 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3915 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3916 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3917 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3918 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3919 return GLU_OUT_OF_MEMORY
;
3923 case GL_UNSIGNED_BYTE
:
3924 halveImage_ubyte(cmpts
, width
, height
,
3925 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3926 element_size
, rowsize
, group_size
);
3929 halveImage_byte(cmpts
, width
, height
,
3930 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3931 element_size
, rowsize
, group_size
);
3933 case GL_UNSIGNED_SHORT
:
3934 halveImage_ushort(cmpts
, width
, height
,
3935 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3936 element_size
, rowsize
, group_size
, myswap_bytes
);
3939 halveImage_short(cmpts
, width
, height
,
3940 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3941 element_size
, rowsize
, group_size
, myswap_bytes
);
3943 case GL_UNSIGNED_INT
:
3944 halveImage_uint(cmpts
, width
, height
,
3945 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3946 element_size
, rowsize
, group_size
, myswap_bytes
);
3949 halveImage_int(cmpts
, width
, height
,
3950 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3951 element_size
, rowsize
, group_size
, myswap_bytes
);
3954 halveImage_float(cmpts
, width
, height
,
3955 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3956 element_size
, rowsize
, group_size
, myswap_bytes
);
3958 case GL_UNSIGNED_BYTE_3_3_2
:
3959 assert(format
== GL_RGB
);
3960 halveImagePackedPixel(3,extract332
,shove332
,
3961 width
,height
,usersImage
,dstImage
,
3962 element_size
,rowsize
,myswap_bytes
);
3964 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3965 assert(format
== GL_RGB
);
3966 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3967 width
,height
,usersImage
,dstImage
,
3968 element_size
,rowsize
,myswap_bytes
);
3970 case GL_UNSIGNED_SHORT_5_6_5
:
3971 halveImagePackedPixel(3,extract565
,shove565
,
3972 width
,height
,usersImage
,dstImage
,
3973 element_size
,rowsize
,myswap_bytes
);
3975 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3976 halveImagePackedPixel(3,extract565rev
,shove565rev
,
3977 width
,height
,usersImage
,dstImage
,
3978 element_size
,rowsize
,myswap_bytes
);
3980 case GL_UNSIGNED_SHORT_4_4_4_4
:
3981 halveImagePackedPixel(4,extract4444
,shove4444
,
3982 width
,height
,usersImage
,dstImage
,
3983 element_size
,rowsize
,myswap_bytes
);
3985 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3986 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
3987 width
,height
,usersImage
,dstImage
,
3988 element_size
,rowsize
,myswap_bytes
);
3990 case GL_UNSIGNED_SHORT_5_5_5_1
:
3991 halveImagePackedPixel(4,extract5551
,shove5551
,
3992 width
,height
,usersImage
,dstImage
,
3993 element_size
,rowsize
,myswap_bytes
);
3995 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3996 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
3997 width
,height
,usersImage
,dstImage
,
3998 element_size
,rowsize
,myswap_bytes
);
4000 case GL_UNSIGNED_INT_8_8_8_8
:
4001 halveImagePackedPixel(4,extract8888
,shove8888
,
4002 width
,height
,usersImage
,dstImage
,
4003 element_size
,rowsize
,myswap_bytes
);
4005 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4006 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4007 width
,height
,usersImage
,dstImage
,
4008 element_size
,rowsize
,myswap_bytes
);
4010 case GL_UNSIGNED_INT_10_10_10_2
:
4011 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4012 width
,height
,usersImage
,dstImage
,
4013 element_size
,rowsize
,myswap_bytes
);
4015 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4016 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4017 width
,height
,usersImage
,dstImage
,
4018 element_size
,rowsize
,myswap_bytes
);
4025 newheight
= height
/2;
4027 if (newwidth
< 1) newwidth
= 1;
4028 if (newheight
< 1) newheight
= 1;
4031 rowsize
= newwidth
* group_size
;
4032 memreq
= image_size(newwidth
, newheight
, format
, type
);
4033 /* Swap srcImage and dstImage */
4034 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4036 case GL_UNSIGNED_BYTE
:
4037 dstImage
= (GLubyte
*)malloc(memreq
);
4040 dstImage
= (GLbyte
*)malloc(memreq
);
4042 case GL_UNSIGNED_SHORT
:
4043 dstImage
= (GLushort
*)malloc(memreq
);
4046 dstImage
= (GLshort
*)malloc(memreq
);
4048 case GL_UNSIGNED_INT
:
4049 dstImage
= (GLuint
*)malloc(memreq
);
4052 dstImage
= (GLint
*)malloc(memreq
);
4055 dstImage
= (GLfloat
*)malloc(memreq
);
4057 case GL_UNSIGNED_BYTE_3_3_2
:
4058 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4059 dstImage
= (GLubyte
*)malloc(memreq
);
4061 case GL_UNSIGNED_SHORT_5_6_5
:
4062 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4063 case GL_UNSIGNED_SHORT_4_4_4_4
:
4064 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4065 case GL_UNSIGNED_SHORT_5_5_5_1
:
4066 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4067 dstImage
= (GLushort
*)malloc(memreq
);
4069 case GL_UNSIGNED_INT_8_8_8_8
:
4070 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4071 case GL_UNSIGNED_INT_10_10_10_2
:
4072 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4073 dstImage
= (GLuint
*)malloc(memreq
);
4076 return GLU_INVALID_ENUM
;
4078 if (dstImage
== NULL
) {
4079 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4080 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4081 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4082 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4083 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4084 return GLU_OUT_OF_MEMORY
;
4086 /* level userLevel+1 is in srcImage; level userLevel already saved */
4087 level
= userLevel
+1;
4088 } else { /* user's image is *not* nice power-of-2 sized square */
4089 memreq
= image_size(newwidth
, newheight
, format
, type
);
4091 case GL_UNSIGNED_BYTE
:
4092 dstImage
= (GLubyte
*)malloc(memreq
);
4095 dstImage
= (GLbyte
*)malloc(memreq
);
4097 case GL_UNSIGNED_SHORT
:
4098 dstImage
= (GLushort
*)malloc(memreq
);
4101 dstImage
= (GLshort
*)malloc(memreq
);
4103 case GL_UNSIGNED_INT
:
4104 dstImage
= (GLuint
*)malloc(memreq
);
4107 dstImage
= (GLint
*)malloc(memreq
);
4110 dstImage
= (GLfloat
*)malloc(memreq
);
4112 case GL_UNSIGNED_BYTE_3_3_2
:
4113 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4114 dstImage
= (GLubyte
*)malloc(memreq
);
4116 case GL_UNSIGNED_SHORT_5_6_5
:
4117 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4118 case GL_UNSIGNED_SHORT_4_4_4_4
:
4119 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4120 case GL_UNSIGNED_SHORT_5_5_5_1
:
4121 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4122 dstImage
= (GLushort
*)malloc(memreq
);
4124 case GL_UNSIGNED_INT_8_8_8_8
:
4125 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4126 case GL_UNSIGNED_INT_10_10_10_2
:
4127 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4128 dstImage
= (GLuint
*)malloc(memreq
);
4131 return GLU_INVALID_ENUM
;
4134 if (dstImage
== NULL
) {
4135 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4136 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4137 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4138 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4139 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4140 return GLU_OUT_OF_MEMORY
;
4144 case GL_UNSIGNED_BYTE
:
4145 scale_internal_ubyte(cmpts
, width
, height
,
4146 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4147 (GLubyte
*)dstImage
, element_size
,
4148 rowsize
, group_size
);
4151 scale_internal_byte(cmpts
, width
, height
,
4152 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4153 (GLbyte
*)dstImage
, element_size
,
4154 rowsize
, group_size
);
4156 case GL_UNSIGNED_SHORT
:
4157 scale_internal_ushort(cmpts
, width
, height
,
4158 (const GLushort
*)usersImage
, newwidth
, newheight
,
4159 (GLushort
*)dstImage
, element_size
,
4160 rowsize
, group_size
, myswap_bytes
);
4163 scale_internal_short(cmpts
, width
, height
,
4164 (const GLshort
*)usersImage
, newwidth
, newheight
,
4165 (GLshort
*)dstImage
, element_size
,
4166 rowsize
, group_size
, myswap_bytes
);
4168 case GL_UNSIGNED_INT
:
4169 scale_internal_uint(cmpts
, width
, height
,
4170 (const GLuint
*)usersImage
, newwidth
, newheight
,
4171 (GLuint
*)dstImage
, element_size
,
4172 rowsize
, group_size
, myswap_bytes
);
4175 scale_internal_int(cmpts
, width
, height
,
4176 (const GLint
*)usersImage
, newwidth
, newheight
,
4177 (GLint
*)dstImage
, element_size
,
4178 rowsize
, group_size
, myswap_bytes
);
4181 scale_internal_float(cmpts
, width
, height
,
4182 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4183 (GLfloat
*)dstImage
, element_size
,
4184 rowsize
, group_size
, myswap_bytes
);
4186 case GL_UNSIGNED_BYTE_3_3_2
:
4187 scaleInternalPackedPixel(3,extract332
,shove332
,
4188 width
, height
,usersImage
,
4189 newwidth
,newheight
,(void *)dstImage
,
4190 element_size
,rowsize
,myswap_bytes
);
4192 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4193 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4194 width
, height
,usersImage
,
4195 newwidth
,newheight
,(void *)dstImage
,
4196 element_size
,rowsize
,myswap_bytes
);
4198 case GL_UNSIGNED_SHORT_5_6_5
:
4199 scaleInternalPackedPixel(3,extract565
,shove565
,
4200 width
, height
,usersImage
,
4201 newwidth
,newheight
,(void *)dstImage
,
4202 element_size
,rowsize
,myswap_bytes
);
4204 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4205 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4206 width
, height
,usersImage
,
4207 newwidth
,newheight
,(void *)dstImage
,
4208 element_size
,rowsize
,myswap_bytes
);
4210 case GL_UNSIGNED_SHORT_4_4_4_4
:
4211 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4212 width
, height
,usersImage
,
4213 newwidth
,newheight
,(void *)dstImage
,
4214 element_size
,rowsize
,myswap_bytes
);
4216 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4217 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4218 width
, height
,usersImage
,
4219 newwidth
,newheight
,(void *)dstImage
,
4220 element_size
,rowsize
,myswap_bytes
);
4222 case GL_UNSIGNED_SHORT_5_5_5_1
:
4223 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4224 width
, height
,usersImage
,
4225 newwidth
,newheight
,(void *)dstImage
,
4226 element_size
,rowsize
,myswap_bytes
);
4228 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4229 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4230 width
, height
,usersImage
,
4231 newwidth
,newheight
,(void *)dstImage
,
4232 element_size
,rowsize
,myswap_bytes
);
4234 case GL_UNSIGNED_INT_8_8_8_8
:
4235 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4236 width
, height
,usersImage
,
4237 newwidth
,newheight
,(void *)dstImage
,
4238 element_size
,rowsize
,myswap_bytes
);
4240 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4241 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4242 width
, height
,usersImage
,
4243 newwidth
,newheight
,(void *)dstImage
,
4244 element_size
,rowsize
,myswap_bytes
);
4246 case GL_UNSIGNED_INT_10_10_10_2
:
4247 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4248 width
, height
,usersImage
,
4249 newwidth
,newheight
,(void *)dstImage
,
4250 element_size
,rowsize
,myswap_bytes
);
4252 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4253 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4254 width
, height
,usersImage
,
4255 newwidth
,newheight
,(void *)dstImage
,
4256 element_size
,rowsize
,myswap_bytes
);
4263 rowsize
= newwidth
* group_size
;
4264 /* Swap dstImage and srcImage */
4265 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4267 if(levels
!= 0) { /* use as little memory as possible */
4269 int nextWidth
= newwidth
/2;
4270 int nextHeight
= newheight
/2;
4271 if (nextWidth
< 1) nextWidth
= 1;
4272 if (nextHeight
< 1) nextHeight
= 1;
4274 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4278 case GL_UNSIGNED_BYTE
:
4279 dstImage
= (GLubyte
*)malloc(memreq
);
4282 dstImage
= (GLbyte
*)malloc(memreq
);
4284 case GL_UNSIGNED_SHORT
:
4285 dstImage
= (GLushort
*)malloc(memreq
);
4288 dstImage
= (GLshort
*)malloc(memreq
);
4290 case GL_UNSIGNED_INT
:
4291 dstImage
= (GLuint
*)malloc(memreq
);
4294 dstImage
= (GLint
*)malloc(memreq
);
4297 dstImage
= (GLfloat
*)malloc(memreq
);
4299 case GL_UNSIGNED_BYTE_3_3_2
:
4300 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4301 dstImage
= (GLubyte
*)malloc(memreq
);
4303 case GL_UNSIGNED_SHORT_5_6_5
:
4304 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4305 case GL_UNSIGNED_SHORT_4_4_4_4
:
4306 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4307 case GL_UNSIGNED_SHORT_5_5_5_1
:
4308 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4309 dstImage
= (GLushort
*)malloc(memreq
);
4311 case GL_UNSIGNED_INT_8_8_8_8
:
4312 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4313 case GL_UNSIGNED_INT_10_10_10_2
:
4314 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4315 dstImage
= (GLuint
*)malloc(memreq
);
4318 return GLU_INVALID_ENUM
;
4320 if (dstImage
== NULL
) {
4321 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4322 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4323 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4324 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4325 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4326 return GLU_OUT_OF_MEMORY
;
4329 /* level userLevel is in srcImage; nothing saved yet */
4333 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4334 if (baseLevel
<= level
&& level
<= maxLevel
) {
4335 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4336 format
, type
, (void *)srcImage
);
4339 level
++; /* update current level for the loop */
4340 for (; level
<= levels
; level
++) {
4342 case GL_UNSIGNED_BYTE
:
4343 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4344 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4345 rowsize
, group_size
);
4348 halveImage_byte(cmpts
, newwidth
, newheight
,
4349 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4350 rowsize
, group_size
);
4352 case GL_UNSIGNED_SHORT
:
4353 halveImage_ushort(cmpts
, newwidth
, newheight
,
4354 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4355 rowsize
, group_size
, myswap_bytes
);
4358 halveImage_short(cmpts
, newwidth
, newheight
,
4359 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4360 rowsize
, group_size
, myswap_bytes
);
4362 case GL_UNSIGNED_INT
:
4363 halveImage_uint(cmpts
, newwidth
, newheight
,
4364 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4365 rowsize
, group_size
, myswap_bytes
);
4368 halveImage_int(cmpts
, newwidth
, newheight
,
4369 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4370 rowsize
, group_size
, myswap_bytes
);
4373 halveImage_float(cmpts
, newwidth
, newheight
,
4374 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4375 rowsize
, group_size
, myswap_bytes
);
4377 case GL_UNSIGNED_BYTE_3_3_2
:
4378 halveImagePackedPixel(3,extract332
,shove332
,
4380 srcImage
,dstImage
,element_size
,rowsize
,
4383 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4384 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4386 srcImage
,dstImage
,element_size
,rowsize
,
4389 case GL_UNSIGNED_SHORT_5_6_5
:
4390 halveImagePackedPixel(3,extract565
,shove565
,
4392 srcImage
,dstImage
,element_size
,rowsize
,
4395 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4396 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4398 srcImage
,dstImage
,element_size
,rowsize
,
4401 case GL_UNSIGNED_SHORT_4_4_4_4
:
4402 halveImagePackedPixel(4,extract4444
,shove4444
,
4404 srcImage
,dstImage
,element_size
,rowsize
,
4407 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4408 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4410 srcImage
,dstImage
,element_size
,rowsize
,
4413 case GL_UNSIGNED_SHORT_5_5_5_1
:
4414 halveImagePackedPixel(4,extract5551
,shove5551
,
4416 srcImage
,dstImage
,element_size
,rowsize
,
4419 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4420 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4422 srcImage
,dstImage
,element_size
,rowsize
,
4425 case GL_UNSIGNED_INT_8_8_8_8
:
4426 halveImagePackedPixel(4,extract8888
,shove8888
,
4428 srcImage
,dstImage
,element_size
,rowsize
,
4431 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4432 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4434 srcImage
,dstImage
,element_size
,rowsize
,
4437 case GL_UNSIGNED_INT_10_10_10_2
:
4438 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4440 srcImage
,dstImage
,element_size
,rowsize
,
4443 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4444 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4446 srcImage
,dstImage
,element_size
,rowsize
,
4454 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4456 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4457 if (newheight
> 1) newheight
/= 2;
4459 /* compute amount to pad per row, if any */
4460 int rowPad
= rowsize
% psm
.unpack_alignment
;
4462 /* should row be padded? */
4463 if (rowPad
== 0) { /* nope, row should not be padded */
4464 /* call tex image with srcImage untouched since it's not padded */
4465 if (baseLevel
<= level
&& level
<= maxLevel
) {
4466 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4467 format
, type
, (void *) srcImage
);
4470 else { /* yes, row should be padded */
4471 /* compute length of new row in bytes, including padding */
4472 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4473 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4475 /* allocate new image for mipmap of size newRowLength x newheight */
4476 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4477 if (newMipmapImage
== NULL
) {
4478 /* out of memory so return */
4479 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4480 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4481 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4482 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4483 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4484 return GLU_OUT_OF_MEMORY
;
4487 /* copy image from srcImage into newMipmapImage by rows */
4489 dstTrav
= (unsigned char *) newMipmapImage
,
4490 srcTrav
= (unsigned char *) srcImage
;
4493 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4494 srcTrav
+= rowsize
) { /* ...is skipped */
4495 memcpy(dstTrav
,srcTrav
,rowsize
);
4496 /* note that the pad bytes are not visited and will contain
4497 * garbage, which is ok.
4501 /* ...and use this new image for mipmapping instead */
4502 if (baseLevel
<= level
&& level
<= maxLevel
) {
4503 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4504 format
, type
, newMipmapImage
);
4506 free(newMipmapImage
); /* don't forget to free it! */
4510 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4511 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4512 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4513 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4514 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4516 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4517 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4521 } /* gluBuild2DMipmapLevelsCore() */
4524 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4525 GLsizei width
, GLsizei height
,
4526 GLenum format
, GLenum type
,
4527 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4532 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4533 if (rc
!= 0) return rc
;
4535 if (width
< 1 || height
< 1) {
4536 return GLU_INVALID_VALUE
;
4539 levels
= computeLog(width
);
4540 level
= computeLog(height
);
4541 if (level
> levels
) levels
=level
;
4544 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4545 return GLU_INVALID_VALUE
;
4547 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4551 userLevel
, baseLevel
, maxLevel
,
4553 } /* gluBuild2DMipmapLevels() */
4556 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4557 GLsizei width
, GLsizei height
,
4558 GLenum format
, GLenum type
,
4561 GLint widthPowerOf2
, heightPowerOf2
;
4564 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4565 if (rc
!= 0) return rc
;
4567 if (width
< 1 || height
< 1) {
4568 return GLU_INVALID_VALUE
;
4571 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4572 &widthPowerOf2
,&heightPowerOf2
);
4574 levels
= computeLog(widthPowerOf2
);
4575 level
= computeLog(heightPowerOf2
);
4576 if (level
> levels
) levels
=level
;
4578 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4580 widthPowerOf2
,heightPowerOf2
,
4583 } /* gluBuild2DMipmaps() */
4587 ** This routine is for the limited case in which
4588 ** type == GL_UNSIGNED_BYTE && format != index &&
4589 ** unpack_alignment = 1 && unpack_swap_bytes == false
4591 ** so all of the work data can be kept as ubytes instead of shorts.
4593 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4594 GLenum target
, GLint components
, GLint width
,
4595 GLint height
, GLenum format
,
4596 GLenum type
, void *data
)
4598 GLint newwidth
, newheight
;
4599 GLint level
, levels
;
4601 GLint newImage_width
;
4602 GLint newImage_height
;
4603 GLubyte
*otherImage
;
4610 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4611 newwidth
= nearestPower(width
);
4612 if (newwidth
> maxsize
) newwidth
= maxsize
;
4613 newheight
= nearestPower(height
);
4614 if (newheight
> maxsize
) newheight
= maxsize
;
4616 closestFit(target
,width
,height
,components
,format
,type
,
4617 &newwidth
,&newheight
);
4619 levels
= computeLog(newwidth
);
4620 level
= computeLog(newheight
);
4621 if (level
> levels
) levels
=level
;
4623 cmpts
= elements_per_group(format
,type
);
4627 ** No need to copy the user data if its in the packed correctly.
4628 ** Make sure that later routines don't change that data.
4630 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4631 newImage
= (GLubyte
*)data
;
4632 newImage_width
= width
;
4633 newImage_height
= height
;
4636 GLint groups_per_line
;
4637 GLint elements_per_line
;
4638 const GLubyte
*start
;
4639 const GLubyte
*iter
;
4643 newImage
= (GLubyte
*)
4644 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4645 newImage_width
= width
;
4646 newImage_height
= height
;
4647 if (newImage
== NULL
) {
4648 return GLU_OUT_OF_MEMORY
;
4652 ** Abbreviated version of fill_image for this restricted case.
4654 if (psm
->unpack_row_length
> 0) {
4655 groups_per_line
= psm
->unpack_row_length
;
4657 groups_per_line
= width
;
4659 rowsize
= groups_per_line
* cmpts
;
4660 elements_per_line
= width
* cmpts
;
4661 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4662 psm
->unpack_skip_pixels
* cmpts
;
4665 for (i
= 0; i
< height
; i
++) {
4667 for (j
= 0; j
< elements_per_line
; j
++) {
4677 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4678 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4679 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4680 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4681 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4683 for (level
= 0; level
<= levels
; level
++) {
4684 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4685 /* Use newImage for this level */
4686 glTexImage2D(target
, level
, components
, newImage_width
,
4687 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4690 if (otherImage
== NULL
) {
4692 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4693 otherImage
= (GLubyte
*) malloc(memreq
);
4694 if (otherImage
== NULL
) {
4695 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4696 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4697 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4698 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4699 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4700 return GLU_OUT_OF_MEMORY
;
4704 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4705 newImage, newwidth, newheight, otherImage);
4707 /* Swap newImage and otherImage */
4708 imageTemp
= otherImage
;
4709 otherImage
= newImage
;
4710 newImage
= imageTemp
;
4712 newImage_width
= newwidth
;
4713 newImage_height
= newheight
;
4714 glTexImage2D(target
, level
, components
, newImage_width
,
4715 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4718 if (newwidth
> 1) newwidth
/= 2;
4719 if (newheight
> 1) newheight
/= 2;
4721 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4722 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4723 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4724 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4725 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4727 if (newImage
!= (const GLubyte
*)data
) {
4728 free((GLbyte
*) newImage
);
4730 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4731 free((GLbyte
*) otherImage
);
4740 static GLint
elements_per_group(GLenum format
, GLenum type
)
4743 * Return the number of elements per group of a specified format
4746 /* If the type is packedpixels then answer is 1 (ignore format) */
4747 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4748 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4749 type
== GL_UNSIGNED_SHORT_5_6_5
||
4750 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4751 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4752 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4753 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4754 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4755 type
== GL_UNSIGNED_INT_8_8_8_8
||
4756 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4757 type
== GL_UNSIGNED_INT_10_10_10_2
||
4758 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4762 /* Types are not packed pixels, so get elements per group */
4767 case GL_LUMINANCE_ALPHA
:
4777 static GLfloat
bytes_per_element(GLenum type
)
4780 * Return the number of bytes per element, based on the element type
4785 case GL_UNSIGNED_SHORT
:
4786 return(sizeof(GLushort
));
4788 return(sizeof(GLshort
));
4789 case GL_UNSIGNED_BYTE
:
4790 return(sizeof(GLubyte
));
4792 return(sizeof(GLbyte
));
4794 return(sizeof(GLint
));
4795 case GL_UNSIGNED_INT
:
4796 return(sizeof(GLuint
));
4798 return(sizeof(GLfloat
));
4799 case GL_UNSIGNED_BYTE_3_3_2
:
4800 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4801 return(sizeof(GLubyte
));
4802 case GL_UNSIGNED_SHORT_5_6_5
:
4803 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4804 case GL_UNSIGNED_SHORT_4_4_4_4
:
4805 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4806 case GL_UNSIGNED_SHORT_5_5_5_1
:
4807 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4808 return(sizeof(GLushort
));
4809 case GL_UNSIGNED_INT_8_8_8_8
:
4810 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4811 case GL_UNSIGNED_INT_10_10_10_2
:
4812 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4813 return(sizeof(GLuint
));
4819 static GLint
is_index(GLenum format
)
4821 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4825 ** Compute memory required for internal packed array of data of given type
4828 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4835 components
= elements_per_group(format
,type
);
4836 if (type
== GL_BITMAP
) {
4837 bytes_per_row
= (width
+ 7) / 8;
4839 bytes_per_row
= bytes_per_element(type
) * width
;
4841 return bytes_per_row
* height
* components
;
4845 ** Extract array from user's data applying all pixel store modes.
4846 ** The internal format used is an array of unsigned shorts.
4848 static void fill_image(const PixelStorageModes
*psm
,
4849 GLint width
, GLint height
, GLenum format
,
4850 GLenum type
, GLboolean index_format
,
4851 const void *userdata
, GLushort
*newimage
)
4857 GLint groups_per_line
;
4859 GLint elements_per_line
;
4860 const GLubyte
*start
;
4861 const GLubyte
*iter
;
4866 myswap_bytes
= psm
->unpack_swap_bytes
;
4867 components
= elements_per_group(format
,type
);
4868 if (psm
->unpack_row_length
> 0) {
4869 groups_per_line
= psm
->unpack_row_length
;
4871 groups_per_line
= width
;
4874 /* All formats except GL_BITMAP fall out trivially */
4875 if (type
== GL_BITMAP
) {
4879 rowsize
= (groups_per_line
* components
+ 7) / 8;
4880 padding
= (rowsize
% psm
->unpack_alignment
);
4882 rowsize
+= psm
->unpack_alignment
- padding
;
4884 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4885 (psm
->unpack_skip_pixels
* components
/ 8);
4886 elements_per_line
= width
* components
;
4888 for (i
= 0; i
< height
; i
++) {
4890 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4891 for (j
= 0; j
< elements_per_line
; j
++) {
4893 if (psm
->unpack_lsb_first
) {
4894 current_bit
= iter
[0] & (1 << bit_offset
);
4896 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4908 if (bit_offset
== 8) {
4917 element_size
= bytes_per_element(type
);
4918 group_size
= element_size
* components
;
4919 if (element_size
== 1) myswap_bytes
= 0;
4921 rowsize
= groups_per_line
* group_size
;
4922 padding
= (rowsize
% psm
->unpack_alignment
);
4924 rowsize
+= psm
->unpack_alignment
- padding
;
4926 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4927 psm
->unpack_skip_pixels
* group_size
;
4928 elements_per_line
= width
* components
;
4931 for (i
= 0; i
< height
; i
++) {
4933 for (j
= 0; j
< elements_per_line
; j
++) {
4935 float extractComponents
[4];
4938 case GL_UNSIGNED_BYTE_3_3_2
:
4939 extract332(0,iter
,extractComponents
);
4940 for (k
= 0; k
< 3; k
++) {
4941 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4944 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4945 extract233rev(0,iter
,extractComponents
);
4946 for (k
= 0; k
< 3; k
++) {
4947 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4950 case GL_UNSIGNED_BYTE
:
4954 *iter2
++ = (*iter
) * 257;
4959 *iter2
++ = *((const GLbyte
*) iter
);
4962 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4965 case GL_UNSIGNED_SHORT_5_6_5
:
4966 extract565(myswap_bytes
,iter
,extractComponents
);
4967 for (k
= 0; k
< 3; k
++) {
4968 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4971 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4972 extract565rev(myswap_bytes
,iter
,extractComponents
);
4973 for (k
= 0; k
< 3; k
++) {
4974 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4977 case GL_UNSIGNED_SHORT_4_4_4_4
:
4978 extract4444(myswap_bytes
,iter
,extractComponents
);
4979 for (k
= 0; k
< 4; k
++) {
4980 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4983 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4984 extract4444rev(myswap_bytes
,iter
,extractComponents
);
4985 for (k
= 0; k
< 4; k
++) {
4986 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4989 case GL_UNSIGNED_SHORT_5_5_5_1
:
4990 extract5551(myswap_bytes
,iter
,extractComponents
);
4991 for (k
= 0; k
< 4; k
++) {
4992 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4995 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4996 extract1555rev(myswap_bytes
,iter
,extractComponents
);
4997 for (k
= 0; k
< 4; k
++) {
4998 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5001 case GL_UNSIGNED_SHORT
:
5004 widget
.ub
[0] = iter
[1];
5005 widget
.ub
[1] = iter
[0];
5007 widget
.ub
[0] = iter
[0];
5008 widget
.ub
[1] = iter
[1];
5010 if (type
== GL_SHORT
) {
5012 *iter2
++ = widget
.s
[0];
5015 *iter2
++ = widget
.s
[0]*2;
5018 *iter2
++ = widget
.us
[0];
5021 case GL_UNSIGNED_INT_8_8_8_8
:
5022 extract8888(myswap_bytes
,iter
,extractComponents
);
5023 for (k
= 0; k
< 4; k
++) {
5024 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5027 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5028 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5029 for (k
= 0; k
< 4; k
++) {
5030 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5033 case GL_UNSIGNED_INT_10_10_10_2
:
5034 extract1010102(myswap_bytes
,iter
,extractComponents
);
5035 for (k
= 0; k
< 4; k
++) {
5036 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5039 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5040 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5041 for (k
= 0; k
< 4; k
++) {
5042 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5046 case GL_UNSIGNED_INT
:
5049 widget
.ub
[0] = iter
[3];
5050 widget
.ub
[1] = iter
[2];
5051 widget
.ub
[2] = iter
[1];
5052 widget
.ub
[3] = iter
[0];
5054 widget
.ub
[0] = iter
[0];
5055 widget
.ub
[1] = iter
[1];
5056 widget
.ub
[2] = iter
[2];
5057 widget
.ub
[3] = iter
[3];
5059 if (type
== GL_FLOAT
) {
5061 *iter2
++ = widget
.f
;
5063 *iter2
++ = 65535 * widget
.f
;
5065 } else if (type
== GL_UNSIGNED_INT
) {
5067 *iter2
++ = widget
.ui
;
5069 *iter2
++ = widget
.ui
>> 16;
5073 *iter2
++ = widget
.i
;
5075 *iter2
++ = widget
.i
>> 15;
5080 iter
+= element_size
;
5084 /* want 'iter' pointing at start, not within, row for assertion
5091 /* iterators should be one byte past end */
5092 if (!isTypePackedPixel(type
)) {
5093 assert(iter2
== &newimage
[width
*height
*components
]);
5096 assert(iter2
== &newimage
[width
*height
*
5097 elements_per_group(format
,0)]);
5099 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5100 psm
->unpack_skip_rows
* rowsize
+
5101 psm
->unpack_skip_pixels
* group_size
] );
5104 } /* fill_image() */
5107 ** Insert array into user's data applying all pixel store modes.
5108 ** The internal format is an array of unsigned shorts.
5109 ** empty_image() because it is the opposite of fill_image().
5111 static void empty_image(const PixelStorageModes
*psm
,
5112 GLint width
, GLint height
, GLenum format
,
5113 GLenum type
, GLboolean index_format
,
5114 const GLushort
*oldimage
, void *userdata
)
5120 GLint groups_per_line
;
5122 GLint elements_per_line
;
5125 const GLushort
*iter2
;
5129 myswap_bytes
= psm
->pack_swap_bytes
;
5130 components
= elements_per_group(format
,type
);
5131 if (psm
->pack_row_length
> 0) {
5132 groups_per_line
= psm
->pack_row_length
;
5134 groups_per_line
= width
;
5137 /* All formats except GL_BITMAP fall out trivially */
5138 if (type
== GL_BITMAP
) {
5142 rowsize
= (groups_per_line
* components
+ 7) / 8;
5143 padding
= (rowsize
% psm
->pack_alignment
);
5145 rowsize
+= psm
->pack_alignment
- padding
;
5147 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5148 (psm
->pack_skip_pixels
* components
/ 8);
5149 elements_per_line
= width
* components
;
5151 for (i
= 0; i
< height
; i
++) {
5153 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5154 for (j
= 0; j
< elements_per_line
; j
++) {
5156 current_bit
= iter2
[0] & 1;
5158 if (iter2
[0] > 32767) {
5166 if (psm
->pack_lsb_first
) {
5167 *iter
|= (1 << bit_offset
);
5169 *iter
|= (1 << (7 - bit_offset
));
5172 if (psm
->pack_lsb_first
) {
5173 *iter
&= ~(1 << bit_offset
);
5175 *iter
&= ~(1 << (7 - bit_offset
));
5180 if (bit_offset
== 8) {
5189 float shoveComponents
[4];
5191 element_size
= bytes_per_element(type
);
5192 group_size
= element_size
* components
;
5193 if (element_size
== 1) myswap_bytes
= 0;
5195 rowsize
= groups_per_line
* group_size
;
5196 padding
= (rowsize
% psm
->pack_alignment
);
5198 rowsize
+= psm
->pack_alignment
- padding
;
5200 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5201 psm
->pack_skip_pixels
* group_size
;
5202 elements_per_line
= width
* components
;
5205 for (i
= 0; i
< height
; i
++) {
5207 for (j
= 0; j
< elements_per_line
; j
++) {
5211 case GL_UNSIGNED_BYTE_3_3_2
:
5212 for (k
= 0; k
< 3; k
++) {
5213 shoveComponents
[k
]= *iter2
++ / 65535.0;
5215 shove332(shoveComponents
,0,(void *)iter
);
5217 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5218 for (k
= 0; k
< 3; k
++) {
5219 shoveComponents
[k
]= *iter2
++ / 65535.0;
5221 shove233rev(shoveComponents
,0,(void *)iter
);
5223 case GL_UNSIGNED_BYTE
:
5227 *iter
= *iter2
++ >> 8;
5232 *((GLbyte
*) iter
) = *iter2
++;
5234 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5237 case GL_UNSIGNED_SHORT_5_6_5
:
5238 for (k
= 0; k
< 3; k
++) {
5239 shoveComponents
[k
]= *iter2
++ / 65535.0;
5241 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5243 iter
[0] = widget
.ub
[1];
5244 iter
[1] = widget
.ub
[0];
5247 *(GLushort
*)iter
= widget
.us
[0];
5250 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5251 for (k
= 0; k
< 3; k
++) {
5252 shoveComponents
[k
]= *iter2
++ / 65535.0;
5254 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5256 iter
[0] = widget
.ub
[1];
5257 iter
[1] = widget
.ub
[0];
5260 *(GLushort
*)iter
= widget
.us
[0];
5263 case GL_UNSIGNED_SHORT_4_4_4_4
:
5264 for (k
= 0; k
< 4; k
++) {
5265 shoveComponents
[k
]= *iter2
++ / 65535.0;
5267 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5269 iter
[0] = widget
.ub
[1];
5270 iter
[1] = widget
.ub
[0];
5272 *(GLushort
*)iter
= widget
.us
[0];
5275 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5276 for (k
= 0; k
< 4; k
++) {
5277 shoveComponents
[k
]= *iter2
++ / 65535.0;
5279 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5281 iter
[0] = widget
.ub
[1];
5282 iter
[1] = widget
.ub
[0];
5284 *(GLushort
*)iter
= widget
.us
[0];
5287 case GL_UNSIGNED_SHORT_5_5_5_1
:
5288 for (k
= 0; k
< 4; k
++) {
5289 shoveComponents
[k
]= *iter2
++ / 65535.0;
5291 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5293 iter
[0] = widget
.ub
[1];
5294 iter
[1] = widget
.ub
[0];
5296 *(GLushort
*)iter
= widget
.us
[0];
5299 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5300 for (k
= 0; k
< 4; k
++) {
5301 shoveComponents
[k
]= *iter2
++ / 65535.0;
5303 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5305 iter
[0] = widget
.ub
[1];
5306 iter
[1] = widget
.ub
[0];
5308 *(GLushort
*)iter
= widget
.us
[0];
5311 case GL_UNSIGNED_SHORT
:
5313 if (type
== GL_SHORT
) {
5315 widget
.s
[0] = *iter2
++;
5317 widget
.s
[0] = *iter2
++ >> 1;
5320 widget
.us
[0] = *iter2
++;
5323 iter
[0] = widget
.ub
[1];
5324 iter
[1] = widget
.ub
[0];
5326 iter
[0] = widget
.ub
[0];
5327 iter
[1] = widget
.ub
[1];
5330 case GL_UNSIGNED_INT_8_8_8_8
:
5331 for (k
= 0; k
< 4; k
++) {
5332 shoveComponents
[k
]= *iter2
++ / 65535.0;
5334 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5336 iter
[3] = widget
.ub
[0];
5337 iter
[2] = widget
.ub
[1];
5338 iter
[1] = widget
.ub
[2];
5339 iter
[0] = widget
.ub
[3];
5341 *(GLuint
*)iter
= widget
.ui
;
5345 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5346 for (k
= 0; k
< 4; k
++) {
5347 shoveComponents
[k
]= *iter2
++ / 65535.0;
5349 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5351 iter
[3] = widget
.ub
[0];
5352 iter
[2] = widget
.ub
[1];
5353 iter
[1] = widget
.ub
[2];
5354 iter
[0] = widget
.ub
[3];
5356 *(GLuint
*)iter
= widget
.ui
;
5359 case GL_UNSIGNED_INT_10_10_10_2
:
5360 for (k
= 0; k
< 4; k
++) {
5361 shoveComponents
[k
]= *iter2
++ / 65535.0;
5363 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5365 iter
[3] = widget
.ub
[0];
5366 iter
[2] = widget
.ub
[1];
5367 iter
[1] = widget
.ub
[2];
5368 iter
[0] = widget
.ub
[3];
5370 *(GLuint
*)iter
= widget
.ui
;
5373 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5374 for (k
= 0; k
< 4; k
++) {
5375 shoveComponents
[k
]= *iter2
++ / 65535.0;
5377 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
5379 iter
[3] = widget
.ub
[0];
5380 iter
[2] = widget
.ub
[1];
5381 iter
[1] = widget
.ub
[2];
5382 iter
[0] = widget
.ub
[3];
5384 *(GLuint
*)iter
= widget
.ui
;
5388 case GL_UNSIGNED_INT
:
5390 if (type
== GL_FLOAT
) {
5392 widget
.f
= *iter2
++;
5394 widget
.f
= *iter2
++ / (float) 65535.0;
5396 } else if (type
== GL_UNSIGNED_INT
) {
5398 widget
.ui
= *iter2
++;
5400 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5404 widget
.i
= *iter2
++;
5406 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5410 iter
[3] = widget
.ub
[0];
5411 iter
[2] = widget
.ub
[1];
5412 iter
[1] = widget
.ub
[2];
5413 iter
[0] = widget
.ub
[3];
5415 iter
[0] = widget
.ub
[0];
5416 iter
[1] = widget
.ub
[1];
5417 iter
[2] = widget
.ub
[2];
5418 iter
[3] = widget
.ub
[3];
5422 iter
+= element_size
;
5426 /* want 'iter' pointing at start, not within, row for assertion
5433 /* iterators should be one byte past end */
5434 if (!isTypePackedPixel(type
)) {
5435 assert(iter2
== &oldimage
[width
*height
*components
]);
5438 assert(iter2
== &oldimage
[width
*height
*
5439 elements_per_group(format
,0)]);
5441 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5442 psm
->pack_skip_rows
* rowsize
+
5443 psm
->pack_skip_pixels
* group_size
] );
5446 } /* empty_image() */
5448 /*--------------------------------------------------------------------------
5449 * Decimation of packed pixel types
5450 *--------------------------------------------------------------------------
5452 static void extract332(int isSwap
,
5453 const void *packedPixel
, GLfloat extractComponents
[])
5455 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5457 isSwap
= isSwap
; /* turn off warnings */
5459 /* 11100000 == 0xe0 */
5460 /* 00011100 == 0x1c */
5461 /* 00000011 == 0x03 */
5463 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5464 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5465 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5466 } /* extract332() */
5468 static void shove332(const GLfloat shoveComponents
[],
5469 int index
, void *packedPixel
)
5471 /* 11100000 == 0xe0 */
5472 /* 00011100 == 0x1c */
5473 /* 00000011 == 0x03 */
5475 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5476 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5477 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5479 /* due to limited precision, need to round before shoving */
5480 ((GLubyte
*)packedPixel
)[index
] =
5481 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5482 ((GLubyte
*)packedPixel
)[index
] |=
5483 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5484 ((GLubyte
*)packedPixel
)[index
] |=
5485 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5488 static void extract233rev(int isSwap
,
5489 const void *packedPixel
, GLfloat extractComponents
[])
5491 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5493 isSwap
= isSwap
; /* turn off warnings */
5495 /* 0000,0111 == 0x07 */
5496 /* 0011,1000 == 0x38 */
5497 /* 1100,0000 == 0xC0 */
5499 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5500 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5501 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5502 } /* extract233rev() */
5504 static void shove233rev(const GLfloat shoveComponents
[],
5505 int index
, void *packedPixel
)
5507 /* 0000,0111 == 0x07 */
5508 /* 0011,1000 == 0x38 */
5509 /* 1100,0000 == 0xC0 */
5511 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5512 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5513 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5515 /* due to limited precision, need to round before shoving */
5516 ((GLubyte
*)packedPixel
)[index
] =
5517 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5518 ((GLubyte
*)packedPixel
)[index
]|=
5519 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5520 ((GLubyte
*)packedPixel
)[index
]|=
5521 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5522 } /* shove233rev() */
5524 static void extract565(int isSwap
,
5525 const void *packedPixel
, GLfloat extractComponents
[])
5527 GLushort ushort
= *(const GLushort
*)packedPixel
;
5530 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5533 ushort
= *(const GLushort
*)packedPixel
;
5536 /* 11111000,00000000 == 0xf800 */
5537 /* 00000111,11100000 == 0x07e0 */
5538 /* 00000000,00011111 == 0x001f */
5540 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5541 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5542 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5543 } /* extract565() */
5545 static void shove565(const GLfloat shoveComponents
[],
5546 int index
,void *packedPixel
)
5548 /* 11111000,00000000 == 0xf800 */
5549 /* 00000111,11100000 == 0x07e0 */
5550 /* 00000000,00011111 == 0x001f */
5552 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5553 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5554 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5556 /* due to limited precision, need to round before shoving */
5557 ((GLushort
*)packedPixel
)[index
] =
5558 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5559 ((GLushort
*)packedPixel
)[index
]|=
5560 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5561 ((GLushort
*)packedPixel
)[index
]|=
5562 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5565 static void extract565rev(int isSwap
,
5566 const void *packedPixel
, GLfloat extractComponents
[])
5568 GLushort ushort
= *(const GLushort
*)packedPixel
;
5571 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5574 ushort
= *(const GLushort
*)packedPixel
;
5577 /* 00000000,00011111 == 0x001f */
5578 /* 00000111,11100000 == 0x07e0 */
5579 /* 11111000,00000000 == 0xf800 */
5581 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5582 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5583 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5584 } /* extract565rev() */
5586 static void shove565rev(const GLfloat shoveComponents
[],
5587 int index
,void *packedPixel
)
5589 /* 00000000,00011111 == 0x001f */
5590 /* 00000111,11100000 == 0x07e0 */
5591 /* 11111000,00000000 == 0xf800 */
5593 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5594 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5595 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5597 /* due to limited precision, need to round before shoving */
5598 ((GLushort
*)packedPixel
)[index
] =
5599 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5600 ((GLushort
*)packedPixel
)[index
]|=
5601 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5602 ((GLushort
*)packedPixel
)[index
]|=
5603 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5604 } /* shove565rev() */
5606 static void extract4444(int isSwap
,const void *packedPixel
,
5607 GLfloat extractComponents
[])
5612 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5615 ushort
= *(const GLushort
*)packedPixel
;
5618 /* 11110000,00000000 == 0xf000 */
5619 /* 00001111,00000000 == 0x0f00 */
5620 /* 00000000,11110000 == 0x00f0 */
5621 /* 00000000,00001111 == 0x000f */
5623 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5624 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5625 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5626 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5627 } /* extract4444() */
5629 static void shove4444(const GLfloat shoveComponents
[],
5630 int index
,void *packedPixel
)
5632 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5633 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5634 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5635 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5637 /* due to limited precision, need to round before shoving */
5638 ((GLushort
*)packedPixel
)[index
] =
5639 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5640 ((GLushort
*)packedPixel
)[index
]|=
5641 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5642 ((GLushort
*)packedPixel
)[index
]|=
5643 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5644 ((GLushort
*)packedPixel
)[index
]|=
5645 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5648 static void extract4444rev(int isSwap
,const void *packedPixel
,
5649 GLfloat extractComponents
[])
5654 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5657 ushort
= *(const GLushort
*)packedPixel
;
5660 /* 00000000,00001111 == 0x000f */
5661 /* 00000000,11110000 == 0x00f0 */
5662 /* 00001111,00000000 == 0x0f00 */
5663 /* 11110000,00000000 == 0xf000 */
5666 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5667 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5668 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5669 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5670 } /* extract4444rev() */
5672 static void shove4444rev(const GLfloat shoveComponents
[],
5673 int index
,void *packedPixel
)
5675 /* 00000000,00001111 == 0x000f */
5676 /* 00000000,11110000 == 0x00f0 */
5677 /* 00001111,00000000 == 0x0f00 */
5678 /* 11110000,00000000 == 0xf000 */
5680 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5681 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5682 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5683 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5685 /* due to limited precision, need to round before shoving */
5686 ((GLushort
*)packedPixel
)[index
] =
5687 ((GLushort
)((shoveComponents
[0] * 15)+0.5) ) & 0x000F;
5688 ((GLushort
*)packedPixel
)[index
]|=
5689 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5690 ((GLushort
*)packedPixel
)[index
]|=
5691 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5692 ((GLushort
*)packedPixel
)[index
]|=
5693 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5694 } /* shove4444rev() */
5696 static void extract5551(int isSwap
,const void *packedPixel
,
5697 GLfloat extractComponents
[])
5702 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5705 ushort
= *(const GLushort
*)packedPixel
;
5708 /* 11111000,00000000 == 0xf800 */
5709 /* 00000111,11000000 == 0x07c0 */
5710 /* 00000000,00111110 == 0x003e */
5711 /* 00000000,00000001 == 0x0001 */
5713 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5714 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5715 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5716 extractComponents
[3]=(float)((ushort
& 0x0001) );
5717 } /* extract5551() */
5719 static void shove5551(const GLfloat shoveComponents
[],
5720 int index
,void *packedPixel
)
5722 /* 11111000,00000000 == 0xf800 */
5723 /* 00000111,11000000 == 0x07c0 */
5724 /* 00000000,00111110 == 0x003e */
5725 /* 00000000,00000001 == 0x0001 */
5727 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5728 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5729 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5730 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5732 /* due to limited precision, need to round before shoving */
5733 ((GLushort
*)packedPixel
)[index
] =
5734 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5735 ((GLushort
*)packedPixel
)[index
]|=
5736 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5737 ((GLushort
*)packedPixel
)[index
]|=
5738 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5739 ((GLushort
*)packedPixel
)[index
]|=
5740 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5743 static void extract1555rev(int isSwap
,const void *packedPixel
,
5744 GLfloat extractComponents
[])
5749 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5752 ushort
= *(const GLushort
*)packedPixel
;
5755 /* 00000000,00011111 == 0x001F */
5756 /* 00000011,11100000 == 0x03E0 */
5757 /* 01111100,00000000 == 0x7C00 */
5758 /* 10000000,00000000 == 0x8000 */
5761 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5762 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5763 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5764 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5765 } /* extract1555rev() */
5767 static void shove1555rev(const GLfloat shoveComponents
[],
5768 int index
,void *packedPixel
)
5770 /* 00000000,00011111 == 0x001F */
5771 /* 00000011,11100000 == 0x03E0 */
5772 /* 01111100,00000000 == 0x7C00 */
5773 /* 10000000,00000000 == 0x8000 */
5775 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5776 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5777 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5778 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5780 /* due to limited precision, need to round before shoving */
5781 ((GLushort
*)packedPixel
)[index
] =
5782 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5783 ((GLushort
*)packedPixel
)[index
]|=
5784 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5785 ((GLushort
*)packedPixel
)[index
]|=
5786 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5787 ((GLushort
*)packedPixel
)[index
]|=
5788 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5789 } /* shove1555rev() */
5791 static void extract8888(int isSwap
,
5792 const void *packedPixel
, GLfloat extractComponents
[])
5797 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5800 uint
= *(const GLuint
*)packedPixel
;
5803 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5804 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5805 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5806 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5809 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5810 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5811 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5812 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5813 } /* extract8888() */
5815 static void shove8888(const GLfloat shoveComponents
[],
5816 int index
,void *packedPixel
)
5818 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5819 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5820 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5821 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5823 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5824 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5825 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5826 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5828 /* due to limited precision, need to round before shoving */
5829 ((GLuint
*)packedPixel
)[index
] =
5830 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5831 ((GLuint
*)packedPixel
)[index
]|=
5832 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5833 ((GLuint
*)packedPixel
)[index
]|=
5834 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5835 ((GLuint
*)packedPixel
)[index
]|=
5836 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5839 static void extract8888rev(int isSwap
,
5840 const void *packedPixel
,GLfloat extractComponents
[])
5845 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5848 uint
= *(const GLuint
*)packedPixel
;
5851 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5852 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5853 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5854 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5857 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5858 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5859 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5860 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5861 } /* extract8888rev() */
5863 static void shove8888rev(const GLfloat shoveComponents
[],
5864 int index
,void *packedPixel
)
5866 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5867 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5868 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5869 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5871 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5872 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5873 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5874 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5876 /* due to limited precision, need to round before shoving */
5877 ((GLuint
*)packedPixel
)[index
] =
5878 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5879 ((GLuint
*)packedPixel
)[index
]|=
5880 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5881 ((GLuint
*)packedPixel
)[index
]|=
5882 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5883 ((GLuint
*)packedPixel
)[index
]|=
5884 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5885 } /* shove8888rev() */
5887 static void extract1010102(int isSwap
,
5888 const void *packedPixel
,GLfloat extractComponents
[])
5893 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5896 uint
= *(const GLuint
*)packedPixel
;
5899 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5900 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5901 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5902 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5905 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5906 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5907 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5908 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5909 } /* extract1010102() */
5911 static void shove1010102(const GLfloat shoveComponents
[],
5912 int index
,void *packedPixel
)
5914 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5915 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5916 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5917 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5919 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5920 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5921 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5922 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5924 /* due to limited precision, need to round before shoving */
5925 ((GLuint
*)packedPixel
)[index
] =
5926 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5927 ((GLuint
*)packedPixel
)[index
]|=
5928 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5929 ((GLuint
*)packedPixel
)[index
]|=
5930 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5931 ((GLuint
*)packedPixel
)[index
]|=
5932 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5933 } /* shove1010102() */
5935 static void extract2101010rev(int isSwap
,
5936 const void *packedPixel
,
5937 GLfloat extractComponents
[])
5942 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5945 uint
= *(const GLuint
*)packedPixel
;
5948 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5949 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5950 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5951 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5954 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5955 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5956 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5957 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5959 } /* extract2101010rev() */
5961 static void shove2101010rev(const GLfloat shoveComponents
[],
5962 int index
,void *packedPixel
)
5964 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5965 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5966 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5967 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5969 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5970 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5971 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5972 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5974 /* due to limited precision, need to round before shoving */
5975 ((GLuint
*)packedPixel
)[index
] =
5976 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
5977 ((GLuint
*)packedPixel
)[index
]|=
5978 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
5979 ((GLuint
*)packedPixel
)[index
]|=
5980 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
5981 ((GLuint
*)packedPixel
)[index
]|=
5982 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
5983 } /* shove2101010rev() */
5985 static void scaleInternalPackedPixel(int components
,
5986 void (*extractPackedPixel
)
5987 (int, const void *,GLfloat
[]),
5988 void (*shovePackedPixel
)
5989 (const GLfloat
[], int, void *),
5990 GLint widthIn
,GLint heightIn
,
5992 GLint widthOut
,GLint heightOut
,
5994 GLint pixelSizeInBytes
,
5995 GLint rowSizeInBytes
,GLint isSwap
)
6001 /* Max components in a format is 4, so... */
6003 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
6008 const char *temp
, *temp0
;
6011 int lowx_int
, highx_int
, lowy_int
, highy_int
;
6012 float x_percent
, y_percent
;
6013 float lowx_float
, highx_float
, lowy_float
, highy_float
;
6014 float convy_float
, convx_float
;
6015 int convy_int
, convx_int
;
6017 const char *left
, *right
;
6019 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
6020 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6021 widthIn
, heightIn
, dataIn
, dataOut
,
6022 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6025 convy
= (float) heightIn
/heightOut
;
6026 convx
= (float) widthIn
/widthOut
;
6027 convy_int
= floor(convy
);
6028 convy_float
= convy
- convy_int
;
6029 convx_int
= floor(convx
);
6030 convx_float
= convx
- convx_int
;
6032 area
= convx
* convy
;
6036 highy_int
= convy_int
;
6037 highy_float
= convy_float
;
6039 for (i
= 0; i
< heightOut
; i
++) {
6042 highx_int
= convx_int
;
6043 highx_float
= convx_float
;
6045 for (j
= 0; j
< widthOut
; j
++) {
6047 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6048 ** to (highx, highy) on input data into this pixel on output
6051 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6053 /* calculate the value for pixels in the 1st row */
6054 xindex
= lowx_int
*pixelSizeInBytes
;
6055 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6057 y_percent
= 1-lowy_float
;
6058 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6059 percent
= y_percent
* (1-lowx_float
);
6061 for (k
= 0, temp_index
= temp
; k
< components
;
6062 k
++, temp_index
+= element_size
) {
6064 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6066 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6070 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6071 for (k
= 0; k
< components
; k
++) {
6072 totals
[k
]+= extractTotals
[k
] * percent
;
6076 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6077 temp
+= pixelSizeInBytes
;
6079 for (k
= 0, temp_index
= temp
; k
< components
;
6080 k
++, temp_index
+= element_size
) {
6083 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6085 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6089 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6090 for (k
= 0; k
< components
; k
++) {
6091 totals
[k
]+= extractTotals
[k
] * y_percent
;
6095 temp
+= pixelSizeInBytes
;
6097 percent
= y_percent
* highx_float
;
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
;
6114 /* calculate the value for pixels in the last row */
6116 y_percent
= highy_float
;
6117 percent
= y_percent
* (1-lowx_float
);
6118 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6120 for (k
= 0, temp_index
= temp
; k
< components
;
6121 k
++, temp_index
+= element_size
) {
6123 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6125 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6129 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6130 for (k
= 0; k
< components
; k
++) {
6131 totals
[k
]+= extractTotals
[k
] * percent
;
6134 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6135 temp
+= pixelSizeInBytes
;
6137 for (k
= 0, temp_index
= temp
; k
< components
;
6138 k
++, temp_index
+= element_size
) {
6141 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6143 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6147 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6148 for (k
= 0; k
< components
; k
++) {
6149 totals
[k
]+= extractTotals
[k
] * y_percent
;
6154 temp
+= pixelSizeInBytes
;
6155 percent
= y_percent
* highx_float
;
6157 for (k
= 0, temp_index
= temp
; k
< components
;
6158 k
++, temp_index
+= element_size
) {
6160 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6162 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6166 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6167 for (k
= 0; k
< components
; k
++) {
6168 totals
[k
]+= extractTotals
[k
] * percent
;
6172 /* calculate the value for pixels in the 1st and last column */
6173 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6174 left
+= rowSizeInBytes
;
6175 right
+= rowSizeInBytes
;
6177 for (k
= 0; k
< components
;
6178 k
++, left
+= element_size
, right
+= element_size
) {
6181 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6182 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6184 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6185 + *(const GLushort
*)right
* highx_float
;
6189 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6190 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6191 for (k
= 0; k
< components
; k
++) {
6192 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6193 extractMoreTotals
[k
]*highx_float
);
6197 } else if (highy_int
> lowy_int
) {
6198 x_percent
= highx_float
- lowx_float
;
6199 percent
= (1-lowy_float
)*x_percent
;
6200 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6202 for (k
= 0, temp_index
= temp
; k
< components
;
6203 k
++, temp_index
+= element_size
) {
6205 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6207 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6211 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6212 for (k
= 0; k
< components
; k
++) {
6213 totals
[k
]+= extractTotals
[k
] * percent
;
6216 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6217 temp
+= rowSizeInBytes
;
6219 for (k
= 0, temp_index
= temp
; k
< components
;
6220 k
++, temp_index
+= element_size
) {
6223 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6225 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6229 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6230 for (k
= 0; k
< components
; k
++) {
6231 totals
[k
]+= extractTotals
[k
] * x_percent
;
6235 percent
= x_percent
* highy_float
;
6236 temp
+= rowSizeInBytes
;
6238 for (k
= 0, temp_index
= temp
; k
< components
;
6239 k
++, temp_index
+= element_size
) {
6241 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6243 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6247 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6248 for (k
= 0; k
< components
; k
++) {
6249 totals
[k
]+= extractTotals
[k
] * percent
;
6252 } else if (highx_int
> lowx_int
) {
6253 y_percent
= highy_float
- lowy_float
;
6254 percent
= (1-lowx_float
)*y_percent
;
6255 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6257 for (k
= 0, temp_index
= temp
; k
< components
;
6258 k
++, temp_index
+= element_size
) {
6260 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6262 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6266 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6267 for (k
= 0; k
< components
; k
++) {
6268 totals
[k
]+= extractTotals
[k
] * percent
;
6271 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6272 temp
+= pixelSizeInBytes
;
6274 for (k
= 0, temp_index
= temp
; k
< components
;
6275 k
++, temp_index
+= element_size
) {
6278 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6280 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6284 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6285 for (k
= 0; k
< components
; k
++) {
6286 totals
[k
]+= extractTotals
[k
] * y_percent
;
6290 temp
+= pixelSizeInBytes
;
6291 percent
= y_percent
* highx_float
;
6293 for (k
= 0, temp_index
= temp
; k
< components
;
6294 k
++, temp_index
+= element_size
) {
6296 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6298 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6302 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6303 for (k
= 0; k
< components
; k
++) {
6304 totals
[k
]+= extractTotals
[k
] * percent
;
6308 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6309 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6311 for (k
= 0, temp_index
= temp
; k
< components
;
6312 k
++, temp_index
+= element_size
) {
6314 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6316 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6320 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6321 for (k
= 0; k
< components
; k
++) {
6322 totals
[k
]+= extractTotals
[k
] * percent
;
6327 /* this is for the pixels in the body */
6328 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6329 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6331 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6333 for (k
= 0, temp_index
= temp
; k
< components
;
6334 k
++, temp_index
+= element_size
) {
6336 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6338 totals
[k
] += *(const GLushort
*)temp_index
;
6342 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6343 for (k
= 0; k
< components
; k
++) {
6344 totals
[k
]+= extractTotals
[k
];
6347 temp
+= pixelSizeInBytes
;
6349 temp0
+= rowSizeInBytes
;
6352 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6354 for (k
= 0; k
< components
; k
++) {
6355 dataout
[outindex
+ k
] = totals
[k
]/area
;
6356 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6359 for (k
= 0; k
< components
; k
++) {
6360 shoveTotals
[k
]= totals
[k
]/area
;
6362 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6364 lowx_int
= highx_int
;
6365 lowx_float
= highx_float
;
6366 highx_int
+= convx_int
;
6367 highx_float
+= convx_float
;
6368 if(highx_float
> 1) {
6373 lowy_int
= highy_int
;
6374 lowy_float
= highy_float
;
6375 highy_int
+= convy_int
;
6376 highy_float
+= convy_float
;
6377 if(highy_float
> 1) {
6383 assert(outindex
== (widthOut
*heightOut
- 1));
6384 } /* scaleInternalPackedPixel() */
6386 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6387 * inputs; not always equal. Output NEVER has row padding.
6389 static void halveImagePackedPixel(int components
,
6390 void (*extractPackedPixel
)
6391 (int, const void *,GLfloat
[]),
6392 void (*shovePackedPixel
)
6393 (const GLfloat
[],int, void *),
6394 GLint width
, GLint height
,
6395 const void *dataIn
, void *dataOut
,
6396 GLint pixelSizeInBytes
,
6397 GLint rowSizeInBytes
, GLint isSwap
)
6399 /* handle case where there is only 1 column/row */
6400 if (width
== 1 || height
== 1) {
6401 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6402 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6403 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6404 rowSizeInBytes
,isSwap
);
6411 int halfWidth
= width
/ 2;
6412 int halfHeight
= height
/ 2;
6413 const char *src
= (const char *) dataIn
;
6414 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6417 for (ii
= 0; ii
< halfHeight
; ii
++) {
6418 for (jj
= 0; jj
< halfWidth
; jj
++) {
6420 float totals
[4]; /* 4 is maximum components */
6421 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6424 (*extractPackedPixel
)(isSwap
,src
,
6425 &extractTotals
[0][0]);
6426 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6427 &extractTotals
[1][0]);
6428 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6429 &extractTotals
[2][0]);
6430 (*extractPackedPixel
)(isSwap
,
6431 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6432 &extractTotals
[3][0]);
6433 for (cc
= 0; cc
< components
; cc
++) {
6436 /* grab 4 pixels to average */
6438 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6439 * extractTotals[2][RED]+extractTotals[3][RED];
6440 * totals[RED]/= 4.0;
6442 for (kk
= 0; kk
< BOX4
; kk
++) {
6443 totals
[cc
]+= extractTotals
[kk
][cc
];
6445 totals
[cc
]/= (float)BOX4
;
6447 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6450 /* skip over to next square of 4 */
6451 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6453 /* skip past pad bytes, if any, to get to next row */
6456 /* src is at beginning of a row here, but it's the second row of
6457 * the square block of 4 pixels that we just worked on so we
6458 * need to go one more row.
6466 src
+= rowSizeInBytes
;
6469 /* both pointers must reach one byte after the end */
6470 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6471 assert(outIndex
== halfWidth
* halfHeight
);
6473 } /* halveImagePackedPixel() */
6475 static void halve1DimagePackedPixel(int components
,
6476 void (*extractPackedPixel
)
6477 (int, const void *,GLfloat
[]),
6478 void (*shovePackedPixel
)
6479 (const GLfloat
[],int, void *),
6480 GLint width
, GLint height
,
6481 const void *dataIn
, void *dataOut
,
6482 GLint pixelSizeInBytes
,
6483 GLint rowSizeInBytes
, GLint isSwap
)
6485 int halfWidth
= width
/ 2;
6486 int halfHeight
= height
/ 2;
6487 const char *src
= (const char *) dataIn
;
6490 assert(width
== 1 || height
== 1); /* must be 1D */
6491 assert(width
!= height
); /* can't be square */
6493 if (height
== 1) { /* 1 row */
6496 assert(width
!= 1); /* widthxheight can't be 1x1 */
6499 /* one horizontal row with possible pad bytes */
6501 for (jj
= 0; jj
< halfWidth
; jj
++) {
6503 float totals
[4]; /* 4 is maximum components */
6504 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6507 /* average two at a time, instead of four */
6508 (*extractPackedPixel
)(isSwap
,src
,
6509 &extractTotals
[0][0]);
6510 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6511 &extractTotals
[1][0]);
6512 for (cc
= 0; cc
< components
; cc
++) {
6515 /* grab 2 pixels to average */
6517 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6518 * totals[RED]/= 2.0;
6520 for (kk
= 0; kk
< BOX2
; kk
++) {
6521 totals
[cc
]+= extractTotals
[kk
][cc
];
6523 totals
[cc
]/= (float)BOX2
;
6525 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6528 /* skip over to next group of 2 */
6529 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6533 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6534 src
+= padBytes
; /* for assertion only */
6536 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6537 assert(outIndex
== halfWidth
* halfHeight
);
6539 else if (width
== 1) { /* 1 column */
6542 assert(height
!= 1); /* widthxheight can't be 1x1 */
6544 /* one vertical column with possible pad bytes per row */
6545 /* average two at a time */
6547 for (jj
= 0; jj
< halfHeight
; jj
++) {
6549 float totals
[4]; /* 4 is maximum components */
6550 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6553 /* average two at a time, instead of four */
6554 (*extractPackedPixel
)(isSwap
,src
,
6555 &extractTotals
[0][0]);
6556 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6557 &extractTotals
[1][0]);
6558 for (cc
= 0; cc
< components
; cc
++) {
6561 /* grab 2 pixels to average */
6563 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6564 * totals[RED]/= 2.0;
6566 for (kk
= 0; kk
< BOX2
; kk
++) {
6567 totals
[cc
]+= extractTotals
[kk
][cc
];
6569 totals
[cc
]/= (float)BOX2
;
6571 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6574 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6577 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6578 assert(outIndex
== halfWidth
* halfHeight
);
6580 } /* halve1DimagePackedPixel() */
6582 /*===========================================================================*/
6584 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6586 * This section ensures that GLU 1.3 will load and run on
6587 * a GL 1.1 implementation. It dynamically resolves the
6588 * call to glTexImage3D() which might not be available.
6589 * Or is it might be supported as an extension.
6590 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6593 typedef void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6594 GLenum internalFormat
,
6595 GLsizei width
, GLsizei height
,
6596 GLsizei depth
, GLint border
,
6597 GLenum format
, GLenum type
,
6598 const GLvoid
*pixels
);
6600 GLAPI TexImage3Dproc pTexImage3D
;
6604 # include <sys/types.h>
6606 WINGDIAPI PROC WINAPI
wglGetProcAddress(LPCSTR
);
6609 static void gluTexImage3D( GLenum target
, GLint level
,
6610 GLenum internalFormat
,
6611 GLsizei width
, GLsizei height
,
6612 GLsizei depth
, GLint border
,
6613 GLenum format
, GLenum type
,
6614 const GLvoid
*pixels
)
6618 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6620 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6622 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6623 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6625 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6630 /* Now call glTexImage3D */
6632 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6633 depth
, border
, format
, type
, pixels
);
6638 /* Only bind to a GL 1.2 implementation: */
6639 #define gluTexImage3D glTexImage3D
6643 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6644 GLenum format
, GLenum type
)
6646 int components
= elements_per_group(format
,type
);
6647 int bytes_per_row
= bytes_per_element(type
) * width
;
6649 assert(width
> 0 && height
> 0 && depth
> 0);
6650 assert(type
!= GL_BITMAP
);
6652 return bytes_per_row
* height
* depth
* components
;
6653 } /* imageSize3D() */
6655 static void fillImage3D(const PixelStorageModes
*psm
,
6656 GLint width
, GLint height
, GLint depth
, GLenum format
,
6657 GLenum type
, GLboolean indexFormat
,
6658 const void *userImage
, GLushort
*newImage
)
6667 int elementsPerLine
;
6670 const GLubyte
*start
, *rowStart
, *iter
;
6674 myswapBytes
= psm
->unpack_swap_bytes
;
6675 components
= elements_per_group(format
,type
);
6676 if (psm
->unpack_row_length
> 0) {
6677 groupsPerLine
= psm
->unpack_row_length
;
6680 groupsPerLine
= width
;
6682 elementSize
= bytes_per_element(type
);
6683 groupSize
= elementSize
* components
;
6684 if (elementSize
== 1) myswapBytes
= 0;
6687 if (psm
->unpack_image_height
> 0) {
6688 rowsPerImage
= psm
->unpack_image_height
;
6691 rowsPerImage
= height
;
6695 rowSize
= groupsPerLine
* groupSize
;
6696 padding
= rowSize
% psm
->unpack_alignment
;
6698 rowSize
+= psm
->unpack_alignment
- padding
;
6701 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6703 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6704 psm
->unpack_skip_pixels
* groupSize
+
6706 psm
->unpack_skip_images
* imageSize
;
6707 elementsPerLine
= width
* components
;
6710 for (dd
= 0; dd
< depth
; dd
++) {
6713 for (hh
= 0; hh
< height
; hh
++) {
6716 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6718 float extractComponents
[4];
6721 case GL_UNSIGNED_BYTE
:
6725 *iter2
++ = (*iter
) * 257;
6730 *iter2
++ = *((const GLbyte
*) iter
);
6733 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6736 case GL_UNSIGNED_BYTE_3_3_2
:
6737 extract332(0,iter
,extractComponents
);
6738 for (k
= 0; k
< 3; k
++) {
6739 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6742 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6743 extract233rev(0,iter
,extractComponents
);
6744 for (k
= 0; k
< 3; k
++) {
6745 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6748 case GL_UNSIGNED_SHORT_5_6_5
:
6749 extract565(myswapBytes
,iter
,extractComponents
);
6750 for (k
= 0; k
< 3; k
++) {
6751 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6754 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6755 extract565rev(myswapBytes
,iter
,extractComponents
);
6756 for (k
= 0; k
< 3; k
++) {
6757 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6760 case GL_UNSIGNED_SHORT_4_4_4_4
:
6761 extract4444(myswapBytes
,iter
,extractComponents
);
6762 for (k
= 0; k
< 4; k
++) {
6763 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6766 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6767 extract4444rev(myswapBytes
,iter
,extractComponents
);
6768 for (k
= 0; k
< 4; k
++) {
6769 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6772 case GL_UNSIGNED_SHORT_5_5_5_1
:
6773 extract5551(myswapBytes
,iter
,extractComponents
);
6774 for (k
= 0; k
< 4; k
++) {
6775 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6778 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6779 extract1555rev(myswapBytes
,iter
,extractComponents
);
6780 for (k
= 0; k
< 4; k
++) {
6781 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6784 case GL_UNSIGNED_SHORT
:
6787 widget
.ub
[0] = iter
[1];
6788 widget
.ub
[1] = iter
[0];
6790 widget
.ub
[0] = iter
[0];
6791 widget
.ub
[1] = iter
[1];
6793 if (type
== GL_SHORT
) {
6795 *iter2
++ = widget
.s
[0];
6798 *iter2
++ = widget
.s
[0]*2;
6801 *iter2
++ = widget
.us
[0];
6804 case GL_UNSIGNED_INT_8_8_8_8
:
6805 extract8888(myswapBytes
,iter
,extractComponents
);
6806 for (k
= 0; k
< 4; k
++) {
6807 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6810 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6811 extract8888rev(myswapBytes
,iter
,extractComponents
);
6812 for (k
= 0; k
< 4; k
++) {
6813 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6816 case GL_UNSIGNED_INT_10_10_10_2
:
6817 extract1010102(myswapBytes
,iter
,extractComponents
);
6818 for (k
= 0; k
< 4; k
++) {
6819 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6822 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6823 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6824 for (k
= 0; k
< 4; k
++) {
6825 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6829 case GL_UNSIGNED_INT
:
6832 widget
.ub
[0] = iter
[3];
6833 widget
.ub
[1] = iter
[2];
6834 widget
.ub
[2] = iter
[1];
6835 widget
.ub
[3] = iter
[0];
6837 widget
.ub
[0] = iter
[0];
6838 widget
.ub
[1] = iter
[1];
6839 widget
.ub
[2] = iter
[2];
6840 widget
.ub
[3] = iter
[3];
6842 if (type
== GL_FLOAT
) {
6844 *iter2
++ = widget
.f
;
6846 *iter2
++ = 65535 * widget
.f
;
6848 } else if (type
== GL_UNSIGNED_INT
) {
6850 *iter2
++ = widget
.ui
;
6852 *iter2
++ = widget
.ui
>> 16;
6856 *iter2
++ = widget
.i
;
6858 *iter2
++ = widget
.i
>> 15;
6870 iter
= rowStart
; /* for assertion purposes */
6876 /* iterators should be one byte past end */
6877 if (!isTypePackedPixel(type
)) {
6878 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6881 assert(iter2
== &newImage
[width
*height
*depth
*
6882 elements_per_group(format
,0)]);
6884 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6885 psm
->unpack_skip_rows
* rowSize
+
6886 psm
->unpack_skip_pixels
* groupSize
+
6888 psm
->unpack_skip_images
* imageSize
] );
6889 } /* fillImage3D () */
6891 static void scaleInternal3D(GLint components
,
6892 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6893 const GLushort
*dataIn
,
6894 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6897 float x
, lowx
, highx
, convx
, halfconvx
;
6898 float y
, lowy
, highy
, convy
, halfconvy
;
6899 float z
, lowz
, highz
, convz
, halfconvz
;
6900 float xpercent
,ypercent
,zpercent
;
6902 /* Max components in a format is 4, so... */
6905 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6908 convz
= (float) depthIn
/depthOut
;
6909 convy
= (float) heightIn
/heightOut
;
6910 convx
= (float) widthIn
/widthOut
;
6911 halfconvx
= convx
/2;
6912 halfconvy
= convy
/2;
6913 halfconvz
= convz
/2;
6914 for (d
= 0; d
< depthOut
; d
++) {
6915 z
= convz
* (d
+0.5);
6916 if (depthIn
> depthOut
) {
6917 highz
= z
+ halfconvz
;
6918 lowz
= z
- halfconvz
;
6923 for (i
= 0; i
< heightOut
; i
++) {
6924 y
= convy
* (i
+0.5);
6925 if (heightIn
> heightOut
) {
6926 highy
= y
+ halfconvy
;
6927 lowy
= y
- halfconvy
;
6932 for (j
= 0; j
< widthOut
; j
++) {
6933 x
= convx
* (j
+0.5);
6934 if (widthIn
> widthOut
) {
6935 highx
= x
+ halfconvx
;
6936 lowx
= x
- halfconvx
;
6943 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6944 ** lowz) to (highx, highy, highz) on input data into this pixel
6947 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6953 zindex
= (zint
+ depthIn
) % depthIn
;
6954 if (highz
< zint
+1) {
6955 zpercent
= highz
- z
;
6957 zpercent
= zint
+1 - z
;
6963 yindex
= (yint
+ heightIn
) % heightIn
;
6964 if (highy
< yint
+1) {
6965 ypercent
= highy
- y
;
6967 ypercent
= yint
+1 - y
;
6974 xindex
= (xint
+ widthIn
) % widthIn
;
6975 if (highx
< xint
+1) {
6976 xpercent
= highx
- x
;
6978 xpercent
= xint
+1 - x
;
6981 percent
= xpercent
* ypercent
* zpercent
;
6984 temp
= (xindex
+ (yindex
*widthIn
) +
6985 (zindex
*widthIn
*heightIn
)) * components
;
6986 for (k
= 0; k
< components
; k
++) {
6987 assert(0 <= (temp
+k
) &&
6989 (widthIn
*heightIn
*depthIn
*components
));
6990 totals
[k
] += dataIn
[temp
+ k
] * percent
;
7005 temp
= (j
+ (i
* widthOut
) +
7006 (d
*widthOut
*heightOut
)) * components
;
7007 for (k
= 0; k
< components
; k
++) {
7008 /* totals[] should be rounded in the case of enlarging an
7009 * RGB ramp when the type is 332 or 4444
7011 assert(0 <= (temp
+k
) &&
7012 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
7013 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
7018 } /* scaleInternal3D() */
7020 static void emptyImage3D(const PixelStorageModes
*psm
,
7021 GLint width
, GLint height
, GLint depth
,
7022 GLenum format
, GLenum type
, GLboolean indexFormat
,
7023 const GLushort
*oldImage
, void *userImage
)
7032 GLubyte
*start
, *rowStart
, *iter
;
7033 int elementsPerLine
;
7034 const GLushort
*iter2
;
7039 myswapBytes
= psm
->pack_swap_bytes
;
7040 components
= elements_per_group(format
,type
);
7041 if (psm
->pack_row_length
> 0) {
7042 groupsPerLine
= psm
->pack_row_length
;
7045 groupsPerLine
= width
;
7048 elementSize
= bytes_per_element(type
);
7049 groupSize
= elementSize
* components
;
7050 if (elementSize
== 1) myswapBytes
= 0;
7053 if (psm
->pack_image_height
> 0) {
7054 rowsPerImage
= psm
->pack_image_height
;
7057 rowsPerImage
= height
;
7062 rowSize
= groupsPerLine
* groupSize
;
7063 padding
= rowSize
% psm
->pack_alignment
;
7065 rowSize
+= psm
->pack_alignment
- padding
;
7068 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7070 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7071 psm
->pack_skip_pixels
* groupSize
+
7073 psm
->pack_skip_images
* imageSize
;
7074 elementsPerLine
= width
* components
;
7077 for (dd
= 0; dd
< depth
; dd
++) {
7080 for (ii
= 0; ii
< height
; ii
++) {
7083 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7085 float shoveComponents
[4];
7088 case GL_UNSIGNED_BYTE
:
7092 *iter
= *iter2
++ >> 8;
7097 *((GLbyte
*) iter
) = *iter2
++;
7099 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7102 case GL_UNSIGNED_BYTE_3_3_2
:
7103 for (k
= 0; k
< 3; k
++) {
7104 shoveComponents
[k
]= *iter2
++ / 65535.0;
7106 shove332(shoveComponents
,0,(void *)iter
);
7108 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7109 for (k
= 0; k
< 3; k
++) {
7110 shoveComponents
[k
]= *iter2
++ / 65535.0;
7112 shove233rev(shoveComponents
,0,(void *)iter
);
7114 case GL_UNSIGNED_SHORT_5_6_5
:
7115 for (k
= 0; k
< 3; k
++) {
7116 shoveComponents
[k
]= *iter2
++ / 65535.0;
7118 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7120 iter
[0] = widget
.ub
[1];
7121 iter
[1] = widget
.ub
[0];
7124 *(GLushort
*)iter
= widget
.us
[0];
7127 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7128 for (k
= 0; k
< 3; k
++) {
7129 shoveComponents
[k
]= *iter2
++ / 65535.0;
7131 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7133 iter
[0] = widget
.ub
[1];
7134 iter
[1] = widget
.ub
[0];
7137 *(GLushort
*)iter
= widget
.us
[0];
7140 case GL_UNSIGNED_SHORT_4_4_4_4
:
7141 for (k
= 0; k
< 4; k
++) {
7142 shoveComponents
[k
]= *iter2
++ / 65535.0;
7144 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7146 iter
[0] = widget
.ub
[1];
7147 iter
[1] = widget
.ub
[0];
7149 *(GLushort
*)iter
= widget
.us
[0];
7152 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7153 for (k
= 0; k
< 4; k
++) {
7154 shoveComponents
[k
]= *iter2
++ / 65535.0;
7156 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7158 iter
[0] = widget
.ub
[1];
7159 iter
[1] = widget
.ub
[0];
7161 *(GLushort
*)iter
= widget
.us
[0];
7164 case GL_UNSIGNED_SHORT_5_5_5_1
:
7165 for (k
= 0; k
< 4; k
++) {
7166 shoveComponents
[k
]= *iter2
++ / 65535.0;
7168 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7170 iter
[0] = widget
.ub
[1];
7171 iter
[1] = widget
.ub
[0];
7173 *(GLushort
*)iter
= widget
.us
[0];
7176 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7177 for (k
= 0; k
< 4; k
++) {
7178 shoveComponents
[k
]= *iter2
++ / 65535.0;
7180 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7182 iter
[0] = widget
.ub
[1];
7183 iter
[1] = widget
.ub
[0];
7185 *(GLushort
*)iter
= widget
.us
[0];
7188 case GL_UNSIGNED_SHORT
:
7190 if (type
== GL_SHORT
) {
7192 widget
.s
[0] = *iter2
++;
7194 widget
.s
[0] = *iter2
++ >> 1;
7197 widget
.us
[0] = *iter2
++;
7200 iter
[0] = widget
.ub
[1];
7201 iter
[1] = widget
.ub
[0];
7203 iter
[0] = widget
.ub
[0];
7204 iter
[1] = widget
.ub
[1];
7207 case GL_UNSIGNED_INT_8_8_8_8
:
7208 for (k
= 0; k
< 4; k
++) {
7209 shoveComponents
[k
]= *iter2
++ / 65535.0;
7211 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7213 iter
[3] = widget
.ub
[0];
7214 iter
[2] = widget
.ub
[1];
7215 iter
[1] = widget
.ub
[2];
7216 iter
[0] = widget
.ub
[3];
7218 *(GLuint
*)iter
= widget
.ui
;
7221 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7222 for (k
= 0; k
< 4; k
++) {
7223 shoveComponents
[k
]= *iter2
++ / 65535.0;
7225 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7227 iter
[3] = widget
.ub
[0];
7228 iter
[2] = widget
.ub
[1];
7229 iter
[1] = widget
.ub
[2];
7230 iter
[0] = widget
.ub
[3];
7232 *(GLuint
*)iter
= widget
.ui
;
7235 case GL_UNSIGNED_INT_10_10_10_2
:
7236 for (k
= 0; k
< 4; k
++) {
7237 shoveComponents
[k
]= *iter2
++ / 65535.0;
7239 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7241 iter
[3] = widget
.ub
[0];
7242 iter
[2] = widget
.ub
[1];
7243 iter
[1] = widget
.ub
[2];
7244 iter
[0] = widget
.ub
[3];
7246 *(GLuint
*)iter
= widget
.ui
;
7249 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7250 for (k
= 0; k
< 4; k
++) {
7251 shoveComponents
[k
]= *iter2
++ / 65535.0;
7253 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7255 iter
[3] = widget
.ub
[0];
7256 iter
[2] = widget
.ub
[1];
7257 iter
[1] = widget
.ub
[2];
7258 iter
[0] = widget
.ub
[3];
7260 *(GLuint
*)iter
= widget
.ui
;
7264 case GL_UNSIGNED_INT
:
7266 if (type
== GL_FLOAT
) {
7268 widget
.f
= *iter2
++;
7270 widget
.f
= *iter2
++ / (float) 65535.0;
7272 } else if (type
== GL_UNSIGNED_INT
) {
7274 widget
.ui
= *iter2
++;
7276 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7280 widget
.i
= *iter2
++;
7282 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
7286 iter
[3] = widget
.ub
[0];
7287 iter
[2] = widget
.ub
[1];
7288 iter
[1] = widget
.ub
[2];
7289 iter
[0] = widget
.ub
[3];
7291 iter
[0] = widget
.ub
[0];
7292 iter
[1] = widget
.ub
[1];
7293 iter
[2] = widget
.ub
[2];
7294 iter
[3] = widget
.ub
[3];
7310 /* iterators should be one byte past end */
7311 if (!isTypePackedPixel(type
)) {
7312 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7315 assert(iter2
== &oldImage
[width
*height
*depth
*
7316 elements_per_group(format
,0)]);
7318 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7319 psm
->unpack_skip_rows
* rowSize
+
7320 psm
->unpack_skip_pixels
* groupSize
+
7322 psm
->unpack_skip_images
* imageSize
] );
7323 } /* emptyImage3D() */
7326 int gluScaleImage3D(GLenum format
,
7327 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7328 GLenum typeIn
, const void *dataIn
,
7329 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7330 GLenum typeOut
, void *dataOut
)
7333 GLushort
*beforeImage
, *afterImage
;
7334 PixelStorageModes psm
;
7336 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7337 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7341 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7342 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7343 return GLU_INVALID_VALUE
;
7346 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7347 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7348 return GLU_INVALID_ENUM
;
7350 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7351 return GLU_INVALID_OPERATION
;
7353 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7354 return GLU_INVALID_OPERATION
;
7357 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7358 GL_UNSIGNED_SHORT
));
7359 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7360 GL_UNSIGNED_SHORT
));
7361 if (beforeImage
== NULL
|| afterImage
== NULL
) {
7362 return GLU_OUT_OF_MEMORY
;
7364 retrieveStoreModes3D(&psm
);
7366 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7367 dataIn
, beforeImage
);
7368 components
= elements_per_group(format
,0);
7369 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7370 widthOut
,heightOut
,depthOut
,afterImage
);
7371 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7372 is_index(format
),afterImage
, dataOut
);
7373 free((void *) beforeImage
);
7374 free((void *) afterImage
);
7377 } /* gluScaleImage3D() */
7380 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7381 GLint internalFormat
, GLenum format
, GLenum type
,
7382 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7384 GLint widthPowerOf2
= nearestPower(width
);
7385 GLint heightPowerOf2
= nearestPower(height
);
7386 GLint depthPowerOf2
= nearestPower(depth
);
7390 /* compute level 1 width & height & depth, clamping each at 1 */
7391 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7392 widthPowerOf2
>> 1 :
7394 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7395 heightPowerOf2
>> 1 :
7397 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7398 depthPowerOf2
>> 1 :
7400 GLenum proxyTarget
= GL_PROXY_TEXTURE_3D
;
7401 assert(widthAtLevelOne
> 0);
7402 assert(heightAtLevelOne
> 0);
7403 assert(depthAtLevelOne
> 0);
7405 /* does width x height x depth at level 1 & all their mipmaps fit? */
7406 assert(target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
);
7407 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7409 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7410 0,format
,type
,NULL
);
7411 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7412 /* does it fit??? */
7413 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7414 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7415 depthPowerOf2
== 1) {
7416 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7419 widthPowerOf2
= widthAtLevelOne
;
7420 heightPowerOf2
= heightAtLevelOne
;
7421 depthPowerOf2
= depthAtLevelOne
;
7423 /* else it does fit */
7424 } while (proxyWidth
== 0);
7425 /* loop must terminate! */
7427 /* return the width & height at level 0 that fits */
7428 *newWidth
= widthPowerOf2
;
7429 *newHeight
= heightPowerOf2
;
7430 *newDepth
= depthPowerOf2
;
7431 /*printf("Proxy Textures\n");*/
7432 } /* closestFit3D() */
7434 static void halveImagePackedPixelSlice(int components
,
7435 void (*extractPackedPixel
)
7436 (int, const void *,GLfloat
[]),
7437 void (*shovePackedPixel
)
7438 (const GLfloat
[],int, void *),
7439 GLint width
, GLint height
, GLint depth
,
7440 const void *dataIn
, void *dataOut
,
7441 GLint pixelSizeInBytes
,
7442 GLint rowSizeInBytes
,
7443 GLint imageSizeInBytes
,
7447 int halfWidth
= width
/ 2;
7448 int halfHeight
= height
/ 2;
7449 int halfDepth
= depth
/ 2;
7450 const char *src
= (const char *)dataIn
;
7453 assert((width
== 1 || height
== 1) && depth
>= 2);
7455 if (width
== height
) { /* a 1-pixel column viewed from top */
7456 assert(width
== 1 && height
== 1);
7459 for (ii
= 0; ii
< halfDepth
; ii
++) {
7461 float extractTotals
[BOX2
][4];
7464 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7465 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7466 &extractTotals
[1][0]);
7467 for (cc
= 0; cc
< components
; cc
++) {
7470 /* average 2 pixels since only a column */
7472 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7473 * totals[RED]/= 2.0;
7475 for (kk
= 0; kk
< BOX2
; kk
++) {
7476 totals
[cc
]+= extractTotals
[kk
][cc
];
7478 totals
[cc
]/= (float)BOX2
;
7481 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7483 /* skip over to next group of 2 */
7484 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7487 else if (height
== 1) { /* horizontal slice viewed from top */
7490 for (ii
= 0; ii
< halfDepth
; ii
++) {
7491 for (jj
= 0; jj
< halfWidth
; jj
++) {
7493 float extractTotals
[BOX4
][4];
7496 (*extractPackedPixel
)(isSwap
,src
,
7497 &extractTotals
[0][0]);
7498 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7499 &extractTotals
[1][0]);
7500 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7501 &extractTotals
[2][0]);
7502 (*extractPackedPixel
)(isSwap
,
7503 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7504 &extractTotals
[3][0]);
7505 for (cc
= 0; cc
< components
; cc
++) {
7508 /* grab 4 pixels to average */
7510 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7511 * extractTotals[2][RED]+extractTotals[3][RED];
7512 * totals[RED]/= 4.0;
7514 for (kk
= 0; kk
< BOX4
; kk
++) {
7515 totals
[cc
]+= extractTotals
[kk
][cc
];
7517 totals
[cc
]/= (float)BOX4
;
7519 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7522 /* skip over to next horizontal square of 4 */
7523 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7529 else if (width
== 1) { /* vertical slice viewed from top */
7530 assert(height
!= 1);
7532 for (ii
= 0; ii
< halfDepth
; ii
++) {
7533 for (jj
= 0; jj
< halfHeight
; jj
++) {
7535 float extractTotals
[BOX4
][4];
7538 (*extractPackedPixel
)(isSwap
,src
,
7539 &extractTotals
[0][0]);
7540 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7541 &extractTotals
[1][0]);
7542 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7543 &extractTotals
[2][0]);
7544 (*extractPackedPixel
)(isSwap
,
7545 (src
+imageSizeInBytes
+rowSizeInBytes
),
7546 &extractTotals
[3][0]);
7547 for (cc
= 0; cc
< components
; cc
++) {
7550 /* grab 4 pixels to average */
7552 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7553 * extractTotals[2][RED]+extractTotals[3][RED];
7554 * totals[RED]/= 4.0;
7556 for (kk
= 0; kk
< BOX4
; kk
++) {
7557 totals
[cc
]+= extractTotals
[kk
][cc
];
7559 totals
[cc
]/= (float)BOX4
;
7561 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7565 /* skip over to next vertical square of 4 */
7566 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7572 } /* halveImagePackedPixelSlice() */
7574 static void halveImagePackedPixel3D(int components
,
7575 void (*extractPackedPixel
)
7576 (int, const void *,GLfloat
[]),
7577 void (*shovePackedPixel
)
7578 (const GLfloat
[],int, void *),
7579 GLint width
, GLint height
, GLint depth
,
7580 const void *dataIn
, void *dataOut
,
7581 GLint pixelSizeInBytes
,
7582 GLint rowSizeInBytes
,
7583 GLint imageSizeInBytes
,
7587 assert(1 <= width
&& 1 <= height
);
7589 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7590 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7591 rowSizeInBytes
,isSwap
);
7594 /* a horizontal or vertical slice viewed from top */
7595 else if (width
== 1 || height
== 1) {
7598 halveImagePackedPixelSlice(components
,
7599 extractPackedPixel
,shovePackedPixel
,
7600 width
, height
, depth
, dataIn
, dataOut
,
7601 pixelSizeInBytes
, rowSizeInBytes
,
7602 imageSizeInBytes
, isSwap
);
7608 int halfWidth
= width
/ 2;
7609 int halfHeight
= height
/ 2;
7610 int halfDepth
= depth
/ 2;
7611 const char *src
= (const char *) dataIn
;
7612 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7615 for (dd
= 0; dd
< halfDepth
; dd
++) {
7616 for (ii
= 0; ii
< halfHeight
; ii
++) {
7617 for (jj
= 0; jj
< halfWidth
; jj
++) {
7619 float totals
[4]; /* 4 is maximum components */
7620 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7623 (*extractPackedPixel
)(isSwap
,src
,
7624 &extractTotals
[0][0]);
7625 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7626 &extractTotals
[1][0]);
7627 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7628 &extractTotals
[2][0]);
7629 (*extractPackedPixel
)(isSwap
,
7630 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7631 &extractTotals
[3][0]);
7633 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7634 &extractTotals
[4][0]);
7635 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7636 &extractTotals
[5][0]);
7637 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7638 &extractTotals
[6][0]);
7639 (*extractPackedPixel
)(isSwap
,
7640 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7641 &extractTotals
[7][0]);
7642 for (cc
= 0; cc
< components
; cc
++) {
7645 /* grab 8 pixels to average */
7647 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7648 * extractTotals[2][RED]+extractTotals[3][RED]+
7649 * extractTotals[4][RED]+extractTotals[5][RED]+
7650 * extractTotals[6][RED]+extractTotals[7][RED];
7651 * totals[RED]/= 8.0;
7653 for (kk
= 0; kk
< BOX8
; kk
++) {
7654 totals
[cc
]+= extractTotals
[kk
][cc
];
7656 totals
[cc
]/= (float)BOX8
;
7658 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7661 /* skip over to next square of 4 */
7662 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7664 /* skip past pad bytes, if any, to get to next row */
7667 /* src is at beginning of a row here, but it's the second row of
7668 * the square block of 4 pixels that we just worked on so we
7669 * need to go one more row.
7677 src
+= rowSizeInBytes
;
7680 src
+= imageSizeInBytes
;
7683 /* both pointers must reach one byte after the end */
7684 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7685 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7688 } /* halveImagePackedPixel3D() */
7690 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7694 GLsizei widthPowerOf2
,
7695 GLsizei heightPowerOf2
,
7696 GLsizei depthPowerOf2
,
7697 GLenum format
, GLenum type
,
7699 GLint baseLevel
,GLint maxLevel
,
7702 GLint newWidth
, newHeight
, newDepth
;
7703 GLint level
, levels
;
7704 const void *usersImage
;
7705 void *srcImage
, *dstImage
;
7706 __GLU_INIT_SWAP_IMAGE
;
7710 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7711 GLint rowsPerImage
, imageSize
;
7712 GLint rowSize
, padding
;
7713 PixelStorageModes psm
;
7715 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7716 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7717 assert(type
!= GL_BITMAP
);
7719 srcImage
= dstImage
= NULL
;
7721 newWidth
= widthPowerOf2
;
7722 newHeight
= heightPowerOf2
;
7723 newDepth
= depthPowerOf2
;
7724 levels
= computeLog(newWidth
);
7725 level
= computeLog(newHeight
);
7726 if (level
> levels
) levels
=level
;
7727 level
= computeLog(newDepth
);
7728 if (level
> levels
) levels
=level
;
7732 retrieveStoreModes3D(&psm
);
7733 myswapBytes
= psm
.unpack_swap_bytes
;
7734 cmpts
= elements_per_group(format
,type
);
7735 if (psm
.unpack_row_length
> 0) {
7736 groupsPerLine
= psm
.unpack_row_length
;
7738 groupsPerLine
= width
;
7741 elementSize
= bytes_per_element(type
);
7742 groupSize
= elementSize
* cmpts
;
7743 if (elementSize
== 1) myswapBytes
= 0;
7746 if (psm
.unpack_image_height
> 0) {
7747 rowsPerImage
= psm
.unpack_image_height
;
7750 rowsPerImage
= height
;
7754 rowSize
= groupsPerLine
* groupSize
;
7755 padding
= (rowSize
% psm
.unpack_alignment
);
7757 rowSize
+= psm
.unpack_alignment
- padding
;
7760 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7762 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7763 psm
.unpack_skip_pixels
* groupSize
+
7765 psm
.unpack_skip_images
* imageSize
;
7767 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7768 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7769 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7770 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7771 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7775 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7776 /* Use usersImage for level userLevel */
7777 if (baseLevel
<= level
&& level
<= maxLevel
) {
7778 gluTexImage3D(target
, level
, internalFormat
, width
,
7779 height
, depth
, 0, format
, type
,
7782 if(levels
== 0) { /* we're done. clean up and return */
7783 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7784 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7785 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7786 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7787 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7788 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7789 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7793 int nextWidth
= newWidth
/2;
7794 int nextHeight
= newHeight
/2;
7795 int nextDepth
= newDepth
/2;
7798 if (nextWidth
< 1) nextWidth
= 1;
7799 if (nextHeight
< 1) nextHeight
= 1;
7800 if (nextDepth
< 1) nextDepth
= 1;
7801 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7804 case GL_UNSIGNED_BYTE
:
7805 dstImage
= (GLubyte
*)malloc(memReq
);
7808 dstImage
= (GLbyte
*)malloc(memReq
);
7810 case GL_UNSIGNED_SHORT
:
7811 dstImage
= (GLushort
*)malloc(memReq
);
7814 dstImage
= (GLshort
*)malloc(memReq
);
7816 case GL_UNSIGNED_INT
:
7817 dstImage
= (GLuint
*)malloc(memReq
);
7820 dstImage
= (GLint
*)malloc(memReq
);
7823 dstImage
= (GLfloat
*)malloc(memReq
);
7825 case GL_UNSIGNED_BYTE_3_3_2
:
7826 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7827 dstImage
= (GLubyte
*)malloc(memReq
);
7829 case GL_UNSIGNED_SHORT_5_6_5
:
7830 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7831 case GL_UNSIGNED_SHORT_4_4_4_4
:
7832 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7833 case GL_UNSIGNED_SHORT_5_5_5_1
:
7834 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7835 dstImage
= (GLushort
*)malloc(memReq
);
7837 case GL_UNSIGNED_INT_8_8_8_8
:
7838 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7839 case GL_UNSIGNED_INT_10_10_10_2
:
7840 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7841 dstImage
= (GLuint
*)malloc(memReq
);
7844 return GLU_INVALID_ENUM
; /* assertion */
7846 if (dstImage
== NULL
) {
7847 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7848 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7849 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7850 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7851 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7852 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7853 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7854 return GLU_OUT_OF_MEMORY
;
7858 case GL_UNSIGNED_BYTE
:
7860 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7862 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7863 imageSize
,myswapBytes
);
7866 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7867 elementSize
,rowSize
,groupSize
);
7872 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7874 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7875 imageSize
,myswapBytes
);
7878 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7879 elementSize
,rowSize
,groupSize
);
7882 case GL_UNSIGNED_SHORT
:
7884 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7886 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7887 imageSize
,myswapBytes
);
7890 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7891 elementSize
,rowSize
,groupSize
,myswapBytes
);
7896 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7898 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7899 imageSize
,myswapBytes
);
7902 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7903 elementSize
,rowSize
,groupSize
,myswapBytes
);
7906 case GL_UNSIGNED_INT
:
7908 halveImage3D(cmpts
,extractUint
,shoveUint
,
7910 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7911 imageSize
,myswapBytes
);
7914 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7915 elementSize
,rowSize
,groupSize
,myswapBytes
);
7920 halveImage3D(cmpts
,extractSint
,shoveSint
,
7922 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7923 imageSize
,myswapBytes
);
7926 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7927 elementSize
,rowSize
,groupSize
,myswapBytes
);
7932 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7934 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7935 imageSize
,myswapBytes
);
7938 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7939 elementSize
,rowSize
,groupSize
,myswapBytes
);
7942 case GL_UNSIGNED_BYTE_3_3_2
:
7943 assert(format
== GL_RGB
);
7944 halveImagePackedPixel3D(3,extract332
,shove332
,
7945 width
,height
,depth
,usersImage
,dstImage
,
7946 elementSize
,rowSize
,imageSize
,myswapBytes
);
7948 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7949 assert(format
== GL_RGB
);
7950 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7951 width
,height
,depth
,usersImage
,dstImage
,
7952 elementSize
,rowSize
,imageSize
,myswapBytes
);
7954 case GL_UNSIGNED_SHORT_5_6_5
:
7955 halveImagePackedPixel3D(3,extract565
,shove565
,
7956 width
,height
,depth
,usersImage
,dstImage
,
7957 elementSize
,rowSize
,imageSize
,myswapBytes
);
7959 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7960 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7961 width
,height
,depth
,usersImage
,dstImage
,
7962 elementSize
,rowSize
,imageSize
,myswapBytes
);
7964 case GL_UNSIGNED_SHORT_4_4_4_4
:
7965 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7966 width
,height
,depth
,usersImage
,dstImage
,
7967 elementSize
,rowSize
,imageSize
,myswapBytes
);
7969 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7970 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
7971 width
,height
,depth
,usersImage
,dstImage
,
7972 elementSize
,rowSize
,imageSize
,myswapBytes
);
7974 case GL_UNSIGNED_SHORT_5_5_5_1
:
7975 halveImagePackedPixel3D(4,extract5551
,shove5551
,
7976 width
,height
,depth
,usersImage
,dstImage
,
7977 elementSize
,rowSize
,imageSize
,myswapBytes
);
7979 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7980 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
7981 width
,height
,depth
,usersImage
,dstImage
,
7982 elementSize
,rowSize
,imageSize
,myswapBytes
);
7984 case GL_UNSIGNED_INT_8_8_8_8
:
7985 halveImagePackedPixel3D(4,extract8888
,shove8888
,
7986 width
,height
,depth
,usersImage
,dstImage
,
7987 elementSize
,rowSize
,imageSize
,myswapBytes
);
7989 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7990 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
7991 width
,height
,depth
,usersImage
,dstImage
,
7992 elementSize
,rowSize
,imageSize
,myswapBytes
);
7994 case GL_UNSIGNED_INT_10_10_10_2
:
7995 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
7996 width
,height
,depth
,usersImage
,dstImage
,
7997 elementSize
,rowSize
,imageSize
,myswapBytes
);
7999 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8000 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8001 width
,height
,depth
,usersImage
,dstImage
,
8002 elementSize
,rowSize
,imageSize
,myswapBytes
);
8009 newHeight
= height
/2;
8012 if (newWidth
< 1) newWidth
= 1;
8013 if (newHeight
< 1) newHeight
= 1;
8014 if (newDepth
< 1) newDepth
= 1;
8017 rowSize
= newWidth
* groupSize
;
8018 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8019 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8020 /* Swap srcImage and dstImage */
8021 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8023 case GL_UNSIGNED_BYTE
:
8024 dstImage
= (GLubyte
*)malloc(memReq
);
8027 dstImage
= (GLbyte
*)malloc(memReq
);
8029 case GL_UNSIGNED_SHORT
:
8030 dstImage
= (GLushort
*)malloc(memReq
);
8033 dstImage
= (GLshort
*)malloc(memReq
);
8035 case GL_UNSIGNED_INT
:
8036 dstImage
= (GLuint
*)malloc(memReq
);
8039 dstImage
= (GLint
*)malloc(memReq
);
8042 dstImage
= (GLfloat
*)malloc(memReq
);
8044 case GL_UNSIGNED_BYTE_3_3_2
:
8045 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8046 dstImage
= (GLubyte
*)malloc(memReq
);
8048 case GL_UNSIGNED_SHORT_5_6_5
:
8049 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8050 case GL_UNSIGNED_SHORT_4_4_4_4
:
8051 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8052 case GL_UNSIGNED_SHORT_5_5_5_1
:
8053 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8054 dstImage
= (GLushort
*)malloc(memReq
);
8056 case GL_UNSIGNED_INT_8_8_8_8
:
8057 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8058 case GL_UNSIGNED_INT_10_10_10_2
:
8059 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8060 dstImage
= (GLuint
*)malloc(memReq
);
8063 return GLU_INVALID_ENUM
; /* assertion */
8065 if (dstImage
== NULL
) {
8066 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8067 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8068 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8069 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8070 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8071 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8072 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8073 return GLU_OUT_OF_MEMORY
;
8075 /* level userLevel+1 is in srcImage; level userLevel already saved */
8076 level
= userLevel
+1;
8077 } else {/* user's image is *not* nice power-of-2 sized square */
8078 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8080 case GL_UNSIGNED_BYTE
:
8081 dstImage
= (GLubyte
*)malloc(memReq
);
8084 dstImage
= (GLbyte
*)malloc(memReq
);
8086 case GL_UNSIGNED_SHORT
:
8087 dstImage
= (GLushort
*)malloc(memReq
);
8090 dstImage
= (GLshort
*)malloc(memReq
);
8092 case GL_UNSIGNED_INT
:
8093 dstImage
= (GLuint
*)malloc(memReq
);
8096 dstImage
= (GLint
*)malloc(memReq
);
8099 dstImage
= (GLfloat
*)malloc(memReq
);
8101 case GL_UNSIGNED_BYTE_3_3_2
:
8102 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8103 dstImage
= (GLubyte
*)malloc(memReq
);
8105 case GL_UNSIGNED_SHORT_5_6_5
:
8106 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8107 case GL_UNSIGNED_SHORT_4_4_4_4
:
8108 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8109 case GL_UNSIGNED_SHORT_5_5_5_1
:
8110 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8111 dstImage
= (GLushort
*)malloc(memReq
);
8113 case GL_UNSIGNED_INT_8_8_8_8
:
8114 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8115 case GL_UNSIGNED_INT_10_10_10_2
:
8116 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8117 dstImage
= (GLuint
*)malloc(memReq
);
8120 return GLU_INVALID_ENUM
; /* assertion */
8123 if (dstImage
== NULL
) {
8124 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8125 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8126 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8127 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8128 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8129 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8130 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8131 return GLU_OUT_OF_MEMORY
;
8133 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8134 width,height,depth,newWidth,newHeight,newDepth);*/
8136 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8137 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8140 rowSize
= newWidth
* groupSize
;
8141 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8142 /* Swap dstImage and srcImage */
8143 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8145 if(levels
!= 0) { /* use as little memory as possible */
8147 int nextWidth
= newWidth
/2;
8148 int nextHeight
= newHeight
/2;
8149 int nextDepth
= newDepth
/2;
8150 if (nextWidth
< 1) nextWidth
= 1;
8151 if (nextHeight
< 1) nextHeight
= 1;
8152 if (nextDepth
< 1) nextDepth
= 1;
8154 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8157 case GL_UNSIGNED_BYTE
:
8158 dstImage
= (GLubyte
*)malloc(memReq
);
8161 dstImage
= (GLbyte
*)malloc(memReq
);
8163 case GL_UNSIGNED_SHORT
:
8164 dstImage
= (GLushort
*)malloc(memReq
);
8167 dstImage
= (GLshort
*)malloc(memReq
);
8169 case GL_UNSIGNED_INT
:
8170 dstImage
= (GLuint
*)malloc(memReq
);
8173 dstImage
= (GLint
*)malloc(memReq
);
8176 dstImage
= (GLfloat
*)malloc(memReq
);
8178 case GL_UNSIGNED_BYTE_3_3_2
:
8179 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8180 dstImage
= (GLubyte
*)malloc(memReq
);
8182 case GL_UNSIGNED_SHORT_5_6_5
:
8183 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8184 case GL_UNSIGNED_SHORT_4_4_4_4
:
8185 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8186 case GL_UNSIGNED_SHORT_5_5_5_1
:
8187 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8188 dstImage
= (GLushort
*)malloc(memReq
);
8190 case GL_UNSIGNED_INT_8_8_8_8
:
8191 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8192 case GL_UNSIGNED_INT_10_10_10_2
:
8193 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8194 dstImage
= (GLuint
*)malloc(memReq
);
8197 return GLU_INVALID_ENUM
; /* assertion */
8199 if (dstImage
== NULL
) {
8200 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8201 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8202 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8203 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8204 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8205 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8206 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8207 return GLU_OUT_OF_MEMORY
;
8210 /* level userLevel is in srcImage; nothing saved yet */
8214 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8215 if (baseLevel
<= level
&& level
<= maxLevel
) {
8216 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8217 0,format
, type
, (void *)srcImage
);
8219 level
++; /* update current level for the loop */
8220 for (; level
<= levels
; level
++) {
8222 case GL_UNSIGNED_BYTE
:
8224 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8225 newWidth
,newHeight
,newDepth
,
8226 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8227 imageSize
,myswapBytes
);
8230 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8231 elementSize
,rowSize
,groupSize
);
8236 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8237 newWidth
,newHeight
,newDepth
,
8238 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8239 imageSize
,myswapBytes
);
8242 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8243 elementSize
,rowSize
,groupSize
);
8246 case GL_UNSIGNED_SHORT
:
8248 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8249 newWidth
,newHeight
,newDepth
,
8250 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8251 imageSize
,myswapBytes
);
8254 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8255 elementSize
,rowSize
,groupSize
,myswapBytes
);
8260 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8261 newWidth
,newHeight
,newDepth
,
8262 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8263 imageSize
,myswapBytes
);
8266 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8267 elementSize
,rowSize
,groupSize
,myswapBytes
);
8270 case GL_UNSIGNED_INT
:
8272 halveImage3D(cmpts
,extractUint
,shoveUint
,
8273 newWidth
,newHeight
,newDepth
,
8274 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8275 imageSize
,myswapBytes
);
8278 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8279 elementSize
,rowSize
,groupSize
,myswapBytes
);
8284 halveImage3D(cmpts
,extractSint
,shoveSint
,
8285 newWidth
,newHeight
,newDepth
,
8286 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8287 imageSize
,myswapBytes
);
8290 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8291 elementSize
,rowSize
,groupSize
,myswapBytes
);
8296 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8297 newWidth
,newHeight
,newDepth
,
8298 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8299 imageSize
,myswapBytes
);
8302 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8303 elementSize
,rowSize
,groupSize
,myswapBytes
);
8306 case GL_UNSIGNED_BYTE_3_3_2
:
8307 halveImagePackedPixel3D(3,extract332
,shove332
,
8308 newWidth
,newHeight
,newDepth
,
8309 srcImage
,dstImage
,elementSize
,rowSize
,
8310 imageSize
,myswapBytes
);
8312 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8313 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8314 newWidth
,newHeight
,newDepth
,
8315 srcImage
,dstImage
,elementSize
,rowSize
,
8316 imageSize
,myswapBytes
);
8318 case GL_UNSIGNED_SHORT_5_6_5
:
8319 halveImagePackedPixel3D(3,extract565
,shove565
,
8320 newWidth
,newHeight
,newDepth
,
8321 srcImage
,dstImage
,elementSize
,rowSize
,
8322 imageSize
,myswapBytes
);
8324 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8325 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8326 newWidth
,newHeight
,newDepth
,
8327 srcImage
,dstImage
,elementSize
,rowSize
,
8328 imageSize
,myswapBytes
);
8330 case GL_UNSIGNED_SHORT_4_4_4_4
:
8331 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8332 newWidth
,newHeight
,newDepth
,
8333 srcImage
,dstImage
,elementSize
,rowSize
,
8334 imageSize
,myswapBytes
);
8336 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8337 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8338 newWidth
,newHeight
,newDepth
,
8339 srcImage
,dstImage
,elementSize
,rowSize
,
8340 imageSize
,myswapBytes
);
8342 case GL_UNSIGNED_SHORT_5_5_5_1
:
8343 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8344 newWidth
,newHeight
,newDepth
,
8345 srcImage
,dstImage
,elementSize
,rowSize
,
8346 imageSize
,myswapBytes
);
8348 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8349 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8350 newWidth
,newHeight
,newDepth
,
8351 srcImage
,dstImage
,elementSize
,rowSize
,
8352 imageSize
,myswapBytes
);
8354 case GL_UNSIGNED_INT_8_8_8_8
:
8355 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8356 newWidth
,newHeight
,newDepth
,
8357 srcImage
,dstImage
,elementSize
,rowSize
,
8358 imageSize
,myswapBytes
);
8360 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8361 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8362 newWidth
,newHeight
,newDepth
,
8363 srcImage
,dstImage
,elementSize
,rowSize
,
8364 imageSize
,myswapBytes
);
8366 case GL_UNSIGNED_INT_10_10_10_2
:
8367 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8368 newWidth
,newHeight
,newDepth
,
8369 srcImage
,dstImage
,elementSize
,rowSize
,
8370 imageSize
,myswapBytes
);
8372 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8373 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8374 newWidth
,newHeight
,newDepth
,
8375 srcImage
,dstImage
,elementSize
,rowSize
,
8376 imageSize
,myswapBytes
);
8383 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8385 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8386 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8387 if (newDepth
> 1) newDepth
/= 2;
8389 /* call tex image with srcImage untouched since it's not padded */
8390 if (baseLevel
<= level
&& level
<= maxLevel
) {
8391 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8392 newDepth
,0, format
, type
, (void *) srcImage
);
8396 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8397 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8398 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8399 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8400 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8401 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8402 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8404 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8405 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8409 } /* gluBuild3DMipmapLevelsCore() */
8412 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8413 GLsizei width
, GLsizei height
, GLsizei depth
,
8414 GLenum format
, GLenum type
,
8415 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8420 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8421 if (rc
!= 0) return rc
;
8423 if (width
< 1 || height
< 1 || depth
< 1) {
8424 return GLU_INVALID_VALUE
;
8427 if(type
== GL_BITMAP
) {
8428 return GLU_INVALID_ENUM
;
8431 levels
= computeLog(width
);
8432 level
= computeLog(height
);
8433 if (level
> levels
) levels
=level
;
8434 level
= computeLog(depth
);
8435 if (level
> levels
) levels
=level
;
8438 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8439 return GLU_INVALID_VALUE
;
8441 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8442 width
, height
, depth
,
8443 width
, height
, depth
,
8445 userLevel
, baseLevel
, maxLevel
,
8447 } /* gluBuild3DMipmapLevels() */
8450 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8451 GLsizei width
, GLsizei height
, GLsizei depth
,
8452 GLenum format
, GLenum type
, const void *data
)
8454 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8457 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8458 if (rc
!= 0) return rc
;
8460 if (width
< 1 || height
< 1 || depth
< 1) {
8461 return GLU_INVALID_VALUE
;
8464 if(type
== GL_BITMAP
) {
8465 return GLU_INVALID_ENUM
;
8468 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8469 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8471 levels
= computeLog(widthPowerOf2
);
8472 level
= computeLog(heightPowerOf2
);
8473 if (level
> levels
) levels
=level
;
8474 level
= computeLog(depthPowerOf2
);
8475 if (level
> levels
) levels
=level
;
8477 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8478 width
, height
, depth
,
8479 widthPowerOf2
, heightPowerOf2
,
8481 format
, type
, 0, 0, levels
,
8483 } /* gluBuild3DMipmaps() */
8485 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8487 isSwap
= isSwap
; /* turn off warnings */
8489 assert(*((const GLubyte
*)ubyte
) <= 255);
8491 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8492 } /* extractUbyte() */
8494 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8496 assert(0.0 <= value
&& value
< 256.0);
8498 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8499 } /* shoveUbyte() */
8501 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8503 isSwap
= isSwap
; /* turn off warnings */
8505 assert(*((const GLbyte
*)sbyte
) <= 127);
8507 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8508 } /* extractSbyte() */
8510 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8512 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8513 } /* shoveSbyte() */
8515 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8520 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8523 ushort
= *(const GLushort
*)uitem
;
8526 assert(ushort
<= 65535);
8528 return (GLdouble
)ushort
;
8529 } /* extractUshort() */
8531 static void shoveUshort(GLdouble value
, int index
, void *data
)
8533 assert(0.0 <= value
&& value
< 65536.0);
8535 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8536 } /* shoveUshort() */
8538 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8543 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8546 sshort
= *(const GLshort
*)sitem
;
8549 assert(sshort
<= 32767);
8551 return (GLdouble
)sshort
;
8552 } /* extractSshort() */
8554 static void shoveSshort(GLdouble value
, int index
, void *data
)
8556 assert(0.0 <= value
&& value
< 32768.0);
8558 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8559 } /* shoveSshort() */
8561 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8566 uint
= __GLU_SWAP_4_BYTES(uitem
);
8569 uint
= *(const GLuint
*)uitem
;
8572 assert(uint
<= 0xffffffff);
8574 return (GLdouble
)uint
;
8575 } /* extractUint() */
8577 static void shoveUint(GLdouble value
, int index
, void *data
)
8579 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8581 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8584 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8589 sint
= __GLU_SWAP_4_BYTES(sitem
);
8592 sint
= *(const GLint
*)sitem
;
8595 assert(sint
<= 0x7fffffff);
8597 return (GLdouble
)sint
;
8598 } /* extractSint() */
8600 static void shoveSint(GLdouble value
, int index
, void *data
)
8602 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8604 ((GLint
*)data
)[index
]= (GLint
)value
;
8607 static GLdouble
extractFloat(int isSwap
, const void *item
)
8612 ffloat
= __GLU_SWAP_4_BYTES(item
);
8615 ffloat
= *(const GLfloat
*)item
;
8618 assert(ffloat
<= 1.0);
8620 return (GLdouble
)ffloat
;
8621 } /* extractFloat() */
8623 static void shoveFloat(GLdouble value
, int index
, void *data
)
8625 assert(0.0 <= value
&& value
<= 1.0);
8627 ((GLfloat
*)data
)[index
]= value
;
8628 } /* shoveFloat() */
8630 static void halveImageSlice(int components
,
8631 GLdouble (*extract
)(int, const void *),
8632 void (*shove
)(GLdouble
, int, void *),
8633 GLint width
, GLint height
, GLint depth
,
8634 const void *dataIn
, void *dataOut
,
8635 GLint elementSizeInBytes
,
8636 GLint groupSizeInBytes
,
8637 GLint rowSizeInBytes
,
8638 GLint imageSizeInBytes
,
8642 int halfWidth
= width
/ 2;
8643 int halfHeight
= height
/ 2;
8644 int halfDepth
= depth
/ 2;
8645 const char *src
= (const char *)dataIn
;
8646 int padBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8649 assert((width
== 1 || height
== 1) && depth
>= 2);
8651 if (width
== height
) { /* a 1-pixel column viewed from top */
8652 /* printf("1-column\n");*/
8653 assert(width
== 1 && height
== 1);
8656 for (ii
= 0; ii
< halfDepth
; ii
++) {
8659 for (cc
= 0; cc
< components
; cc
++) {
8661 double extractTotals
[BOX2
][4];
8664 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8665 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8667 /* average 2 pixels since only a column */
8669 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8670 * totals[RED]/= 2.0;
8672 for (kk
= 0; kk
< BOX2
; kk
++) {
8673 totals
[cc
]+= extractTotals
[kk
][cc
];
8675 totals
[cc
]/= (double)BOX2
;
8677 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8679 src
+= elementSizeInBytes
;
8682 /* skip over to next group of 2 */
8683 src
+= rowSizeInBytes
;
8686 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8687 assert(outIndex
== halfDepth
* components
);
8689 else if (height
== 1) { /* horizontal slice viewed from top */
8690 /* printf("horizontal slice\n"); */
8693 for (ii
= 0; ii
< halfDepth
; ii
++) {
8694 for (jj
= 0; jj
< halfWidth
; jj
++) {
8697 for (cc
= 0; cc
< components
; cc
++) {
8700 double extractTotals
[BOX4
][4];
8702 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8703 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8704 (src
+groupSizeInBytes
));
8705 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8706 (src
+imageSizeInBytes
));
8707 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8708 (src
+imageSizeInBytes
+groupSizeInBytes
));
8710 /* grab 4 pixels to average */
8712 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8713 * extractTotals[2][RED]+extractTotals[3][RED];
8714 * totals[RED]/= 4.0;
8716 for (kk
= 0; kk
< BOX4
; kk
++) {
8717 totals
[cc
]+= extractTotals
[kk
][cc
];
8719 totals
[cc
]/= (double)BOX4
;
8721 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8724 src
+= elementSizeInBytes
;
8727 /* skip over to next horizontal square of 4 */
8728 src
+= groupSizeInBytes
;
8732 src
+= rowSizeInBytes
;
8735 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8736 assert(outIndex
== halfWidth
* halfDepth
* components
);
8738 else if (width
== 1) { /* vertical slice viewed from top */
8739 /* printf("vertical slice\n"); */
8740 assert(height
!= 1);
8742 for (ii
= 0; ii
< halfDepth
; ii
++) {
8743 for (jj
= 0; jj
< halfHeight
; jj
++) {
8746 for (cc
= 0; cc
< components
; cc
++) {
8749 double extractTotals
[BOX4
][4];
8751 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8752 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8753 (src
+rowSizeInBytes
));
8754 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8755 (src
+imageSizeInBytes
));
8756 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8757 (src
+imageSizeInBytes
+rowSizeInBytes
));
8759 /* grab 4 pixels to average */
8761 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8762 * extractTotals[2][RED]+extractTotals[3][RED];
8763 * totals[RED]/= 4.0;
8765 for (kk
= 0; kk
< BOX4
; kk
++) {
8766 totals
[cc
]+= extractTotals
[kk
][cc
];
8768 totals
[cc
]/= (double)BOX4
;
8770 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8773 src
+= elementSizeInBytes
;
8777 /* skip over to next vertical square of 4 */
8778 src
+= rowSizeInBytes
;
8781 src
+= imageSizeInBytes
;
8784 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8785 assert(outIndex
== halfHeight
* halfDepth
* components
);
8788 } /* halveImageSlice() */
8790 static void halveImage3D(int components
,
8791 GLdouble (*extract
)(int, const void *),
8792 void (*shove
)(GLdouble
, int, void *),
8793 GLint width
, GLint height
, GLint depth
,
8794 const void *dataIn
, void *dataOut
,
8795 GLint elementSizeInBytes
,
8796 GLint groupSizeInBytes
,
8797 GLint rowSizeInBytes
,
8798 GLint imageSizeInBytes
,
8803 /* a horizontal/vertical/one-column slice viewed from top */
8804 if (width
== 1 || height
== 1) {
8807 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8808 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8809 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8815 int halfWidth
= width
/ 2;
8816 int halfHeight
= height
/ 2;
8817 int halfDepth
= depth
/ 2;
8818 const char *src
= (const char *) dataIn
;
8819 int padBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8822 for (dd
= 0; dd
< halfDepth
; dd
++) {
8823 for (ii
= 0; ii
< halfHeight
; ii
++) {
8824 for (jj
= 0; jj
< halfWidth
; jj
++) {
8827 for (cc
= 0; cc
< components
; cc
++) {
8830 double totals
[4]; /* 4 is maximum components */
8831 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8833 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8834 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8835 (src
+groupSizeInBytes
));
8836 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8837 (src
+rowSizeInBytes
));
8838 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8839 (src
+rowSizeInBytes
+groupSizeInBytes
));
8841 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8842 (src
+imageSizeInBytes
));
8844 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8845 (src
+groupSizeInBytes
+imageSizeInBytes
));
8846 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8847 (src
+rowSizeInBytes
+imageSizeInBytes
));
8848 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8849 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8853 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8854 * extractTotals[2][RED]+extractTotals[3][RED]+
8855 * extractTotals[4][RED]+extractTotals[5][RED]+
8856 * extractTotals[6][RED]+extractTotals[7][RED];
8857 * totals[RED]/= 8.0;
8859 for (kk
= 0; kk
< BOX8
; kk
++) {
8860 totals
[cc
]+= extractTotals
[kk
][cc
];
8862 totals
[cc
]/= (double)BOX8
;
8864 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8868 src
+= elementSizeInBytes
; /* go to next component */
8871 /* skip over to next square of 4 */
8872 src
+= groupSizeInBytes
;
8874 /* skip past pad bytes, if any, to get to next row */
8877 /* src is at beginning of a row here, but it's the second row of
8878 * the square block of 4 pixels that we just worked on so we
8879 * need to go one more row.
8887 src
+= rowSizeInBytes
;
8890 src
+= imageSizeInBytes
;
8893 /* both pointers must reach one byte after the end */
8894 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8895 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8897 } /* halveImage3D() */