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
;
384 /* handle case where there is only 1 column/row */
385 if (width
== 1 || height
== 1) {
386 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
387 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
388 element_size
,ysize
,group_size
);
392 newwidth
= width
/ 2;
393 newheight
= height
/ 2;
394 padBytes
= ysize
- (width
*group_size
);
396 t
= (const char *)datain
;
399 for (i
= 0; i
< newheight
; i
++) {
400 for (j
= 0; j
< newwidth
; j
++) {
401 for (k
= 0; k
< components
; k
++) {
402 s
[0] = (*(const GLubyte
*)t
+
403 *(const GLubyte
*)(t
+group_size
) +
404 *(const GLubyte
*)(t
+ysize
) +
405 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
406 s
++; t
+= element_size
;
416 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
417 const GLubyte
*dataIn
, GLubyte
*dataOut
,
418 GLint element_size
, GLint ysize
,
421 GLint halfWidth
= width
/ 2;
422 GLint halfHeight
= height
/ 2;
423 const char *src
= (const char *) dataIn
;
424 GLubyte
*dest
= dataOut
;
427 assert(width
== 1 || height
== 1); /* must be 1D */
428 assert(width
!= height
); /* can't be square */
430 if (height
== 1) { /* 1 row */
431 assert(width
!= 1); /* widthxheight can't be 1x1 */
434 for (jj
= 0; jj
< halfWidth
; jj
++) {
436 for (kk
= 0; kk
< components
; kk
++) {
437 *dest
= (*(const GLubyte
*)src
+
438 *(const GLubyte
*)(src
+group_size
)) / 2;
443 src
+= group_size
; /* skip to next 2 */
446 int padBytes
= ysize
- (width
*group_size
);
447 src
+= padBytes
; /* for assertion only */
450 else if (width
== 1) { /* 1 column */
451 int padBytes
= ysize
- (width
* group_size
);
452 assert(height
!= 1); /* widthxheight can't be 1x1 */
454 /* one vertical column with possible pad bytes per row */
455 /* average two at a time */
457 for (jj
= 0; jj
< halfHeight
; jj
++) {
459 for (kk
= 0; kk
< components
; kk
++) {
460 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
465 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
470 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
471 assert((char *)dest
== &((char *)dataOut
)
472 [components
* element_size
* halfWidth
* halfHeight
]);
473 } /* halve1Dimage_ubyte() */
475 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
476 const GLbyte
*datain
, GLbyte
*dataout
,
478 GLint ysize
, GLint group_size
)
481 int newwidth
, newheight
;
486 /* handle case where there is only 1 column/row */
487 if (width
== 1 || height
== 1) {
488 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
489 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
490 element_size
,ysize
,group_size
);
494 newwidth
= width
/ 2;
495 newheight
= height
/ 2;
496 padBytes
= ysize
- (width
*group_size
);
498 t
= (const char *)datain
;
501 for (i
= 0; i
< newheight
; i
++) {
502 for (j
= 0; j
< newwidth
; j
++) {
503 for (k
= 0; k
< components
; k
++) {
504 s
[0] = (*(const GLbyte
*)t
+
505 *(const GLbyte
*)(t
+group_size
) +
506 *(const GLbyte
*)(t
+ysize
) +
507 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
508 s
++; t
+= element_size
;
517 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
518 const GLbyte
*dataIn
, GLbyte
*dataOut
,
519 GLint element_size
,GLint ysize
, GLint group_size
)
521 GLint halfWidth
= width
/ 2;
522 GLint halfHeight
= height
/ 2;
523 const char *src
= (const char *) dataIn
;
524 GLbyte
*dest
= dataOut
;
527 assert(width
== 1 || height
== 1); /* must be 1D */
528 assert(width
!= height
); /* can't be square */
530 if (height
== 1) { /* 1 row */
531 assert(width
!= 1); /* widthxheight can't be 1x1 */
534 for (jj
= 0; jj
< halfWidth
; jj
++) {
536 for (kk
= 0; kk
< components
; kk
++) {
537 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
542 src
+= group_size
; /* skip to next 2 */
545 int padBytes
= ysize
- (width
*group_size
);
546 src
+= padBytes
; /* for assertion only */
549 else if (width
== 1) { /* 1 column */
550 int padBytes
= ysize
- (width
* group_size
);
551 assert(height
!= 1); /* widthxheight can't be 1x1 */
553 /* one vertical column with possible pad bytes per row */
554 /* average two at a time */
556 for (jj
= 0; jj
< halfHeight
; jj
++) {
558 for (kk
= 0; kk
< components
; kk
++) {
559 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
564 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
568 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
571 assert((char *)dest
== &((char *)dataOut
)
572 [components
* element_size
* halfWidth
* halfHeight
]);
573 } /* halve1Dimage_byte() */
575 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
576 const GLushort
*datain
, GLushort
*dataout
,
577 GLint element_size
, GLint ysize
, GLint group_size
,
581 int newwidth
, newheight
;
586 /* handle case where there is only 1 column/row */
587 if (width
== 1 || height
== 1) {
588 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
589 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
590 element_size
,ysize
,group_size
, myswap_bytes
);
594 newwidth
= width
/ 2;
595 newheight
= height
/ 2;
596 padBytes
= ysize
- (width
*group_size
);
598 t
= (const char *)datain
;
602 for (i
= 0; i
< newheight
; i
++) {
603 for (j
= 0; j
< newwidth
; j
++) {
604 for (k
= 0; k
< components
; k
++) {
605 s
[0] = (*(const GLushort
*)t
+
606 *(const GLushort
*)(t
+group_size
) +
607 *(const GLushort
*)(t
+ysize
) +
608 *(const GLushort
*)(t
+ysize
+group_size
) + 2) / 4;
609 s
++; t
+= element_size
;
617 for (i
= 0; i
< newheight
; i
++) {
618 for (j
= 0; j
< newwidth
; j
++) {
619 for (k
= 0; k
< components
; k
++) {
620 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
621 __GLU_SWAP_2_BYTES(t
+group_size
) +
622 __GLU_SWAP_2_BYTES(t
+ysize
) +
623 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
624 s
++; t
+= element_size
;
633 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
634 const GLushort
*dataIn
, GLushort
*dataOut
,
635 GLint element_size
, GLint ysize
,
636 GLint group_size
, GLint myswap_bytes
)
638 GLint halfWidth
= width
/ 2;
639 GLint halfHeight
= height
/ 2;
640 const char *src
= (const char *) dataIn
;
641 GLushort
*dest
= dataOut
;
644 assert(width
== 1 || height
== 1); /* must be 1D */
645 assert(width
!= height
); /* can't be square */
647 if (height
== 1) { /* 1 row */
648 assert(width
!= 1); /* widthxheight can't be 1x1 */
651 for (jj
= 0; jj
< halfWidth
; jj
++) {
653 for (kk
= 0; kk
< components
; kk
++) {
655 GLushort ushort
[BOX2
];
657 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
658 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
661 ushort
[0]= *(const GLushort
*)src
;
662 ushort
[1]= *(const GLushort
*)(src
+group_size
);
665 *dest
= (ushort
[0] + ushort
[1]) / 2;
669 src
+= group_size
; /* skip to next 2 */
672 int padBytes
= ysize
- (width
*group_size
);
673 src
+= padBytes
; /* for assertion only */
676 else if (width
== 1) { /* 1 column */
677 int padBytes
= ysize
- (width
* group_size
);
678 assert(height
!= 1); /* widthxheight can't be 1x1 */
680 /* one vertical column with possible pad bytes per row */
681 /* average two at a time */
683 for (jj
= 0; jj
< halfHeight
; jj
++) {
685 for (kk
= 0; kk
< components
; kk
++) {
687 GLushort ushort
[BOX2
];
689 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
690 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
693 ushort
[0]= *(const GLushort
*)src
;
694 ushort
[1]= *(const GLushort
*)(src
+ysize
);
696 *dest
= (ushort
[0] + ushort
[1]) / 2;
701 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
705 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
708 assert((char *)dest
== &((char *)dataOut
)
709 [components
* element_size
* halfWidth
* halfHeight
]);
711 } /* halve1Dimage_ushort() */
714 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
715 const GLshort
*datain
, GLshort
*dataout
,
716 GLint element_size
, GLint ysize
, GLint group_size
,
720 int newwidth
, newheight
;
725 /* handle case where there is only 1 column/row */
726 if (width
== 1 || height
== 1) {
727 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
728 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
729 element_size
,ysize
,group_size
, myswap_bytes
);
733 newwidth
= width
/ 2;
734 newheight
= height
/ 2;
735 padBytes
= ysize
- (width
*group_size
);
737 t
= (const char *)datain
;
741 for (i
= 0; i
< newheight
; i
++) {
742 for (j
= 0; j
< newwidth
; j
++) {
743 for (k
= 0; k
< components
; k
++) {
744 s
[0] = (*(const GLshort
*)t
+
745 *(const GLshort
*)(t
+group_size
) +
746 *(const GLshort
*)(t
+ysize
) +
747 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
748 s
++; t
+= element_size
;
756 for (i
= 0; i
< newheight
; i
++) {
757 for (j
= 0; j
< newwidth
; j
++) {
758 for (k
= 0; k
< components
; k
++) {
761 b
= __GLU_SWAP_2_BYTES(t
);
762 buf
= *(const GLshort
*)&b
;
763 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
764 buf
+= *(const GLshort
*)&b
;
765 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
766 buf
+= *(const GLshort
*)&b
;
767 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
768 buf
+= *(const GLshort
*)&b
;
769 s
[0] = (GLshort
)((buf
+2)/4);
770 s
++; t
+= element_size
;
779 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
780 const GLshort
*dataIn
, GLshort
*dataOut
,
781 GLint element_size
, GLint ysize
,
782 GLint group_size
, GLint myswap_bytes
)
784 GLint halfWidth
= width
/ 2;
785 GLint halfHeight
= height
/ 2;
786 const char *src
= (const char *) dataIn
;
787 GLshort
*dest
= dataOut
;
790 assert(width
== 1 || height
== 1); /* must be 1D */
791 assert(width
!= height
); /* can't be square */
793 if (height
== 1) { /* 1 row */
794 assert(width
!= 1); /* widthxheight can't be 1x1 */
797 for (jj
= 0; jj
< halfWidth
; jj
++) {
799 for (kk
= 0; kk
< components
; kk
++) {
801 GLshort sshort
[BOX2
];
803 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
804 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
807 sshort
[0]= *(const GLshort
*)src
;
808 sshort
[1]= *(const GLshort
*)(src
+group_size
);
811 *dest
= (sshort
[0] + sshort
[1]) / 2;
815 src
+= group_size
; /* skip to next 2 */
818 int padBytes
= ysize
- (width
*group_size
);
819 src
+= padBytes
; /* for assertion only */
822 else if (width
== 1) { /* 1 column */
823 int padBytes
= ysize
- (width
* group_size
);
824 assert(height
!= 1); /* widthxheight can't be 1x1 */
826 /* one vertical column with possible pad bytes per row */
827 /* average two at a time */
829 for (jj
= 0; jj
< halfHeight
; jj
++) {
831 for (kk
= 0; kk
< components
; kk
++) {
833 GLshort sshort
[BOX2
];
835 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
836 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
839 sshort
[0]= *(const GLshort
*)src
;
840 sshort
[1]= *(const GLshort
*)(src
+ysize
);
842 *dest
= (sshort
[0] + sshort
[1]) / 2;
847 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
851 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
854 assert((char *)dest
== &((char *)dataOut
)
855 [components
* element_size
* halfWidth
* halfHeight
]);
857 } /* halve1Dimage_short() */
860 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
861 const GLuint
*datain
, GLuint
*dataout
,
862 GLint element_size
, GLint ysize
, GLint group_size
,
866 int newwidth
, newheight
;
871 /* handle case where there is only 1 column/row */
872 if (width
== 1 || height
== 1) {
873 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
874 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
875 element_size
,ysize
,group_size
, myswap_bytes
);
879 newwidth
= width
/ 2;
880 newheight
= height
/ 2;
881 padBytes
= ysize
- (width
*group_size
);
883 t
= (const char *)datain
;
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 */
891 s
[0] = ((double)*(const GLuint
*)t
+
892 (double)*(const GLuint
*)(t
+group_size
) +
893 (double)*(const GLuint
*)(t
+ysize
) +
894 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
895 s
++; t
+= element_size
;
904 for (i
= 0; i
< newheight
; i
++) {
905 for (j
= 0; j
< newwidth
; j
++) {
906 for (k
= 0; k
< components
; k
++) {
907 /* need to cast to double to hold large unsigned ints */
909 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
910 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
911 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
912 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
913 s
[0] = (GLuint
)(buf
/4 + 0.5);
915 s
++; t
+= element_size
;
925 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
926 const GLuint
*dataIn
, GLuint
*dataOut
,
927 GLint element_size
, GLint ysize
,
928 GLint group_size
, GLint myswap_bytes
)
930 GLint halfWidth
= width
/ 2;
931 GLint halfHeight
= height
/ 2;
932 const char *src
= (const char *) dataIn
;
933 GLuint
*dest
= dataOut
;
936 assert(width
== 1 || height
== 1); /* must be 1D */
937 assert(width
!= height
); /* can't be square */
939 if (height
== 1) { /* 1 row */
940 assert(width
!= 1); /* widthxheight can't be 1x1 */
943 for (jj
= 0; jj
< halfWidth
; jj
++) {
945 for (kk
= 0; kk
< components
; kk
++) {
949 uint
[0]= __GLU_SWAP_4_BYTES(src
);
950 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
953 uint
[0]= *(const GLuint
*)src
;
954 uint
[1]= *(const GLuint
*)(src
+group_size
);
956 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
961 src
+= group_size
; /* skip to next 2 */
964 int padBytes
= ysize
- (width
*group_size
);
965 src
+= padBytes
; /* for assertion only */
968 else if (width
== 1) { /* 1 column */
969 int padBytes
= ysize
- (width
* group_size
);
970 assert(height
!= 1); /* widthxheight can't be 1x1 */
972 /* one vertical column with possible pad bytes per row */
973 /* average two at a time */
975 for (jj
= 0; jj
< halfHeight
; jj
++) {
977 for (kk
= 0; kk
< components
; kk
++) {
981 uint
[0]= __GLU_SWAP_4_BYTES(src
);
982 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
985 uint
[0]= *(const GLuint
*)src
;
986 uint
[1]= *(const GLuint
*)(src
+ysize
);
988 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
993 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
997 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1000 assert((char *)dest
== &((char *)dataOut
)
1001 [components
* element_size
* halfWidth
* halfHeight
]);
1003 } /* halve1Dimage_uint() */
1005 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
1006 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
1007 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
1010 int newwidth
, newheight
;
1015 /* handle case where there is only 1 column/row */
1016 if (width
== 1 || height
== 1) {
1017 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1018 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1019 element_size
,ysize
,group_size
, myswap_bytes
);
1023 newwidth
= width
/ 2;
1024 newheight
= height
/ 2;
1025 padBytes
= ysize
- (width
*group_size
);
1027 t
= (const char *)datain
;
1029 /* Piece o' cake! */
1031 for (i
= 0; i
< newheight
; i
++) {
1032 for (j
= 0; j
< newwidth
; j
++) {
1033 for (k
= 0; k
< components
; k
++) {
1034 s
[0] = ((float)*(const GLint
*)t
+
1035 (float)*(const GLint
*)(t
+group_size
) +
1036 (float)*(const GLint
*)(t
+ysize
) +
1037 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1038 s
++; t
+= element_size
;
1046 for (i
= 0; i
< newheight
; i
++) {
1047 for (j
= 0; j
< newwidth
; j
++) {
1048 for (k
= 0; k
< components
; k
++) {
1051 b
= __GLU_SWAP_4_BYTES(t
);
1053 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1055 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1057 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1059 s
[0] = (GLint
)(buf
/4 + 0.5);
1061 s
++; t
+= element_size
;
1071 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1072 const GLint
*dataIn
, GLint
*dataOut
,
1073 GLint element_size
, GLint ysize
,
1074 GLint group_size
, GLint myswap_bytes
)
1076 GLint halfWidth
= width
/ 2;
1077 GLint halfHeight
= height
/ 2;
1078 const char *src
= (const char *) dataIn
;
1079 GLint
*dest
= dataOut
;
1082 assert(width
== 1 || height
== 1); /* must be 1D */
1083 assert(width
!= height
); /* can't be square */
1085 if (height
== 1) { /* 1 row */
1086 assert(width
!= 1); /* widthxheight can't be 1x1 */
1089 for (jj
= 0; jj
< halfWidth
; jj
++) {
1091 for (kk
= 0; kk
< components
; kk
++) {
1095 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1096 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1099 uint
[0]= *(const GLuint
*)src
;
1100 uint
[1]= *(const GLuint
*)(src
+group_size
);
1102 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1107 src
+= group_size
; /* skip to next 2 */
1110 int padBytes
= ysize
- (width
*group_size
);
1111 src
+= padBytes
; /* for assertion only */
1114 else if (width
== 1) { /* 1 column */
1115 int padBytes
= ysize
- (width
* group_size
);
1116 assert(height
!= 1); /* widthxheight can't be 1x1 */
1118 /* one vertical column with possible pad bytes per row */
1119 /* average two at a time */
1121 for (jj
= 0; jj
< halfHeight
; jj
++) {
1123 for (kk
= 0; kk
< components
; kk
++) {
1127 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1128 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1131 uint
[0]= *(const GLuint
*)src
;
1132 uint
[1]= *(const GLuint
*)(src
+ysize
);
1134 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1139 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1143 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1146 assert((char *)dest
== &((char *)dataOut
)
1147 [components
* element_size
* halfWidth
* halfHeight
]);
1149 } /* halve1Dimage_int() */
1152 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1153 const GLfloat
*datain
, GLfloat
*dataout
,
1154 GLint element_size
, GLint ysize
, GLint group_size
,
1158 int newwidth
, newheight
;
1163 /* handle case where there is only 1 column/row */
1164 if (width
== 1 || height
== 1) {
1165 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1166 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1167 element_size
,ysize
,group_size
, myswap_bytes
);
1171 newwidth
= width
/ 2;
1172 newheight
= height
/ 2;
1173 padBytes
= ysize
- (width
*group_size
);
1175 t
= (const char *)datain
;
1177 /* Piece o' cake! */
1179 for (i
= 0; i
< newheight
; i
++) {
1180 for (j
= 0; j
< newwidth
; j
++) {
1181 for (k
= 0; k
< components
; k
++) {
1182 s
[0] = (*(const GLfloat
*)t
+
1183 *(const GLfloat
*)(t
+group_size
) +
1184 *(const GLfloat
*)(t
+ysize
) +
1185 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1186 s
++; t
+= element_size
;
1194 for (i
= 0; i
< newheight
; i
++) {
1195 for (j
= 0; j
< newwidth
; j
++) {
1196 for (k
= 0; k
< components
; k
++) {
1197 union { GLuint b
; GLfloat f
; } swapbuf
;
1198 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
);
1200 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1202 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1204 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1207 s
++; t
+= element_size
;
1217 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1218 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1219 GLint element_size
, GLint ysize
,
1220 GLint group_size
, GLint myswap_bytes
)
1222 GLint halfWidth
= width
/ 2;
1223 GLint halfHeight
= height
/ 2;
1224 const char *src
= (const char *) dataIn
;
1225 GLfloat
*dest
= dataOut
;
1228 assert(width
== 1 || height
== 1); /* must be 1D */
1229 assert(width
!= height
); /* can't be square */
1231 if (height
== 1) { /* 1 row */
1232 assert(width
!= 1); /* widthxheight can't be 1x1 */
1235 for (jj
= 0; jj
< halfWidth
; jj
++) {
1237 for (kk
= 0; kk
< components
; kk
++) {
1239 GLfloat sfloat
[BOX2
];
1241 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1242 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1245 sfloat
[0]= *(const GLfloat
*)src
;
1246 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1249 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1253 src
+= group_size
; /* skip to next 2 */
1256 int padBytes
= ysize
- (width
*group_size
);
1257 src
+= padBytes
; /* for assertion only */
1260 else if (width
== 1) { /* 1 column */
1261 int padBytes
= ysize
- (width
* group_size
);
1262 assert(height
!= 1); /* widthxheight can't be 1x1 */
1264 /* one vertical column with possible pad bytes per row */
1265 /* average two at a time */
1267 for (jj
= 0; jj
< halfHeight
; jj
++) {
1269 for (kk
= 0; kk
< components
; kk
++) {
1271 GLfloat sfloat
[BOX2
];
1273 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1274 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1277 sfloat
[0]= *(const GLfloat
*)src
;
1278 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1280 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1285 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1286 src
+= ysize
; /* skip to odd row */
1290 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1291 assert((char *)dest
== &((char *)dataOut
)
1292 [components
* element_size
* halfWidth
* halfHeight
]);
1293 } /* halve1Dimage_float() */
1295 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1296 const GLushort
*datain
,
1297 GLint widthout
, GLint heightout
,
1300 float x
, lowx
, highx
, convx
, halfconvx
;
1301 float y
, lowy
, highy
, convy
, halfconvy
;
1302 float xpercent
,ypercent
;
1304 /* Max components in a format is 4, so... */
1307 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1310 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1311 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1314 convy
= (float) heightin
/heightout
;
1315 convx
= (float) widthin
/widthout
;
1316 halfconvx
= convx
/2;
1317 halfconvy
= convy
/2;
1318 for (i
= 0; i
< heightout
; i
++) {
1319 y
= convy
* (i
+0.5);
1320 if (heightin
> heightout
) {
1321 highy
= y
+ halfconvy
;
1322 lowy
= y
- halfconvy
;
1327 for (j
= 0; j
< widthout
; j
++) {
1328 x
= convx
* (j
+0.5);
1329 if (widthin
> widthout
) {
1330 highx
= x
+ halfconvx
;
1331 lowx
= x
- halfconvx
;
1338 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1339 ** to (highx, highy) on input data into this pixel on output
1342 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1348 yindex
= (yint
+ heightin
) % heightin
;
1349 if (highy
< yint
+1) {
1350 ypercent
= highy
- y
;
1352 ypercent
= yint
+1 - y
;
1359 xindex
= (xint
+ widthin
) % widthin
;
1360 if (highx
< xint
+1) {
1361 xpercent
= highx
- x
;
1363 xpercent
= xint
+1 - x
;
1366 percent
= xpercent
* ypercent
;
1368 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1369 for (k
= 0; k
< components
; k
++) {
1370 totals
[k
] += datain
[temp
+ k
] * percent
;
1380 temp
= (j
+ (i
* widthout
)) * components
;
1381 for (k
= 0; k
< components
; k
++) {
1382 /* totals[] should be rounded in the case of enlarging an RGB
1383 * ramp when the type is 332 or 4444
1385 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1391 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1392 GLint heightin
, const GLubyte
*datain
,
1393 GLint widthout
, GLint heightout
,
1394 GLubyte
*dataout
, GLint element_size
,
1395 GLint ysize
, GLint group_size
)
1400 /* Max components in a format is 4, so... */
1405 const char *temp
, *temp0
;
1406 const char *temp_index
;
1409 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1410 float x_percent
, y_percent
;
1411 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1412 float convy_float
, convx_float
;
1413 int convy_int
, convx_int
;
1415 const char *left
, *right
;
1417 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1418 halveImage_ubyte(components
, widthin
, heightin
,
1419 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1420 element_size
, ysize
, group_size
);
1423 convy
= (float) heightin
/heightout
;
1424 convx
= (float) widthin
/widthout
;
1425 convy_int
= floor(convy
);
1426 convy_float
= convy
- convy_int
;
1427 convx_int
= floor(convx
);
1428 convx_float
= convx
- convx_int
;
1430 area
= convx
* convy
;
1434 highy_int
= convy_int
;
1435 highy_float
= convy_float
;
1437 for (i
= 0; i
< heightout
; i
++) {
1438 /* Clamp here to be sure we don't read beyond input buffer. */
1439 if (highy_int
>= heightin
)
1440 highy_int
= heightin
- 1;
1443 highx_int
= convx_int
;
1444 highx_float
= convx_float
;
1446 for (j
= 0; j
< widthout
; j
++) {
1449 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1450 ** to (highx, highy) on input data into this pixel on output
1453 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1455 /* calculate the value for pixels in the 1st row */
1456 xindex
= lowx_int
*group_size
;
1457 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1459 y_percent
= 1-lowy_float
;
1460 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1461 percent
= y_percent
* (1-lowx_float
);
1462 for (k
= 0, temp_index
= temp
; k
< components
;
1463 k
++, temp_index
+= element_size
) {
1464 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1467 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1469 for (k
= 0, temp_index
= temp
; k
< components
;
1470 k
++, temp_index
+= element_size
) {
1471 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1476 percent
= y_percent
* highx_float
;
1477 for (k
= 0, temp_index
= temp
; k
< components
;
1478 k
++, temp_index
+= element_size
) {
1479 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1482 /* calculate the value for pixels in the last row */
1483 y_percent
= highy_float
;
1484 percent
= y_percent
* (1-lowx_float
);
1485 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1486 for (k
= 0, temp_index
= temp
; k
< components
;
1487 k
++, temp_index
+= element_size
) {
1488 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1490 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1492 for (k
= 0, temp_index
= temp
; k
< components
;
1493 k
++, temp_index
+= element_size
) {
1494 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1498 percent
= y_percent
* highx_float
;
1499 for (k
= 0, temp_index
= temp
; k
< components
;
1500 k
++, temp_index
+= element_size
) {
1501 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1505 /* calculate the value for pixels in the 1st and last column */
1506 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1509 for (k
= 0; k
< components
;
1510 k
++, left
+= element_size
, right
+= element_size
) {
1511 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1512 +(GLubyte
)(*(right
))*highx_float
;
1515 } else if (highy_int
> lowy_int
) {
1516 x_percent
= highx_float
- lowx_float
;
1517 percent
= (1-lowy_float
)*x_percent
;
1518 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1519 for (k
= 0, temp_index
= temp
; k
< components
;
1520 k
++, temp_index
+= element_size
) {
1521 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1523 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1525 for (k
= 0, temp_index
= temp
; k
< components
;
1526 k
++, temp_index
+= element_size
) {
1527 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1530 percent
= x_percent
* highy_float
;
1532 for (k
= 0, temp_index
= temp
; k
< components
;
1533 k
++, temp_index
+= element_size
) {
1534 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1536 } else if (highx_int
> lowx_int
) {
1537 y_percent
= highy_float
- lowy_float
;
1538 percent
= (1-lowx_float
)*y_percent
;
1539 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1540 for (k
= 0, temp_index
= temp
; k
< components
;
1541 k
++, temp_index
+= element_size
) {
1542 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1544 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1546 for (k
= 0, temp_index
= temp
; k
< components
;
1547 k
++, temp_index
+= element_size
) {
1548 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1552 percent
= y_percent
* highx_float
;
1553 for (k
= 0, temp_index
= temp
; k
< components
;
1554 k
++, temp_index
+= element_size
) {
1555 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1558 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1559 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1560 for (k
= 0, temp_index
= temp
; k
< components
;
1561 k
++, temp_index
+= element_size
) {
1562 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1568 /* this is for the pixels in the body */
1569 temp0
= (const char *)datain
+ xindex
+ group_size
+
1571 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1573 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1574 for (k
= 0, temp_index
= temp
; k
< components
;
1575 k
++, temp_index
+= element_size
) {
1576 totals
[k
] += (GLubyte
)(*(temp_index
));
1583 outindex
= (j
+ (i
* widthout
)) * components
;
1584 for (k
= 0; k
< components
; k
++) {
1585 dataout
[outindex
+ k
] = totals
[k
]/area
;
1586 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1588 lowx_int
= highx_int
;
1589 lowx_float
= highx_float
;
1590 highx_int
+= convx_int
;
1591 highx_float
+= convx_float
;
1592 if(highx_float
> 1) {
1597 lowy_int
= highy_int
;
1598 lowy_float
= highy_float
;
1599 highy_int
+= convy_int
;
1600 highy_float
+= convy_float
;
1601 if(highy_float
> 1) {
1608 static void scale_internal_byte(GLint components
, GLint widthin
,
1609 GLint heightin
, const GLbyte
*datain
,
1610 GLint widthout
, GLint heightout
,
1611 GLbyte
*dataout
, GLint element_size
,
1612 GLint ysize
, GLint group_size
)
1617 /* Max components in a format is 4, so... */
1622 const char *temp
, *temp0
;
1623 const char *temp_index
;
1626 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1627 float x_percent
, y_percent
;
1628 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1629 float convy_float
, convx_float
;
1630 int convy_int
, convx_int
;
1632 const char *left
, *right
;
1634 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1635 halveImage_byte(components
, widthin
, heightin
,
1636 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1637 element_size
, ysize
, group_size
);
1640 convy
= (float) heightin
/heightout
;
1641 convx
= (float) widthin
/widthout
;
1642 convy_int
= floor(convy
);
1643 convy_float
= convy
- convy_int
;
1644 convx_int
= floor(convx
);
1645 convx_float
= convx
- convx_int
;
1647 area
= convx
* convy
;
1651 highy_int
= convy_int
;
1652 highy_float
= convy_float
;
1654 for (i
= 0; i
< heightout
; i
++) {
1655 /* Clamp here to be sure we don't read beyond input buffer. */
1656 if (highy_int
>= heightin
)
1657 highy_int
= heightin
- 1;
1660 highx_int
= convx_int
;
1661 highx_float
= convx_float
;
1663 for (j
= 0; j
< widthout
; j
++) {
1666 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1667 ** to (highx, highy) on input data into this pixel on output
1670 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1672 /* calculate the value for pixels in the 1st row */
1673 xindex
= lowx_int
*group_size
;
1674 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1676 y_percent
= 1-lowy_float
;
1677 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1678 percent
= y_percent
* (1-lowx_float
);
1679 for (k
= 0, temp_index
= temp
; k
< components
;
1680 k
++, temp_index
+= element_size
) {
1681 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1684 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1686 for (k
= 0, temp_index
= temp
; k
< components
;
1687 k
++, temp_index
+= element_size
) {
1688 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1693 percent
= y_percent
* highx_float
;
1694 for (k
= 0, temp_index
= temp
; k
< components
;
1695 k
++, temp_index
+= element_size
) {
1696 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1699 /* calculate the value for pixels in the last row */
1700 y_percent
= highy_float
;
1701 percent
= y_percent
* (1-lowx_float
);
1702 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1703 for (k
= 0, temp_index
= temp
; k
< components
;
1704 k
++, temp_index
+= element_size
) {
1705 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1707 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1709 for (k
= 0, temp_index
= temp
; k
< components
;
1710 k
++, temp_index
+= element_size
) {
1711 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1715 percent
= y_percent
* highx_float
;
1716 for (k
= 0, temp_index
= temp
; k
< components
;
1717 k
++, temp_index
+= element_size
) {
1718 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1722 /* calculate the value for pixels in the 1st and last column */
1723 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1726 for (k
= 0; k
< components
;
1727 k
++, left
+= element_size
, right
+= element_size
) {
1728 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1729 +(GLbyte
)(*(right
))*highx_float
;
1732 } else if (highy_int
> lowy_int
) {
1733 x_percent
= highx_float
- lowx_float
;
1734 percent
= (1-lowy_float
)*x_percent
;
1735 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1736 for (k
= 0, temp_index
= temp
; k
< components
;
1737 k
++, temp_index
+= element_size
) {
1738 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1740 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1742 for (k
= 0, temp_index
= temp
; k
< components
;
1743 k
++, temp_index
+= element_size
) {
1744 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1747 percent
= x_percent
* highy_float
;
1749 for (k
= 0, temp_index
= temp
; k
< components
;
1750 k
++, temp_index
+= element_size
) {
1751 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1753 } else if (highx_int
> lowx_int
) {
1754 y_percent
= highy_float
- lowy_float
;
1755 percent
= (1-lowx_float
)*y_percent
;
1756 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1757 for (k
= 0, temp_index
= temp
; k
< components
;
1758 k
++, temp_index
+= element_size
) {
1759 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1761 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1763 for (k
= 0, temp_index
= temp
; k
< components
;
1764 k
++, temp_index
+= element_size
) {
1765 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1769 percent
= y_percent
* highx_float
;
1770 for (k
= 0, temp_index
= temp
; k
< components
;
1771 k
++, temp_index
+= element_size
) {
1772 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1775 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1776 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1777 for (k
= 0, temp_index
= temp
; k
< components
;
1778 k
++, temp_index
+= element_size
) {
1779 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1785 /* this is for the pixels in the body */
1786 temp0
= (const char *)datain
+ xindex
+ group_size
+
1788 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1790 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1791 for (k
= 0, temp_index
= temp
; k
< components
;
1792 k
++, temp_index
+= element_size
) {
1793 totals
[k
] += (GLbyte
)(*(temp_index
));
1800 outindex
= (j
+ (i
* widthout
)) * components
;
1801 for (k
= 0; k
< components
; k
++) {
1802 dataout
[outindex
+ k
] = totals
[k
]/area
;
1803 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1805 lowx_int
= highx_int
;
1806 lowx_float
= highx_float
;
1807 highx_int
+= convx_int
;
1808 highx_float
+= convx_float
;
1809 if(highx_float
> 1) {
1814 lowy_int
= highy_int
;
1815 lowy_float
= highy_float
;
1816 highy_int
+= convy_int
;
1817 highy_float
+= convy_float
;
1818 if(highy_float
> 1) {
1825 static void scale_internal_ushort(GLint components
, GLint widthin
,
1826 GLint heightin
, const GLushort
*datain
,
1827 GLint widthout
, GLint heightout
,
1828 GLushort
*dataout
, GLint element_size
,
1829 GLint ysize
, GLint group_size
,
1835 /* Max components in a format is 4, so... */
1840 const char *temp
, *temp0
;
1841 const char *temp_index
;
1844 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1845 float x_percent
, y_percent
;
1846 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1847 float convy_float
, convx_float
;
1848 int convy_int
, convx_int
;
1850 const char *left
, *right
;
1852 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1853 halveImage_ushort(components
, widthin
, heightin
,
1854 (const GLushort
*)datain
, (GLushort
*)dataout
,
1855 element_size
, ysize
, group_size
, myswap_bytes
);
1858 convy
= (float) heightin
/heightout
;
1859 convx
= (float) widthin
/widthout
;
1860 convy_int
= floor(convy
);
1861 convy_float
= convy
- convy_int
;
1862 convx_int
= floor(convx
);
1863 convx_float
= convx
- convx_int
;
1865 area
= convx
* convy
;
1869 highy_int
= convy_int
;
1870 highy_float
= convy_float
;
1872 for (i
= 0; i
< heightout
; i
++) {
1873 /* Clamp here to be sure we don't read beyond input buffer. */
1874 if (highy_int
>= heightin
)
1875 highy_int
= heightin
- 1;
1878 highx_int
= convx_int
;
1879 highx_float
= convx_float
;
1881 for (j
= 0; j
< widthout
; j
++) {
1883 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1884 ** to (highx, highy) on input data into this pixel on output
1887 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1889 /* calculate the value for pixels in the 1st row */
1890 xindex
= lowx_int
*group_size
;
1891 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1893 y_percent
= 1-lowy_float
;
1894 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1895 percent
= y_percent
* (1-lowx_float
);
1896 for (k
= 0, temp_index
= temp
; k
< components
;
1897 k
++, temp_index
+= element_size
) {
1899 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1901 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1905 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1907 for (k
= 0, temp_index
= temp
; k
< components
;
1908 k
++, temp_index
+= element_size
) {
1911 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1913 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1919 percent
= y_percent
* highx_float
;
1920 for (k
= 0, temp_index
= temp
; k
< components
;
1921 k
++, temp_index
+= element_size
) {
1923 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1925 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1929 /* calculate the value for pixels in the last row */
1930 y_percent
= highy_float
;
1931 percent
= y_percent
* (1-lowx_float
);
1932 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1933 for (k
= 0, temp_index
= temp
; k
< components
;
1934 k
++, temp_index
+= element_size
) {
1936 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1938 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1941 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1943 for (k
= 0, temp_index
= temp
; k
< components
;
1944 k
++, temp_index
+= element_size
) {
1947 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1949 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1954 percent
= y_percent
* highx_float
;
1955 for (k
= 0, temp_index
= temp
; k
< components
;
1956 k
++, temp_index
+= element_size
) {
1958 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1960 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1964 /* calculate the value for pixels in the 1st and last column */
1965 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1968 for (k
= 0; k
< components
;
1969 k
++, left
+= element_size
, right
+= element_size
) {
1972 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1973 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1975 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1976 + *(const GLushort
*)right
* highx_float
;
1980 } else if (highy_int
> lowy_int
) {
1981 x_percent
= highx_float
- lowx_float
;
1982 percent
= (1-lowy_float
)*x_percent
;
1983 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1984 for (k
= 0, temp_index
= temp
; k
< components
;
1985 k
++, temp_index
+= element_size
) {
1987 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1989 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1992 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1994 for (k
= 0, temp_index
= temp
; k
< components
;
1995 k
++, temp_index
+= element_size
) {
1998 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
2000 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
2004 percent
= x_percent
* highy_float
;
2006 for (k
= 0, temp_index
= temp
; k
< components
;
2007 k
++, temp_index
+= element_size
) {
2009 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2011 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2014 } else if (highx_int
> lowx_int
) {
2015 y_percent
= highy_float
- lowy_float
;
2016 percent
= (1-lowx_float
)*y_percent
;
2017 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2018 for (k
= 0, temp_index
= temp
; k
< components
;
2019 k
++, temp_index
+= element_size
) {
2021 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2023 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2026 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2028 for (k
= 0, temp_index
= temp
; k
< components
;
2029 k
++, temp_index
+= element_size
) {
2032 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2034 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2039 percent
= y_percent
* highx_float
;
2040 for (k
= 0, temp_index
= temp
; k
< components
;
2041 k
++, temp_index
+= element_size
) {
2043 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2045 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2049 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2050 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2051 for (k
= 0, temp_index
= temp
; k
< components
;
2052 k
++, temp_index
+= element_size
) {
2054 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2056 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2061 /* this is for the pixels in the body */
2062 temp0
= (const char *)datain
+ xindex
+ group_size
+
2064 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2066 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2067 for (k
= 0, temp_index
= temp
; k
< components
;
2068 k
++, temp_index
+= element_size
) {
2070 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2072 totals
[k
] += *(const GLushort
*)temp_index
;
2080 outindex
= (j
+ (i
* widthout
)) * components
;
2081 for (k
= 0; k
< components
; k
++) {
2082 dataout
[outindex
+ k
] = totals
[k
]/area
;
2083 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2085 lowx_int
= highx_int
;
2086 lowx_float
= highx_float
;
2087 highx_int
+= convx_int
;
2088 highx_float
+= convx_float
;
2089 if(highx_float
> 1) {
2094 lowy_int
= highy_int
;
2095 lowy_float
= highy_float
;
2096 highy_int
+= convy_int
;
2097 highy_float
+= convy_float
;
2098 if(highy_float
> 1) {
2105 static void scale_internal_short(GLint components
, GLint widthin
,
2106 GLint heightin
, const GLshort
*datain
,
2107 GLint widthout
, GLint heightout
,
2108 GLshort
*dataout
, GLint element_size
,
2109 GLint ysize
, GLint group_size
,
2115 /* Max components in a format is 4, so... */
2120 const char *temp
, *temp0
;
2121 const char *temp_index
;
2124 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2125 float x_percent
, y_percent
;
2126 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2127 float convy_float
, convx_float
;
2128 int convy_int
, convx_int
;
2130 const char *left
, *right
;
2132 GLushort swapbuf
; /* unsigned buffer */
2134 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2135 halveImage_short(components
, widthin
, heightin
,
2136 (const GLshort
*)datain
, (GLshort
*)dataout
,
2137 element_size
, ysize
, group_size
, myswap_bytes
);
2140 convy
= (float) heightin
/heightout
;
2141 convx
= (float) widthin
/widthout
;
2142 convy_int
= floor(convy
);
2143 convy_float
= convy
- convy_int
;
2144 convx_int
= floor(convx
);
2145 convx_float
= convx
- convx_int
;
2147 area
= convx
* convy
;
2151 highy_int
= convy_int
;
2152 highy_float
= convy_float
;
2154 for (i
= 0; i
< heightout
; i
++) {
2155 /* Clamp here to be sure we don't read beyond input buffer. */
2156 if (highy_int
>= heightin
)
2157 highy_int
= heightin
- 1;
2160 highx_int
= convx_int
;
2161 highx_float
= convx_float
;
2163 for (j
= 0; j
< widthout
; j
++) {
2165 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2166 ** to (highx, highy) on input data into this pixel on output
2169 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2171 /* calculate the value for pixels in the 1st row */
2172 xindex
= lowx_int
*group_size
;
2173 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2175 y_percent
= 1-lowy_float
;
2176 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2177 percent
= y_percent
* (1-lowx_float
);
2178 for (k
= 0, temp_index
= temp
; k
< components
;
2179 k
++, temp_index
+= element_size
) {
2181 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2182 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2184 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2188 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2190 for (k
= 0, temp_index
= temp
; k
< components
;
2191 k
++, temp_index
+= element_size
) {
2193 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2194 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2196 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2202 percent
= y_percent
* highx_float
;
2203 for (k
= 0, temp_index
= temp
; k
< components
;
2204 k
++, temp_index
+= element_size
) {
2206 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2207 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2209 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2213 /* calculate the value for pixels in the last row */
2214 y_percent
= highy_float
;
2215 percent
= y_percent
* (1-lowx_float
);
2216 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2217 for (k
= 0, temp_index
= temp
; k
< components
;
2218 k
++, temp_index
+= element_size
) {
2220 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2221 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2223 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2226 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2228 for (k
= 0, temp_index
= temp
; k
< components
;
2229 k
++, temp_index
+= element_size
) {
2231 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2232 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2234 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2239 percent
= y_percent
* highx_float
;
2240 for (k
= 0, temp_index
= temp
; k
< components
;
2241 k
++, temp_index
+= element_size
) {
2243 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2244 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2246 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2250 /* calculate the value for pixels in the 1st and last column */
2251 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2254 for (k
= 0; k
< components
;
2255 k
++, left
+= element_size
, right
+= element_size
) {
2257 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2258 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2259 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2260 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2262 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2263 + *(const GLshort
*)right
* highx_float
;
2267 } else if (highy_int
> lowy_int
) {
2268 x_percent
= highx_float
- lowx_float
;
2269 percent
= (1-lowy_float
)*x_percent
;
2270 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2271 for (k
= 0, temp_index
= temp
; k
< components
;
2272 k
++, temp_index
+= element_size
) {
2274 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2275 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2277 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2280 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
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
* x_percent
;
2288 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2292 percent
= x_percent
* highy_float
;
2294 for (k
= 0, temp_index
= temp
; k
< components
;
2295 k
++, temp_index
+= element_size
) {
2297 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2298 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2300 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2303 } else if (highx_int
> lowx_int
) {
2304 y_percent
= highy_float
- lowy_float
;
2305 percent
= (1-lowx_float
)*y_percent
;
2307 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2308 for (k
= 0, temp_index
= temp
; k
< components
;
2309 k
++, temp_index
+= element_size
) {
2311 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2312 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2314 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2317 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2319 for (k
= 0, temp_index
= temp
; k
< components
;
2320 k
++, temp_index
+= element_size
) {
2322 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2323 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2325 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2330 percent
= y_percent
* highx_float
;
2331 for (k
= 0, temp_index
= temp
; k
< components
;
2332 k
++, temp_index
+= element_size
) {
2334 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2335 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2337 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2341 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2342 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2343 for (k
= 0, temp_index
= temp
; k
< components
;
2344 k
++, temp_index
+= element_size
) {
2346 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2347 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2349 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2354 /* this is for the pixels in the body */
2355 temp0
= (const char *)datain
+ xindex
+ group_size
+
2357 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2359 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2360 for (k
= 0, temp_index
= temp
; k
< components
;
2361 k
++, temp_index
+= element_size
) {
2363 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2364 totals
[k
] += *(const GLshort
*)&swapbuf
;
2366 totals
[k
] += *(const GLshort
*)temp_index
;
2374 outindex
= (j
+ (i
* widthout
)) * components
;
2375 for (k
= 0; k
< components
; k
++) {
2376 dataout
[outindex
+ k
] = totals
[k
]/area
;
2377 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2379 lowx_int
= highx_int
;
2380 lowx_float
= highx_float
;
2381 highx_int
+= convx_int
;
2382 highx_float
+= convx_float
;
2383 if(highx_float
> 1) {
2388 lowy_int
= highy_int
;
2389 lowy_float
= highy_float
;
2390 highy_int
+= convy_int
;
2391 highy_float
+= convy_float
;
2392 if(highy_float
> 1) {
2399 static void scale_internal_uint(GLint components
, GLint widthin
,
2400 GLint heightin
, const GLuint
*datain
,
2401 GLint widthout
, GLint heightout
,
2402 GLuint
*dataout
, GLint element_size
,
2403 GLint ysize
, GLint group_size
,
2409 /* Max components in a format is 4, so... */
2414 const char *temp
, *temp0
;
2415 const char *temp_index
;
2418 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2419 float x_percent
, y_percent
;
2420 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2421 float convy_float
, convx_float
;
2422 int convy_int
, convx_int
;
2424 const char *left
, *right
;
2426 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2427 halveImage_uint(components
, widthin
, heightin
,
2428 (const GLuint
*)datain
, (GLuint
*)dataout
,
2429 element_size
, ysize
, group_size
, myswap_bytes
);
2432 convy
= (float) heightin
/heightout
;
2433 convx
= (float) widthin
/widthout
;
2434 convy_int
= floor(convy
);
2435 convy_float
= convy
- convy_int
;
2436 convx_int
= floor(convx
);
2437 convx_float
= convx
- convx_int
;
2439 area
= convx
* convy
;
2443 highy_int
= convy_int
;
2444 highy_float
= convy_float
;
2446 for (i
= 0; i
< heightout
; i
++) {
2447 /* Clamp here to be sure we don't read beyond input buffer. */
2448 if (highy_int
>= heightin
)
2449 highy_int
= heightin
- 1;
2452 highx_int
= convx_int
;
2453 highx_float
= convx_float
;
2455 for (j
= 0; j
< widthout
; j
++) {
2457 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2458 ** to (highx, highy) on input data into this pixel on output
2461 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2463 /* calculate the value for pixels in the 1st row */
2464 xindex
= lowx_int
*group_size
;
2465 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2467 y_percent
= 1-lowy_float
;
2468 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2469 percent
= y_percent
* (1-lowx_float
);
2470 for (k
= 0, temp_index
= temp
; k
< components
;
2471 k
++, temp_index
+= element_size
) {
2473 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2475 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2479 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2481 for (k
= 0, temp_index
= temp
; k
< components
;
2482 k
++, temp_index
+= element_size
) {
2485 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2487 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2493 percent
= y_percent
* highx_float
;
2494 for (k
= 0, temp_index
= temp
; k
< components
;
2495 k
++, temp_index
+= element_size
) {
2497 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2499 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2503 /* calculate the value for pixels in the last row */
2504 y_percent
= highy_float
;
2505 percent
= y_percent
* (1-lowx_float
);
2506 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2507 for (k
= 0, temp_index
= temp
; k
< components
;
2508 k
++, temp_index
+= element_size
) {
2510 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2512 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2515 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2517 for (k
= 0, temp_index
= temp
; k
< components
;
2518 k
++, temp_index
+= element_size
) {
2521 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2523 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2528 percent
= y_percent
* highx_float
;
2529 for (k
= 0, temp_index
= temp
; k
< components
;
2530 k
++, temp_index
+= element_size
) {
2532 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2534 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2538 /* calculate the value for pixels in the 1st and last column */
2539 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2542 for (k
= 0; k
< components
;
2543 k
++, left
+= element_size
, right
+= element_size
) {
2546 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2547 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2549 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2550 + *(const GLuint
*)right
* highx_float
;
2554 } else if (highy_int
> lowy_int
) {
2555 x_percent
= highx_float
- lowx_float
;
2556 percent
= (1-lowy_float
)*x_percent
;
2557 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2558 for (k
= 0, temp_index
= temp
; k
< components
;
2559 k
++, temp_index
+= element_size
) {
2561 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2563 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2566 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2568 for (k
= 0, temp_index
= temp
; k
< components
;
2569 k
++, temp_index
+= element_size
) {
2572 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2574 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2578 percent
= x_percent
* highy_float
;
2580 for (k
= 0, temp_index
= temp
; k
< components
;
2581 k
++, temp_index
+= element_size
) {
2583 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2585 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2588 } else if (highx_int
> lowx_int
) {
2589 y_percent
= highy_float
- lowy_float
;
2590 percent
= (1-lowx_float
)*y_percent
;
2592 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2593 for (k
= 0, temp_index
= temp
; k
< components
;
2594 k
++, temp_index
+= element_size
) {
2596 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2598 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2601 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2603 for (k
= 0, temp_index
= temp
; k
< components
;
2604 k
++, temp_index
+= element_size
) {
2607 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2609 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2614 percent
= y_percent
* highx_float
;
2615 for (k
= 0, temp_index
= temp
; k
< components
;
2616 k
++, temp_index
+= element_size
) {
2618 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2620 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2624 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2625 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2626 for (k
= 0, temp_index
= temp
; k
< components
;
2627 k
++, temp_index
+= element_size
) {
2629 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2631 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2636 /* this is for the pixels in the body */
2637 temp0
= (const char *)datain
+ xindex
+ group_size
+
2639 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2641 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2642 for (k
= 0, temp_index
= temp
; k
< components
;
2643 k
++, temp_index
+= element_size
) {
2645 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2647 totals
[k
] += *(const GLuint
*)temp_index
;
2655 outindex
= (j
+ (i
* widthout
)) * components
;
2656 for (k
= 0; k
< components
; k
++) {
2657 /* clamp at UINT_MAX */
2658 float value
= totals
[k
]/area
;
2659 if (value
>= (float) UINT_MAX
) { /* need '=' */
2660 dataout
[outindex
+ k
] = UINT_MAX
;
2662 else dataout
[outindex
+ k
] = value
;
2664 lowx_int
= highx_int
;
2665 lowx_float
= highx_float
;
2666 highx_int
+= convx_int
;
2667 highx_float
+= convx_float
;
2668 if(highx_float
> 1) {
2673 lowy_int
= highy_int
;
2674 lowy_float
= highy_float
;
2675 highy_int
+= convy_int
;
2676 highy_float
+= convy_float
;
2677 if(highy_float
> 1) {
2686 static void scale_internal_int(GLint components
, GLint widthin
,
2687 GLint heightin
, const GLint
*datain
,
2688 GLint widthout
, GLint heightout
,
2689 GLint
*dataout
, GLint element_size
,
2690 GLint ysize
, GLint group_size
,
2696 /* Max components in a format is 4, so... */
2701 const char *temp
, *temp0
;
2702 const char *temp_index
;
2705 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2706 float x_percent
, y_percent
;
2707 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2708 float convy_float
, convx_float
;
2709 int convy_int
, convx_int
;
2711 const char *left
, *right
;
2713 GLuint swapbuf
; /* unsigned buffer */
2715 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2716 halveImage_int(components
, widthin
, heightin
,
2717 (const GLint
*)datain
, (GLint
*)dataout
,
2718 element_size
, ysize
, group_size
, myswap_bytes
);
2721 convy
= (float) heightin
/heightout
;
2722 convx
= (float) widthin
/widthout
;
2723 convy_int
= floor(convy
);
2724 convy_float
= convy
- convy_int
;
2725 convx_int
= floor(convx
);
2726 convx_float
= convx
- convx_int
;
2728 area
= convx
* convy
;
2732 highy_int
= convy_int
;
2733 highy_float
= convy_float
;
2735 for (i
= 0; i
< heightout
; i
++) {
2736 /* Clamp here to be sure we don't read beyond input buffer. */
2737 if (highy_int
>= heightin
)
2738 highy_int
= heightin
- 1;
2741 highx_int
= convx_int
;
2742 highx_float
= convx_float
;
2744 for (j
= 0; j
< widthout
; j
++) {
2746 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2747 ** to (highx, highy) on input data into this pixel on output
2750 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2752 /* calculate the value for pixels in the 1st row */
2753 xindex
= lowx_int
*group_size
;
2754 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2756 y_percent
= 1-lowy_float
;
2757 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2758 percent
= y_percent
* (1-lowx_float
);
2759 for (k
= 0, temp_index
= temp
; k
< components
;
2760 k
++, temp_index
+= element_size
) {
2762 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2763 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2765 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2769 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2771 for (k
= 0, temp_index
= temp
; k
< components
;
2772 k
++, temp_index
+= element_size
) {
2774 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2775 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2777 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2783 percent
= y_percent
* highx_float
;
2784 for (k
= 0, temp_index
= temp
; k
< components
;
2785 k
++, temp_index
+= element_size
) {
2787 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2788 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2790 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2794 /* calculate the value for pixels in the last row */
2795 y_percent
= highy_float
;
2796 percent
= y_percent
* (1-lowx_float
);
2797 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2798 for (k
= 0, temp_index
= temp
; k
< components
;
2799 k
++, temp_index
+= element_size
) {
2801 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2802 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2804 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2807 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2809 for (k
= 0, temp_index
= temp
; k
< components
;
2810 k
++, temp_index
+= element_size
) {
2812 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2813 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2815 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2820 percent
= y_percent
* highx_float
;
2821 for (k
= 0, temp_index
= temp
; k
< components
;
2822 k
++, temp_index
+= element_size
) {
2824 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2825 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2827 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2831 /* calculate the value for pixels in the 1st and last column */
2832 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2835 for (k
= 0; k
< components
;
2836 k
++, left
+= element_size
, right
+= element_size
) {
2838 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2839 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2840 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2841 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2843 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2844 + *(const GLint
*)right
* highx_float
;
2848 } else if (highy_int
> lowy_int
) {
2849 x_percent
= highx_float
- lowx_float
;
2850 percent
= (1-lowy_float
)*x_percent
;
2851 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2852 for (k
= 0, temp_index
= temp
; k
< components
;
2853 k
++, temp_index
+= element_size
) {
2855 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2856 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2858 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2861 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
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
* x_percent
;
2869 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2873 percent
= x_percent
* highy_float
;
2875 for (k
= 0, temp_index
= temp
; k
< components
;
2876 k
++, temp_index
+= element_size
) {
2878 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2879 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2881 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2884 } else if (highx_int
> lowx_int
) {
2885 y_percent
= highy_float
- lowy_float
;
2886 percent
= (1-lowx_float
)*y_percent
;
2888 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2889 for (k
= 0, temp_index
= temp
; k
< components
;
2890 k
++, temp_index
+= element_size
) {
2892 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2893 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2895 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2898 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2900 for (k
= 0, temp_index
= temp
; k
< components
;
2901 k
++, temp_index
+= element_size
) {
2903 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2904 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2906 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2911 percent
= y_percent
* highx_float
;
2912 for (k
= 0, temp_index
= temp
; k
< components
;
2913 k
++, temp_index
+= element_size
) {
2915 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2916 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2918 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2922 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2923 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2924 for (k
= 0, temp_index
= temp
; k
< components
;
2925 k
++, temp_index
+= element_size
) {
2927 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2928 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2930 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2935 /* this is for the pixels in the body */
2936 temp0
= (const char *)datain
+ xindex
+ group_size
+
2938 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2940 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2941 for (k
= 0, temp_index
= temp
; k
< components
;
2942 k
++, temp_index
+= element_size
) {
2944 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2945 totals
[k
] += *(const GLint
*)&swapbuf
;
2947 totals
[k
] += *(const GLint
*)temp_index
;
2955 outindex
= (j
+ (i
* widthout
)) * components
;
2956 for (k
= 0; k
< components
; k
++) {
2957 dataout
[outindex
+ k
] = totals
[k
]/area
;
2958 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2960 lowx_int
= highx_int
;
2961 lowx_float
= highx_float
;
2962 highx_int
+= convx_int
;
2963 highx_float
+= convx_float
;
2964 if(highx_float
> 1) {
2969 lowy_int
= highy_int
;
2970 lowy_float
= highy_float
;
2971 highy_int
+= convy_int
;
2972 highy_float
+= convy_float
;
2973 if(highy_float
> 1) {
2982 static void scale_internal_float(GLint components
, GLint widthin
,
2983 GLint heightin
, const GLfloat
*datain
,
2984 GLint widthout
, GLint heightout
,
2985 GLfloat
*dataout
, GLint element_size
,
2986 GLint ysize
, GLint group_size
,
2992 /* Max components in a format is 4, so... */
2997 const char *temp
, *temp0
;
2998 const char *temp_index
;
3001 int lowx_int
, highx_int
, lowy_int
, highy_int
;
3002 float x_percent
, y_percent
;
3003 float lowx_float
, highx_float
, lowy_float
, highy_float
;
3004 float convy_float
, convx_float
;
3005 int convy_int
, convx_int
;
3007 const char *left
, *right
;
3009 union { GLuint b
; GLfloat f
; } swapbuf
;
3011 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
3012 halveImage_float(components
, widthin
, heightin
,
3013 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
3014 element_size
, ysize
, group_size
, myswap_bytes
);
3017 convy
= (float) heightin
/heightout
;
3018 convx
= (float) widthin
/widthout
;
3019 convy_int
= floor(convy
);
3020 convy_float
= convy
- convy_int
;
3021 convx_int
= floor(convx
);
3022 convx_float
= convx
- convx_int
;
3024 area
= convx
* convy
;
3028 highy_int
= convy_int
;
3029 highy_float
= convy_float
;
3031 for (i
= 0; i
< heightout
; i
++) {
3032 /* Clamp here to be sure we don't read beyond input buffer. */
3033 if (highy_int
>= heightin
)
3034 highy_int
= heightin
- 1;
3037 highx_int
= convx_int
;
3038 highx_float
= convx_float
;
3040 for (j
= 0; j
< widthout
; j
++) {
3042 ** Ok, now apply box filter to box that goes from (lowx, lowy)
3043 ** to (highx, highy) on input data into this pixel on output
3046 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3048 /* calculate the value for pixels in the 1st row */
3049 xindex
= lowx_int
*group_size
;
3050 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3052 y_percent
= 1-lowy_float
;
3053 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3054 percent
= y_percent
* (1-lowx_float
);
3055 for (k
= 0, temp_index
= temp
; k
< components
;
3056 k
++, temp_index
+= element_size
) {
3058 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3059 totals
[k
] += swapbuf
.f
* percent
;
3061 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3065 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3067 for (k
= 0, temp_index
= temp
; k
< components
;
3068 k
++, temp_index
+= element_size
) {
3070 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3071 totals
[k
] += swapbuf
.f
* y_percent
;
3073 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3079 percent
= y_percent
* highx_float
;
3080 for (k
= 0, temp_index
= temp
; k
< components
;
3081 k
++, temp_index
+= element_size
) {
3083 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3084 totals
[k
] += swapbuf
.f
* percent
;
3086 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3090 /* calculate the value for pixels in the last row */
3091 y_percent
= highy_float
;
3092 percent
= y_percent
* (1-lowx_float
);
3093 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3094 for (k
= 0, temp_index
= temp
; k
< components
;
3095 k
++, temp_index
+= element_size
) {
3097 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3098 totals
[k
] += swapbuf
.f
* percent
;
3100 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3103 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3105 for (k
= 0, temp_index
= temp
; k
< components
;
3106 k
++, temp_index
+= element_size
) {
3108 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3109 totals
[k
] += swapbuf
.f
* y_percent
;
3111 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3116 percent
= y_percent
* highx_float
;
3117 for (k
= 0, temp_index
= temp
; k
< components
;
3118 k
++, temp_index
+= element_size
) {
3120 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3121 totals
[k
] += swapbuf
.f
* percent
;
3123 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3127 /* calculate the value for pixels in the 1st and last column */
3128 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3131 for (k
= 0; k
< components
;
3132 k
++, left
+= element_size
, right
+= element_size
) {
3134 swapbuf
.b
= __GLU_SWAP_4_BYTES(left
);
3135 totals
[k
] += swapbuf
.f
* (1-lowx_float
);
3136 swapbuf
.b
= __GLU_SWAP_4_BYTES(right
);
3137 totals
[k
] += swapbuf
.f
* highx_float
;
3139 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3140 + *(const GLfloat
*)right
* highx_float
;
3144 } else if (highy_int
> lowy_int
) {
3145 x_percent
= highx_float
- lowx_float
;
3146 percent
= (1-lowy_float
)*x_percent
;
3147 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3148 for (k
= 0, temp_index
= temp
; k
< components
;
3149 k
++, temp_index
+= element_size
) {
3151 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3152 totals
[k
] += swapbuf
.f
* percent
;
3154 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3157 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
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
* x_percent
;
3165 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3169 percent
= x_percent
* highy_float
;
3171 for (k
= 0, temp_index
= temp
; k
< components
;
3172 k
++, temp_index
+= element_size
) {
3174 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3175 totals
[k
] += swapbuf
.f
* percent
;
3177 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3180 } else if (highx_int
> lowx_int
) {
3181 y_percent
= highy_float
- lowy_float
;
3182 percent
= (1-lowx_float
)*y_percent
;
3184 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3185 for (k
= 0, temp_index
= temp
; k
< components
;
3186 k
++, temp_index
+= element_size
) {
3188 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3189 totals
[k
] += swapbuf
.f
* percent
;
3191 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3194 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3196 for (k
= 0, temp_index
= temp
; k
< components
;
3197 k
++, temp_index
+= element_size
) {
3199 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3200 totals
[k
] += swapbuf
.f
* y_percent
;
3202 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3207 percent
= y_percent
* highx_float
;
3208 for (k
= 0, temp_index
= temp
; k
< components
;
3209 k
++, temp_index
+= element_size
) {
3211 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3212 totals
[k
] += swapbuf
.f
* percent
;
3214 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3218 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3219 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3220 for (k
= 0, temp_index
= temp
; k
< components
;
3221 k
++, temp_index
+= element_size
) {
3223 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3224 totals
[k
] += swapbuf
.f
* percent
;
3226 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3231 /* this is for the pixels in the body */
3232 temp0
= (const char *)datain
+ xindex
+ group_size
+
3234 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3236 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3237 for (k
= 0, temp_index
= temp
; k
< components
;
3238 k
++, temp_index
+= element_size
) {
3240 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3241 totals
[k
] += swapbuf
.f
;
3243 totals
[k
] += *(const GLfloat
*)temp_index
;
3251 outindex
= (j
+ (i
* widthout
)) * components
;
3252 for (k
= 0; k
< components
; k
++) {
3253 dataout
[outindex
+ k
] = totals
[k
]/area
;
3254 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3256 lowx_int
= highx_int
;
3257 lowx_float
= highx_float
;
3258 highx_int
+= convx_int
;
3259 highx_float
+= convx_float
;
3260 if(highx_float
> 1) {
3265 lowy_int
= highy_int
;
3266 lowy_float
= highy_float
;
3267 highy_int
+= convy_int
;
3268 highy_float
+= convy_float
;
3269 if(highy_float
> 1) {
3276 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3278 if (!legalFormat(format
) || !legalType(type
)) {
3279 return GLU_INVALID_ENUM
;
3281 if (format
== GL_STENCIL_INDEX
) {
3282 return GLU_INVALID_ENUM
;
3285 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3286 return GLU_INVALID_OPERATION
;
3290 } /* checkMipmapArgs() */
3292 static GLboolean
legalFormat(GLenum format
)
3295 case GL_COLOR_INDEX
:
3296 case GL_STENCIL_INDEX
:
3297 case GL_DEPTH_COMPONENT
:
3305 case GL_LUMINANCE_ALPHA
:
3315 static GLboolean
legalType(GLenum type
)
3320 case GL_UNSIGNED_BYTE
:
3322 case GL_UNSIGNED_SHORT
:
3324 case GL_UNSIGNED_INT
:
3326 case GL_UNSIGNED_BYTE_3_3_2
:
3327 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3328 case GL_UNSIGNED_SHORT_5_6_5
:
3329 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3330 case GL_UNSIGNED_SHORT_4_4_4_4
:
3331 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3332 case GL_UNSIGNED_SHORT_5_5_5_1
:
3333 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3334 case GL_UNSIGNED_INT_8_8_8_8
:
3335 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3336 case GL_UNSIGNED_INT_10_10_10_2
:
3337 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3345 static GLboolean
isTypePackedPixel(GLenum type
)
3347 assert(legalType(type
));
3349 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3350 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3351 type
== GL_UNSIGNED_SHORT_5_6_5
||
3352 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3353 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3354 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3355 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3356 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3357 type
== GL_UNSIGNED_INT_8_8_8_8
||
3358 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3359 type
== GL_UNSIGNED_INT_10_10_10_2
||
3360 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3364 } /* isTypePackedPixel() */
3366 /* Determines if the packed pixel type is compatible with the format */
3367 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3369 /* if not a packed pixel type then return true */
3370 if (!isTypePackedPixel(type
)) {
3374 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3375 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3376 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3377 && format
!= GL_RGB
)
3380 /* 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 &
3381 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3383 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3384 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3385 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3386 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3387 type
== GL_UNSIGNED_INT_8_8_8_8
||
3388 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3389 type
== GL_UNSIGNED_INT_10_10_10_2
||
3390 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3391 (format
!= GL_RGBA
&&
3392 format
!= GL_BGRA
)) {
3397 } /* isLegalFormatForPackedPixelType() */
3399 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3402 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3403 totalLevels
< maxLevel
)
3405 else return GL_TRUE
;
3406 } /* isLegalLevels() */
3408 /* Given user requested texture size, determine if it fits. If it
3409 * doesn't then halve both sides and make the determination again
3410 * until it does fit (for IR only).
3411 * Note that proxy textures are not implemented in RE* even though
3412 * they advertise the texture extension.
3413 * Note that proxy textures are implemented but not according to spec in
3416 static void closestFit(GLenum target
, GLint width
, GLint height
,
3417 GLint internalFormat
, GLenum format
, GLenum type
,
3418 GLint
*newWidth
, GLint
*newHeight
)
3420 /* Use proxy textures if OpenGL version is >= 1.1 */
3421 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3423 GLint widthPowerOf2
= nearestPower(width
);
3424 GLint heightPowerOf2
= nearestPower(height
);
3428 /* compute level 1 width & height, clamping each at 1 */
3429 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3430 widthPowerOf2
>> 1 :
3432 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3433 heightPowerOf2
>> 1 :
3436 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3438 /* does width x height at level 1 & all their mipmaps fit? */
3439 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3440 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3441 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3443 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3445 #if defined(GL_ARB_texture_cube_map)
3446 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3447 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3448 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3449 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3450 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3451 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3452 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3453 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3455 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3457 #endif /* GL_ARB_texture_cube_map */
3459 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3460 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3461 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3462 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3464 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3465 /* does it fit??? */
3466 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3467 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3468 /* An 1x1 texture couldn't fit for some reason, so
3469 * break out. This should never happen. But things
3470 * happen. The disadvantage with this if-statement is
3471 * that we will never be aware of when this happens
3472 * since it will silently branch out.
3474 goto noProxyTextures
;
3476 widthPowerOf2
= widthAtLevelOne
;
3477 heightPowerOf2
= heightAtLevelOne
;
3479 /* else it does fit */
3480 } while (proxyWidth
== 0);
3481 /* loop must terminate! */
3483 /* return the width & height at level 0 that fits */
3484 *newWidth
= widthPowerOf2
;
3485 *newHeight
= heightPowerOf2
;
3486 /*printf("Proxy Textures\n");*/
3487 } /* if gluCheckExtension() */
3488 else { /* no texture extension, so do this instead */
3493 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3494 /* clamp user's texture sizes to maximum sizes, if necessary */
3495 *newWidth
= nearestPower(width
);
3496 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3497 *newHeight
= nearestPower(height
);
3498 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3499 /*printf("NO proxy textures\n");*/
3501 } /* closestFit() */
3504 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3505 GLenum typein
, const void *datain
,
3506 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3510 GLushort
*beforeImage
;
3511 GLushort
*afterImage
;
3512 PixelStorageModes psm
;
3514 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3517 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3518 return GLU_INVALID_VALUE
;
3520 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3521 return GLU_INVALID_ENUM
;
3523 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3524 return GLU_INVALID_OPERATION
;
3526 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3527 return GLU_INVALID_OPERATION
;
3530 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3532 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3533 if (beforeImage
== NULL
|| afterImage
== NULL
) {
3534 return GLU_OUT_OF_MEMORY
;
3537 retrieveStoreModes(&psm
);
3538 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3539 datain
, beforeImage
);
3540 components
= elements_per_group(format
, 0);
3541 scale_internal(components
, widthin
, heightin
, beforeImage
,
3542 widthout
, heightout
, afterImage
);
3543 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3544 is_index(format
), afterImage
, dataout
);
3545 free((GLbyte
*) beforeImage
);
3546 free((GLbyte
*) afterImage
);
3551 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3553 GLsizei widthPowerOf2
,
3554 GLenum format
, GLenum type
,
3555 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3559 GLint level
, levels
;
3561 GLint newImage_width
;
3562 GLushort
*otherImage
;
3563 GLushort
*imageTemp
;
3566 PixelStorageModes psm
;
3568 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3573 newwidth
= widthPowerOf2
;
3574 levels
= computeLog(newwidth
);
3578 retrieveStoreModes(&psm
);
3579 newImage
= (GLushort
*)
3580 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3581 newImage_width
= width
;
3582 if (newImage
== NULL
) {
3583 return GLU_OUT_OF_MEMORY
;
3585 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3587 cmpts
= elements_per_group(format
,type
);
3588 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3589 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3590 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3591 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3593 ** If swap_bytes was set, swapping occurred in fill_image.
3595 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3597 for (level
= userLevel
; level
<= levels
; level
++) {
3598 if (newImage_width
== newwidth
) {
3599 /* Use newImage for this level */
3600 if (baseLevel
<= level
&& level
<= maxLevel
) {
3601 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3602 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3605 if (otherImage
== NULL
) {
3606 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3607 otherImage
= (GLushort
*) malloc(memreq
);
3608 if (otherImage
== NULL
) {
3609 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3610 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3611 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3612 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3613 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3614 return GLU_OUT_OF_MEMORY
;
3617 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3618 newwidth
, 1, otherImage
);
3619 /* Swap newImage and otherImage */
3620 imageTemp
= otherImage
;
3621 otherImage
= newImage
;
3622 newImage
= imageTemp
;
3624 newImage_width
= newwidth
;
3625 if (baseLevel
<= level
&& level
<= maxLevel
) {
3626 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3627 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3630 if (newwidth
> 1) newwidth
/= 2;
3632 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3633 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3634 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3635 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3636 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3638 free((GLbyte
*) newImage
);
3640 free((GLbyte
*) otherImage
);
3646 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3648 GLenum format
, GLenum type
,
3649 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3654 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3655 if (rc
!= 0) return rc
;
3658 return GLU_INVALID_VALUE
;
3661 levels
= computeLog(width
);
3664 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3665 return GLU_INVALID_VALUE
;
3667 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3670 userLevel
, baseLevel
, maxLevel
,
3672 } /* gluBuild1DMipmapLevels() */
3675 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3676 GLenum format
, GLenum type
,
3679 GLint widthPowerOf2
;
3683 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3684 if (rc
!= 0) return rc
;
3687 return GLU_INVALID_VALUE
;
3690 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3691 levels
= computeLog(widthPowerOf2
);
3693 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3696 format
,type
,0,0,levels
,data
);
3699 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3700 GLint width
, GLint height
, GLenum format
,
3701 GLenum type
, const void *data
)
3703 GLint newwidth
, newheight
;
3704 GLint level
, levels
;
3706 GLint newImage_width
;
3707 GLint newImage_height
;
3708 GLushort
*otherImage
;
3709 GLushort
*imageTemp
;
3712 PixelStorageModes psm
;
3714 retrieveStoreModes(&psm
);
3717 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3718 newwidth
= nearestPower(width
);
3719 if (newwidth
> maxsize
) newwidth
= maxsize
;
3720 newheight
= nearestPower(height
);
3721 if (newheight
> maxsize
) newheight
= maxsize
;
3723 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3724 &newwidth
,&newheight
);
3726 levels
= computeLog(newwidth
);
3727 level
= computeLog(newheight
);
3728 if (level
> levels
) levels
=level
;
3731 newImage
= (GLushort
*)
3732 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3733 newImage_width
= width
;
3734 newImage_height
= height
;
3735 if (newImage
== NULL
) {
3736 return GLU_OUT_OF_MEMORY
;
3739 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3742 cmpts
= elements_per_group(format
,type
);
3743 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3744 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3745 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3746 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3748 ** If swap_bytes was set, swapping occurred in fill_image.
3750 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3752 for (level
= 0; level
<= levels
; level
++) {
3753 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3754 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3755 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3758 if (otherImage
== NULL
) {
3760 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3761 otherImage
= (GLushort
*) malloc(memreq
);
3762 if (otherImage
== NULL
) {
3763 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3764 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3765 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3766 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3767 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3768 return GLU_OUT_OF_MEMORY
;
3771 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3772 newwidth
, newheight
, otherImage
);
3773 /* Swap newImage and otherImage */
3774 imageTemp
= otherImage
;
3775 otherImage
= newImage
;
3776 newImage
= imageTemp
;
3778 newImage_width
= newwidth
;
3779 newImage_height
= newheight
;
3780 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3781 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3784 if (newwidth
> 1) newwidth
/= 2;
3785 if (newheight
> 1) newheight
/= 2;
3787 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3788 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3789 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3790 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3791 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3793 free((GLbyte
*) newImage
);
3795 free((GLbyte
*) otherImage
);
3800 /* To make swapping images less error prone */
3801 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3802 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3804 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3805 GLsizei width
, GLsizei height
,
3806 GLsizei widthPowerOf2
,
3807 GLsizei heightPowerOf2
,
3808 GLenum format
, GLenum type
,
3810 GLint baseLevel
,GLint maxLevel
,
3813 GLint newwidth
, newheight
;
3814 GLint level
, levels
;
3815 const void *usersImage
; /* passed from user. Don't touch! */
3816 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3817 __GLU_INIT_SWAP_IMAGE
;
3821 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3822 GLint rowsize
, padding
;
3823 PixelStorageModes psm
;
3825 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3826 assert(width
>= 1 && height
>= 1);
3828 if(type
== GL_BITMAP
) {
3829 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3830 format
, type
, data
);
3833 srcImage
= dstImage
= NULL
;
3835 newwidth
= widthPowerOf2
;
3836 newheight
= heightPowerOf2
;
3837 levels
= computeLog(newwidth
);
3838 level
= computeLog(newheight
);
3839 if (level
> levels
) levels
=level
;
3843 retrieveStoreModes(&psm
);
3844 myswap_bytes
= psm
.unpack_swap_bytes
;
3845 cmpts
= elements_per_group(format
,type
);
3846 if (psm
.unpack_row_length
> 0) {
3847 groups_per_line
= psm
.unpack_row_length
;
3849 groups_per_line
= width
;
3852 element_size
= bytes_per_element(type
);
3853 group_size
= element_size
* cmpts
;
3854 if (element_size
== 1) myswap_bytes
= 0;
3856 rowsize
= groups_per_line
* group_size
;
3857 padding
= (rowsize
% psm
.unpack_alignment
);
3859 rowsize
+= psm
.unpack_alignment
- padding
;
3861 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3862 psm
.unpack_skip_pixels
* group_size
;
3864 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3865 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3867 /* don't change ROW_LENGTH until the non-power-of-two path below */
3868 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3873 /* already power-of-two square */
3874 if (width
== newwidth
&& height
== newheight
) {
3875 /* Use usersImage for level userLevel */
3876 if (baseLevel
<= level
&& level
<= maxLevel
) {
3877 glTexImage2D(target
, level
, internalFormat
, width
,
3878 height
, 0, format
, type
,
3881 if(levels
== 0) { /* we're done. clean up and return */
3882 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3883 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3884 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3885 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3886 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3890 int nextWidth
= newwidth
/2;
3891 int nextHeight
= newheight
/2;
3894 if (nextWidth
< 1) nextWidth
= 1;
3895 if (nextHeight
< 1) nextHeight
= 1;
3896 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3900 case GL_UNSIGNED_BYTE
:
3901 dstImage
= (GLubyte
*)malloc(memreq
);
3904 dstImage
= (GLbyte
*)malloc(memreq
);
3906 case GL_UNSIGNED_SHORT
:
3907 dstImage
= (GLushort
*)malloc(memreq
);
3910 dstImage
= (GLshort
*)malloc(memreq
);
3912 case GL_UNSIGNED_INT
:
3913 dstImage
= (GLuint
*)malloc(memreq
);
3916 dstImage
= (GLint
*)malloc(memreq
);
3919 dstImage
= (GLfloat
*)malloc(memreq
);
3921 case GL_UNSIGNED_BYTE_3_3_2
:
3922 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3923 dstImage
= (GLubyte
*)malloc(memreq
);
3925 case GL_UNSIGNED_SHORT_5_6_5
:
3926 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3927 case GL_UNSIGNED_SHORT_4_4_4_4
:
3928 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3929 case GL_UNSIGNED_SHORT_5_5_5_1
:
3930 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3931 dstImage
= (GLushort
*)malloc(memreq
);
3933 case GL_UNSIGNED_INT_8_8_8_8
:
3934 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3935 case GL_UNSIGNED_INT_10_10_10_2
:
3936 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3937 dstImage
= (GLuint
*)malloc(memreq
);
3940 return GLU_INVALID_ENUM
;
3942 if (dstImage
== NULL
) {
3943 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3944 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3945 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3946 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3947 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3948 return GLU_OUT_OF_MEMORY
;
3952 case GL_UNSIGNED_BYTE
:
3953 halveImage_ubyte(cmpts
, width
, height
,
3954 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3955 element_size
, rowsize
, group_size
);
3958 halveImage_byte(cmpts
, width
, height
,
3959 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3960 element_size
, rowsize
, group_size
);
3962 case GL_UNSIGNED_SHORT
:
3963 halveImage_ushort(cmpts
, width
, height
,
3964 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3965 element_size
, rowsize
, group_size
, myswap_bytes
);
3968 halveImage_short(cmpts
, width
, height
,
3969 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3970 element_size
, rowsize
, group_size
, myswap_bytes
);
3972 case GL_UNSIGNED_INT
:
3973 halveImage_uint(cmpts
, width
, height
,
3974 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3975 element_size
, rowsize
, group_size
, myswap_bytes
);
3978 halveImage_int(cmpts
, width
, height
,
3979 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3980 element_size
, rowsize
, group_size
, myswap_bytes
);
3983 halveImage_float(cmpts
, width
, height
,
3984 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3985 element_size
, rowsize
, group_size
, myswap_bytes
);
3987 case GL_UNSIGNED_BYTE_3_3_2
:
3988 assert(format
== GL_RGB
);
3989 halveImagePackedPixel(3,extract332
,shove332
,
3990 width
,height
,usersImage
,dstImage
,
3991 element_size
,rowsize
,myswap_bytes
);
3993 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3994 assert(format
== GL_RGB
);
3995 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3996 width
,height
,usersImage
,dstImage
,
3997 element_size
,rowsize
,myswap_bytes
);
3999 case GL_UNSIGNED_SHORT_5_6_5
:
4000 halveImagePackedPixel(3,extract565
,shove565
,
4001 width
,height
,usersImage
,dstImage
,
4002 element_size
,rowsize
,myswap_bytes
);
4004 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4005 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4006 width
,height
,usersImage
,dstImage
,
4007 element_size
,rowsize
,myswap_bytes
);
4009 case GL_UNSIGNED_SHORT_4_4_4_4
:
4010 halveImagePackedPixel(4,extract4444
,shove4444
,
4011 width
,height
,usersImage
,dstImage
,
4012 element_size
,rowsize
,myswap_bytes
);
4014 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4015 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4016 width
,height
,usersImage
,dstImage
,
4017 element_size
,rowsize
,myswap_bytes
);
4019 case GL_UNSIGNED_SHORT_5_5_5_1
:
4020 halveImagePackedPixel(4,extract5551
,shove5551
,
4021 width
,height
,usersImage
,dstImage
,
4022 element_size
,rowsize
,myswap_bytes
);
4024 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4025 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4026 width
,height
,usersImage
,dstImage
,
4027 element_size
,rowsize
,myswap_bytes
);
4029 case GL_UNSIGNED_INT_8_8_8_8
:
4030 halveImagePackedPixel(4,extract8888
,shove8888
,
4031 width
,height
,usersImage
,dstImage
,
4032 element_size
,rowsize
,myswap_bytes
);
4034 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4035 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4036 width
,height
,usersImage
,dstImage
,
4037 element_size
,rowsize
,myswap_bytes
);
4039 case GL_UNSIGNED_INT_10_10_10_2
:
4040 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4041 width
,height
,usersImage
,dstImage
,
4042 element_size
,rowsize
,myswap_bytes
);
4044 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4045 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4046 width
,height
,usersImage
,dstImage
,
4047 element_size
,rowsize
,myswap_bytes
);
4054 newheight
= height
/2;
4056 if (newwidth
< 1) newwidth
= 1;
4057 if (newheight
< 1) newheight
= 1;
4060 rowsize
= newwidth
* group_size
;
4061 memreq
= image_size(newwidth
, newheight
, format
, type
);
4062 /* Swap srcImage and dstImage */
4063 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4065 case GL_UNSIGNED_BYTE
:
4066 dstImage
= (GLubyte
*)malloc(memreq
);
4069 dstImage
= (GLbyte
*)malloc(memreq
);
4071 case GL_UNSIGNED_SHORT
:
4072 dstImage
= (GLushort
*)malloc(memreq
);
4075 dstImage
= (GLshort
*)malloc(memreq
);
4077 case GL_UNSIGNED_INT
:
4078 dstImage
= (GLuint
*)malloc(memreq
);
4081 dstImage
= (GLint
*)malloc(memreq
);
4084 dstImage
= (GLfloat
*)malloc(memreq
);
4086 case GL_UNSIGNED_BYTE_3_3_2
:
4087 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4088 dstImage
= (GLubyte
*)malloc(memreq
);
4090 case GL_UNSIGNED_SHORT_5_6_5
:
4091 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4092 case GL_UNSIGNED_SHORT_4_4_4_4
:
4093 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4094 case GL_UNSIGNED_SHORT_5_5_5_1
:
4095 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4096 dstImage
= (GLushort
*)malloc(memreq
);
4098 case GL_UNSIGNED_INT_8_8_8_8
:
4099 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4100 case GL_UNSIGNED_INT_10_10_10_2
:
4101 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4102 dstImage
= (GLuint
*)malloc(memreq
);
4105 return GLU_INVALID_ENUM
;
4107 if (dstImage
== NULL
) {
4108 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4109 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4110 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4111 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4112 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4113 return GLU_OUT_OF_MEMORY
;
4115 /* level userLevel+1 is in srcImage; level userLevel already saved */
4116 level
= userLevel
+1;
4117 } else { /* user's image is *not* nice power-of-2 sized square */
4120 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4122 memreq
= image_size(newwidth
, newheight
, format
, type
);
4124 case GL_UNSIGNED_BYTE
:
4125 dstImage
= (GLubyte
*)malloc(memreq
);
4128 dstImage
= (GLbyte
*)malloc(memreq
);
4130 case GL_UNSIGNED_SHORT
:
4131 dstImage
= (GLushort
*)malloc(memreq
);
4134 dstImage
= (GLshort
*)malloc(memreq
);
4136 case GL_UNSIGNED_INT
:
4137 dstImage
= (GLuint
*)malloc(memreq
);
4140 dstImage
= (GLint
*)malloc(memreq
);
4143 dstImage
= (GLfloat
*)malloc(memreq
);
4145 case GL_UNSIGNED_BYTE_3_3_2
:
4146 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4147 dstImage
= (GLubyte
*)malloc(memreq
);
4149 case GL_UNSIGNED_SHORT_5_6_5
:
4150 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4151 case GL_UNSIGNED_SHORT_4_4_4_4
:
4152 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4153 case GL_UNSIGNED_SHORT_5_5_5_1
:
4154 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4155 dstImage
= (GLushort
*)malloc(memreq
);
4157 case GL_UNSIGNED_INT_8_8_8_8
:
4158 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4159 case GL_UNSIGNED_INT_10_10_10_2
:
4160 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4161 dstImage
= (GLuint
*)malloc(memreq
);
4164 return GLU_INVALID_ENUM
;
4167 if (dstImage
== NULL
) {
4168 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4169 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4170 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4171 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4172 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4173 return GLU_OUT_OF_MEMORY
;
4177 case GL_UNSIGNED_BYTE
:
4178 scale_internal_ubyte(cmpts
, width
, height
,
4179 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4180 (GLubyte
*)dstImage
, element_size
,
4181 rowsize
, group_size
);
4184 scale_internal_byte(cmpts
, width
, height
,
4185 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4186 (GLbyte
*)dstImage
, element_size
,
4187 rowsize
, group_size
);
4189 case GL_UNSIGNED_SHORT
:
4190 scale_internal_ushort(cmpts
, width
, height
,
4191 (const GLushort
*)usersImage
, newwidth
, newheight
,
4192 (GLushort
*)dstImage
, element_size
,
4193 rowsize
, group_size
, myswap_bytes
);
4196 scale_internal_short(cmpts
, width
, height
,
4197 (const GLshort
*)usersImage
, newwidth
, newheight
,
4198 (GLshort
*)dstImage
, element_size
,
4199 rowsize
, group_size
, myswap_bytes
);
4201 case GL_UNSIGNED_INT
:
4202 scale_internal_uint(cmpts
, width
, height
,
4203 (const GLuint
*)usersImage
, newwidth
, newheight
,
4204 (GLuint
*)dstImage
, element_size
,
4205 rowsize
, group_size
, myswap_bytes
);
4208 scale_internal_int(cmpts
, width
, height
,
4209 (const GLint
*)usersImage
, newwidth
, newheight
,
4210 (GLint
*)dstImage
, element_size
,
4211 rowsize
, group_size
, myswap_bytes
);
4214 scale_internal_float(cmpts
, width
, height
,
4215 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4216 (GLfloat
*)dstImage
, element_size
,
4217 rowsize
, group_size
, myswap_bytes
);
4219 case GL_UNSIGNED_BYTE_3_3_2
:
4220 scaleInternalPackedPixel(3,extract332
,shove332
,
4221 width
, height
,usersImage
,
4222 newwidth
,newheight
,(void *)dstImage
,
4223 element_size
,rowsize
,myswap_bytes
);
4225 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4226 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4227 width
, height
,usersImage
,
4228 newwidth
,newheight
,(void *)dstImage
,
4229 element_size
,rowsize
,myswap_bytes
);
4231 case GL_UNSIGNED_SHORT_5_6_5
:
4232 scaleInternalPackedPixel(3,extract565
,shove565
,
4233 width
, height
,usersImage
,
4234 newwidth
,newheight
,(void *)dstImage
,
4235 element_size
,rowsize
,myswap_bytes
);
4237 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4238 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4239 width
, height
,usersImage
,
4240 newwidth
,newheight
,(void *)dstImage
,
4241 element_size
,rowsize
,myswap_bytes
);
4243 case GL_UNSIGNED_SHORT_4_4_4_4
:
4244 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4245 width
, height
,usersImage
,
4246 newwidth
,newheight
,(void *)dstImage
,
4247 element_size
,rowsize
,myswap_bytes
);
4249 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4250 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4251 width
, height
,usersImage
,
4252 newwidth
,newheight
,(void *)dstImage
,
4253 element_size
,rowsize
,myswap_bytes
);
4255 case GL_UNSIGNED_SHORT_5_5_5_1
:
4256 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4257 width
, height
,usersImage
,
4258 newwidth
,newheight
,(void *)dstImage
,
4259 element_size
,rowsize
,myswap_bytes
);
4261 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4262 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4263 width
, height
,usersImage
,
4264 newwidth
,newheight
,(void *)dstImage
,
4265 element_size
,rowsize
,myswap_bytes
);
4267 case GL_UNSIGNED_INT_8_8_8_8
:
4268 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4269 width
, height
,usersImage
,
4270 newwidth
,newheight
,(void *)dstImage
,
4271 element_size
,rowsize
,myswap_bytes
);
4273 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4274 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4275 width
, height
,usersImage
,
4276 newwidth
,newheight
,(void *)dstImage
,
4277 element_size
,rowsize
,myswap_bytes
);
4279 case GL_UNSIGNED_INT_10_10_10_2
:
4280 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4281 width
, height
,usersImage
,
4282 newwidth
,newheight
,(void *)dstImage
,
4283 element_size
,rowsize
,myswap_bytes
);
4285 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4286 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4287 width
, height
,usersImage
,
4288 newwidth
,newheight
,(void *)dstImage
,
4289 element_size
,rowsize
,myswap_bytes
);
4296 rowsize
= newwidth
* group_size
;
4297 /* Swap dstImage and srcImage */
4298 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4300 if(levels
!= 0) { /* use as little memory as possible */
4302 int nextWidth
= newwidth
/2;
4303 int nextHeight
= newheight
/2;
4304 if (nextWidth
< 1) nextWidth
= 1;
4305 if (nextHeight
< 1) nextHeight
= 1;
4307 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4311 case GL_UNSIGNED_BYTE
:
4312 dstImage
= (GLubyte
*)malloc(memreq
);
4315 dstImage
= (GLbyte
*)malloc(memreq
);
4317 case GL_UNSIGNED_SHORT
:
4318 dstImage
= (GLushort
*)malloc(memreq
);
4321 dstImage
= (GLshort
*)malloc(memreq
);
4323 case GL_UNSIGNED_INT
:
4324 dstImage
= (GLuint
*)malloc(memreq
);
4327 dstImage
= (GLint
*)malloc(memreq
);
4330 dstImage
= (GLfloat
*)malloc(memreq
);
4332 case GL_UNSIGNED_BYTE_3_3_2
:
4333 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4334 dstImage
= (GLubyte
*)malloc(memreq
);
4336 case GL_UNSIGNED_SHORT_5_6_5
:
4337 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4338 case GL_UNSIGNED_SHORT_4_4_4_4
:
4339 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4340 case GL_UNSIGNED_SHORT_5_5_5_1
:
4341 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4342 dstImage
= (GLushort
*)malloc(memreq
);
4344 case GL_UNSIGNED_INT_8_8_8_8
:
4345 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4346 case GL_UNSIGNED_INT_10_10_10_2
:
4347 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4348 dstImage
= (GLuint
*)malloc(memreq
);
4351 return GLU_INVALID_ENUM
;
4353 if (dstImage
== NULL
) {
4354 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4355 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4356 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4357 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4358 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4359 return GLU_OUT_OF_MEMORY
;
4362 /* level userLevel is in srcImage; nothing saved yet */
4366 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4367 if (baseLevel
<= level
&& level
<= maxLevel
) {
4368 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4369 format
, type
, (void *)srcImage
);
4372 level
++; /* update current level for the loop */
4373 for (; level
<= levels
; level
++) {
4375 case GL_UNSIGNED_BYTE
:
4376 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4377 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4378 rowsize
, group_size
);
4381 halveImage_byte(cmpts
, newwidth
, newheight
,
4382 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4383 rowsize
, group_size
);
4385 case GL_UNSIGNED_SHORT
:
4386 halveImage_ushort(cmpts
, newwidth
, newheight
,
4387 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4388 rowsize
, group_size
, myswap_bytes
);
4391 halveImage_short(cmpts
, newwidth
, newheight
,
4392 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4393 rowsize
, group_size
, myswap_bytes
);
4395 case GL_UNSIGNED_INT
:
4396 halveImage_uint(cmpts
, newwidth
, newheight
,
4397 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4398 rowsize
, group_size
, myswap_bytes
);
4401 halveImage_int(cmpts
, newwidth
, newheight
,
4402 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4403 rowsize
, group_size
, myswap_bytes
);
4406 halveImage_float(cmpts
, newwidth
, newheight
,
4407 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4408 rowsize
, group_size
, myswap_bytes
);
4410 case GL_UNSIGNED_BYTE_3_3_2
:
4411 halveImagePackedPixel(3,extract332
,shove332
,
4413 srcImage
,dstImage
,element_size
,rowsize
,
4416 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4417 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4419 srcImage
,dstImage
,element_size
,rowsize
,
4422 case GL_UNSIGNED_SHORT_5_6_5
:
4423 halveImagePackedPixel(3,extract565
,shove565
,
4425 srcImage
,dstImage
,element_size
,rowsize
,
4428 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4429 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4431 srcImage
,dstImage
,element_size
,rowsize
,
4434 case GL_UNSIGNED_SHORT_4_4_4_4
:
4435 halveImagePackedPixel(4,extract4444
,shove4444
,
4437 srcImage
,dstImage
,element_size
,rowsize
,
4440 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4441 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4443 srcImage
,dstImage
,element_size
,rowsize
,
4446 case GL_UNSIGNED_SHORT_5_5_5_1
:
4447 halveImagePackedPixel(4,extract5551
,shove5551
,
4449 srcImage
,dstImage
,element_size
,rowsize
,
4452 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4453 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4455 srcImage
,dstImage
,element_size
,rowsize
,
4458 case GL_UNSIGNED_INT_8_8_8_8
:
4459 halveImagePackedPixel(4,extract8888
,shove8888
,
4461 srcImage
,dstImage
,element_size
,rowsize
,
4464 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4465 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4467 srcImage
,dstImage
,element_size
,rowsize
,
4470 case GL_UNSIGNED_INT_10_10_10_2
:
4471 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4473 srcImage
,dstImage
,element_size
,rowsize
,
4476 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4477 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4479 srcImage
,dstImage
,element_size
,rowsize
,
4487 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4489 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4490 if (newheight
> 1) newheight
/= 2;
4492 /* compute amount to pad per row, if any */
4493 int rowPad
= rowsize
% psm
.unpack_alignment
;
4495 /* should row be padded? */
4496 if (rowPad
== 0) { /* nope, row should not be padded */
4497 /* call tex image with srcImage untouched since it's not padded */
4498 if (baseLevel
<= level
&& level
<= maxLevel
) {
4499 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4500 format
, type
, (void *) srcImage
);
4503 else { /* yes, row should be padded */
4504 /* compute length of new row in bytes, including padding */
4505 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4506 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4508 /* allocate new image for mipmap of size newRowLength x newheight */
4509 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4510 if (newMipmapImage
== NULL
) {
4511 /* out of memory so return */
4512 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4513 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4514 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4515 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4516 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4517 return GLU_OUT_OF_MEMORY
;
4520 /* copy image from srcImage into newMipmapImage by rows */
4522 dstTrav
= (unsigned char *) newMipmapImage
,
4523 srcTrav
= (unsigned char *) srcImage
;
4526 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4527 srcTrav
+= rowsize
) { /* ...is skipped */
4528 memcpy(dstTrav
,srcTrav
,rowsize
);
4529 /* note that the pad bytes are not visited and will contain
4530 * garbage, which is ok.
4534 /* ...and use this new image for mipmapping instead */
4535 if (baseLevel
<= level
&& level
<= maxLevel
) {
4536 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4537 format
, type
, newMipmapImage
);
4539 free(newMipmapImage
); /* don't forget to free it! */
4543 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4544 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4545 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4546 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4547 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4549 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4550 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4554 } /* gluBuild2DMipmapLevelsCore() */
4557 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4558 GLsizei width
, GLsizei height
,
4559 GLenum format
, GLenum type
,
4560 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4565 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4566 if (rc
!= 0) return rc
;
4568 if (width
< 1 || height
< 1) {
4569 return GLU_INVALID_VALUE
;
4572 levels
= computeLog(width
);
4573 level
= computeLog(height
);
4574 if (level
> levels
) levels
=level
;
4577 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4578 return GLU_INVALID_VALUE
;
4580 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4584 userLevel
, baseLevel
, maxLevel
,
4586 } /* gluBuild2DMipmapLevels() */
4589 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4590 GLsizei width
, GLsizei height
,
4591 GLenum format
, GLenum type
,
4594 GLint widthPowerOf2
, heightPowerOf2
;
4597 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4598 if (rc
!= 0) return rc
;
4600 if (width
< 1 || height
< 1) {
4601 return GLU_INVALID_VALUE
;
4604 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4605 &widthPowerOf2
,&heightPowerOf2
);
4607 levels
= computeLog(widthPowerOf2
);
4608 level
= computeLog(heightPowerOf2
);
4609 if (level
> levels
) levels
=level
;
4611 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4613 widthPowerOf2
,heightPowerOf2
,
4616 } /* gluBuild2DMipmaps() */
4620 ** This routine is for the limited case in which
4621 ** type == GL_UNSIGNED_BYTE && format != index &&
4622 ** unpack_alignment = 1 && unpack_swap_bytes == false
4624 ** so all of the work data can be kept as ubytes instead of shorts.
4626 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4627 GLenum target
, GLint components
, GLint width
,
4628 GLint height
, GLenum format
,
4629 GLenum type
, void *data
)
4631 GLint newwidth
, newheight
;
4632 GLint level
, levels
;
4634 GLint newImage_width
;
4635 GLint newImage_height
;
4636 GLubyte
*otherImage
;
4643 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4644 newwidth
= nearestPower(width
);
4645 if (newwidth
> maxsize
) newwidth
= maxsize
;
4646 newheight
= nearestPower(height
);
4647 if (newheight
> maxsize
) newheight
= maxsize
;
4649 closestFit(target
,width
,height
,components
,format
,type
,
4650 &newwidth
,&newheight
);
4652 levels
= computeLog(newwidth
);
4653 level
= computeLog(newheight
);
4654 if (level
> levels
) levels
=level
;
4656 cmpts
= elements_per_group(format
,type
);
4660 ** No need to copy the user data if its in the packed correctly.
4661 ** Make sure that later routines don't change that data.
4663 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4664 newImage
= (GLubyte
*)data
;
4665 newImage_width
= width
;
4666 newImage_height
= height
;
4669 GLint groups_per_line
;
4670 GLint elements_per_line
;
4671 const GLubyte
*start
;
4672 const GLubyte
*iter
;
4676 newImage
= (GLubyte
*)
4677 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4678 newImage_width
= width
;
4679 newImage_height
= height
;
4680 if (newImage
== NULL
) {
4681 return GLU_OUT_OF_MEMORY
;
4685 ** Abbreviated version of fill_image for this restricted case.
4687 if (psm
->unpack_row_length
> 0) {
4688 groups_per_line
= psm
->unpack_row_length
;
4690 groups_per_line
= width
;
4692 rowsize
= groups_per_line
* cmpts
;
4693 elements_per_line
= width
* cmpts
;
4694 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4695 psm
->unpack_skip_pixels
* cmpts
;
4698 for (i
= 0; i
< height
; i
++) {
4700 for (j
= 0; j
< elements_per_line
; j
++) {
4710 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4711 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4712 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4713 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4714 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4716 for (level
= 0; level
<= levels
; level
++) {
4717 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4718 /* Use newImage for this level */
4719 glTexImage2D(target
, level
, components
, newImage_width
,
4720 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4723 if (otherImage
== NULL
) {
4725 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4726 otherImage
= (GLubyte
*) malloc(memreq
);
4727 if (otherImage
== NULL
) {
4728 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4729 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4730 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4731 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4732 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4733 return GLU_OUT_OF_MEMORY
;
4737 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4738 newImage, newwidth, newheight, otherImage);
4740 /* Swap newImage and otherImage */
4741 imageTemp
= otherImage
;
4742 otherImage
= newImage
;
4743 newImage
= imageTemp
;
4745 newImage_width
= newwidth
;
4746 newImage_height
= newheight
;
4747 glTexImage2D(target
, level
, components
, newImage_width
,
4748 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4751 if (newwidth
> 1) newwidth
/= 2;
4752 if (newheight
> 1) newheight
/= 2;
4754 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4755 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4756 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4757 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4758 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4760 if (newImage
!= (const GLubyte
*)data
) {
4761 free((GLbyte
*) newImage
);
4763 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4764 free((GLbyte
*) otherImage
);
4773 static GLint
elements_per_group(GLenum format
, GLenum type
)
4776 * Return the number of elements per group of a specified format
4779 /* If the type is packedpixels then answer is 1 (ignore format) */
4780 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4781 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4782 type
== GL_UNSIGNED_SHORT_5_6_5
||
4783 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4784 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4785 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4786 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4787 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4788 type
== GL_UNSIGNED_INT_8_8_8_8
||
4789 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4790 type
== GL_UNSIGNED_INT_10_10_10_2
||
4791 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4795 /* Types are not packed pixels, so get elements per group */
4800 case GL_LUMINANCE_ALPHA
:
4810 static GLfloat
bytes_per_element(GLenum type
)
4813 * Return the number of bytes per element, based on the element type
4818 case GL_UNSIGNED_SHORT
:
4819 return(sizeof(GLushort
));
4821 return(sizeof(GLshort
));
4822 case GL_UNSIGNED_BYTE
:
4823 return(sizeof(GLubyte
));
4825 return(sizeof(GLbyte
));
4827 return(sizeof(GLint
));
4828 case GL_UNSIGNED_INT
:
4829 return(sizeof(GLuint
));
4831 return(sizeof(GLfloat
));
4832 case GL_UNSIGNED_BYTE_3_3_2
:
4833 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4834 return(sizeof(GLubyte
));
4835 case GL_UNSIGNED_SHORT_5_6_5
:
4836 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4837 case GL_UNSIGNED_SHORT_4_4_4_4
:
4838 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4839 case GL_UNSIGNED_SHORT_5_5_5_1
:
4840 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4841 return(sizeof(GLushort
));
4842 case GL_UNSIGNED_INT_8_8_8_8
:
4843 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4844 case GL_UNSIGNED_INT_10_10_10_2
:
4845 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4846 return(sizeof(GLuint
));
4852 static GLint
is_index(GLenum format
)
4854 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4858 ** Compute memory required for internal packed array of data of given type
4861 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4868 components
= elements_per_group(format
,type
);
4869 if (type
== GL_BITMAP
) {
4870 bytes_per_row
= (width
+ 7) / 8;
4872 bytes_per_row
= bytes_per_element(type
) * width
;
4874 return bytes_per_row
* height
* components
;
4878 ** Extract array from user's data applying all pixel store modes.
4879 ** The internal format used is an array of unsigned shorts.
4881 static void fill_image(const PixelStorageModes
*psm
,
4882 GLint width
, GLint height
, GLenum format
,
4883 GLenum type
, GLboolean index_format
,
4884 const void *userdata
, GLushort
*newimage
)
4890 GLint groups_per_line
;
4892 GLint elements_per_line
;
4893 const GLubyte
*start
;
4894 const GLubyte
*iter
;
4899 myswap_bytes
= psm
->unpack_swap_bytes
;
4900 components
= elements_per_group(format
,type
);
4901 if (psm
->unpack_row_length
> 0) {
4902 groups_per_line
= psm
->unpack_row_length
;
4904 groups_per_line
= width
;
4907 /* All formats except GL_BITMAP fall out trivially */
4908 if (type
== GL_BITMAP
) {
4912 rowsize
= (groups_per_line
* components
+ 7) / 8;
4913 padding
= (rowsize
% psm
->unpack_alignment
);
4915 rowsize
+= psm
->unpack_alignment
- padding
;
4917 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4918 (psm
->unpack_skip_pixels
* components
/ 8);
4919 elements_per_line
= width
* components
;
4921 for (i
= 0; i
< height
; i
++) {
4923 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4924 for (j
= 0; j
< elements_per_line
; j
++) {
4926 if (psm
->unpack_lsb_first
) {
4927 current_bit
= iter
[0] & (1 << bit_offset
);
4929 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4941 if (bit_offset
== 8) {
4950 element_size
= bytes_per_element(type
);
4951 group_size
= element_size
* components
;
4952 if (element_size
== 1) myswap_bytes
= 0;
4954 rowsize
= groups_per_line
* group_size
;
4955 padding
= (rowsize
% psm
->unpack_alignment
);
4957 rowsize
+= psm
->unpack_alignment
- padding
;
4959 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4960 psm
->unpack_skip_pixels
* group_size
;
4961 elements_per_line
= width
* components
;
4964 for (i
= 0; i
< height
; i
++) {
4966 for (j
= 0; j
< elements_per_line
; j
++) {
4968 float extractComponents
[4];
4971 case GL_UNSIGNED_BYTE_3_3_2
:
4972 extract332(0,iter
,extractComponents
);
4973 for (k
= 0; k
< 3; k
++) {
4974 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4977 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4978 extract233rev(0,iter
,extractComponents
);
4979 for (k
= 0; k
< 3; k
++) {
4980 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4983 case GL_UNSIGNED_BYTE
:
4987 *iter2
++ = (*iter
) * 257;
4992 *iter2
++ = *((const GLbyte
*) iter
);
4995 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4998 case GL_UNSIGNED_SHORT_5_6_5
:
4999 extract565(myswap_bytes
,iter
,extractComponents
);
5000 for (k
= 0; k
< 3; k
++) {
5001 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5004 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5005 extract565rev(myswap_bytes
,iter
,extractComponents
);
5006 for (k
= 0; k
< 3; k
++) {
5007 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5010 case GL_UNSIGNED_SHORT_4_4_4_4
:
5011 extract4444(myswap_bytes
,iter
,extractComponents
);
5012 for (k
= 0; k
< 4; k
++) {
5013 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5016 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5017 extract4444rev(myswap_bytes
,iter
,extractComponents
);
5018 for (k
= 0; k
< 4; k
++) {
5019 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5022 case GL_UNSIGNED_SHORT_5_5_5_1
:
5023 extract5551(myswap_bytes
,iter
,extractComponents
);
5024 for (k
= 0; k
< 4; k
++) {
5025 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5028 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5029 extract1555rev(myswap_bytes
,iter
,extractComponents
);
5030 for (k
= 0; k
< 4; k
++) {
5031 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5034 case GL_UNSIGNED_SHORT
:
5037 widget
.ub
[0] = iter
[1];
5038 widget
.ub
[1] = iter
[0];
5040 widget
.ub
[0] = iter
[0];
5041 widget
.ub
[1] = iter
[1];
5043 if (type
== GL_SHORT
) {
5045 *iter2
++ = widget
.s
[0];
5048 *iter2
++ = widget
.s
[0]*2;
5051 *iter2
++ = widget
.us
[0];
5054 case GL_UNSIGNED_INT_8_8_8_8
:
5055 extract8888(myswap_bytes
,iter
,extractComponents
);
5056 for (k
= 0; k
< 4; k
++) {
5057 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5060 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5061 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5062 for (k
= 0; k
< 4; k
++) {
5063 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5066 case GL_UNSIGNED_INT_10_10_10_2
:
5067 extract1010102(myswap_bytes
,iter
,extractComponents
);
5068 for (k
= 0; k
< 4; k
++) {
5069 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5072 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5073 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5074 for (k
= 0; k
< 4; k
++) {
5075 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5079 case GL_UNSIGNED_INT
:
5082 widget
.ub
[0] = iter
[3];
5083 widget
.ub
[1] = iter
[2];
5084 widget
.ub
[2] = iter
[1];
5085 widget
.ub
[3] = iter
[0];
5087 widget
.ub
[0] = iter
[0];
5088 widget
.ub
[1] = iter
[1];
5089 widget
.ub
[2] = iter
[2];
5090 widget
.ub
[3] = iter
[3];
5092 if (type
== GL_FLOAT
) {
5094 *iter2
++ = widget
.f
;
5096 *iter2
++ = 65535 * widget
.f
;
5098 } else if (type
== GL_UNSIGNED_INT
) {
5100 *iter2
++ = widget
.ui
;
5102 *iter2
++ = widget
.ui
>> 16;
5106 *iter2
++ = widget
.i
;
5108 *iter2
++ = widget
.i
>> 15;
5113 iter
+= element_size
;
5117 /* want 'iter' pointing at start, not within, row for assertion
5124 /* iterators should be one byte past end */
5125 if (!isTypePackedPixel(type
)) {
5126 assert(iter2
== &newimage
[width
*height
*components
]);
5129 assert(iter2
== &newimage
[width
*height
*
5130 elements_per_group(format
,0)]);
5132 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5133 psm
->unpack_skip_rows
* rowsize
+
5134 psm
->unpack_skip_pixels
* group_size
] );
5137 } /* fill_image() */
5140 ** Insert array into user's data applying all pixel store modes.
5141 ** The internal format is an array of unsigned shorts.
5142 ** empty_image() because it is the opposite of fill_image().
5144 static void empty_image(const PixelStorageModes
*psm
,
5145 GLint width
, GLint height
, GLenum format
,
5146 GLenum type
, GLboolean index_format
,
5147 const GLushort
*oldimage
, void *userdata
)
5153 GLint groups_per_line
;
5155 GLint elements_per_line
;
5158 const GLushort
*iter2
;
5162 myswap_bytes
= psm
->pack_swap_bytes
;
5163 components
= elements_per_group(format
,type
);
5164 if (psm
->pack_row_length
> 0) {
5165 groups_per_line
= psm
->pack_row_length
;
5167 groups_per_line
= width
;
5170 /* All formats except GL_BITMAP fall out trivially */
5171 if (type
== GL_BITMAP
) {
5175 rowsize
= (groups_per_line
* components
+ 7) / 8;
5176 padding
= (rowsize
% psm
->pack_alignment
);
5178 rowsize
+= psm
->pack_alignment
- padding
;
5180 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5181 (psm
->pack_skip_pixels
* components
/ 8);
5182 elements_per_line
= width
* components
;
5184 for (i
= 0; i
< height
; i
++) {
5186 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5187 for (j
= 0; j
< elements_per_line
; j
++) {
5189 current_bit
= iter2
[0] & 1;
5191 if (iter2
[0] > 32767) {
5199 if (psm
->pack_lsb_first
) {
5200 *iter
|= (1 << bit_offset
);
5202 *iter
|= (1 << (7 - bit_offset
));
5205 if (psm
->pack_lsb_first
) {
5206 *iter
&= ~(1 << bit_offset
);
5208 *iter
&= ~(1 << (7 - bit_offset
));
5213 if (bit_offset
== 8) {
5222 float shoveComponents
[4];
5224 element_size
= bytes_per_element(type
);
5225 group_size
= element_size
* components
;
5226 if (element_size
== 1) myswap_bytes
= 0;
5228 rowsize
= groups_per_line
* group_size
;
5229 padding
= (rowsize
% psm
->pack_alignment
);
5231 rowsize
+= psm
->pack_alignment
- padding
;
5233 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5234 psm
->pack_skip_pixels
* group_size
;
5235 elements_per_line
= width
* components
;
5238 for (i
= 0; i
< height
; i
++) {
5240 for (j
= 0; j
< elements_per_line
; j
++) {
5244 case GL_UNSIGNED_BYTE_3_3_2
:
5245 for (k
= 0; k
< 3; k
++) {
5246 shoveComponents
[k
]= *iter2
++ / 65535.0;
5248 shove332(shoveComponents
,0,(void *)iter
);
5250 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5251 for (k
= 0; k
< 3; k
++) {
5252 shoveComponents
[k
]= *iter2
++ / 65535.0;
5254 shove233rev(shoveComponents
,0,(void *)iter
);
5256 case GL_UNSIGNED_BYTE
:
5260 *iter
= *iter2
++ >> 8;
5265 *((GLbyte
*) iter
) = *iter2
++;
5267 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5270 case GL_UNSIGNED_SHORT_5_6_5
:
5271 for (k
= 0; k
< 3; k
++) {
5272 shoveComponents
[k
]= *iter2
++ / 65535.0;
5274 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5276 iter
[0] = widget
.ub
[1];
5277 iter
[1] = widget
.ub
[0];
5280 *(GLushort
*)iter
= widget
.us
[0];
5283 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5284 for (k
= 0; k
< 3; k
++) {
5285 shoveComponents
[k
]= *iter2
++ / 65535.0;
5287 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5289 iter
[0] = widget
.ub
[1];
5290 iter
[1] = widget
.ub
[0];
5293 *(GLushort
*)iter
= widget
.us
[0];
5296 case GL_UNSIGNED_SHORT_4_4_4_4
:
5297 for (k
= 0; k
< 4; k
++) {
5298 shoveComponents
[k
]= *iter2
++ / 65535.0;
5300 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5302 iter
[0] = widget
.ub
[1];
5303 iter
[1] = widget
.ub
[0];
5305 *(GLushort
*)iter
= widget
.us
[0];
5308 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5309 for (k
= 0; k
< 4; k
++) {
5310 shoveComponents
[k
]= *iter2
++ / 65535.0;
5312 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5314 iter
[0] = widget
.ub
[1];
5315 iter
[1] = widget
.ub
[0];
5317 *(GLushort
*)iter
= widget
.us
[0];
5320 case GL_UNSIGNED_SHORT_5_5_5_1
:
5321 for (k
= 0; k
< 4; k
++) {
5322 shoveComponents
[k
]= *iter2
++ / 65535.0;
5324 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5326 iter
[0] = widget
.ub
[1];
5327 iter
[1] = widget
.ub
[0];
5329 *(GLushort
*)iter
= widget
.us
[0];
5332 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5333 for (k
= 0; k
< 4; k
++) {
5334 shoveComponents
[k
]= *iter2
++ / 65535.0;
5336 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5338 iter
[0] = widget
.ub
[1];
5339 iter
[1] = widget
.ub
[0];
5341 *(GLushort
*)iter
= widget
.us
[0];
5344 case GL_UNSIGNED_SHORT
:
5346 if (type
== GL_SHORT
) {
5348 widget
.s
[0] = *iter2
++;
5350 widget
.s
[0] = *iter2
++ >> 1;
5353 widget
.us
[0] = *iter2
++;
5356 iter
[0] = widget
.ub
[1];
5357 iter
[1] = widget
.ub
[0];
5359 iter
[0] = widget
.ub
[0];
5360 iter
[1] = widget
.ub
[1];
5363 case GL_UNSIGNED_INT_8_8_8_8
:
5364 for (k
= 0; k
< 4; k
++) {
5365 shoveComponents
[k
]= *iter2
++ / 65535.0;
5367 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5369 iter
[3] = widget
.ub
[0];
5370 iter
[2] = widget
.ub
[1];
5371 iter
[1] = widget
.ub
[2];
5372 iter
[0] = widget
.ub
[3];
5374 *(GLuint
*)iter
= widget
.ui
;
5378 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5379 for (k
= 0; k
< 4; k
++) {
5380 shoveComponents
[k
]= *iter2
++ / 65535.0;
5382 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5384 iter
[3] = widget
.ub
[0];
5385 iter
[2] = widget
.ub
[1];
5386 iter
[1] = widget
.ub
[2];
5387 iter
[0] = widget
.ub
[3];
5389 *(GLuint
*)iter
= widget
.ui
;
5392 case GL_UNSIGNED_INT_10_10_10_2
:
5393 for (k
= 0; k
< 4; k
++) {
5394 shoveComponents
[k
]= *iter2
++ / 65535.0;
5396 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5398 iter
[3] = widget
.ub
[0];
5399 iter
[2] = widget
.ub
[1];
5400 iter
[1] = widget
.ub
[2];
5401 iter
[0] = widget
.ub
[3];
5403 *(GLuint
*)iter
= widget
.ui
;
5406 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5407 for (k
= 0; k
< 4; k
++) {
5408 shoveComponents
[k
]= *iter2
++ / 65535.0;
5410 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
5412 iter
[3] = widget
.ub
[0];
5413 iter
[2] = widget
.ub
[1];
5414 iter
[1] = widget
.ub
[2];
5415 iter
[0] = widget
.ub
[3];
5417 *(GLuint
*)iter
= widget
.ui
;
5421 case GL_UNSIGNED_INT
:
5423 if (type
== GL_FLOAT
) {
5425 widget
.f
= *iter2
++;
5427 widget
.f
= *iter2
++ / (float) 65535.0;
5429 } else if (type
== GL_UNSIGNED_INT
) {
5431 widget
.ui
= *iter2
++;
5433 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5437 widget
.i
= *iter2
++;
5439 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5443 iter
[3] = widget
.ub
[0];
5444 iter
[2] = widget
.ub
[1];
5445 iter
[1] = widget
.ub
[2];
5446 iter
[0] = widget
.ub
[3];
5448 iter
[0] = widget
.ub
[0];
5449 iter
[1] = widget
.ub
[1];
5450 iter
[2] = widget
.ub
[2];
5451 iter
[3] = widget
.ub
[3];
5455 iter
+= element_size
;
5459 /* want 'iter' pointing at start, not within, row for assertion
5466 /* iterators should be one byte past end */
5467 if (!isTypePackedPixel(type
)) {
5468 assert(iter2
== &oldimage
[width
*height
*components
]);
5471 assert(iter2
== &oldimage
[width
*height
*
5472 elements_per_group(format
,0)]);
5474 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5475 psm
->pack_skip_rows
* rowsize
+
5476 psm
->pack_skip_pixels
* group_size
] );
5479 } /* empty_image() */
5481 /*--------------------------------------------------------------------------
5482 * Decimation of packed pixel types
5483 *--------------------------------------------------------------------------
5485 static void extract332(int isSwap
,
5486 const void *packedPixel
, GLfloat extractComponents
[])
5488 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5490 isSwap
= isSwap
; /* turn off warnings */
5492 /* 11100000 == 0xe0 */
5493 /* 00011100 == 0x1c */
5494 /* 00000011 == 0x03 */
5496 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5497 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5498 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5499 } /* extract332() */
5501 static void shove332(const GLfloat shoveComponents
[],
5502 int index
, void *packedPixel
)
5504 /* 11100000 == 0xe0 */
5505 /* 00011100 == 0x1c */
5506 /* 00000011 == 0x03 */
5508 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5509 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5510 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5512 /* due to limited precision, need to round before shoving */
5513 ((GLubyte
*)packedPixel
)[index
] =
5514 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5515 ((GLubyte
*)packedPixel
)[index
] |=
5516 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5517 ((GLubyte
*)packedPixel
)[index
] |=
5518 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5521 static void extract233rev(int isSwap
,
5522 const void *packedPixel
, GLfloat extractComponents
[])
5524 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5526 isSwap
= isSwap
; /* turn off warnings */
5528 /* 0000,0111 == 0x07 */
5529 /* 0011,1000 == 0x38 */
5530 /* 1100,0000 == 0xC0 */
5532 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5533 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5534 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5535 } /* extract233rev() */
5537 static void shove233rev(const GLfloat shoveComponents
[],
5538 int index
, void *packedPixel
)
5540 /* 0000,0111 == 0x07 */
5541 /* 0011,1000 == 0x38 */
5542 /* 1100,0000 == 0xC0 */
5544 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5545 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5546 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5548 /* due to limited precision, need to round before shoving */
5549 ((GLubyte
*)packedPixel
)[index
] =
5550 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5551 ((GLubyte
*)packedPixel
)[index
]|=
5552 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5553 ((GLubyte
*)packedPixel
)[index
]|=
5554 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5555 } /* shove233rev() */
5557 static void extract565(int isSwap
,
5558 const void *packedPixel
, GLfloat extractComponents
[])
5560 GLushort ushort
= *(const GLushort
*)packedPixel
;
5563 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5566 ushort
= *(const GLushort
*)packedPixel
;
5569 /* 11111000,00000000 == 0xf800 */
5570 /* 00000111,11100000 == 0x07e0 */
5571 /* 00000000,00011111 == 0x001f */
5573 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5574 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5575 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5576 } /* extract565() */
5578 static void shove565(const GLfloat shoveComponents
[],
5579 int index
,void *packedPixel
)
5581 /* 11111000,00000000 == 0xf800 */
5582 /* 00000111,11100000 == 0x07e0 */
5583 /* 00000000,00011111 == 0x001f */
5585 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5586 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5587 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5589 /* due to limited precision, need to round before shoving */
5590 ((GLushort
*)packedPixel
)[index
] =
5591 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5592 ((GLushort
*)packedPixel
)[index
]|=
5593 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5594 ((GLushort
*)packedPixel
)[index
]|=
5595 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5598 static void extract565rev(int isSwap
,
5599 const void *packedPixel
, GLfloat extractComponents
[])
5601 GLushort ushort
= *(const GLushort
*)packedPixel
;
5604 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5607 ushort
= *(const GLushort
*)packedPixel
;
5610 /* 00000000,00011111 == 0x001f */
5611 /* 00000111,11100000 == 0x07e0 */
5612 /* 11111000,00000000 == 0xf800 */
5614 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5615 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5616 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5617 } /* extract565rev() */
5619 static void shove565rev(const GLfloat shoveComponents
[],
5620 int index
,void *packedPixel
)
5622 /* 00000000,00011111 == 0x001f */
5623 /* 00000111,11100000 == 0x07e0 */
5624 /* 11111000,00000000 == 0xf800 */
5626 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5627 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5628 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5630 /* due to limited precision, need to round before shoving */
5631 ((GLushort
*)packedPixel
)[index
] =
5632 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5633 ((GLushort
*)packedPixel
)[index
]|=
5634 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5635 ((GLushort
*)packedPixel
)[index
]|=
5636 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5637 } /* shove565rev() */
5639 static void extract4444(int isSwap
,const void *packedPixel
,
5640 GLfloat extractComponents
[])
5645 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5648 ushort
= *(const GLushort
*)packedPixel
;
5651 /* 11110000,00000000 == 0xf000 */
5652 /* 00001111,00000000 == 0x0f00 */
5653 /* 00000000,11110000 == 0x00f0 */
5654 /* 00000000,00001111 == 0x000f */
5656 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5657 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5658 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5659 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5660 } /* extract4444() */
5662 static void shove4444(const GLfloat shoveComponents
[],
5663 int index
,void *packedPixel
)
5665 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5666 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5667 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5668 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5670 /* due to limited precision, need to round before shoving */
5671 ((GLushort
*)packedPixel
)[index
] =
5672 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5673 ((GLushort
*)packedPixel
)[index
]|=
5674 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5675 ((GLushort
*)packedPixel
)[index
]|=
5676 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5677 ((GLushort
*)packedPixel
)[index
]|=
5678 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5681 static void extract4444rev(int isSwap
,const void *packedPixel
,
5682 GLfloat extractComponents
[])
5687 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5690 ushort
= *(const GLushort
*)packedPixel
;
5693 /* 00000000,00001111 == 0x000f */
5694 /* 00000000,11110000 == 0x00f0 */
5695 /* 00001111,00000000 == 0x0f00 */
5696 /* 11110000,00000000 == 0xf000 */
5699 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5700 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5701 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5702 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5703 } /* extract4444rev() */
5705 static void shove4444rev(const GLfloat shoveComponents
[],
5706 int index
,void *packedPixel
)
5708 /* 00000000,00001111 == 0x000f */
5709 /* 00000000,11110000 == 0x00f0 */
5710 /* 00001111,00000000 == 0x0f00 */
5711 /* 11110000,00000000 == 0xf000 */
5713 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5714 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5715 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5716 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5718 /* due to limited precision, need to round before shoving */
5719 ((GLushort
*)packedPixel
)[index
] =
5720 ((GLushort
)((shoveComponents
[0] * 15)+0.5) ) & 0x000F;
5721 ((GLushort
*)packedPixel
)[index
]|=
5722 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5723 ((GLushort
*)packedPixel
)[index
]|=
5724 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5725 ((GLushort
*)packedPixel
)[index
]|=
5726 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5727 } /* shove4444rev() */
5729 static void extract5551(int isSwap
,const void *packedPixel
,
5730 GLfloat extractComponents
[])
5735 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5738 ushort
= *(const GLushort
*)packedPixel
;
5741 /* 11111000,00000000 == 0xf800 */
5742 /* 00000111,11000000 == 0x07c0 */
5743 /* 00000000,00111110 == 0x003e */
5744 /* 00000000,00000001 == 0x0001 */
5746 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5747 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5748 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5749 extractComponents
[3]=(float)((ushort
& 0x0001) );
5750 } /* extract5551() */
5752 static void shove5551(const GLfloat shoveComponents
[],
5753 int index
,void *packedPixel
)
5755 /* 11111000,00000000 == 0xf800 */
5756 /* 00000111,11000000 == 0x07c0 */
5757 /* 00000000,00111110 == 0x003e */
5758 /* 00000000,00000001 == 0x0001 */
5760 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5761 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5762 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5763 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5765 /* due to limited precision, need to round before shoving */
5766 ((GLushort
*)packedPixel
)[index
] =
5767 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5768 ((GLushort
*)packedPixel
)[index
]|=
5769 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5770 ((GLushort
*)packedPixel
)[index
]|=
5771 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5772 ((GLushort
*)packedPixel
)[index
]|=
5773 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5776 static void extract1555rev(int isSwap
,const void *packedPixel
,
5777 GLfloat extractComponents
[])
5782 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5785 ushort
= *(const GLushort
*)packedPixel
;
5788 /* 00000000,00011111 == 0x001F */
5789 /* 00000011,11100000 == 0x03E0 */
5790 /* 01111100,00000000 == 0x7C00 */
5791 /* 10000000,00000000 == 0x8000 */
5794 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5795 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5796 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5797 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5798 } /* extract1555rev() */
5800 static void shove1555rev(const GLfloat shoveComponents
[],
5801 int index
,void *packedPixel
)
5803 /* 00000000,00011111 == 0x001F */
5804 /* 00000011,11100000 == 0x03E0 */
5805 /* 01111100,00000000 == 0x7C00 */
5806 /* 10000000,00000000 == 0x8000 */
5808 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5809 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5810 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5811 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5813 /* due to limited precision, need to round before shoving */
5814 ((GLushort
*)packedPixel
)[index
] =
5815 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5816 ((GLushort
*)packedPixel
)[index
]|=
5817 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5818 ((GLushort
*)packedPixel
)[index
]|=
5819 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5820 ((GLushort
*)packedPixel
)[index
]|=
5821 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5822 } /* shove1555rev() */
5824 static void extract8888(int isSwap
,
5825 const void *packedPixel
, GLfloat extractComponents
[])
5830 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5833 uint
= *(const GLuint
*)packedPixel
;
5836 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5837 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5838 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5839 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5842 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5843 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5844 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5845 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5846 } /* extract8888() */
5848 static void shove8888(const GLfloat shoveComponents
[],
5849 int index
,void *packedPixel
)
5851 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5852 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5853 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5854 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5856 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5857 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5858 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5859 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5861 /* due to limited precision, need to round before shoving */
5862 ((GLuint
*)packedPixel
)[index
] =
5863 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5864 ((GLuint
*)packedPixel
)[index
]|=
5865 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5866 ((GLuint
*)packedPixel
)[index
]|=
5867 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5868 ((GLuint
*)packedPixel
)[index
]|=
5869 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5872 static void extract8888rev(int isSwap
,
5873 const void *packedPixel
,GLfloat extractComponents
[])
5878 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5881 uint
= *(const GLuint
*)packedPixel
;
5884 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5885 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5886 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5887 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5890 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5891 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5892 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5893 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5894 } /* extract8888rev() */
5896 static void shove8888rev(const GLfloat shoveComponents
[],
5897 int index
,void *packedPixel
)
5899 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5900 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5901 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5902 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5904 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5905 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5906 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5907 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5909 /* due to limited precision, need to round before shoving */
5910 ((GLuint
*)packedPixel
)[index
] =
5911 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5912 ((GLuint
*)packedPixel
)[index
]|=
5913 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5914 ((GLuint
*)packedPixel
)[index
]|=
5915 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5916 ((GLuint
*)packedPixel
)[index
]|=
5917 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5918 } /* shove8888rev() */
5920 static void extract1010102(int isSwap
,
5921 const void *packedPixel
,GLfloat extractComponents
[])
5926 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5929 uint
= *(const GLuint
*)packedPixel
;
5932 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5933 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5934 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5935 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5938 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5939 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5940 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5941 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5942 } /* extract1010102() */
5944 static void shove1010102(const GLfloat shoveComponents
[],
5945 int index
,void *packedPixel
)
5947 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5948 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5949 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5950 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5952 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5953 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5954 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5955 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5957 /* due to limited precision, need to round before shoving */
5958 ((GLuint
*)packedPixel
)[index
] =
5959 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5960 ((GLuint
*)packedPixel
)[index
]|=
5961 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5962 ((GLuint
*)packedPixel
)[index
]|=
5963 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5964 ((GLuint
*)packedPixel
)[index
]|=
5965 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5966 } /* shove1010102() */
5968 static void extract2101010rev(int isSwap
,
5969 const void *packedPixel
,
5970 GLfloat extractComponents
[])
5975 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5978 uint
= *(const GLuint
*)packedPixel
;
5981 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5982 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5983 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5984 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5987 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5988 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5989 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5990 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5992 } /* extract2101010rev() */
5994 static void shove2101010rev(const GLfloat shoveComponents
[],
5995 int index
,void *packedPixel
)
5997 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5998 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5999 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
6000 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
6002 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
6003 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
6004 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
6005 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
6007 /* due to limited precision, need to round before shoving */
6008 ((GLuint
*)packedPixel
)[index
] =
6009 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
6010 ((GLuint
*)packedPixel
)[index
]|=
6011 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
6012 ((GLuint
*)packedPixel
)[index
]|=
6013 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
6014 ((GLuint
*)packedPixel
)[index
]|=
6015 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
6016 } /* shove2101010rev() */
6018 static void scaleInternalPackedPixel(int components
,
6019 void (*extractPackedPixel
)
6020 (int, const void *,GLfloat
[]),
6021 void (*shovePackedPixel
)
6022 (const GLfloat
[], int, void *),
6023 GLint widthIn
,GLint heightIn
,
6025 GLint widthOut
,GLint heightOut
,
6027 GLint pixelSizeInBytes
,
6028 GLint rowSizeInBytes
,GLint isSwap
)
6034 /* Max components in a format is 4, so... */
6036 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
6041 const char *temp
, *temp0
;
6044 int lowx_int
, highx_int
, lowy_int
, highy_int
;
6045 float x_percent
, y_percent
;
6046 float lowx_float
, highx_float
, lowy_float
, highy_float
;
6047 float convy_float
, convx_float
;
6048 int convy_int
, convx_int
;
6050 const char *left
, *right
;
6052 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
6053 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6054 widthIn
, heightIn
, dataIn
, dataOut
,
6055 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6058 convy
= (float) heightIn
/heightOut
;
6059 convx
= (float) widthIn
/widthOut
;
6060 convy_int
= floor(convy
);
6061 convy_float
= convy
- convy_int
;
6062 convx_int
= floor(convx
);
6063 convx_float
= convx
- convx_int
;
6065 area
= convx
* convy
;
6069 highy_int
= convy_int
;
6070 highy_float
= convy_float
;
6072 for (i
= 0; i
< heightOut
; i
++) {
6075 highx_int
= convx_int
;
6076 highx_float
= convx_float
;
6078 for (j
= 0; j
< widthOut
; j
++) {
6080 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6081 ** to (highx, highy) on input data into this pixel on output
6084 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6086 /* calculate the value for pixels in the 1st row */
6087 xindex
= lowx_int
*pixelSizeInBytes
;
6088 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6090 y_percent
= 1-lowy_float
;
6091 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6092 percent
= y_percent
* (1-lowx_float
);
6094 for (k
= 0, temp_index
= temp
; k
< components
;
6095 k
++, temp_index
+= element_size
) {
6097 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6099 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6103 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6104 for (k
= 0; k
< components
; k
++) {
6105 totals
[k
]+= extractTotals
[k
] * percent
;
6109 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6110 temp
+= pixelSizeInBytes
;
6112 for (k
= 0, temp_index
= temp
; k
< components
;
6113 k
++, temp_index
+= element_size
) {
6116 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6118 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6122 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6123 for (k
= 0; k
< components
; k
++) {
6124 totals
[k
]+= extractTotals
[k
] * y_percent
;
6128 temp
+= pixelSizeInBytes
;
6130 percent
= y_percent
* highx_float
;
6132 for (k
= 0, temp_index
= temp
; k
< components
;
6133 k
++, temp_index
+= element_size
) {
6135 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6137 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6141 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6142 for (k
= 0; k
< components
; k
++) {
6143 totals
[k
]+= extractTotals
[k
] * percent
;
6147 /* calculate the value for pixels in the last row */
6149 y_percent
= highy_float
;
6150 percent
= y_percent
* (1-lowx_float
);
6151 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6153 for (k
= 0, temp_index
= temp
; k
< components
;
6154 k
++, temp_index
+= element_size
) {
6156 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6158 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6162 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6163 for (k
= 0; k
< components
; k
++) {
6164 totals
[k
]+= extractTotals
[k
] * percent
;
6167 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6168 temp
+= pixelSizeInBytes
;
6170 for (k
= 0, temp_index
= temp
; k
< components
;
6171 k
++, temp_index
+= element_size
) {
6174 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6176 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6180 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6181 for (k
= 0; k
< components
; k
++) {
6182 totals
[k
]+= extractTotals
[k
] * y_percent
;
6187 temp
+= pixelSizeInBytes
;
6188 percent
= y_percent
* highx_float
;
6190 for (k
= 0, temp_index
= temp
; k
< components
;
6191 k
++, temp_index
+= element_size
) {
6193 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6195 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6199 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6200 for (k
= 0; k
< components
; k
++) {
6201 totals
[k
]+= extractTotals
[k
] * percent
;
6205 /* calculate the value for pixels in the 1st and last column */
6206 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6207 left
+= rowSizeInBytes
;
6208 right
+= rowSizeInBytes
;
6210 for (k
= 0; k
< components
;
6211 k
++, left
+= element_size
, right
+= element_size
) {
6214 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6215 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6217 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6218 + *(const GLushort
*)right
* highx_float
;
6222 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6223 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6224 for (k
= 0; k
< components
; k
++) {
6225 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6226 extractMoreTotals
[k
]*highx_float
);
6230 } else if (highy_int
> lowy_int
) {
6231 x_percent
= highx_float
- lowx_float
;
6232 percent
= (1-lowy_float
)*x_percent
;
6233 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6235 for (k
= 0, temp_index
= temp
; k
< components
;
6236 k
++, temp_index
+= element_size
) {
6238 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6240 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6244 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6245 for (k
= 0; k
< components
; k
++) {
6246 totals
[k
]+= extractTotals
[k
] * percent
;
6249 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6250 temp
+= rowSizeInBytes
;
6252 for (k
= 0, temp_index
= temp
; k
< components
;
6253 k
++, temp_index
+= element_size
) {
6256 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6258 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6262 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6263 for (k
= 0; k
< components
; k
++) {
6264 totals
[k
]+= extractTotals
[k
] * x_percent
;
6268 percent
= x_percent
* highy_float
;
6269 temp
+= rowSizeInBytes
;
6271 for (k
= 0, temp_index
= temp
; k
< components
;
6272 k
++, temp_index
+= element_size
) {
6274 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6276 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6280 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6281 for (k
= 0; k
< components
; k
++) {
6282 totals
[k
]+= extractTotals
[k
] * percent
;
6285 } else if (highx_int
> lowx_int
) {
6286 y_percent
= highy_float
- lowy_float
;
6287 percent
= (1-lowx_float
)*y_percent
;
6288 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6290 for (k
= 0, temp_index
= temp
; k
< components
;
6291 k
++, temp_index
+= element_size
) {
6293 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6295 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6299 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6300 for (k
= 0; k
< components
; k
++) {
6301 totals
[k
]+= extractTotals
[k
] * percent
;
6304 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6305 temp
+= pixelSizeInBytes
;
6307 for (k
= 0, temp_index
= temp
; k
< components
;
6308 k
++, temp_index
+= element_size
) {
6311 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6313 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6317 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6318 for (k
= 0; k
< components
; k
++) {
6319 totals
[k
]+= extractTotals
[k
] * y_percent
;
6323 temp
+= pixelSizeInBytes
;
6324 percent
= y_percent
* highx_float
;
6326 for (k
= 0, temp_index
= temp
; k
< components
;
6327 k
++, temp_index
+= element_size
) {
6329 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6331 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6335 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6336 for (k
= 0; k
< components
; k
++) {
6337 totals
[k
]+= extractTotals
[k
] * percent
;
6341 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6342 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6344 for (k
= 0, temp_index
= temp
; k
< components
;
6345 k
++, temp_index
+= element_size
) {
6347 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6349 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6353 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6354 for (k
= 0; k
< components
; k
++) {
6355 totals
[k
]+= extractTotals
[k
] * percent
;
6360 /* this is for the pixels in the body */
6361 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6362 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6364 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6366 for (k
= 0, temp_index
= temp
; k
< components
;
6367 k
++, temp_index
+= element_size
) {
6369 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6371 totals
[k
] += *(const GLushort
*)temp_index
;
6375 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6376 for (k
= 0; k
< components
; k
++) {
6377 totals
[k
]+= extractTotals
[k
];
6380 temp
+= pixelSizeInBytes
;
6382 temp0
+= rowSizeInBytes
;
6385 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6387 for (k
= 0; k
< components
; k
++) {
6388 dataout
[outindex
+ k
] = totals
[k
]/area
;
6389 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6392 for (k
= 0; k
< components
; k
++) {
6393 shoveTotals
[k
]= totals
[k
]/area
;
6395 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6397 lowx_int
= highx_int
;
6398 lowx_float
= highx_float
;
6399 highx_int
+= convx_int
;
6400 highx_float
+= convx_float
;
6401 if(highx_float
> 1) {
6406 lowy_int
= highy_int
;
6407 lowy_float
= highy_float
;
6408 highy_int
+= convy_int
;
6409 highy_float
+= convy_float
;
6410 if(highy_float
> 1) {
6416 assert(outindex
== (widthOut
*heightOut
- 1));
6417 } /* scaleInternalPackedPixel() */
6419 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6420 * inputs; not always equal. Output NEVER has row padding.
6422 static void halveImagePackedPixel(int components
,
6423 void (*extractPackedPixel
)
6424 (int, const void *,GLfloat
[]),
6425 void (*shovePackedPixel
)
6426 (const GLfloat
[],int, void *),
6427 GLint width
, GLint height
,
6428 const void *dataIn
, void *dataOut
,
6429 GLint pixelSizeInBytes
,
6430 GLint rowSizeInBytes
, GLint isSwap
)
6432 /* handle case where there is only 1 column/row */
6433 if (width
== 1 || height
== 1) {
6434 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6435 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6436 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6437 rowSizeInBytes
,isSwap
);
6444 int halfWidth
= width
/ 2;
6445 int halfHeight
= height
/ 2;
6446 const char *src
= (const char *) dataIn
;
6447 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6450 for (ii
= 0; ii
< halfHeight
; ii
++) {
6451 for (jj
= 0; jj
< halfWidth
; jj
++) {
6453 float totals
[4]; /* 4 is maximum components */
6454 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6457 (*extractPackedPixel
)(isSwap
,src
,
6458 &extractTotals
[0][0]);
6459 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6460 &extractTotals
[1][0]);
6461 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6462 &extractTotals
[2][0]);
6463 (*extractPackedPixel
)(isSwap
,
6464 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6465 &extractTotals
[3][0]);
6466 for (cc
= 0; cc
< components
; cc
++) {
6469 /* grab 4 pixels to average */
6471 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6472 * extractTotals[2][RED]+extractTotals[3][RED];
6473 * totals[RED]/= 4.0;
6475 for (kk
= 0; kk
< BOX4
; kk
++) {
6476 totals
[cc
]+= extractTotals
[kk
][cc
];
6478 totals
[cc
]/= (float)BOX4
;
6480 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6483 /* skip over to next square of 4 */
6484 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6486 /* skip past pad bytes, if any, to get to next row */
6489 /* src is at beginning of a row here, but it's the second row of
6490 * the square block of 4 pixels that we just worked on so we
6491 * need to go one more row.
6499 src
+= rowSizeInBytes
;
6502 /* both pointers must reach one byte after the end */
6503 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6504 assert(outIndex
== halfWidth
* halfHeight
);
6506 } /* halveImagePackedPixel() */
6508 static void halve1DimagePackedPixel(int components
,
6509 void (*extractPackedPixel
)
6510 (int, const void *,GLfloat
[]),
6511 void (*shovePackedPixel
)
6512 (const GLfloat
[],int, void *),
6513 GLint width
, GLint height
,
6514 const void *dataIn
, void *dataOut
,
6515 GLint pixelSizeInBytes
,
6516 GLint rowSizeInBytes
, GLint isSwap
)
6518 int halfWidth
= width
/ 2;
6519 int halfHeight
= height
/ 2;
6520 const char *src
= (const char *) dataIn
;
6523 assert(width
== 1 || height
== 1); /* must be 1D */
6524 assert(width
!= height
); /* can't be square */
6526 if (height
== 1) { /* 1 row */
6529 assert(width
!= 1); /* widthxheight can't be 1x1 */
6532 /* one horizontal row with possible pad bytes */
6534 for (jj
= 0; jj
< halfWidth
; jj
++) {
6536 float totals
[4]; /* 4 is maximum components */
6537 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6540 /* average two at a time, instead of four */
6541 (*extractPackedPixel
)(isSwap
,src
,
6542 &extractTotals
[0][0]);
6543 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6544 &extractTotals
[1][0]);
6545 for (cc
= 0; cc
< components
; cc
++) {
6548 /* grab 2 pixels to average */
6550 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6551 * totals[RED]/= 2.0;
6553 for (kk
= 0; kk
< BOX2
; kk
++) {
6554 totals
[cc
]+= extractTotals
[kk
][cc
];
6556 totals
[cc
]/= (float)BOX2
;
6558 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6561 /* skip over to next group of 2 */
6562 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6566 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6567 src
+= padBytes
; /* for assertion only */
6569 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6570 assert(outIndex
== halfWidth
* halfHeight
);
6572 else if (width
== 1) { /* 1 column */
6575 assert(height
!= 1); /* widthxheight can't be 1x1 */
6577 /* one vertical column with possible pad bytes per row */
6578 /* average two at a time */
6580 for (jj
= 0; jj
< halfHeight
; jj
++) {
6582 float totals
[4]; /* 4 is maximum components */
6583 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6586 /* average two at a time, instead of four */
6587 (*extractPackedPixel
)(isSwap
,src
,
6588 &extractTotals
[0][0]);
6589 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6590 &extractTotals
[1][0]);
6591 for (cc
= 0; cc
< components
; cc
++) {
6594 /* grab 2 pixels to average */
6596 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6597 * totals[RED]/= 2.0;
6599 for (kk
= 0; kk
< BOX2
; kk
++) {
6600 totals
[cc
]+= extractTotals
[kk
][cc
];
6602 totals
[cc
]/= (float)BOX2
;
6604 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6607 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6610 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6611 assert(outIndex
== halfWidth
* halfHeight
);
6613 } /* halve1DimagePackedPixel() */
6615 /*===========================================================================*/
6617 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6619 * This section ensures that GLU 1.3 will load and run on
6620 * a GL 1.1 implementation. It dynamically resolves the
6621 * call to glTexImage3D() which might not be available.
6622 * Or is it might be supported as an extension.
6623 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6626 typedef void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6627 GLenum internalFormat
,
6628 GLsizei width
, GLsizei height
,
6629 GLsizei depth
, GLint border
,
6630 GLenum format
, GLenum type
,
6631 const GLvoid
*pixels
);
6633 static TexImage3Dproc pTexImage3D
= 0;
6637 # include <sys/types.h>
6639 WINGDIAPI PROC WINAPI
wglGetProcAddress(LPCSTR
);
6642 static void gluTexImage3D( GLenum target
, GLint level
,
6643 GLenum internalFormat
,
6644 GLsizei width
, GLsizei height
,
6645 GLsizei depth
, GLint border
,
6646 GLenum format
, GLenum type
,
6647 const GLvoid
*pixels
)
6651 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6653 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6655 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6656 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6658 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6663 /* Now call glTexImage3D */
6665 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6666 depth
, border
, format
, type
, pixels
);
6671 /* Only bind to a GL 1.2 implementation: */
6672 #define gluTexImage3D glTexImage3D
6676 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6677 GLenum format
, GLenum type
)
6679 int components
= elements_per_group(format
,type
);
6680 int bytes_per_row
= bytes_per_element(type
) * width
;
6682 assert(width
> 0 && height
> 0 && depth
> 0);
6683 assert(type
!= GL_BITMAP
);
6685 return bytes_per_row
* height
* depth
* components
;
6686 } /* imageSize3D() */
6688 static void fillImage3D(const PixelStorageModes
*psm
,
6689 GLint width
, GLint height
, GLint depth
, GLenum format
,
6690 GLenum type
, GLboolean indexFormat
,
6691 const void *userImage
, GLushort
*newImage
)
6700 int elementsPerLine
;
6703 const GLubyte
*start
, *rowStart
, *iter
;
6707 myswapBytes
= psm
->unpack_swap_bytes
;
6708 components
= elements_per_group(format
,type
);
6709 if (psm
->unpack_row_length
> 0) {
6710 groupsPerLine
= psm
->unpack_row_length
;
6713 groupsPerLine
= width
;
6715 elementSize
= bytes_per_element(type
);
6716 groupSize
= elementSize
* components
;
6717 if (elementSize
== 1) myswapBytes
= 0;
6720 if (psm
->unpack_image_height
> 0) {
6721 rowsPerImage
= psm
->unpack_image_height
;
6724 rowsPerImage
= height
;
6728 rowSize
= groupsPerLine
* groupSize
;
6729 padding
= rowSize
% psm
->unpack_alignment
;
6731 rowSize
+= psm
->unpack_alignment
- padding
;
6734 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6736 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6737 psm
->unpack_skip_pixels
* groupSize
+
6739 psm
->unpack_skip_images
* imageSize
;
6740 elementsPerLine
= width
* components
;
6743 for (dd
= 0; dd
< depth
; dd
++) {
6746 for (hh
= 0; hh
< height
; hh
++) {
6749 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6751 float extractComponents
[4];
6754 case GL_UNSIGNED_BYTE
:
6758 *iter2
++ = (*iter
) * 257;
6763 *iter2
++ = *((const GLbyte
*) iter
);
6766 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6769 case GL_UNSIGNED_BYTE_3_3_2
:
6770 extract332(0,iter
,extractComponents
);
6771 for (k
= 0; k
< 3; k
++) {
6772 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6775 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6776 extract233rev(0,iter
,extractComponents
);
6777 for (k
= 0; k
< 3; k
++) {
6778 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6781 case GL_UNSIGNED_SHORT_5_6_5
:
6782 extract565(myswapBytes
,iter
,extractComponents
);
6783 for (k
= 0; k
< 3; k
++) {
6784 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6787 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6788 extract565rev(myswapBytes
,iter
,extractComponents
);
6789 for (k
= 0; k
< 3; k
++) {
6790 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6793 case GL_UNSIGNED_SHORT_4_4_4_4
:
6794 extract4444(myswapBytes
,iter
,extractComponents
);
6795 for (k
= 0; k
< 4; k
++) {
6796 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6799 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6800 extract4444rev(myswapBytes
,iter
,extractComponents
);
6801 for (k
= 0; k
< 4; k
++) {
6802 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6805 case GL_UNSIGNED_SHORT_5_5_5_1
:
6806 extract5551(myswapBytes
,iter
,extractComponents
);
6807 for (k
= 0; k
< 4; k
++) {
6808 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6811 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6812 extract1555rev(myswapBytes
,iter
,extractComponents
);
6813 for (k
= 0; k
< 4; k
++) {
6814 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6817 case GL_UNSIGNED_SHORT
:
6820 widget
.ub
[0] = iter
[1];
6821 widget
.ub
[1] = iter
[0];
6823 widget
.ub
[0] = iter
[0];
6824 widget
.ub
[1] = iter
[1];
6826 if (type
== GL_SHORT
) {
6828 *iter2
++ = widget
.s
[0];
6831 *iter2
++ = widget
.s
[0]*2;
6834 *iter2
++ = widget
.us
[0];
6837 case GL_UNSIGNED_INT_8_8_8_8
:
6838 extract8888(myswapBytes
,iter
,extractComponents
);
6839 for (k
= 0; k
< 4; k
++) {
6840 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6843 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6844 extract8888rev(myswapBytes
,iter
,extractComponents
);
6845 for (k
= 0; k
< 4; k
++) {
6846 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6849 case GL_UNSIGNED_INT_10_10_10_2
:
6850 extract1010102(myswapBytes
,iter
,extractComponents
);
6851 for (k
= 0; k
< 4; k
++) {
6852 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6855 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6856 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6857 for (k
= 0; k
< 4; k
++) {
6858 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6862 case GL_UNSIGNED_INT
:
6865 widget
.ub
[0] = iter
[3];
6866 widget
.ub
[1] = iter
[2];
6867 widget
.ub
[2] = iter
[1];
6868 widget
.ub
[3] = iter
[0];
6870 widget
.ub
[0] = iter
[0];
6871 widget
.ub
[1] = iter
[1];
6872 widget
.ub
[2] = iter
[2];
6873 widget
.ub
[3] = iter
[3];
6875 if (type
== GL_FLOAT
) {
6877 *iter2
++ = widget
.f
;
6879 *iter2
++ = 65535 * widget
.f
;
6881 } else if (type
== GL_UNSIGNED_INT
) {
6883 *iter2
++ = widget
.ui
;
6885 *iter2
++ = widget
.ui
>> 16;
6889 *iter2
++ = widget
.i
;
6891 *iter2
++ = widget
.i
>> 15;
6903 iter
= rowStart
; /* for assertion purposes */
6909 /* iterators should be one byte past end */
6910 if (!isTypePackedPixel(type
)) {
6911 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6914 assert(iter2
== &newImage
[width
*height
*depth
*
6915 elements_per_group(format
,0)]);
6917 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6918 psm
->unpack_skip_rows
* rowSize
+
6919 psm
->unpack_skip_pixels
* groupSize
+
6921 psm
->unpack_skip_images
* imageSize
] );
6922 } /* fillImage3D () */
6924 static void scaleInternal3D(GLint components
,
6925 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6926 const GLushort
*dataIn
,
6927 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6930 float x
, lowx
, highx
, convx
, halfconvx
;
6931 float y
, lowy
, highy
, convy
, halfconvy
;
6932 float z
, lowz
, highz
, convz
, halfconvz
;
6933 float xpercent
,ypercent
,zpercent
;
6935 /* Max components in a format is 4, so... */
6938 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6941 convz
= (float) depthIn
/depthOut
;
6942 convy
= (float) heightIn
/heightOut
;
6943 convx
= (float) widthIn
/widthOut
;
6944 halfconvx
= convx
/2;
6945 halfconvy
= convy
/2;
6946 halfconvz
= convz
/2;
6947 for (d
= 0; d
< depthOut
; d
++) {
6948 z
= convz
* (d
+0.5);
6949 if (depthIn
> depthOut
) {
6950 highz
= z
+ halfconvz
;
6951 lowz
= z
- halfconvz
;
6956 for (i
= 0; i
< heightOut
; i
++) {
6957 y
= convy
* (i
+0.5);
6958 if (heightIn
> heightOut
) {
6959 highy
= y
+ halfconvy
;
6960 lowy
= y
- halfconvy
;
6965 for (j
= 0; j
< widthOut
; j
++) {
6966 x
= convx
* (j
+0.5);
6967 if (widthIn
> widthOut
) {
6968 highx
= x
+ halfconvx
;
6969 lowx
= x
- halfconvx
;
6976 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6977 ** lowz) to (highx, highy, highz) on input data into this pixel
6980 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6986 zindex
= (zint
+ depthIn
) % depthIn
;
6987 if (highz
< zint
+1) {
6988 zpercent
= highz
- z
;
6990 zpercent
= zint
+1 - z
;
6996 yindex
= (yint
+ heightIn
) % heightIn
;
6997 if (highy
< yint
+1) {
6998 ypercent
= highy
- y
;
7000 ypercent
= yint
+1 - y
;
7007 xindex
= (xint
+ widthIn
) % widthIn
;
7008 if (highx
< xint
+1) {
7009 xpercent
= highx
- x
;
7011 xpercent
= xint
+1 - x
;
7014 percent
= xpercent
* ypercent
* zpercent
;
7017 temp
= (xindex
+ (yindex
*widthIn
) +
7018 (zindex
*widthIn
*heightIn
)) * components
;
7019 for (k
= 0; k
< components
; k
++) {
7020 assert(0 <= (temp
+k
) &&
7022 (widthIn
*heightIn
*depthIn
*components
));
7023 totals
[k
] += dataIn
[temp
+ k
] * percent
;
7038 temp
= (j
+ (i
* widthOut
) +
7039 (d
*widthOut
*heightOut
)) * components
;
7040 for (k
= 0; k
< components
; k
++) {
7041 /* totals[] should be rounded in the case of enlarging an
7042 * RGB ramp when the type is 332 or 4444
7044 assert(0 <= (temp
+k
) &&
7045 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
7046 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
7051 } /* scaleInternal3D() */
7053 static void emptyImage3D(const PixelStorageModes
*psm
,
7054 GLint width
, GLint height
, GLint depth
,
7055 GLenum format
, GLenum type
, GLboolean indexFormat
,
7056 const GLushort
*oldImage
, void *userImage
)
7065 GLubyte
*start
, *rowStart
, *iter
;
7066 int elementsPerLine
;
7067 const GLushort
*iter2
;
7072 myswapBytes
= psm
->pack_swap_bytes
;
7073 components
= elements_per_group(format
,type
);
7074 if (psm
->pack_row_length
> 0) {
7075 groupsPerLine
= psm
->pack_row_length
;
7078 groupsPerLine
= width
;
7081 elementSize
= bytes_per_element(type
);
7082 groupSize
= elementSize
* components
;
7083 if (elementSize
== 1) myswapBytes
= 0;
7086 if (psm
->pack_image_height
> 0) {
7087 rowsPerImage
= psm
->pack_image_height
;
7090 rowsPerImage
= height
;
7095 rowSize
= groupsPerLine
* groupSize
;
7096 padding
= rowSize
% psm
->pack_alignment
;
7098 rowSize
+= psm
->pack_alignment
- padding
;
7101 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7103 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7104 psm
->pack_skip_pixels
* groupSize
+
7106 psm
->pack_skip_images
* imageSize
;
7107 elementsPerLine
= width
* components
;
7110 for (dd
= 0; dd
< depth
; dd
++) {
7113 for (ii
= 0; ii
< height
; ii
++) {
7116 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7118 float shoveComponents
[4];
7121 case GL_UNSIGNED_BYTE
:
7125 *iter
= *iter2
++ >> 8;
7130 *((GLbyte
*) iter
) = *iter2
++;
7132 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7135 case GL_UNSIGNED_BYTE_3_3_2
:
7136 for (k
= 0; k
< 3; k
++) {
7137 shoveComponents
[k
]= *iter2
++ / 65535.0;
7139 shove332(shoveComponents
,0,(void *)iter
);
7141 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7142 for (k
= 0; k
< 3; k
++) {
7143 shoveComponents
[k
]= *iter2
++ / 65535.0;
7145 shove233rev(shoveComponents
,0,(void *)iter
);
7147 case GL_UNSIGNED_SHORT_5_6_5
:
7148 for (k
= 0; k
< 3; k
++) {
7149 shoveComponents
[k
]= *iter2
++ / 65535.0;
7151 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7153 iter
[0] = widget
.ub
[1];
7154 iter
[1] = widget
.ub
[0];
7157 *(GLushort
*)iter
= widget
.us
[0];
7160 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7161 for (k
= 0; k
< 3; k
++) {
7162 shoveComponents
[k
]= *iter2
++ / 65535.0;
7164 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7166 iter
[0] = widget
.ub
[1];
7167 iter
[1] = widget
.ub
[0];
7170 *(GLushort
*)iter
= widget
.us
[0];
7173 case GL_UNSIGNED_SHORT_4_4_4_4
:
7174 for (k
= 0; k
< 4; k
++) {
7175 shoveComponents
[k
]= *iter2
++ / 65535.0;
7177 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7179 iter
[0] = widget
.ub
[1];
7180 iter
[1] = widget
.ub
[0];
7182 *(GLushort
*)iter
= widget
.us
[0];
7185 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7186 for (k
= 0; k
< 4; k
++) {
7187 shoveComponents
[k
]= *iter2
++ / 65535.0;
7189 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7191 iter
[0] = widget
.ub
[1];
7192 iter
[1] = widget
.ub
[0];
7194 *(GLushort
*)iter
= widget
.us
[0];
7197 case GL_UNSIGNED_SHORT_5_5_5_1
:
7198 for (k
= 0; k
< 4; k
++) {
7199 shoveComponents
[k
]= *iter2
++ / 65535.0;
7201 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7203 iter
[0] = widget
.ub
[1];
7204 iter
[1] = widget
.ub
[0];
7206 *(GLushort
*)iter
= widget
.us
[0];
7209 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7210 for (k
= 0; k
< 4; k
++) {
7211 shoveComponents
[k
]= *iter2
++ / 65535.0;
7213 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7215 iter
[0] = widget
.ub
[1];
7216 iter
[1] = widget
.ub
[0];
7218 *(GLushort
*)iter
= widget
.us
[0];
7221 case GL_UNSIGNED_SHORT
:
7223 if (type
== GL_SHORT
) {
7225 widget
.s
[0] = *iter2
++;
7227 widget
.s
[0] = *iter2
++ >> 1;
7230 widget
.us
[0] = *iter2
++;
7233 iter
[0] = widget
.ub
[1];
7234 iter
[1] = widget
.ub
[0];
7236 iter
[0] = widget
.ub
[0];
7237 iter
[1] = widget
.ub
[1];
7240 case GL_UNSIGNED_INT_8_8_8_8
:
7241 for (k
= 0; k
< 4; k
++) {
7242 shoveComponents
[k
]= *iter2
++ / 65535.0;
7244 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7246 iter
[3] = widget
.ub
[0];
7247 iter
[2] = widget
.ub
[1];
7248 iter
[1] = widget
.ub
[2];
7249 iter
[0] = widget
.ub
[3];
7251 *(GLuint
*)iter
= widget
.ui
;
7254 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7255 for (k
= 0; k
< 4; k
++) {
7256 shoveComponents
[k
]= *iter2
++ / 65535.0;
7258 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7260 iter
[3] = widget
.ub
[0];
7261 iter
[2] = widget
.ub
[1];
7262 iter
[1] = widget
.ub
[2];
7263 iter
[0] = widget
.ub
[3];
7265 *(GLuint
*)iter
= widget
.ui
;
7268 case GL_UNSIGNED_INT_10_10_10_2
:
7269 for (k
= 0; k
< 4; k
++) {
7270 shoveComponents
[k
]= *iter2
++ / 65535.0;
7272 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7274 iter
[3] = widget
.ub
[0];
7275 iter
[2] = widget
.ub
[1];
7276 iter
[1] = widget
.ub
[2];
7277 iter
[0] = widget
.ub
[3];
7279 *(GLuint
*)iter
= widget
.ui
;
7282 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7283 for (k
= 0; k
< 4; k
++) {
7284 shoveComponents
[k
]= *iter2
++ / 65535.0;
7286 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7288 iter
[3] = widget
.ub
[0];
7289 iter
[2] = widget
.ub
[1];
7290 iter
[1] = widget
.ub
[2];
7291 iter
[0] = widget
.ub
[3];
7293 *(GLuint
*)iter
= widget
.ui
;
7297 case GL_UNSIGNED_INT
:
7299 if (type
== GL_FLOAT
) {
7301 widget
.f
= *iter2
++;
7303 widget
.f
= *iter2
++ / (float) 65535.0;
7305 } else if (type
== GL_UNSIGNED_INT
) {
7307 widget
.ui
= *iter2
++;
7309 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7313 widget
.i
= *iter2
++;
7315 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
7319 iter
[3] = widget
.ub
[0];
7320 iter
[2] = widget
.ub
[1];
7321 iter
[1] = widget
.ub
[2];
7322 iter
[0] = widget
.ub
[3];
7324 iter
[0] = widget
.ub
[0];
7325 iter
[1] = widget
.ub
[1];
7326 iter
[2] = widget
.ub
[2];
7327 iter
[3] = widget
.ub
[3];
7343 /* iterators should be one byte past end */
7344 if (!isTypePackedPixel(type
)) {
7345 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7348 assert(iter2
== &oldImage
[width
*height
*depth
*
7349 elements_per_group(format
,0)]);
7351 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7352 psm
->unpack_skip_rows
* rowSize
+
7353 psm
->unpack_skip_pixels
* groupSize
+
7355 psm
->unpack_skip_images
* imageSize
] );
7356 } /* emptyImage3D() */
7359 int gluScaleImage3D(GLenum format
,
7360 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7361 GLenum typeIn
, const void *dataIn
,
7362 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7363 GLenum typeOut
, void *dataOut
)
7366 GLushort
*beforeImage
, *afterImage
;
7367 PixelStorageModes psm
;
7369 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7370 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7374 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7375 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7376 return GLU_INVALID_VALUE
;
7379 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7380 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7381 return GLU_INVALID_ENUM
;
7383 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7384 return GLU_INVALID_OPERATION
;
7386 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7387 return GLU_INVALID_OPERATION
;
7390 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7391 GL_UNSIGNED_SHORT
));
7392 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7393 GL_UNSIGNED_SHORT
));
7394 if (beforeImage
== NULL
|| afterImage
== NULL
) {
7395 return GLU_OUT_OF_MEMORY
;
7397 retrieveStoreModes3D(&psm
);
7399 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7400 dataIn
, beforeImage
);
7401 components
= elements_per_group(format
,0);
7402 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7403 widthOut
,heightOut
,depthOut
,afterImage
);
7404 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7405 is_index(format
),afterImage
, dataOut
);
7406 free((void *) beforeImage
);
7407 free((void *) afterImage
);
7410 } /* gluScaleImage3D() */
7413 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7414 GLint internalFormat
, GLenum format
, GLenum type
,
7415 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7417 GLint widthPowerOf2
= nearestPower(width
);
7418 GLint heightPowerOf2
= nearestPower(height
);
7419 GLint depthPowerOf2
= nearestPower(depth
);
7423 /* compute level 1 width & height & depth, clamping each at 1 */
7424 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7425 widthPowerOf2
>> 1 :
7427 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7428 heightPowerOf2
>> 1 :
7430 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7431 depthPowerOf2
>> 1 :
7433 GLenum proxyTarget
= GL_PROXY_TEXTURE_3D
;
7434 assert(widthAtLevelOne
> 0);
7435 assert(heightAtLevelOne
> 0);
7436 assert(depthAtLevelOne
> 0);
7438 /* does width x height x depth at level 1 & all their mipmaps fit? */
7439 assert(target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
);
7440 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7442 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7443 0,format
,type
,NULL
);
7444 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7445 /* does it fit??? */
7446 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7447 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7448 depthPowerOf2
== 1) {
7449 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7452 widthPowerOf2
= widthAtLevelOne
;
7453 heightPowerOf2
= heightAtLevelOne
;
7454 depthPowerOf2
= depthAtLevelOne
;
7456 /* else it does fit */
7457 } while (proxyWidth
== 0);
7458 /* loop must terminate! */
7460 /* return the width & height at level 0 that fits */
7461 *newWidth
= widthPowerOf2
;
7462 *newHeight
= heightPowerOf2
;
7463 *newDepth
= depthPowerOf2
;
7464 /*printf("Proxy Textures\n");*/
7465 } /* closestFit3D() */
7467 static void halveImagePackedPixelSlice(int components
,
7468 void (*extractPackedPixel
)
7469 (int, const void *,GLfloat
[]),
7470 void (*shovePackedPixel
)
7471 (const GLfloat
[],int, void *),
7472 GLint width
, GLint height
, GLint depth
,
7473 const void *dataIn
, void *dataOut
,
7474 GLint pixelSizeInBytes
,
7475 GLint rowSizeInBytes
,
7476 GLint imageSizeInBytes
,
7480 int halfWidth
= width
/ 2;
7481 int halfHeight
= height
/ 2;
7482 int halfDepth
= depth
/ 2;
7483 const char *src
= (const char *)dataIn
;
7486 assert((width
== 1 || height
== 1) && depth
>= 2);
7488 if (width
== height
) { /* a 1-pixel column viewed from top */
7489 assert(width
== 1 && height
== 1);
7492 for (ii
= 0; ii
< halfDepth
; ii
++) {
7494 float extractTotals
[BOX2
][4];
7497 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7498 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7499 &extractTotals
[1][0]);
7500 for (cc
= 0; cc
< components
; cc
++) {
7503 /* average 2 pixels since only a column */
7505 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7506 * totals[RED]/= 2.0;
7508 for (kk
= 0; kk
< BOX2
; kk
++) {
7509 totals
[cc
]+= extractTotals
[kk
][cc
];
7511 totals
[cc
]/= (float)BOX2
;
7514 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7516 /* skip over to next group of 2 */
7517 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7520 else if (height
== 1) { /* horizontal slice viewed from top */
7523 for (ii
= 0; ii
< halfDepth
; ii
++) {
7524 for (jj
= 0; jj
< halfWidth
; jj
++) {
7526 float extractTotals
[BOX4
][4];
7529 (*extractPackedPixel
)(isSwap
,src
,
7530 &extractTotals
[0][0]);
7531 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7532 &extractTotals
[1][0]);
7533 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7534 &extractTotals
[2][0]);
7535 (*extractPackedPixel
)(isSwap
,
7536 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7537 &extractTotals
[3][0]);
7538 for (cc
= 0; cc
< components
; cc
++) {
7541 /* grab 4 pixels to average */
7543 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7544 * extractTotals[2][RED]+extractTotals[3][RED];
7545 * totals[RED]/= 4.0;
7547 for (kk
= 0; kk
< BOX4
; kk
++) {
7548 totals
[cc
]+= extractTotals
[kk
][cc
];
7550 totals
[cc
]/= (float)BOX4
;
7552 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7555 /* skip over to next horizontal square of 4 */
7556 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7562 else if (width
== 1) { /* vertical slice viewed from top */
7563 assert(height
!= 1);
7565 for (ii
= 0; ii
< halfDepth
; ii
++) {
7566 for (jj
= 0; jj
< halfHeight
; jj
++) {
7568 float extractTotals
[BOX4
][4];
7571 (*extractPackedPixel
)(isSwap
,src
,
7572 &extractTotals
[0][0]);
7573 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7574 &extractTotals
[1][0]);
7575 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7576 &extractTotals
[2][0]);
7577 (*extractPackedPixel
)(isSwap
,
7578 (src
+imageSizeInBytes
+rowSizeInBytes
),
7579 &extractTotals
[3][0]);
7580 for (cc
= 0; cc
< components
; cc
++) {
7583 /* grab 4 pixels to average */
7585 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7586 * extractTotals[2][RED]+extractTotals[3][RED];
7587 * totals[RED]/= 4.0;
7589 for (kk
= 0; kk
< BOX4
; kk
++) {
7590 totals
[cc
]+= extractTotals
[kk
][cc
];
7592 totals
[cc
]/= (float)BOX4
;
7594 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7598 /* skip over to next vertical square of 4 */
7599 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7605 } /* halveImagePackedPixelSlice() */
7607 static void halveImagePackedPixel3D(int components
,
7608 void (*extractPackedPixel
)
7609 (int, const void *,GLfloat
[]),
7610 void (*shovePackedPixel
)
7611 (const GLfloat
[],int, void *),
7612 GLint width
, GLint height
, GLint depth
,
7613 const void *dataIn
, void *dataOut
,
7614 GLint pixelSizeInBytes
,
7615 GLint rowSizeInBytes
,
7616 GLint imageSizeInBytes
,
7620 assert(1 <= width
&& 1 <= height
);
7622 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7623 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7624 rowSizeInBytes
,isSwap
);
7627 /* a horizontal or vertical slice viewed from top */
7628 else if (width
== 1 || height
== 1) {
7631 halveImagePackedPixelSlice(components
,
7632 extractPackedPixel
,shovePackedPixel
,
7633 width
, height
, depth
, dataIn
, dataOut
,
7634 pixelSizeInBytes
, rowSizeInBytes
,
7635 imageSizeInBytes
, isSwap
);
7641 int halfWidth
= width
/ 2;
7642 int halfHeight
= height
/ 2;
7643 int halfDepth
= depth
/ 2;
7644 const char *src
= (const char *) dataIn
;
7645 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7648 for (dd
= 0; dd
< halfDepth
; dd
++) {
7649 for (ii
= 0; ii
< halfHeight
; ii
++) {
7650 for (jj
= 0; jj
< halfWidth
; jj
++) {
7652 float totals
[4]; /* 4 is maximum components */
7653 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7656 (*extractPackedPixel
)(isSwap
,src
,
7657 &extractTotals
[0][0]);
7658 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7659 &extractTotals
[1][0]);
7660 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7661 &extractTotals
[2][0]);
7662 (*extractPackedPixel
)(isSwap
,
7663 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7664 &extractTotals
[3][0]);
7666 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7667 &extractTotals
[4][0]);
7668 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7669 &extractTotals
[5][0]);
7670 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7671 &extractTotals
[6][0]);
7672 (*extractPackedPixel
)(isSwap
,
7673 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7674 &extractTotals
[7][0]);
7675 for (cc
= 0; cc
< components
; cc
++) {
7678 /* grab 8 pixels to average */
7680 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7681 * extractTotals[2][RED]+extractTotals[3][RED]+
7682 * extractTotals[4][RED]+extractTotals[5][RED]+
7683 * extractTotals[6][RED]+extractTotals[7][RED];
7684 * totals[RED]/= 8.0;
7686 for (kk
= 0; kk
< BOX8
; kk
++) {
7687 totals
[cc
]+= extractTotals
[kk
][cc
];
7689 totals
[cc
]/= (float)BOX8
;
7691 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7694 /* skip over to next square of 4 */
7695 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7697 /* skip past pad bytes, if any, to get to next row */
7700 /* src is at beginning of a row here, but it's the second row of
7701 * the square block of 4 pixels that we just worked on so we
7702 * need to go one more row.
7710 src
+= rowSizeInBytes
;
7713 src
+= imageSizeInBytes
;
7716 /* both pointers must reach one byte after the end */
7717 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7718 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7721 } /* halveImagePackedPixel3D() */
7723 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7727 GLsizei widthPowerOf2
,
7728 GLsizei heightPowerOf2
,
7729 GLsizei depthPowerOf2
,
7730 GLenum format
, GLenum type
,
7732 GLint baseLevel
,GLint maxLevel
,
7735 GLint newWidth
, newHeight
, newDepth
;
7736 GLint level
, levels
;
7737 const void *usersImage
;
7738 void *srcImage
, *dstImage
;
7739 __GLU_INIT_SWAP_IMAGE
;
7743 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7744 GLint rowsPerImage
, imageSize
;
7745 GLint rowSize
, padding
;
7746 PixelStorageModes psm
;
7748 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7749 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7750 assert(type
!= GL_BITMAP
);
7752 srcImage
= dstImage
= NULL
;
7754 newWidth
= widthPowerOf2
;
7755 newHeight
= heightPowerOf2
;
7756 newDepth
= depthPowerOf2
;
7757 levels
= computeLog(newWidth
);
7758 level
= computeLog(newHeight
);
7759 if (level
> levels
) levels
=level
;
7760 level
= computeLog(newDepth
);
7761 if (level
> levels
) levels
=level
;
7765 retrieveStoreModes3D(&psm
);
7766 myswapBytes
= psm
.unpack_swap_bytes
;
7767 cmpts
= elements_per_group(format
,type
);
7768 if (psm
.unpack_row_length
> 0) {
7769 groupsPerLine
= psm
.unpack_row_length
;
7771 groupsPerLine
= width
;
7774 elementSize
= bytes_per_element(type
);
7775 groupSize
= elementSize
* cmpts
;
7776 if (elementSize
== 1) myswapBytes
= 0;
7779 if (psm
.unpack_image_height
> 0) {
7780 rowsPerImage
= psm
.unpack_image_height
;
7783 rowsPerImage
= height
;
7787 rowSize
= groupsPerLine
* groupSize
;
7788 padding
= (rowSize
% psm
.unpack_alignment
);
7790 rowSize
+= psm
.unpack_alignment
- padding
;
7793 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7795 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7796 psm
.unpack_skip_pixels
* groupSize
+
7798 psm
.unpack_skip_images
* imageSize
;
7800 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7801 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7802 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7803 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7804 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7808 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7809 /* Use usersImage for level userLevel */
7810 if (baseLevel
<= level
&& level
<= maxLevel
) {
7811 gluTexImage3D(target
, level
, internalFormat
, width
,
7812 height
, depth
, 0, format
, type
,
7815 if(levels
== 0) { /* we're done. clean up and return */
7816 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7817 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7818 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7819 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7820 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7821 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7822 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7826 int nextWidth
= newWidth
/2;
7827 int nextHeight
= newHeight
/2;
7828 int nextDepth
= newDepth
/2;
7831 if (nextWidth
< 1) nextWidth
= 1;
7832 if (nextHeight
< 1) nextHeight
= 1;
7833 if (nextDepth
< 1) nextDepth
= 1;
7834 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7837 case GL_UNSIGNED_BYTE
:
7838 dstImage
= (GLubyte
*)malloc(memReq
);
7841 dstImage
= (GLbyte
*)malloc(memReq
);
7843 case GL_UNSIGNED_SHORT
:
7844 dstImage
= (GLushort
*)malloc(memReq
);
7847 dstImage
= (GLshort
*)malloc(memReq
);
7849 case GL_UNSIGNED_INT
:
7850 dstImage
= (GLuint
*)malloc(memReq
);
7853 dstImage
= (GLint
*)malloc(memReq
);
7856 dstImage
= (GLfloat
*)malloc(memReq
);
7858 case GL_UNSIGNED_BYTE_3_3_2
:
7859 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7860 dstImage
= (GLubyte
*)malloc(memReq
);
7862 case GL_UNSIGNED_SHORT_5_6_5
:
7863 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7864 case GL_UNSIGNED_SHORT_4_4_4_4
:
7865 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7866 case GL_UNSIGNED_SHORT_5_5_5_1
:
7867 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7868 dstImage
= (GLushort
*)malloc(memReq
);
7870 case GL_UNSIGNED_INT_8_8_8_8
:
7871 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7872 case GL_UNSIGNED_INT_10_10_10_2
:
7873 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7874 dstImage
= (GLuint
*)malloc(memReq
);
7877 return GLU_INVALID_ENUM
; /* assertion */
7879 if (dstImage
== NULL
) {
7880 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7881 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7882 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7883 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7884 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7885 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7886 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7887 return GLU_OUT_OF_MEMORY
;
7891 case GL_UNSIGNED_BYTE
:
7893 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7895 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7896 imageSize
,myswapBytes
);
7899 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7900 elementSize
,rowSize
,groupSize
);
7905 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7907 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7908 imageSize
,myswapBytes
);
7911 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7912 elementSize
,rowSize
,groupSize
);
7915 case GL_UNSIGNED_SHORT
:
7917 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7919 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7920 imageSize
,myswapBytes
);
7923 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7924 elementSize
,rowSize
,groupSize
,myswapBytes
);
7929 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7931 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7932 imageSize
,myswapBytes
);
7935 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7936 elementSize
,rowSize
,groupSize
,myswapBytes
);
7939 case GL_UNSIGNED_INT
:
7941 halveImage3D(cmpts
,extractUint
,shoveUint
,
7943 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7944 imageSize
,myswapBytes
);
7947 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7948 elementSize
,rowSize
,groupSize
,myswapBytes
);
7953 halveImage3D(cmpts
,extractSint
,shoveSint
,
7955 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7956 imageSize
,myswapBytes
);
7959 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7960 elementSize
,rowSize
,groupSize
,myswapBytes
);
7965 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7967 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7968 imageSize
,myswapBytes
);
7971 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7972 elementSize
,rowSize
,groupSize
,myswapBytes
);
7975 case GL_UNSIGNED_BYTE_3_3_2
:
7976 assert(format
== GL_RGB
);
7977 halveImagePackedPixel3D(3,extract332
,shove332
,
7978 width
,height
,depth
,usersImage
,dstImage
,
7979 elementSize
,rowSize
,imageSize
,myswapBytes
);
7981 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7982 assert(format
== GL_RGB
);
7983 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7984 width
,height
,depth
,usersImage
,dstImage
,
7985 elementSize
,rowSize
,imageSize
,myswapBytes
);
7987 case GL_UNSIGNED_SHORT_5_6_5
:
7988 halveImagePackedPixel3D(3,extract565
,shove565
,
7989 width
,height
,depth
,usersImage
,dstImage
,
7990 elementSize
,rowSize
,imageSize
,myswapBytes
);
7992 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7993 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7994 width
,height
,depth
,usersImage
,dstImage
,
7995 elementSize
,rowSize
,imageSize
,myswapBytes
);
7997 case GL_UNSIGNED_SHORT_4_4_4_4
:
7998 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7999 width
,height
,depth
,usersImage
,dstImage
,
8000 elementSize
,rowSize
,imageSize
,myswapBytes
);
8002 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8003 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8004 width
,height
,depth
,usersImage
,dstImage
,
8005 elementSize
,rowSize
,imageSize
,myswapBytes
);
8007 case GL_UNSIGNED_SHORT_5_5_5_1
:
8008 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8009 width
,height
,depth
,usersImage
,dstImage
,
8010 elementSize
,rowSize
,imageSize
,myswapBytes
);
8012 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8013 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8014 width
,height
,depth
,usersImage
,dstImage
,
8015 elementSize
,rowSize
,imageSize
,myswapBytes
);
8017 case GL_UNSIGNED_INT_8_8_8_8
:
8018 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8019 width
,height
,depth
,usersImage
,dstImage
,
8020 elementSize
,rowSize
,imageSize
,myswapBytes
);
8022 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8023 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8024 width
,height
,depth
,usersImage
,dstImage
,
8025 elementSize
,rowSize
,imageSize
,myswapBytes
);
8027 case GL_UNSIGNED_INT_10_10_10_2
:
8028 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8029 width
,height
,depth
,usersImage
,dstImage
,
8030 elementSize
,rowSize
,imageSize
,myswapBytes
);
8032 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8033 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8034 width
,height
,depth
,usersImage
,dstImage
,
8035 elementSize
,rowSize
,imageSize
,myswapBytes
);
8042 newHeight
= height
/2;
8045 if (newWidth
< 1) newWidth
= 1;
8046 if (newHeight
< 1) newHeight
= 1;
8047 if (newDepth
< 1) newDepth
= 1;
8050 rowSize
= newWidth
* groupSize
;
8051 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8052 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8053 /* Swap srcImage and dstImage */
8054 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8056 case GL_UNSIGNED_BYTE
:
8057 dstImage
= (GLubyte
*)malloc(memReq
);
8060 dstImage
= (GLbyte
*)malloc(memReq
);
8062 case GL_UNSIGNED_SHORT
:
8063 dstImage
= (GLushort
*)malloc(memReq
);
8066 dstImage
= (GLshort
*)malloc(memReq
);
8068 case GL_UNSIGNED_INT
:
8069 dstImage
= (GLuint
*)malloc(memReq
);
8072 dstImage
= (GLint
*)malloc(memReq
);
8075 dstImage
= (GLfloat
*)malloc(memReq
);
8077 case GL_UNSIGNED_BYTE_3_3_2
:
8078 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8079 dstImage
= (GLubyte
*)malloc(memReq
);
8081 case GL_UNSIGNED_SHORT_5_6_5
:
8082 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8083 case GL_UNSIGNED_SHORT_4_4_4_4
:
8084 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8085 case GL_UNSIGNED_SHORT_5_5_5_1
:
8086 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8087 dstImage
= (GLushort
*)malloc(memReq
);
8089 case GL_UNSIGNED_INT_8_8_8_8
:
8090 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8091 case GL_UNSIGNED_INT_10_10_10_2
:
8092 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8093 dstImage
= (GLuint
*)malloc(memReq
);
8096 return GLU_INVALID_ENUM
; /* assertion */
8098 if (dstImage
== NULL
) {
8099 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8100 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8101 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8102 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8103 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8104 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8105 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8106 return GLU_OUT_OF_MEMORY
;
8108 /* level userLevel+1 is in srcImage; level userLevel already saved */
8109 level
= userLevel
+1;
8110 } else {/* user's image is *not* nice power-of-2 sized square */
8111 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8113 case GL_UNSIGNED_BYTE
:
8114 dstImage
= (GLubyte
*)malloc(memReq
);
8117 dstImage
= (GLbyte
*)malloc(memReq
);
8119 case GL_UNSIGNED_SHORT
:
8120 dstImage
= (GLushort
*)malloc(memReq
);
8123 dstImage
= (GLshort
*)malloc(memReq
);
8125 case GL_UNSIGNED_INT
:
8126 dstImage
= (GLuint
*)malloc(memReq
);
8129 dstImage
= (GLint
*)malloc(memReq
);
8132 dstImage
= (GLfloat
*)malloc(memReq
);
8134 case GL_UNSIGNED_BYTE_3_3_2
:
8135 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8136 dstImage
= (GLubyte
*)malloc(memReq
);
8138 case GL_UNSIGNED_SHORT_5_6_5
:
8139 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8140 case GL_UNSIGNED_SHORT_4_4_4_4
:
8141 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8142 case GL_UNSIGNED_SHORT_5_5_5_1
:
8143 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8144 dstImage
= (GLushort
*)malloc(memReq
);
8146 case GL_UNSIGNED_INT_8_8_8_8
:
8147 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8148 case GL_UNSIGNED_INT_10_10_10_2
:
8149 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8150 dstImage
= (GLuint
*)malloc(memReq
);
8153 return GLU_INVALID_ENUM
; /* assertion */
8156 if (dstImage
== NULL
) {
8157 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8158 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8159 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8160 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8161 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8162 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8163 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8164 return GLU_OUT_OF_MEMORY
;
8166 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8167 width,height,depth,newWidth,newHeight,newDepth);*/
8169 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8170 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8173 rowSize
= newWidth
* groupSize
;
8174 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8175 /* Swap dstImage and srcImage */
8176 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8178 if(levels
!= 0) { /* use as little memory as possible */
8180 int nextWidth
= newWidth
/2;
8181 int nextHeight
= newHeight
/2;
8182 int nextDepth
= newDepth
/2;
8183 if (nextWidth
< 1) nextWidth
= 1;
8184 if (nextHeight
< 1) nextHeight
= 1;
8185 if (nextDepth
< 1) nextDepth
= 1;
8187 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8190 case GL_UNSIGNED_BYTE
:
8191 dstImage
= (GLubyte
*)malloc(memReq
);
8194 dstImage
= (GLbyte
*)malloc(memReq
);
8196 case GL_UNSIGNED_SHORT
:
8197 dstImage
= (GLushort
*)malloc(memReq
);
8200 dstImage
= (GLshort
*)malloc(memReq
);
8202 case GL_UNSIGNED_INT
:
8203 dstImage
= (GLuint
*)malloc(memReq
);
8206 dstImage
= (GLint
*)malloc(memReq
);
8209 dstImage
= (GLfloat
*)malloc(memReq
);
8211 case GL_UNSIGNED_BYTE_3_3_2
:
8212 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8213 dstImage
= (GLubyte
*)malloc(memReq
);
8215 case GL_UNSIGNED_SHORT_5_6_5
:
8216 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8217 case GL_UNSIGNED_SHORT_4_4_4_4
:
8218 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8219 case GL_UNSIGNED_SHORT_5_5_5_1
:
8220 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8221 dstImage
= (GLushort
*)malloc(memReq
);
8223 case GL_UNSIGNED_INT_8_8_8_8
:
8224 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8225 case GL_UNSIGNED_INT_10_10_10_2
:
8226 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8227 dstImage
= (GLuint
*)malloc(memReq
);
8230 return GLU_INVALID_ENUM
; /* assertion */
8232 if (dstImage
== NULL
) {
8233 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8234 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8235 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8236 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8237 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8238 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8239 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8240 return GLU_OUT_OF_MEMORY
;
8243 /* level userLevel is in srcImage; nothing saved yet */
8247 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8248 if (baseLevel
<= level
&& level
<= maxLevel
) {
8249 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8250 0,format
, type
, (void *)srcImage
);
8252 level
++; /* update current level for the loop */
8253 for (; level
<= levels
; level
++) {
8255 case GL_UNSIGNED_BYTE
:
8257 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8258 newWidth
,newHeight
,newDepth
,
8259 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8260 imageSize
,myswapBytes
);
8263 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8264 elementSize
,rowSize
,groupSize
);
8269 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8270 newWidth
,newHeight
,newDepth
,
8271 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8272 imageSize
,myswapBytes
);
8275 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8276 elementSize
,rowSize
,groupSize
);
8279 case GL_UNSIGNED_SHORT
:
8281 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8282 newWidth
,newHeight
,newDepth
,
8283 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8284 imageSize
,myswapBytes
);
8287 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8288 elementSize
,rowSize
,groupSize
,myswapBytes
);
8293 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8294 newWidth
,newHeight
,newDepth
,
8295 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8296 imageSize
,myswapBytes
);
8299 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8300 elementSize
,rowSize
,groupSize
,myswapBytes
);
8303 case GL_UNSIGNED_INT
:
8305 halveImage3D(cmpts
,extractUint
,shoveUint
,
8306 newWidth
,newHeight
,newDepth
,
8307 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8308 imageSize
,myswapBytes
);
8311 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8312 elementSize
,rowSize
,groupSize
,myswapBytes
);
8317 halveImage3D(cmpts
,extractSint
,shoveSint
,
8318 newWidth
,newHeight
,newDepth
,
8319 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8320 imageSize
,myswapBytes
);
8323 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8324 elementSize
,rowSize
,groupSize
,myswapBytes
);
8329 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8330 newWidth
,newHeight
,newDepth
,
8331 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8332 imageSize
,myswapBytes
);
8335 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8336 elementSize
,rowSize
,groupSize
,myswapBytes
);
8339 case GL_UNSIGNED_BYTE_3_3_2
:
8340 halveImagePackedPixel3D(3,extract332
,shove332
,
8341 newWidth
,newHeight
,newDepth
,
8342 srcImage
,dstImage
,elementSize
,rowSize
,
8343 imageSize
,myswapBytes
);
8345 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8346 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8347 newWidth
,newHeight
,newDepth
,
8348 srcImage
,dstImage
,elementSize
,rowSize
,
8349 imageSize
,myswapBytes
);
8351 case GL_UNSIGNED_SHORT_5_6_5
:
8352 halveImagePackedPixel3D(3,extract565
,shove565
,
8353 newWidth
,newHeight
,newDepth
,
8354 srcImage
,dstImage
,elementSize
,rowSize
,
8355 imageSize
,myswapBytes
);
8357 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8358 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8359 newWidth
,newHeight
,newDepth
,
8360 srcImage
,dstImage
,elementSize
,rowSize
,
8361 imageSize
,myswapBytes
);
8363 case GL_UNSIGNED_SHORT_4_4_4_4
:
8364 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8365 newWidth
,newHeight
,newDepth
,
8366 srcImage
,dstImage
,elementSize
,rowSize
,
8367 imageSize
,myswapBytes
);
8369 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8370 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8371 newWidth
,newHeight
,newDepth
,
8372 srcImage
,dstImage
,elementSize
,rowSize
,
8373 imageSize
,myswapBytes
);
8375 case GL_UNSIGNED_SHORT_5_5_5_1
:
8376 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8377 newWidth
,newHeight
,newDepth
,
8378 srcImage
,dstImage
,elementSize
,rowSize
,
8379 imageSize
,myswapBytes
);
8381 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8382 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8383 newWidth
,newHeight
,newDepth
,
8384 srcImage
,dstImage
,elementSize
,rowSize
,
8385 imageSize
,myswapBytes
);
8387 case GL_UNSIGNED_INT_8_8_8_8
:
8388 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8389 newWidth
,newHeight
,newDepth
,
8390 srcImage
,dstImage
,elementSize
,rowSize
,
8391 imageSize
,myswapBytes
);
8393 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8394 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8395 newWidth
,newHeight
,newDepth
,
8396 srcImage
,dstImage
,elementSize
,rowSize
,
8397 imageSize
,myswapBytes
);
8399 case GL_UNSIGNED_INT_10_10_10_2
:
8400 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8401 newWidth
,newHeight
,newDepth
,
8402 srcImage
,dstImage
,elementSize
,rowSize
,
8403 imageSize
,myswapBytes
);
8405 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8406 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8407 newWidth
,newHeight
,newDepth
,
8408 srcImage
,dstImage
,elementSize
,rowSize
,
8409 imageSize
,myswapBytes
);
8416 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8418 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8419 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8420 if (newDepth
> 1) newDepth
/= 2;
8422 /* call tex image with srcImage untouched since it's not padded */
8423 if (baseLevel
<= level
&& level
<= maxLevel
) {
8424 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8425 newDepth
,0, format
, type
, (void *) srcImage
);
8429 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8430 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8431 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8432 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8433 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8434 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8435 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8437 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8438 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8442 } /* gluBuild3DMipmapLevelsCore() */
8445 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8446 GLsizei width
, GLsizei height
, GLsizei depth
,
8447 GLenum format
, GLenum type
,
8448 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8453 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8454 if (rc
!= 0) return rc
;
8456 if (width
< 1 || height
< 1 || depth
< 1) {
8457 return GLU_INVALID_VALUE
;
8460 if(type
== GL_BITMAP
) {
8461 return GLU_INVALID_ENUM
;
8464 levels
= computeLog(width
);
8465 level
= computeLog(height
);
8466 if (level
> levels
) levels
=level
;
8467 level
= computeLog(depth
);
8468 if (level
> levels
) levels
=level
;
8471 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8472 return GLU_INVALID_VALUE
;
8474 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8475 width
, height
, depth
,
8476 width
, height
, depth
,
8478 userLevel
, baseLevel
, maxLevel
,
8480 } /* gluBuild3DMipmapLevels() */
8483 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8484 GLsizei width
, GLsizei height
, GLsizei depth
,
8485 GLenum format
, GLenum type
, const void *data
)
8487 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8490 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8491 if (rc
!= 0) return rc
;
8493 if (width
< 1 || height
< 1 || depth
< 1) {
8494 return GLU_INVALID_VALUE
;
8497 if(type
== GL_BITMAP
) {
8498 return GLU_INVALID_ENUM
;
8501 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8502 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8504 levels
= computeLog(widthPowerOf2
);
8505 level
= computeLog(heightPowerOf2
);
8506 if (level
> levels
) levels
=level
;
8507 level
= computeLog(depthPowerOf2
);
8508 if (level
> levels
) levels
=level
;
8510 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8511 width
, height
, depth
,
8512 widthPowerOf2
, heightPowerOf2
,
8514 format
, type
, 0, 0, levels
,
8516 } /* gluBuild3DMipmaps() */
8518 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8520 isSwap
= isSwap
; /* turn off warnings */
8522 assert(*((const GLubyte
*)ubyte
) <= 255);
8524 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8525 } /* extractUbyte() */
8527 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8529 assert(0.0 <= value
&& value
< 256.0);
8531 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8532 } /* shoveUbyte() */
8534 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8536 isSwap
= isSwap
; /* turn off warnings */
8538 assert(*((const GLbyte
*)sbyte
) <= 127);
8540 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8541 } /* extractSbyte() */
8543 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8545 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8546 } /* shoveSbyte() */
8548 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8553 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8556 ushort
= *(const GLushort
*)uitem
;
8559 assert(ushort
<= 65535);
8561 return (GLdouble
)ushort
;
8562 } /* extractUshort() */
8564 static void shoveUshort(GLdouble value
, int index
, void *data
)
8566 assert(0.0 <= value
&& value
< 65536.0);
8568 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8569 } /* shoveUshort() */
8571 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8576 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8579 sshort
= *(const GLshort
*)sitem
;
8582 assert(sshort
<= 32767);
8584 return (GLdouble
)sshort
;
8585 } /* extractSshort() */
8587 static void shoveSshort(GLdouble value
, int index
, void *data
)
8589 assert(0.0 <= value
&& value
< 32768.0);
8591 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8592 } /* shoveSshort() */
8594 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8599 uint
= __GLU_SWAP_4_BYTES(uitem
);
8602 uint
= *(const GLuint
*)uitem
;
8605 assert(uint
<= 0xffffffff);
8607 return (GLdouble
)uint
;
8608 } /* extractUint() */
8610 static void shoveUint(GLdouble value
, int index
, void *data
)
8612 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8614 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8617 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8622 sint
= __GLU_SWAP_4_BYTES(sitem
);
8625 sint
= *(const GLint
*)sitem
;
8628 assert(sint
<= 0x7fffffff);
8630 return (GLdouble
)sint
;
8631 } /* extractSint() */
8633 static void shoveSint(GLdouble value
, int index
, void *data
)
8635 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8637 ((GLint
*)data
)[index
]= (GLint
)value
;
8640 static GLdouble
extractFloat(int isSwap
, const void *item
)
8645 ffloat
= __GLU_SWAP_4_BYTES(item
);
8648 ffloat
= *(const GLfloat
*)item
;
8651 assert(ffloat
<= 1.0);
8653 return (GLdouble
)ffloat
;
8654 } /* extractFloat() */
8656 static void shoveFloat(GLdouble value
, int index
, void *data
)
8658 assert(0.0 <= value
&& value
<= 1.0);
8660 ((GLfloat
*)data
)[index
]= value
;
8661 } /* shoveFloat() */
8663 static void halveImageSlice(int components
,
8664 GLdouble (*extract
)(int, const void *),
8665 void (*shove
)(GLdouble
, int, void *),
8666 GLint width
, GLint height
, GLint depth
,
8667 const void *dataIn
, void *dataOut
,
8668 GLint elementSizeInBytes
,
8669 GLint groupSizeInBytes
,
8670 GLint rowSizeInBytes
,
8671 GLint imageSizeInBytes
,
8675 int halfWidth
= width
/ 2;
8676 int halfHeight
= height
/ 2;
8677 int halfDepth
= depth
/ 2;
8678 const char *src
= (const char *)dataIn
;
8679 int rowPadBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8680 int imagePadBytes
= imageSizeInBytes
- (width
*height
*groupSizeInBytes
);
8683 assert((width
== 1 || height
== 1) && depth
>= 2);
8685 if (width
== height
) { /* a 1-pixel column viewed from top */
8686 /* printf("1-column\n");*/
8687 assert(width
== 1 && height
== 1);
8690 for (ii
= 0; ii
< halfDepth
; ii
++) {
8693 for (cc
= 0; cc
< components
; cc
++) {
8695 double extractTotals
[BOX2
][4];
8698 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8699 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8701 /* average 2 pixels since only a column */
8703 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8704 * totals[RED]/= 2.0;
8706 for (kk
= 0; kk
< BOX2
; kk
++) {
8707 totals
[cc
]+= extractTotals
[kk
][cc
];
8709 totals
[cc
]/= (double)BOX2
;
8711 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8713 src
+= elementSizeInBytes
;
8716 /* skip over to next group of 2 */
8717 src
+= rowSizeInBytes
;
8720 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8721 assert(outIndex
== halfDepth
* components
);
8723 else if (height
== 1) { /* horizontal slice viewed from top */
8724 /* printf("horizontal slice\n"); */
8727 for (ii
= 0; ii
< halfDepth
; ii
++) {
8728 for (jj
= 0; jj
< halfWidth
; jj
++) {
8731 for (cc
= 0; cc
< components
; cc
++) {
8734 double extractTotals
[BOX4
][4];
8736 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8737 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8738 (src
+groupSizeInBytes
));
8739 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8740 (src
+imageSizeInBytes
));
8741 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8742 (src
+imageSizeInBytes
+groupSizeInBytes
));
8744 /* grab 4 pixels to average */
8746 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8747 * extractTotals[2][RED]+extractTotals[3][RED];
8748 * totals[RED]/= 4.0;
8750 for (kk
= 0; kk
< BOX4
; kk
++) {
8751 totals
[cc
]+= extractTotals
[kk
][cc
];
8753 totals
[cc
]/= (double)BOX4
;
8755 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8758 src
+= elementSizeInBytes
;
8761 /* skip over to next horizontal square of 4 */
8762 src
+= groupSizeInBytes
;
8766 src
+= rowSizeInBytes
;
8769 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8770 assert(outIndex
== halfWidth
* halfDepth
* components
);
8772 else if (width
== 1) { /* vertical slice viewed from top */
8773 /* printf("vertical slice\n"); */
8774 assert(height
!= 1);
8776 for (ii
= 0; ii
< halfDepth
; ii
++) {
8777 for (jj
= 0; jj
< halfHeight
; jj
++) {
8780 for (cc
= 0; cc
< components
; cc
++) {
8783 double extractTotals
[BOX4
][4];
8785 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8786 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8787 (src
+rowSizeInBytes
));
8788 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8789 (src
+imageSizeInBytes
));
8790 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8791 (src
+imageSizeInBytes
+rowSizeInBytes
));
8793 /* grab 4 pixels to average */
8795 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8796 * extractTotals[2][RED]+extractTotals[3][RED];
8797 * totals[RED]/= 4.0;
8799 for (kk
= 0; kk
< BOX4
; kk
++) {
8800 totals
[cc
]+= extractTotals
[kk
][cc
];
8802 totals
[cc
]/= (double)BOX4
;
8804 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8807 src
+= elementSizeInBytes
;
8811 /* skip over to next vertical square of 4 */
8812 src
+= rowSizeInBytes
;
8814 src
+= imagePadBytes
;
8816 src
+= imageSizeInBytes
;
8819 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8820 assert(outIndex
== halfHeight
* halfDepth
* components
);
8823 } /* halveImageSlice() */
8825 static void halveImage3D(int components
,
8826 GLdouble (*extract
)(int, const void *),
8827 void (*shove
)(GLdouble
, int, void *),
8828 GLint width
, GLint height
, GLint depth
,
8829 const void *dataIn
, void *dataOut
,
8830 GLint elementSizeInBytes
,
8831 GLint groupSizeInBytes
,
8832 GLint rowSizeInBytes
,
8833 GLint imageSizeInBytes
,
8838 /* a horizontal/vertical/one-column slice viewed from top */
8839 if (width
== 1 || height
== 1) {
8842 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8843 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8844 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8850 int halfWidth
= width
/ 2;
8851 int halfHeight
= height
/ 2;
8852 int halfDepth
= depth
/ 2;
8853 const char *src
= (const char *) dataIn
;
8854 int rowPadBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8855 int imagePadBytes
= imageSizeInBytes
- (width
*height
*groupSizeInBytes
);
8858 for (dd
= 0; dd
< halfDepth
; dd
++) {
8859 for (ii
= 0; ii
< halfHeight
; ii
++) {
8860 for (jj
= 0; jj
< halfWidth
; jj
++) {
8863 for (cc
= 0; cc
< components
; cc
++) {
8866 double totals
[4]; /* 4 is maximum components */
8867 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8869 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8870 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8871 (src
+groupSizeInBytes
));
8872 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8873 (src
+rowSizeInBytes
));
8874 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8875 (src
+rowSizeInBytes
+groupSizeInBytes
));
8877 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8878 (src
+imageSizeInBytes
));
8880 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8881 (src
+groupSizeInBytes
+imageSizeInBytes
));
8882 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8883 (src
+rowSizeInBytes
+imageSizeInBytes
));
8884 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8885 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8889 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8890 * extractTotals[2][RED]+extractTotals[3][RED]+
8891 * extractTotals[4][RED]+extractTotals[5][RED]+
8892 * extractTotals[6][RED]+extractTotals[7][RED];
8893 * totals[RED]/= 8.0;
8895 for (kk
= 0; kk
< BOX8
; kk
++) {
8896 totals
[cc
]+= extractTotals
[kk
][cc
];
8898 totals
[cc
]/= (double)BOX8
;
8900 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8904 src
+= elementSizeInBytes
; /* go to next component */
8907 /* skip over to next square of 4 */
8908 src
+= groupSizeInBytes
;
8910 /* skip past pad bytes, if any, to get to next row */
8913 /* src is at beginning of a row here, but it's the second row of
8914 * the square block of 4 pixels that we just worked on so we
8915 * need to go one more row.
8923 src
+= rowSizeInBytes
;
8926 /* skip past pad bytes, if any, to get to next image */
8927 src
+= imagePadBytes
;
8929 src
+= imageSizeInBytes
;
8932 /* both pointers must reach one byte after the end */
8933 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8934 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8936 } /* halveImage3D() */