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.
44 #include <limits.h> /* UINT_MAX */
58 /* Pixel storage modes */
61 GLint pack_row_length
;
63 GLint pack_skip_pixels
;
65 GLint pack_swap_bytes
;
66 GLint pack_skip_images
;
67 GLint pack_image_height
;
69 GLint unpack_alignment
;
70 GLint unpack_row_length
;
71 GLint unpack_skip_rows
;
72 GLint unpack_skip_pixels
;
73 GLint unpack_lsb_first
;
74 GLint unpack_swap_bytes
;
75 GLint unpack_skip_images
;
76 GLint unpack_image_height
;
79 static int gluBuild1DMipmapLevelsCore(GLenum
, GLint
,
82 GLenum
, GLenum
, GLint
, GLint
, GLint
,
84 static int gluBuild2DMipmapLevelsCore(GLenum
, GLint
,
87 GLenum
, GLenum
, GLint
, GLint
, GLint
,
89 static int gluBuild3DMipmapLevelsCore(GLenum
, GLint
,
90 GLsizei
, GLsizei
, GLsizei
,
91 GLsizei
, GLsizei
, GLsizei
,
92 GLenum
, GLenum
, GLint
, GLint
, GLint
,
96 * internal function declarations
98 static GLfloat
bytes_per_element(GLenum type
);
99 static GLint
elements_per_group(GLenum format
, GLenum type
);
100 static GLint
is_index(GLenum format
);
101 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
);
102 static void fill_image(const PixelStorageModes
*,
103 GLint width
, GLint height
, GLenum format
,
104 GLenum type
, GLboolean index_format
,
105 const void *userdata
, GLushort
*newimage
);
106 static void empty_image(const PixelStorageModes
*,
107 GLint width
, GLint height
, GLenum format
,
108 GLenum type
, GLboolean index_format
,
109 const GLushort
*oldimage
, void *userdata
);
110 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
111 const GLushort
*datain
,
112 GLint widthout
, GLint heightout
,
115 static void scale_internal_ubyte(GLint components
, GLint widthin
,
116 GLint heightin
, const GLubyte
*datain
,
117 GLint widthout
, GLint heightout
,
118 GLubyte
*dataout
, GLint element_size
,
119 GLint ysize
, GLint group_size
);
120 static void scale_internal_byte(GLint components
, GLint widthin
,
121 GLint heightin
, const GLbyte
*datain
,
122 GLint widthout
, GLint heightout
,
123 GLbyte
*dataout
, GLint element_size
,
124 GLint ysize
, GLint group_size
);
125 static void scale_internal_ushort(GLint components
, GLint widthin
,
126 GLint heightin
, const GLushort
*datain
,
127 GLint widthout
, GLint heightout
,
128 GLushort
*dataout
, GLint element_size
,
129 GLint ysize
, GLint group_size
,
131 static void scale_internal_short(GLint components
, GLint widthin
,
132 GLint heightin
, const GLshort
*datain
,
133 GLint widthout
, GLint heightout
,
134 GLshort
*dataout
, GLint element_size
,
135 GLint ysize
, GLint group_size
,
137 static void scale_internal_uint(GLint components
, GLint widthin
,
138 GLint heightin
, const GLuint
*datain
,
139 GLint widthout
, GLint heightout
,
140 GLuint
*dataout
, GLint element_size
,
141 GLint ysize
, GLint group_size
,
143 static void scale_internal_int(GLint components
, GLint widthin
,
144 GLint heightin
, const GLint
*datain
,
145 GLint widthout
, GLint heightout
,
146 GLint
*dataout
, GLint element_size
,
147 GLint ysize
, GLint group_size
,
149 static void scale_internal_float(GLint components
, GLint widthin
,
150 GLint heightin
, const GLfloat
*datain
,
151 GLint widthout
, GLint heightout
,
152 GLfloat
*dataout
, GLint element_size
,
153 GLint ysize
, GLint group_size
,
156 static int checkMipmapArgs(GLenum
, GLenum
, GLenum
);
157 static GLboolean
legalFormat(GLenum
);
158 static GLboolean
legalType(GLenum
);
159 static GLboolean
isTypePackedPixel(GLenum
);
160 static GLboolean
isLegalFormatForPackedPixelType(GLenum
, GLenum
);
161 static GLboolean
isLegalLevels(GLint
, GLint
, GLint
, GLint
);
162 static void closestFit(GLenum
, GLint
, GLint
, GLint
, GLenum
, GLenum
,
165 /* all extract/shove routines must return double to handle unsigned ints */
166 static GLdouble
extractUbyte(int, const void *);
167 static void shoveUbyte(GLdouble
, int, void *);
168 static GLdouble
extractSbyte(int, const void *);
169 static void shoveSbyte(GLdouble
, int, void *);
170 static GLdouble
extractUshort(int, const void *);
171 static void shoveUshort(GLdouble
, int, void *);
172 static GLdouble
extractSshort(int, const void *);
173 static void shoveSshort(GLdouble
, int, void *);
174 static GLdouble
extractUint(int, const void *);
175 static void shoveUint(GLdouble
, int, void *);
176 static GLdouble
extractSint(int, const void *);
177 static void shoveSint(GLdouble
, int, void *);
178 static GLdouble
extractFloat(int, const void *);
179 static void shoveFloat(GLdouble
, int, void *);
180 static void halveImageSlice(int, GLdouble (*)(int, const void *),
181 void (*)(GLdouble
, int, void *),
183 const void *, void *,
184 GLint
, GLint
, GLint
, GLint
, GLint
);
185 static void halveImage3D(int, GLdouble (*)(int, const void *),
186 void (*)(GLdouble
, int, void *),
188 const void *, void *,
189 GLint
, GLint
, GLint
, GLint
, GLint
);
191 /* packedpixel type scale routines */
192 static void extract332(int,const void *, GLfloat
[]);
193 static void shove332(const GLfloat
[],int ,void *);
194 static void extract233rev(int,const void *, GLfloat
[]);
195 static void shove233rev(const GLfloat
[],int ,void *);
196 static void extract565(int,const void *, GLfloat
[]);
197 static void shove565(const GLfloat
[],int ,void *);
198 static void extract565rev(int,const void *, GLfloat
[]);
199 static void shove565rev(const GLfloat
[],int ,void *);
200 static void extract4444(int,const void *, GLfloat
[]);
201 static void shove4444(const GLfloat
[],int ,void *);
202 static void extract4444rev(int,const void *, GLfloat
[]);
203 static void shove4444rev(const GLfloat
[],int ,void *);
204 static void extract5551(int,const void *, GLfloat
[]);
205 static void shove5551(const GLfloat
[],int ,void *);
206 static void extract1555rev(int,const void *, GLfloat
[]);
207 static void shove1555rev(const GLfloat
[],int ,void *);
208 static void extract8888(int,const void *, GLfloat
[]);
209 static void shove8888(const GLfloat
[],int ,void *);
210 static void extract8888rev(int,const void *, GLfloat
[]);
211 static void shove8888rev(const GLfloat
[],int ,void *);
212 static void extract1010102(int,const void *, GLfloat
[]);
213 static void shove1010102(const GLfloat
[],int ,void *);
214 static void extract2101010rev(int,const void *, GLfloat
[]);
215 static void shove2101010rev(const GLfloat
[],int ,void *);
216 static void scaleInternalPackedPixel(int,
217 void (*)(int, const void *,GLfloat
[]),
218 void (*)(const GLfloat
[],int, void *),
219 GLint
,GLint
, const void *,
220 GLint
,GLint
,void *,GLint
,GLint
,GLint
);
221 static void halveImagePackedPixel(int,
222 void (*)(int, const void *,GLfloat
[]),
223 void (*)(const GLfloat
[],int, void *),
224 GLint
, GLint
, const void *,
225 void *, GLint
, GLint
, GLint
);
226 static void halve1DimagePackedPixel(int,
227 void (*)(int, const void *,GLfloat
[]),
228 void (*)(const GLfloat
[],int, void *),
229 GLint
, GLint
, const void *,
230 void *, GLint
, GLint
, GLint
);
232 static void halve1Dimage_ubyte(GLint
, GLuint
, GLuint
,const GLubyte
*,
233 GLubyte
*, GLint
, GLint
, GLint
);
234 static void halve1Dimage_byte(GLint
, GLuint
, GLuint
,const GLbyte
*, GLbyte
*,
235 GLint
, GLint
, GLint
);
236 static void halve1Dimage_ushort(GLint
, GLuint
, GLuint
, const GLushort
*,
237 GLushort
*, GLint
, GLint
, GLint
, GLint
);
238 static void halve1Dimage_short(GLint
, GLuint
, GLuint
,const GLshort
*, GLshort
*,
239 GLint
, GLint
, GLint
, GLint
);
240 static void halve1Dimage_uint(GLint
, GLuint
, GLuint
, const GLuint
*, GLuint
*,
241 GLint
, GLint
, GLint
, GLint
);
242 static void halve1Dimage_int(GLint
, GLuint
, GLuint
, const GLint
*, GLint
*,
243 GLint
, GLint
, GLint
, GLint
);
244 static void halve1Dimage_float(GLint
, GLuint
, GLuint
, const GLfloat
*, GLfloat
*,
245 GLint
, GLint
, GLint
, GLint
);
247 static GLint
imageSize3D(GLint
, GLint
, GLint
, GLenum
,GLenum
);
248 static void fillImage3D(const PixelStorageModes
*, GLint
, GLint
, GLint
,GLenum
,
249 GLenum
, GLboolean
, const void *, GLushort
*);
250 static void emptyImage3D(const PixelStorageModes
*,
251 GLint
, GLint
, GLint
, GLenum
,
253 const GLushort
*, void *);
254 static void scaleInternal3D(GLint
, GLint
, GLint
, GLint
, const GLushort
*,
255 GLint
, GLint
, GLint
, GLushort
*);
257 static void retrieveStoreModes(PixelStorageModes
*psm
)
259 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
260 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
261 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
262 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
263 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
264 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
266 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
267 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
268 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
269 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
270 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
271 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
274 static void retrieveStoreModes3D(PixelStorageModes
*psm
)
276 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
277 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
278 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
279 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
280 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
281 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
282 glGetIntegerv(GL_UNPACK_SKIP_IMAGES
, &psm
->unpack_skip_images
);
283 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT
, &psm
->unpack_image_height
);
285 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
286 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
287 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
288 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
289 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
290 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
291 glGetIntegerv(GL_PACK_SKIP_IMAGES
, &psm
->pack_skip_images
);
292 glGetIntegerv(GL_PACK_IMAGE_HEIGHT
, &psm
->pack_image_height
);
295 static int computeLog(GLuint value
)
302 if (value
== 0) return -1;
307 if (value
!= 1) return -1;
316 ** Compute the nearest power of 2 number. This algorithm is a little
317 ** strange, but it works quite well.
319 static int nearestPower(GLuint value
)
326 if (value
== 0) return -1;
331 } else if (value
== 3) {
339 #define __GLU_SWAP_2_BYTES(s)\
340 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
342 #define __GLU_SWAP_4_BYTES(s)\
343 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
344 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
345 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
347 static void halveImage(GLint components
, GLuint width
, GLuint height
,
348 const GLushort
*datain
, GLushort
*dataout
)
351 int newwidth
, newheight
;
356 newwidth
= width
/ 2;
357 newheight
= height
/ 2;
358 delta
= width
* components
;
363 for (i
= 0; i
< newheight
; i
++) {
364 for (j
= 0; j
< newwidth
; j
++) {
365 for (k
= 0; k
< components
; k
++) {
366 s
[0] = (t
[0] + t
[components
] + t
[delta
] +
367 t
[delta
+components
] + 2) / 4;
376 static void halveImage_ubyte(GLint components
, GLuint width
, GLuint height
,
377 const GLubyte
*datain
, GLubyte
*dataout
,
378 GLint element_size
, GLint ysize
, GLint group_size
)
381 int newwidth
, newheight
;
385 /* handle case where there is only 1 column/row */
386 if (width
== 1 || height
== 1) {
387 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
388 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
389 element_size
,ysize
,group_size
);
393 newwidth
= width
/ 2;
394 newheight
= height
/ 2;
396 t
= (const char *)datain
;
399 for (i
= 0; i
< newheight
; i
++) {
400 for (j
= 0; j
< newwidth
; j
++) {
401 for (k
= 0; k
< components
; k
++) {
402 s
[0] = (*(const GLubyte
*)t
+
403 *(const GLubyte
*)(t
+group_size
) +
404 *(const GLubyte
*)(t
+ysize
) +
405 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
406 s
++; t
+= element_size
;
415 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
416 const GLubyte
*dataIn
, GLubyte
*dataOut
,
417 GLint element_size
, GLint ysize
,
420 GLint halfWidth
= width
/ 2;
421 GLint halfHeight
= height
/ 2;
422 const char *src
= (const char *) dataIn
;
423 GLubyte
*dest
= dataOut
;
426 assert(width
== 1 || height
== 1); /* must be 1D */
427 assert(width
!= height
); /* can't be square */
429 if (height
== 1) { /* 1 row */
430 assert(width
!= 1); /* widthxheight can't be 1x1 */
433 for (jj
= 0; jj
< halfWidth
; jj
++) {
435 for (kk
= 0; kk
< components
; kk
++) {
436 *dest
= (*(const GLubyte
*)src
+
437 *(const GLubyte
*)(src
+group_size
)) / 2;
442 src
+= group_size
; /* skip to next 2 */
445 int padBytes
= ysize
- (width
*group_size
);
446 src
+= padBytes
; /* for assertion only */
449 else if (width
== 1) { /* 1 column */
450 int padBytes
= ysize
- (width
* group_size
);
451 assert(height
!= 1); /* widthxheight can't be 1x1 */
453 /* one vertical column with possible pad bytes per row */
454 /* average two at a time */
456 for (jj
= 0; jj
< halfHeight
; jj
++) {
458 for (kk
= 0; kk
< components
; kk
++) {
459 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
464 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
469 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
470 assert((char *)dest
== &((char *)dataOut
)
471 [components
* element_size
* halfWidth
* halfHeight
]);
472 } /* halve1Dimage_ubyte() */
474 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
475 const GLbyte
*datain
, GLbyte
*dataout
,
477 GLint ysize
, GLint group_size
)
480 int newwidth
, newheight
;
484 /* handle case where there is only 1 column/row */
485 if (width
== 1 || height
== 1) {
486 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
487 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
488 element_size
,ysize
,group_size
);
492 newwidth
= width
/ 2;
493 newheight
= height
/ 2;
495 t
= (const char *)datain
;
498 for (i
= 0; i
< newheight
; i
++) {
499 for (j
= 0; j
< newwidth
; j
++) {
500 for (k
= 0; k
< components
; k
++) {
501 s
[0] = (*(const GLbyte
*)t
+
502 *(const GLbyte
*)(t
+group_size
) +
503 *(const GLbyte
*)(t
+ysize
) +
504 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
505 s
++; t
+= element_size
;
513 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
514 const GLbyte
*dataIn
, GLbyte
*dataOut
,
515 GLint element_size
,GLint ysize
, GLint group_size
)
517 GLint halfWidth
= width
/ 2;
518 GLint halfHeight
= height
/ 2;
519 const char *src
= (const char *) dataIn
;
520 GLbyte
*dest
= dataOut
;
523 assert(width
== 1 || height
== 1); /* must be 1D */
524 assert(width
!= height
); /* can't be square */
526 if (height
== 1) { /* 1 row */
527 assert(width
!= 1); /* widthxheight can't be 1x1 */
530 for (jj
= 0; jj
< halfWidth
; jj
++) {
532 for (kk
= 0; kk
< components
; kk
++) {
533 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
538 src
+= group_size
; /* skip to next 2 */
541 int padBytes
= ysize
- (width
*group_size
);
542 src
+= padBytes
; /* for assertion only */
545 else if (width
== 1) { /* 1 column */
546 int padBytes
= ysize
- (width
* group_size
);
547 assert(height
!= 1); /* widthxheight can't be 1x1 */
549 /* one vertical column with possible pad bytes per row */
550 /* average two at a time */
552 for (jj
= 0; jj
< halfHeight
; jj
++) {
554 for (kk
= 0; kk
< components
; kk
++) {
555 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
560 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
564 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
567 assert((char *)dest
== &((char *)dataOut
)
568 [components
* element_size
* halfWidth
* halfHeight
]);
569 } /* halve1Dimage_byte() */
571 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
572 const GLushort
*datain
, GLushort
*dataout
,
573 GLint element_size
, GLint ysize
, GLint group_size
,
577 int newwidth
, newheight
;
581 /* handle case where there is only 1 column/row */
582 if (width
== 1 || height
== 1) {
583 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
584 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
585 element_size
,ysize
,group_size
, myswap_bytes
);
589 newwidth
= width
/ 2;
590 newheight
= height
/ 2;
592 t
= (const char *)datain
;
596 for (i
= 0; i
< newheight
; i
++) {
597 for (j
= 0; j
< newwidth
; j
++) {
598 for (k
= 0; k
< components
; k
++) {
599 s
[0] = (*(const GLushort
*)t
+
600 *(const GLushort
*)(t
+group_size
) +
601 *(const GLushort
*)(t
+ysize
) +
602 *(const GLushort
*)(t
+ysize
+group_size
) + 2) / 4;
603 s
++; t
+= element_size
;
610 for (i
= 0; i
< newheight
; i
++) {
611 for (j
= 0; j
< newwidth
; j
++) {
612 for (k
= 0; k
< components
; k
++) {
613 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
614 __GLU_SWAP_2_BYTES(t
+group_size
) +
615 __GLU_SWAP_2_BYTES(t
+ysize
) +
616 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
617 s
++; t
+= element_size
;
625 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
626 const GLushort
*dataIn
, GLushort
*dataOut
,
627 GLint element_size
, GLint ysize
,
628 GLint group_size
, GLint myswap_bytes
)
630 GLint halfWidth
= width
/ 2;
631 GLint halfHeight
= height
/ 2;
632 const char *src
= (const char *) dataIn
;
633 GLushort
*dest
= dataOut
;
636 assert(width
== 1 || height
== 1); /* must be 1D */
637 assert(width
!= height
); /* can't be square */
639 if (height
== 1) { /* 1 row */
640 assert(width
!= 1); /* widthxheight can't be 1x1 */
643 for (jj
= 0; jj
< halfWidth
; jj
++) {
645 for (kk
= 0; kk
< components
; kk
++) {
647 GLushort ushort
[BOX2
];
649 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
650 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
653 ushort
[0]= *(const GLushort
*)src
;
654 ushort
[1]= *(const GLushort
*)(src
+group_size
);
657 *dest
= (ushort
[0] + ushort
[1]) / 2;
661 src
+= group_size
; /* skip to next 2 */
664 int padBytes
= ysize
- (width
*group_size
);
665 src
+= padBytes
; /* for assertion only */
668 else if (width
== 1) { /* 1 column */
669 int padBytes
= ysize
- (width
* group_size
);
670 assert(height
!= 1); /* widthxheight can't be 1x1 */
672 /* one vertical column with possible pad bytes per row */
673 /* average two at a time */
675 for (jj
= 0; jj
< halfHeight
; jj
++) {
677 for (kk
= 0; kk
< components
; kk
++) {
679 GLushort ushort
[BOX2
];
681 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
682 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
685 ushort
[0]= *(const GLushort
*)src
;
686 ushort
[1]= *(const GLushort
*)(src
+ysize
);
688 *dest
= (ushort
[0] + ushort
[1]) / 2;
693 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
697 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
700 assert((char *)dest
== &((char *)dataOut
)
701 [components
* element_size
* halfWidth
* halfHeight
]);
703 } /* halve1Dimage_ushort() */
706 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
707 const GLshort
*datain
, GLshort
*dataout
,
708 GLint element_size
, GLint ysize
, GLint group_size
,
712 int newwidth
, newheight
;
716 /* handle case where there is only 1 column/row */
717 if (width
== 1 || height
== 1) {
718 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
719 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
720 element_size
,ysize
,group_size
, myswap_bytes
);
724 newwidth
= width
/ 2;
725 newheight
= height
/ 2;
727 t
= (const char *)datain
;
731 for (i
= 0; i
< newheight
; i
++) {
732 for (j
= 0; j
< newwidth
; j
++) {
733 for (k
= 0; k
< components
; k
++) {
734 s
[0] = (*(const GLshort
*)t
+
735 *(const GLshort
*)(t
+group_size
) +
736 *(const GLshort
*)(t
+ysize
) +
737 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
738 s
++; t
+= element_size
;
745 for (i
= 0; i
< newheight
; i
++) {
746 for (j
= 0; j
< newwidth
; j
++) {
747 for (k
= 0; k
< components
; k
++) {
750 b
= __GLU_SWAP_2_BYTES(t
);
751 buf
= *(const GLshort
*)&b
;
752 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
753 buf
+= *(const GLshort
*)&b
;
754 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
755 buf
+= *(const GLshort
*)&b
;
756 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
757 buf
+= *(const GLshort
*)&b
;
758 s
[0] = (GLshort
)((buf
+2)/4);
759 s
++; t
+= element_size
;
767 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
768 const GLshort
*dataIn
, GLshort
*dataOut
,
769 GLint element_size
, GLint ysize
,
770 GLint group_size
, GLint myswap_bytes
)
772 GLint halfWidth
= width
/ 2;
773 GLint halfHeight
= height
/ 2;
774 const char *src
= (const char *) dataIn
;
775 GLshort
*dest
= dataOut
;
778 assert(width
== 1 || height
== 1); /* must be 1D */
779 assert(width
!= height
); /* can't be square */
781 if (height
== 1) { /* 1 row */
782 assert(width
!= 1); /* widthxheight can't be 1x1 */
785 for (jj
= 0; jj
< halfWidth
; jj
++) {
787 for (kk
= 0; kk
< components
; kk
++) {
789 GLshort sshort
[BOX2
];
791 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
792 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
795 sshort
[0]= *(const GLshort
*)src
;
796 sshort
[1]= *(const GLshort
*)(src
+group_size
);
799 *dest
= (sshort
[0] + sshort
[1]) / 2;
803 src
+= group_size
; /* skip to next 2 */
806 int padBytes
= ysize
- (width
*group_size
);
807 src
+= padBytes
; /* for assertion only */
810 else if (width
== 1) { /* 1 column */
811 int padBytes
= ysize
- (width
* group_size
);
812 assert(height
!= 1); /* widthxheight can't be 1x1 */
814 /* one vertical column with possible pad bytes per row */
815 /* average two at a time */
817 for (jj
= 0; jj
< halfHeight
; jj
++) {
819 for (kk
= 0; kk
< components
; kk
++) {
821 GLshort sshort
[BOX2
];
823 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
824 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
827 sshort
[0]= *(const GLshort
*)src
;
828 sshort
[1]= *(const GLshort
*)(src
+ysize
);
830 *dest
= (sshort
[0] + sshort
[1]) / 2;
835 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
839 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
842 assert((char *)dest
== &((char *)dataOut
)
843 [components
* element_size
* halfWidth
* halfHeight
]);
845 } /* halve1Dimage_short() */
848 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
849 const GLuint
*datain
, GLuint
*dataout
,
850 GLint element_size
, GLint ysize
, GLint group_size
,
854 int newwidth
, newheight
;
858 /* handle case where there is only 1 column/row */
859 if (width
== 1 || height
== 1) {
860 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
861 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
862 element_size
,ysize
,group_size
, myswap_bytes
);
866 newwidth
= width
/ 2;
867 newheight
= height
/ 2;
869 t
= (const char *)datain
;
873 for (i
= 0; i
< newheight
; i
++) {
874 for (j
= 0; j
< newwidth
; j
++) {
875 for (k
= 0; k
< components
; k
++) {
876 /* need to cast to double to hold large unsigned ints */
877 s
[0] = ((double)*(const GLuint
*)t
+
878 (double)*(const GLuint
*)(t
+group_size
) +
879 (double)*(const GLuint
*)(t
+ysize
) +
880 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
881 s
++; t
+= element_size
;
889 for (i
= 0; i
< newheight
; i
++) {
890 for (j
= 0; j
< newwidth
; j
++) {
891 for (k
= 0; k
< components
; k
++) {
892 /* need to cast to double to hold large unsigned ints */
894 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
895 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
896 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
897 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
898 s
[0] = (GLuint
)(buf
/4 + 0.5);
900 s
++; t
+= element_size
;
909 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
910 const GLuint
*dataIn
, GLuint
*dataOut
,
911 GLint element_size
, GLint ysize
,
912 GLint group_size
, GLint myswap_bytes
)
914 GLint halfWidth
= width
/ 2;
915 GLint halfHeight
= height
/ 2;
916 const char *src
= (const char *) dataIn
;
917 GLuint
*dest
= dataOut
;
920 assert(width
== 1 || height
== 1); /* must be 1D */
921 assert(width
!= height
); /* can't be square */
923 if (height
== 1) { /* 1 row */
924 assert(width
!= 1); /* widthxheight can't be 1x1 */
927 for (jj
= 0; jj
< halfWidth
; jj
++) {
929 for (kk
= 0; kk
< components
; kk
++) {
933 uint
[0]= __GLU_SWAP_4_BYTES(src
);
934 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
937 uint
[0]= *(const GLuint
*)src
;
938 uint
[1]= *(const GLuint
*)(src
+group_size
);
940 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
945 src
+= group_size
; /* skip to next 2 */
948 int padBytes
= ysize
- (width
*group_size
);
949 src
+= padBytes
; /* for assertion only */
952 else if (width
== 1) { /* 1 column */
953 int padBytes
= ysize
- (width
* group_size
);
954 assert(height
!= 1); /* widthxheight can't be 1x1 */
956 /* one vertical column with possible pad bytes per row */
957 /* average two at a time */
959 for (jj
= 0; jj
< halfHeight
; jj
++) {
961 for (kk
= 0; kk
< components
; kk
++) {
965 uint
[0]= __GLU_SWAP_4_BYTES(src
);
966 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
969 uint
[0]= *(const GLuint
*)src
;
970 uint
[1]= *(const GLuint
*)(src
+ysize
);
972 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
977 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
981 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
984 assert((char *)dest
== &((char *)dataOut
)
985 [components
* element_size
* halfWidth
* halfHeight
]);
987 } /* halve1Dimage_uint() */
989 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
990 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
991 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
994 int newwidth
, newheight
;
998 /* handle case where there is only 1 column/row */
999 if (width
== 1 || height
== 1) {
1000 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1001 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1002 element_size
,ysize
,group_size
, myswap_bytes
);
1006 newwidth
= width
/ 2;
1007 newheight
= height
/ 2;
1009 t
= (const char *)datain
;
1011 /* Piece o' cake! */
1013 for (i
= 0; i
< newheight
; i
++) {
1014 for (j
= 0; j
< newwidth
; j
++) {
1015 for (k
= 0; k
< components
; k
++) {
1016 s
[0] = ((float)*(const GLint
*)t
+
1017 (float)*(const GLint
*)(t
+group_size
) +
1018 (float)*(const GLint
*)(t
+ysize
) +
1019 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1020 s
++; t
+= element_size
;
1027 for (i
= 0; i
< newheight
; i
++) {
1028 for (j
= 0; j
< newwidth
; j
++) {
1029 for (k
= 0; k
< components
; k
++) {
1032 b
= __GLU_SWAP_4_BYTES(t
);
1034 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1036 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1038 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1040 s
[0] = (GLint
)(buf
/4 + 0.5);
1042 s
++; t
+= element_size
;
1051 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1052 const GLint
*dataIn
, GLint
*dataOut
,
1053 GLint element_size
, GLint ysize
,
1054 GLint group_size
, GLint myswap_bytes
)
1056 GLint halfWidth
= width
/ 2;
1057 GLint halfHeight
= height
/ 2;
1058 const char *src
= (const char *) dataIn
;
1059 GLint
*dest
= dataOut
;
1062 assert(width
== 1 || height
== 1); /* must be 1D */
1063 assert(width
!= height
); /* can't be square */
1065 if (height
== 1) { /* 1 row */
1066 assert(width
!= 1); /* widthxheight can't be 1x1 */
1069 for (jj
= 0; jj
< halfWidth
; jj
++) {
1071 for (kk
= 0; kk
< components
; kk
++) {
1075 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1076 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1079 uint
[0]= *(const GLuint
*)src
;
1080 uint
[1]= *(const GLuint
*)(src
+group_size
);
1082 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1087 src
+= group_size
; /* skip to next 2 */
1090 int padBytes
= ysize
- (width
*group_size
);
1091 src
+= padBytes
; /* for assertion only */
1094 else if (width
== 1) { /* 1 column */
1095 int padBytes
= ysize
- (width
* group_size
);
1096 assert(height
!= 1); /* widthxheight can't be 1x1 */
1098 /* one vertical column with possible pad bytes per row */
1099 /* average two at a time */
1101 for (jj
= 0; jj
< halfHeight
; jj
++) {
1103 for (kk
= 0; kk
< components
; kk
++) {
1107 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1108 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1111 uint
[0]= *(const GLuint
*)src
;
1112 uint
[1]= *(const GLuint
*)(src
+ysize
);
1114 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1119 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1123 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1126 assert((char *)dest
== &((char *)dataOut
)
1127 [components
* element_size
* halfWidth
* halfHeight
]);
1129 } /* halve1Dimage_int() */
1132 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1133 const GLfloat
*datain
, GLfloat
*dataout
,
1134 GLint element_size
, GLint ysize
, GLint group_size
,
1138 int newwidth
, newheight
;
1142 /* handle case where there is only 1 column/row */
1143 if (width
== 1 || height
== 1) {
1144 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1145 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1146 element_size
,ysize
,group_size
, myswap_bytes
);
1150 newwidth
= width
/ 2;
1151 newheight
= height
/ 2;
1153 t
= (const char *)datain
;
1155 /* Piece o' cake! */
1157 for (i
= 0; i
< newheight
; i
++) {
1158 for (j
= 0; j
< newwidth
; j
++) {
1159 for (k
= 0; k
< components
; k
++) {
1160 s
[0] = (*(const GLfloat
*)t
+
1161 *(const GLfloat
*)(t
+group_size
) +
1162 *(const GLfloat
*)(t
+ysize
) +
1163 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1164 s
++; t
+= element_size
;
1171 for (i
= 0; i
< newheight
; i
++) {
1172 for (j
= 0; j
< newwidth
; j
++) {
1173 for (k
= 0; k
< components
; k
++) {
1175 b
= __GLU_SWAP_4_BYTES(t
);
1176 s
[0] = *(GLfloat
*)&b
;
1177 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1178 s
[0] += *(GLfloat
*)&b
;
1179 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1180 s
[0] += *(GLfloat
*)&b
;
1181 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1182 s
[0] += *(GLfloat
*)&b
;
1184 s
++; t
+= element_size
;
1193 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1194 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1195 GLint element_size
, GLint ysize
,
1196 GLint group_size
, GLint myswap_bytes
)
1198 GLint halfWidth
= width
/ 2;
1199 GLint halfHeight
= height
/ 2;
1200 const char *src
= (const char *) dataIn
;
1201 GLfloat
*dest
= dataOut
;
1204 assert(width
== 1 || height
== 1); /* must be 1D */
1205 assert(width
!= height
); /* can't be square */
1207 if (height
== 1) { /* 1 row */
1208 assert(width
!= 1); /* widthxheight can't be 1x1 */
1211 for (jj
= 0; jj
< halfWidth
; jj
++) {
1213 for (kk
= 0; kk
< components
; kk
++) {
1215 GLfloat sfloat
[BOX2
];
1217 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1218 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1221 sfloat
[0]= *(const GLfloat
*)src
;
1222 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1225 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1229 src
+= group_size
; /* skip to next 2 */
1232 int padBytes
= ysize
- (width
*group_size
);
1233 src
+= padBytes
; /* for assertion only */
1236 else if (width
== 1) { /* 1 column */
1237 int padBytes
= ysize
- (width
* group_size
);
1238 assert(height
!= 1); /* widthxheight can't be 1x1 */
1240 /* one vertical column with possible pad bytes per row */
1241 /* average two at a time */
1243 for (jj
= 0; jj
< halfHeight
; jj
++) {
1245 for (kk
= 0; kk
< components
; kk
++) {
1247 GLfloat sfloat
[BOX2
];
1249 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1250 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1253 sfloat
[0]= *(const GLfloat
*)src
;
1254 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1256 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1261 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1262 src
+= ysize
; /* skip to odd row */
1266 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1267 assert((char *)dest
== &((char *)dataOut
)
1268 [components
* element_size
* halfWidth
* halfHeight
]);
1269 } /* halve1Dimage_float() */
1271 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1272 const GLushort
*datain
,
1273 GLint widthout
, GLint heightout
,
1276 float x
, lowx
, highx
, convx
, halfconvx
;
1277 float y
, lowy
, highy
, convy
, halfconvy
;
1278 float xpercent
,ypercent
;
1280 /* Max components in a format is 4, so... */
1283 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1286 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1287 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1290 convy
= (float) heightin
/heightout
;
1291 convx
= (float) widthin
/widthout
;
1292 halfconvx
= convx
/2;
1293 halfconvy
= convy
/2;
1294 for (i
= 0; i
< heightout
; i
++) {
1295 y
= convy
* (i
+0.5);
1296 if (heightin
> heightout
) {
1297 highy
= y
+ halfconvy
;
1298 lowy
= y
- halfconvy
;
1303 for (j
= 0; j
< widthout
; j
++) {
1304 x
= convx
* (j
+0.5);
1305 if (widthin
> widthout
) {
1306 highx
= x
+ halfconvx
;
1307 lowx
= x
- halfconvx
;
1314 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1315 ** to (highx, highy) on input data into this pixel on output
1318 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1324 yindex
= (yint
+ heightin
) % heightin
;
1325 if (highy
< yint
+1) {
1326 ypercent
= highy
- y
;
1328 ypercent
= yint
+1 - y
;
1335 xindex
= (xint
+ widthin
) % widthin
;
1336 if (highx
< xint
+1) {
1337 xpercent
= highx
- x
;
1339 xpercent
= xint
+1 - x
;
1342 percent
= xpercent
* ypercent
;
1344 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1345 for (k
= 0; k
< components
; k
++) {
1346 totals
[k
] += datain
[temp
+ k
] * percent
;
1356 temp
= (j
+ (i
* widthout
)) * components
;
1357 for (k
= 0; k
< components
; k
++) {
1358 /* totals[] should be rounded in the case of enlarging an RGB
1359 * ramp when the type is 332 or 4444
1361 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1367 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1368 GLint heightin
, const GLubyte
*datain
,
1369 GLint widthout
, GLint heightout
,
1370 GLubyte
*dataout
, GLint element_size
,
1371 GLint ysize
, GLint group_size
)
1376 /* Max components in a format is 4, so... */
1381 const char *temp
, *temp0
;
1382 const char *temp_index
;
1385 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1386 float x_percent
, y_percent
;
1387 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1388 float convy_float
, convx_float
;
1389 int convy_int
, convx_int
;
1391 const char *left
, *right
;
1393 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1394 halveImage_ubyte(components
, widthin
, heightin
,
1395 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1396 element_size
, ysize
, group_size
);
1399 convy
= (float) heightin
/heightout
;
1400 convx
= (float) widthin
/widthout
;
1401 convy_int
= floor(convy
);
1402 convy_float
= convy
- convy_int
;
1403 convx_int
= floor(convx
);
1404 convx_float
= convx
- convx_int
;
1406 area
= convx
* convy
;
1410 highy_int
= convy_int
;
1411 highy_float
= convy_float
;
1413 for (i
= 0; i
< heightout
; i
++) {
1416 highx_int
= convx_int
;
1417 highx_float
= convx_float
;
1419 for (j
= 0; j
< widthout
; j
++) {
1422 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1423 ** to (highx, highy) on input data into this pixel on output
1426 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1428 /* calculate the value for pixels in the 1st row */
1429 xindex
= lowx_int
*group_size
;
1430 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1432 y_percent
= 1-lowy_float
;
1433 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1434 percent
= y_percent
* (1-lowx_float
);
1435 for (k
= 0, temp_index
= temp
; k
< components
;
1436 k
++, temp_index
+= element_size
) {
1437 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1440 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1442 for (k
= 0, temp_index
= temp
; k
< components
;
1443 k
++, temp_index
+= element_size
) {
1444 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1449 percent
= y_percent
* highx_float
;
1450 for (k
= 0, temp_index
= temp
; k
< components
;
1451 k
++, temp_index
+= element_size
) {
1452 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1455 /* calculate the value for pixels in the last row */
1456 y_percent
= highy_float
;
1457 percent
= y_percent
* (1-lowx_float
);
1458 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1459 for (k
= 0, temp_index
= temp
; k
< components
;
1460 k
++, temp_index
+= element_size
) {
1461 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1463 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1465 for (k
= 0, temp_index
= temp
; k
< components
;
1466 k
++, temp_index
+= element_size
) {
1467 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1471 percent
= y_percent
* highx_float
;
1472 for (k
= 0, temp_index
= temp
; k
< components
;
1473 k
++, temp_index
+= element_size
) {
1474 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1478 /* calculate the value for pixels in the 1st and last column */
1479 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1482 for (k
= 0; k
< components
;
1483 k
++, left
+= element_size
, right
+= element_size
) {
1484 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1485 +(GLubyte
)(*(right
))*highx_float
;
1488 } else if (highy_int
> lowy_int
) {
1489 x_percent
= highx_float
- lowx_float
;
1490 percent
= (1-lowy_float
)*x_percent
;
1491 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1492 for (k
= 0, temp_index
= temp
; k
< components
;
1493 k
++, temp_index
+= element_size
) {
1494 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1496 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1498 for (k
= 0, temp_index
= temp
; k
< components
;
1499 k
++, temp_index
+= element_size
) {
1500 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1503 percent
= x_percent
* highy_float
;
1505 for (k
= 0, temp_index
= temp
; k
< components
;
1506 k
++, temp_index
+= element_size
) {
1507 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1509 } else if (highx_int
> lowx_int
) {
1510 y_percent
= highy_float
- lowy_float
;
1511 percent
= (1-lowx_float
)*y_percent
;
1512 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1513 for (k
= 0, temp_index
= temp
; k
< components
;
1514 k
++, temp_index
+= element_size
) {
1515 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1517 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1519 for (k
= 0, temp_index
= temp
; k
< components
;
1520 k
++, temp_index
+= element_size
) {
1521 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1525 percent
= y_percent
* highx_float
;
1526 for (k
= 0, temp_index
= temp
; k
< components
;
1527 k
++, temp_index
+= element_size
) {
1528 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1531 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1532 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1533 for (k
= 0, temp_index
= temp
; k
< components
;
1534 k
++, temp_index
+= element_size
) {
1535 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1541 /* this is for the pixels in the body */
1542 temp0
= (const char *)datain
+ xindex
+ group_size
+
1544 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1546 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1547 for (k
= 0, temp_index
= temp
; k
< components
;
1548 k
++, temp_index
+= element_size
) {
1549 totals
[k
] += (GLubyte
)(*(temp_index
));
1556 outindex
= (j
+ (i
* widthout
)) * components
;
1557 for (k
= 0; k
< components
; k
++) {
1558 dataout
[outindex
+ k
] = totals
[k
]/area
;
1559 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1561 lowx_int
= highx_int
;
1562 lowx_float
= highx_float
;
1563 highx_int
+= convx_int
;
1564 highx_float
+= convx_float
;
1565 if(highx_float
> 1) {
1570 lowy_int
= highy_int
;
1571 lowy_float
= highy_float
;
1572 highy_int
+= convy_int
;
1573 highy_float
+= convy_float
;
1574 if(highy_float
> 1) {
1581 static void scale_internal_byte(GLint components
, GLint widthin
,
1582 GLint heightin
, const GLbyte
*datain
,
1583 GLint widthout
, GLint heightout
,
1584 GLbyte
*dataout
, GLint element_size
,
1585 GLint ysize
, GLint group_size
)
1590 /* Max components in a format is 4, so... */
1595 const char *temp
, *temp0
;
1596 const char *temp_index
;
1599 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1600 float x_percent
, y_percent
;
1601 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1602 float convy_float
, convx_float
;
1603 int convy_int
, convx_int
;
1605 const char *left
, *right
;
1607 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1608 halveImage_byte(components
, widthin
, heightin
,
1609 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1610 element_size
, ysize
, group_size
);
1613 convy
= (float) heightin
/heightout
;
1614 convx
= (float) widthin
/widthout
;
1615 convy_int
= floor(convy
);
1616 convy_float
= convy
- convy_int
;
1617 convx_int
= floor(convx
);
1618 convx_float
= convx
- convx_int
;
1620 area
= convx
* convy
;
1624 highy_int
= convy_int
;
1625 highy_float
= convy_float
;
1627 for (i
= 0; i
< heightout
; i
++) {
1630 highx_int
= convx_int
;
1631 highx_float
= convx_float
;
1633 for (j
= 0; j
< widthout
; j
++) {
1636 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1637 ** to (highx, highy) on input data into this pixel on output
1640 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1642 /* calculate the value for pixels in the 1st row */
1643 xindex
= lowx_int
*group_size
;
1644 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1646 y_percent
= 1-lowy_float
;
1647 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1648 percent
= y_percent
* (1-lowx_float
);
1649 for (k
= 0, temp_index
= temp
; k
< components
;
1650 k
++, temp_index
+= element_size
) {
1651 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1654 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1656 for (k
= 0, temp_index
= temp
; k
< components
;
1657 k
++, temp_index
+= element_size
) {
1658 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1663 percent
= y_percent
* highx_float
;
1664 for (k
= 0, temp_index
= temp
; k
< components
;
1665 k
++, temp_index
+= element_size
) {
1666 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1669 /* calculate the value for pixels in the last row */
1670 y_percent
= highy_float
;
1671 percent
= y_percent
* (1-lowx_float
);
1672 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1673 for (k
= 0, temp_index
= temp
; k
< components
;
1674 k
++, temp_index
+= element_size
) {
1675 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1677 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1679 for (k
= 0, temp_index
= temp
; k
< components
;
1680 k
++, temp_index
+= element_size
) {
1681 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1685 percent
= y_percent
* highx_float
;
1686 for (k
= 0, temp_index
= temp
; k
< components
;
1687 k
++, temp_index
+= element_size
) {
1688 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1692 /* calculate the value for pixels in the 1st and last column */
1693 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1696 for (k
= 0; k
< components
;
1697 k
++, left
+= element_size
, right
+= element_size
) {
1698 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1699 +(GLbyte
)(*(right
))*highx_float
;
1702 } else if (highy_int
> lowy_int
) {
1703 x_percent
= highx_float
- lowx_float
;
1704 percent
= (1-lowy_float
)*x_percent
;
1705 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1706 for (k
= 0, temp_index
= temp
; k
< components
;
1707 k
++, temp_index
+= element_size
) {
1708 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1710 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1712 for (k
= 0, temp_index
= temp
; k
< components
;
1713 k
++, temp_index
+= element_size
) {
1714 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1717 percent
= x_percent
* highy_float
;
1719 for (k
= 0, temp_index
= temp
; k
< components
;
1720 k
++, temp_index
+= element_size
) {
1721 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1723 } else if (highx_int
> lowx_int
) {
1724 y_percent
= highy_float
- lowy_float
;
1725 percent
= (1-lowx_float
)*y_percent
;
1726 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1727 for (k
= 0, temp_index
= temp
; k
< components
;
1728 k
++, temp_index
+= element_size
) {
1729 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1731 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1733 for (k
= 0, temp_index
= temp
; k
< components
;
1734 k
++, temp_index
+= element_size
) {
1735 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1739 percent
= y_percent
* highx_float
;
1740 for (k
= 0, temp_index
= temp
; k
< components
;
1741 k
++, temp_index
+= element_size
) {
1742 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1745 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1746 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1747 for (k
= 0, temp_index
= temp
; k
< components
;
1748 k
++, temp_index
+= element_size
) {
1749 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1755 /* this is for the pixels in the body */
1756 temp0
= (const char *)datain
+ xindex
+ group_size
+
1758 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1760 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1761 for (k
= 0, temp_index
= temp
; k
< components
;
1762 k
++, temp_index
+= element_size
) {
1763 totals
[k
] += (GLbyte
)(*(temp_index
));
1770 outindex
= (j
+ (i
* widthout
)) * components
;
1771 for (k
= 0; k
< components
; k
++) {
1772 dataout
[outindex
+ k
] = totals
[k
]/area
;
1773 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1775 lowx_int
= highx_int
;
1776 lowx_float
= highx_float
;
1777 highx_int
+= convx_int
;
1778 highx_float
+= convx_float
;
1779 if(highx_float
> 1) {
1784 lowy_int
= highy_int
;
1785 lowy_float
= highy_float
;
1786 highy_int
+= convy_int
;
1787 highy_float
+= convy_float
;
1788 if(highy_float
> 1) {
1795 static void scale_internal_ushort(GLint components
, GLint widthin
,
1796 GLint heightin
, const GLushort
*datain
,
1797 GLint widthout
, GLint heightout
,
1798 GLushort
*dataout
, GLint element_size
,
1799 GLint ysize
, GLint group_size
,
1805 /* Max components in a format is 4, so... */
1810 const char *temp
, *temp0
;
1811 const char *temp_index
;
1814 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1815 float x_percent
, y_percent
;
1816 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1817 float convy_float
, convx_float
;
1818 int convy_int
, convx_int
;
1820 const char *left
, *right
;
1822 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1823 halveImage_ushort(components
, widthin
, heightin
,
1824 (const GLushort
*)datain
, (GLushort
*)dataout
,
1825 element_size
, ysize
, group_size
, myswap_bytes
);
1828 convy
= (float) heightin
/heightout
;
1829 convx
= (float) widthin
/widthout
;
1830 convy_int
= floor(convy
);
1831 convy_float
= convy
- convy_int
;
1832 convx_int
= floor(convx
);
1833 convx_float
= convx
- convx_int
;
1835 area
= convx
* convy
;
1839 highy_int
= convy_int
;
1840 highy_float
= convy_float
;
1842 for (i
= 0; i
< heightout
; i
++) {
1845 highx_int
= convx_int
;
1846 highx_float
= convx_float
;
1848 for (j
= 0; j
< widthout
; j
++) {
1850 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1851 ** to (highx, highy) on input data into this pixel on output
1854 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1856 /* calculate the value for pixels in the 1st row */
1857 xindex
= lowx_int
*group_size
;
1858 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1860 y_percent
= 1-lowy_float
;
1861 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1862 percent
= y_percent
* (1-lowx_float
);
1863 for (k
= 0, temp_index
= temp
; k
< components
;
1864 k
++, temp_index
+= element_size
) {
1866 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1868 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1872 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1874 for (k
= 0, temp_index
= temp
; k
< components
;
1875 k
++, temp_index
+= element_size
) {
1878 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1880 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1886 percent
= y_percent
* highx_float
;
1887 for (k
= 0, temp_index
= temp
; k
< components
;
1888 k
++, temp_index
+= element_size
) {
1890 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1892 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1896 /* calculate the value for pixels in the last row */
1897 y_percent
= highy_float
;
1898 percent
= y_percent
* (1-lowx_float
);
1899 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1900 for (k
= 0, temp_index
= temp
; k
< components
;
1901 k
++, temp_index
+= element_size
) {
1903 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1905 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1908 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1910 for (k
= 0, temp_index
= temp
; k
< components
;
1911 k
++, temp_index
+= element_size
) {
1914 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1916 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1921 percent
= y_percent
* highx_float
;
1922 for (k
= 0, temp_index
= temp
; k
< components
;
1923 k
++, temp_index
+= element_size
) {
1925 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1927 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1931 /* calculate the value for pixels in the 1st and last column */
1932 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1935 for (k
= 0; k
< components
;
1936 k
++, left
+= element_size
, right
+= element_size
) {
1939 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1940 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1942 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1943 + *(const GLushort
*)right
* highx_float
;
1947 } else if (highy_int
> lowy_int
) {
1948 x_percent
= highx_float
- lowx_float
;
1949 percent
= (1-lowy_float
)*x_percent
;
1950 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1951 for (k
= 0, temp_index
= temp
; k
< components
;
1952 k
++, temp_index
+= element_size
) {
1954 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1956 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1959 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1961 for (k
= 0, temp_index
= temp
; k
< components
;
1962 k
++, temp_index
+= element_size
) {
1965 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
1967 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
1971 percent
= x_percent
* highy_float
;
1973 for (k
= 0, temp_index
= temp
; k
< components
;
1974 k
++, temp_index
+= element_size
) {
1976 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1978 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1981 } else if (highx_int
> lowx_int
) {
1982 y_percent
= highy_float
- lowy_float
;
1983 percent
= (1-lowx_float
)*y_percent
;
1984 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1985 for (k
= 0, temp_index
= temp
; k
< components
;
1986 k
++, temp_index
+= element_size
) {
1988 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1990 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1993 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1995 for (k
= 0, temp_index
= temp
; k
< components
;
1996 k
++, temp_index
+= element_size
) {
1999 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2001 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2006 percent
= y_percent
* highx_float
;
2007 for (k
= 0, temp_index
= temp
; k
< components
;
2008 k
++, temp_index
+= element_size
) {
2010 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2012 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2016 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2017 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2018 for (k
= 0, temp_index
= temp
; k
< components
;
2019 k
++, temp_index
+= element_size
) {
2021 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2023 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2028 /* this is for the pixels in the body */
2029 temp0
= (const char *)datain
+ xindex
+ group_size
+
2031 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2033 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2034 for (k
= 0, temp_index
= temp
; k
< components
;
2035 k
++, temp_index
+= element_size
) {
2037 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2039 totals
[k
] += *(const GLushort
*)temp_index
;
2047 outindex
= (j
+ (i
* widthout
)) * components
;
2048 for (k
= 0; k
< components
; k
++) {
2049 dataout
[outindex
+ k
] = totals
[k
]/area
;
2050 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2052 lowx_int
= highx_int
;
2053 lowx_float
= highx_float
;
2054 highx_int
+= convx_int
;
2055 highx_float
+= convx_float
;
2056 if(highx_float
> 1) {
2061 lowy_int
= highy_int
;
2062 lowy_float
= highy_float
;
2063 highy_int
+= convy_int
;
2064 highy_float
+= convy_float
;
2065 if(highy_float
> 1) {
2072 static void scale_internal_short(GLint components
, GLint widthin
,
2073 GLint heightin
, const GLshort
*datain
,
2074 GLint widthout
, GLint heightout
,
2075 GLshort
*dataout
, GLint element_size
,
2076 GLint ysize
, GLint group_size
,
2082 /* Max components in a format is 4, so... */
2087 const char *temp
, *temp0
;
2088 const char *temp_index
;
2091 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2092 float x_percent
, y_percent
;
2093 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2094 float convy_float
, convx_float
;
2095 int convy_int
, convx_int
;
2097 const char *left
, *right
;
2099 GLushort swapbuf
; /* unsigned buffer */
2101 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2102 halveImage_short(components
, widthin
, heightin
,
2103 (const GLshort
*)datain
, (GLshort
*)dataout
,
2104 element_size
, ysize
, group_size
, myswap_bytes
);
2107 convy
= (float) heightin
/heightout
;
2108 convx
= (float) widthin
/widthout
;
2109 convy_int
= floor(convy
);
2110 convy_float
= convy
- convy_int
;
2111 convx_int
= floor(convx
);
2112 convx_float
= convx
- convx_int
;
2114 area
= convx
* convy
;
2118 highy_int
= convy_int
;
2119 highy_float
= convy_float
;
2121 for (i
= 0; i
< heightout
; i
++) {
2124 highx_int
= convx_int
;
2125 highx_float
= convx_float
;
2127 for (j
= 0; j
< widthout
; j
++) {
2129 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2130 ** to (highx, highy) on input data into this pixel on output
2133 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2135 /* calculate the value for pixels in the 1st row */
2136 xindex
= lowx_int
*group_size
;
2137 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2139 y_percent
= 1-lowy_float
;
2140 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2141 percent
= y_percent
* (1-lowx_float
);
2142 for (k
= 0, temp_index
= temp
; k
< components
;
2143 k
++, temp_index
+= element_size
) {
2145 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2146 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2148 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2152 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2154 for (k
= 0, temp_index
= temp
; k
< components
;
2155 k
++, temp_index
+= element_size
) {
2157 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2158 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2160 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2166 percent
= y_percent
* highx_float
;
2167 for (k
= 0, temp_index
= temp
; k
< components
;
2168 k
++, temp_index
+= element_size
) {
2170 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2171 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2173 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2177 /* calculate the value for pixels in the last row */
2178 y_percent
= highy_float
;
2179 percent
= y_percent
* (1-lowx_float
);
2180 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2181 for (k
= 0, temp_index
= temp
; k
< components
;
2182 k
++, temp_index
+= element_size
) {
2184 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2185 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2187 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2190 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2192 for (k
= 0, temp_index
= temp
; k
< components
;
2193 k
++, temp_index
+= element_size
) {
2195 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2196 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2198 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2203 percent
= y_percent
* highx_float
;
2204 for (k
= 0, temp_index
= temp
; k
< components
;
2205 k
++, temp_index
+= element_size
) {
2207 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2208 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2210 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2214 /* calculate the value for pixels in the 1st and last column */
2215 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2218 for (k
= 0; k
< components
;
2219 k
++, left
+= element_size
, right
+= element_size
) {
2221 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2222 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2223 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2224 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2226 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2227 + *(const GLshort
*)right
* highx_float
;
2231 } else if (highy_int
> lowy_int
) {
2232 x_percent
= highx_float
- lowx_float
;
2233 percent
= (1-lowy_float
)*x_percent
;
2234 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2235 for (k
= 0, temp_index
= temp
; k
< components
;
2236 k
++, temp_index
+= element_size
) {
2238 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2239 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2241 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2244 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2246 for (k
= 0, temp_index
= temp
; k
< components
;
2247 k
++, temp_index
+= element_size
) {
2249 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2250 totals
[k
] += *(const GLshort
*)&swapbuf
* x_percent
;
2252 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2256 percent
= x_percent
* highy_float
;
2258 for (k
= 0, temp_index
= temp
; k
< components
;
2259 k
++, temp_index
+= element_size
) {
2261 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2262 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2264 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2267 } else if (highx_int
> lowx_int
) {
2268 y_percent
= highy_float
- lowy_float
;
2269 percent
= (1-lowx_float
)*y_percent
;
2271 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2272 for (k
= 0, temp_index
= temp
; k
< components
;
2273 k
++, temp_index
+= element_size
) {
2275 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2276 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2278 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2281 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2283 for (k
= 0, temp_index
= temp
; k
< components
;
2284 k
++, temp_index
+= element_size
) {
2286 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2287 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2289 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2294 percent
= y_percent
* highx_float
;
2295 for (k
= 0, temp_index
= temp
; k
< components
;
2296 k
++, temp_index
+= element_size
) {
2298 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2299 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2301 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2305 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2306 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2307 for (k
= 0, temp_index
= temp
; k
< components
;
2308 k
++, temp_index
+= element_size
) {
2310 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2311 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2313 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2318 /* this is for the pixels in the body */
2319 temp0
= (const char *)datain
+ xindex
+ group_size
+
2321 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2323 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2324 for (k
= 0, temp_index
= temp
; k
< components
;
2325 k
++, temp_index
+= element_size
) {
2327 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2328 totals
[k
] += *(const GLshort
*)&swapbuf
;
2330 totals
[k
] += *(const GLshort
*)temp_index
;
2338 outindex
= (j
+ (i
* widthout
)) * components
;
2339 for (k
= 0; k
< components
; k
++) {
2340 dataout
[outindex
+ k
] = totals
[k
]/area
;
2341 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2343 lowx_int
= highx_int
;
2344 lowx_float
= highx_float
;
2345 highx_int
+= convx_int
;
2346 highx_float
+= convx_float
;
2347 if(highx_float
> 1) {
2352 lowy_int
= highy_int
;
2353 lowy_float
= highy_float
;
2354 highy_int
+= convy_int
;
2355 highy_float
+= convy_float
;
2356 if(highy_float
> 1) {
2363 static void scale_internal_uint(GLint components
, GLint widthin
,
2364 GLint heightin
, const GLuint
*datain
,
2365 GLint widthout
, GLint heightout
,
2366 GLuint
*dataout
, GLint element_size
,
2367 GLint ysize
, GLint group_size
,
2373 /* Max components in a format is 4, so... */
2378 const char *temp
, *temp0
;
2379 const char *temp_index
;
2382 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2383 float x_percent
, y_percent
;
2384 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2385 float convy_float
, convx_float
;
2386 int convy_int
, convx_int
;
2388 const char *left
, *right
;
2390 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2391 halveImage_uint(components
, widthin
, heightin
,
2392 (const GLuint
*)datain
, (GLuint
*)dataout
,
2393 element_size
, ysize
, group_size
, myswap_bytes
);
2396 convy
= (float) heightin
/heightout
;
2397 convx
= (float) widthin
/widthout
;
2398 convy_int
= floor(convy
);
2399 convy_float
= convy
- convy_int
;
2400 convx_int
= floor(convx
);
2401 convx_float
= convx
- convx_int
;
2403 area
= convx
* convy
;
2407 highy_int
= convy_int
;
2408 highy_float
= convy_float
;
2410 for (i
= 0; i
< heightout
; i
++) {
2413 highx_int
= convx_int
;
2414 highx_float
= convx_float
;
2416 for (j
= 0; j
< widthout
; j
++) {
2418 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2419 ** to (highx, highy) on input data into this pixel on output
2422 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2424 /* calculate the value for pixels in the 1st row */
2425 xindex
= lowx_int
*group_size
;
2426 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2428 y_percent
= 1-lowy_float
;
2429 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2430 percent
= y_percent
* (1-lowx_float
);
2431 for (k
= 0, temp_index
= temp
; k
< components
;
2432 k
++, temp_index
+= element_size
) {
2434 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2436 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2440 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2442 for (k
= 0, temp_index
= temp
; k
< components
;
2443 k
++, temp_index
+= element_size
) {
2446 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2448 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2454 percent
= y_percent
* highx_float
;
2455 for (k
= 0, temp_index
= temp
; k
< components
;
2456 k
++, temp_index
+= element_size
) {
2458 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2460 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2464 /* calculate the value for pixels in the last row */
2465 y_percent
= highy_float
;
2466 percent
= y_percent
* (1-lowx_float
);
2467 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2468 for (k
= 0, temp_index
= temp
; k
< components
;
2469 k
++, temp_index
+= element_size
) {
2471 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2473 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2476 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2478 for (k
= 0, temp_index
= temp
; k
< components
;
2479 k
++, temp_index
+= element_size
) {
2482 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2484 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2489 percent
= y_percent
* highx_float
;
2490 for (k
= 0, temp_index
= temp
; k
< components
;
2491 k
++, temp_index
+= element_size
) {
2493 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2495 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2499 /* calculate the value for pixels in the 1st and last column */
2500 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2503 for (k
= 0; k
< components
;
2504 k
++, left
+= element_size
, right
+= element_size
) {
2507 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2508 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2510 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2511 + *(const GLuint
*)right
* highx_float
;
2515 } else if (highy_int
> lowy_int
) {
2516 x_percent
= highx_float
- lowx_float
;
2517 percent
= (1-lowy_float
)*x_percent
;
2518 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2519 for (k
= 0, temp_index
= temp
; k
< components
;
2520 k
++, temp_index
+= element_size
) {
2522 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2524 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2527 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2529 for (k
= 0, temp_index
= temp
; k
< components
;
2530 k
++, temp_index
+= element_size
) {
2533 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2535 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2539 percent
= x_percent
* highy_float
;
2541 for (k
= 0, temp_index
= temp
; k
< components
;
2542 k
++, temp_index
+= element_size
) {
2544 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2546 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2549 } else if (highx_int
> lowx_int
) {
2550 y_percent
= highy_float
- lowy_float
;
2551 percent
= (1-lowx_float
)*y_percent
;
2553 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2554 for (k
= 0, temp_index
= temp
; k
< components
;
2555 k
++, temp_index
+= element_size
) {
2557 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2559 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2562 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2564 for (k
= 0, temp_index
= temp
; k
< components
;
2565 k
++, temp_index
+= element_size
) {
2568 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2570 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2575 percent
= y_percent
* highx_float
;
2576 for (k
= 0, temp_index
= temp
; k
< components
;
2577 k
++, temp_index
+= element_size
) {
2579 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2581 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2585 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2586 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2587 for (k
= 0, temp_index
= temp
; k
< components
;
2588 k
++, temp_index
+= element_size
) {
2590 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2592 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2597 /* this is for the pixels in the body */
2598 temp0
= (const char *)datain
+ xindex
+ group_size
+
2600 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2602 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2603 for (k
= 0, temp_index
= temp
; k
< components
;
2604 k
++, temp_index
+= element_size
) {
2606 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2608 totals
[k
] += *(const GLuint
*)temp_index
;
2616 outindex
= (j
+ (i
* widthout
)) * components
;
2617 for (k
= 0; k
< components
; k
++) {
2618 /* clamp at UINT_MAX */
2619 float value
= totals
[k
]/area
;
2620 if (value
>= (float) UINT_MAX
) { /* need '=' */
2621 dataout
[outindex
+ k
] = UINT_MAX
;
2623 else dataout
[outindex
+ k
] = value
;
2625 lowx_int
= highx_int
;
2626 lowx_float
= highx_float
;
2627 highx_int
+= convx_int
;
2628 highx_float
+= convx_float
;
2629 if(highx_float
> 1) {
2634 lowy_int
= highy_int
;
2635 lowy_float
= highy_float
;
2636 highy_int
+= convy_int
;
2637 highy_float
+= convy_float
;
2638 if(highy_float
> 1) {
2647 static void scale_internal_int(GLint components
, GLint widthin
,
2648 GLint heightin
, const GLint
*datain
,
2649 GLint widthout
, GLint heightout
,
2650 GLint
*dataout
, GLint element_size
,
2651 GLint ysize
, GLint group_size
,
2657 /* Max components in a format is 4, so... */
2662 const char *temp
, *temp0
;
2663 const char *temp_index
;
2666 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2667 float x_percent
, y_percent
;
2668 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2669 float convy_float
, convx_float
;
2670 int convy_int
, convx_int
;
2672 const char *left
, *right
;
2674 GLuint swapbuf
; /* unsigned buffer */
2676 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2677 halveImage_int(components
, widthin
, heightin
,
2678 (const GLint
*)datain
, (GLint
*)dataout
,
2679 element_size
, ysize
, group_size
, myswap_bytes
);
2682 convy
= (float) heightin
/heightout
;
2683 convx
= (float) widthin
/widthout
;
2684 convy_int
= floor(convy
);
2685 convy_float
= convy
- convy_int
;
2686 convx_int
= floor(convx
);
2687 convx_float
= convx
- convx_int
;
2689 area
= convx
* convy
;
2693 highy_int
= convy_int
;
2694 highy_float
= convy_float
;
2696 for (i
= 0; i
< heightout
; i
++) {
2699 highx_int
= convx_int
;
2700 highx_float
= convx_float
;
2702 for (j
= 0; j
< widthout
; j
++) {
2704 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2705 ** to (highx, highy) on input data into this pixel on output
2708 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2710 /* calculate the value for pixels in the 1st row */
2711 xindex
= lowx_int
*group_size
;
2712 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2714 y_percent
= 1-lowy_float
;
2715 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2716 percent
= y_percent
* (1-lowx_float
);
2717 for (k
= 0, temp_index
= temp
; k
< components
;
2718 k
++, temp_index
+= element_size
) {
2720 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2721 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2723 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2727 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2729 for (k
= 0, temp_index
= temp
; k
< components
;
2730 k
++, temp_index
+= element_size
) {
2732 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2733 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2735 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2741 percent
= y_percent
* highx_float
;
2742 for (k
= 0, temp_index
= temp
; k
< components
;
2743 k
++, temp_index
+= element_size
) {
2745 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2746 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2748 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2752 /* calculate the value for pixels in the last row */
2753 y_percent
= highy_float
;
2754 percent
= y_percent
* (1-lowx_float
);
2755 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2756 for (k
= 0, temp_index
= temp
; k
< components
;
2757 k
++, temp_index
+= element_size
) {
2759 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2760 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2762 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2765 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2767 for (k
= 0, temp_index
= temp
; k
< components
;
2768 k
++, temp_index
+= element_size
) {
2770 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2771 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2773 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2778 percent
= y_percent
* highx_float
;
2779 for (k
= 0, temp_index
= temp
; k
< components
;
2780 k
++, temp_index
+= element_size
) {
2782 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2783 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2785 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2789 /* calculate the value for pixels in the 1st and last column */
2790 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2793 for (k
= 0; k
< components
;
2794 k
++, left
+= element_size
, right
+= element_size
) {
2796 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2797 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2798 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2799 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2801 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2802 + *(const GLint
*)right
* highx_float
;
2806 } else if (highy_int
> lowy_int
) {
2807 x_percent
= highx_float
- lowx_float
;
2808 percent
= (1-lowy_float
)*x_percent
;
2809 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2810 for (k
= 0, temp_index
= temp
; k
< components
;
2811 k
++, temp_index
+= element_size
) {
2813 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2814 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2816 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2819 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2821 for (k
= 0, temp_index
= temp
; k
< components
;
2822 k
++, temp_index
+= element_size
) {
2824 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2825 totals
[k
] += *(const GLint
*)&swapbuf
* x_percent
;
2827 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2831 percent
= x_percent
* highy_float
;
2833 for (k
= 0, temp_index
= temp
; k
< components
;
2834 k
++, temp_index
+= element_size
) {
2836 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2837 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2839 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2842 } else if (highx_int
> lowx_int
) {
2843 y_percent
= highy_float
- lowy_float
;
2844 percent
= (1-lowx_float
)*y_percent
;
2846 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2847 for (k
= 0, temp_index
= temp
; k
< components
;
2848 k
++, temp_index
+= element_size
) {
2850 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2851 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2853 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2856 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2858 for (k
= 0, temp_index
= temp
; k
< components
;
2859 k
++, temp_index
+= element_size
) {
2861 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2862 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2864 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2869 percent
= y_percent
* highx_float
;
2870 for (k
= 0, temp_index
= temp
; k
< components
;
2871 k
++, temp_index
+= element_size
) {
2873 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2874 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2876 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2880 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2881 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2882 for (k
= 0, temp_index
= temp
; k
< components
;
2883 k
++, temp_index
+= element_size
) {
2885 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2886 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2888 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2893 /* this is for the pixels in the body */
2894 temp0
= (const char *)datain
+ xindex
+ group_size
+
2896 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2898 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2899 for (k
= 0, temp_index
= temp
; k
< components
;
2900 k
++, temp_index
+= element_size
) {
2902 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2903 totals
[k
] += *(const GLint
*)&swapbuf
;
2905 totals
[k
] += *(const GLint
*)temp_index
;
2913 outindex
= (j
+ (i
* widthout
)) * components
;
2914 for (k
= 0; k
< components
; k
++) {
2915 dataout
[outindex
+ k
] = totals
[k
]/area
;
2916 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2918 lowx_int
= highx_int
;
2919 lowx_float
= highx_float
;
2920 highx_int
+= convx_int
;
2921 highx_float
+= convx_float
;
2922 if(highx_float
> 1) {
2927 lowy_int
= highy_int
;
2928 lowy_float
= highy_float
;
2929 highy_int
+= convy_int
;
2930 highy_float
+= convy_float
;
2931 if(highy_float
> 1) {
2940 static void scale_internal_float(GLint components
, GLint widthin
,
2941 GLint heightin
, const GLfloat
*datain
,
2942 GLint widthout
, GLint heightout
,
2943 GLfloat
*dataout
, GLint element_size
,
2944 GLint ysize
, GLint group_size
,
2950 /* Max components in a format is 4, so... */
2955 const char *temp
, *temp0
;
2956 const char *temp_index
;
2959 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2960 float x_percent
, y_percent
;
2961 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2962 float convy_float
, convx_float
;
2963 int convy_int
, convx_int
;
2965 const char *left
, *right
;
2967 GLuint swapbuf
; /* unsigned buffer */
2969 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2970 halveImage_float(components
, widthin
, heightin
,
2971 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
2972 element_size
, ysize
, group_size
, myswap_bytes
);
2975 convy
= (float) heightin
/heightout
;
2976 convx
= (float) widthin
/widthout
;
2977 convy_int
= floor(convy
);
2978 convy_float
= convy
- convy_int
;
2979 convx_int
= floor(convx
);
2980 convx_float
= convx
- convx_int
;
2982 area
= convx
* convy
;
2986 highy_int
= convy_int
;
2987 highy_float
= convy_float
;
2989 for (i
= 0; i
< heightout
; i
++) {
2992 highx_int
= convx_int
;
2993 highx_float
= convx_float
;
2995 for (j
= 0; j
< widthout
; j
++) {
2997 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2998 ** to (highx, highy) on input data into this pixel on output
3001 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3003 /* calculate the value for pixels in the 1st row */
3004 xindex
= lowx_int
*group_size
;
3005 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3007 y_percent
= 1-lowy_float
;
3008 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3009 percent
= y_percent
* (1-lowx_float
);
3010 for (k
= 0, temp_index
= temp
; k
< components
;
3011 k
++, temp_index
+= element_size
) {
3013 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3014 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3016 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3020 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3022 for (k
= 0, temp_index
= temp
; k
< components
;
3023 k
++, temp_index
+= element_size
) {
3025 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3026 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3028 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3034 percent
= y_percent
* highx_float
;
3035 for (k
= 0, temp_index
= temp
; k
< components
;
3036 k
++, temp_index
+= element_size
) {
3038 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3039 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3041 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3045 /* calculate the value for pixels in the last row */
3046 y_percent
= highy_float
;
3047 percent
= y_percent
* (1-lowx_float
);
3048 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3049 for (k
= 0, temp_index
= temp
; k
< components
;
3050 k
++, temp_index
+= element_size
) {
3052 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3053 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3055 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3058 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3060 for (k
= 0, temp_index
= temp
; k
< components
;
3061 k
++, temp_index
+= element_size
) {
3063 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3064 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3066 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3071 percent
= y_percent
* highx_float
;
3072 for (k
= 0, temp_index
= temp
; k
< components
;
3073 k
++, temp_index
+= element_size
) {
3075 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3076 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3078 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3082 /* calculate the value for pixels in the 1st and last column */
3083 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3086 for (k
= 0; k
< components
;
3087 k
++, left
+= element_size
, right
+= element_size
) {
3089 swapbuf
= __GLU_SWAP_4_BYTES(left
);
3090 totals
[k
] += *(const GLfloat
*)&swapbuf
* (1-lowx_float
);
3091 swapbuf
= __GLU_SWAP_4_BYTES(right
);
3092 totals
[k
] += *(const GLfloat
*)&swapbuf
* highx_float
;
3094 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3095 + *(const GLfloat
*)right
* highx_float
;
3099 } else if (highy_int
> lowy_int
) {
3100 x_percent
= highx_float
- lowx_float
;
3101 percent
= (1-lowy_float
)*x_percent
;
3102 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3103 for (k
= 0, temp_index
= temp
; k
< components
;
3104 k
++, temp_index
+= element_size
) {
3106 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3107 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3109 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3112 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3114 for (k
= 0, temp_index
= temp
; k
< components
;
3115 k
++, temp_index
+= element_size
) {
3117 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3118 totals
[k
] += *(const GLfloat
*)&swapbuf
* x_percent
;
3120 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3124 percent
= x_percent
* highy_float
;
3126 for (k
= 0, temp_index
= temp
; k
< components
;
3127 k
++, temp_index
+= element_size
) {
3129 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3130 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3132 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3135 } else if (highx_int
> lowx_int
) {
3136 y_percent
= highy_float
- lowy_float
;
3137 percent
= (1-lowx_float
)*y_percent
;
3139 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3140 for (k
= 0, temp_index
= temp
; k
< components
;
3141 k
++, temp_index
+= element_size
) {
3143 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3144 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3146 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3149 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3151 for (k
= 0, temp_index
= temp
; k
< components
;
3152 k
++, temp_index
+= element_size
) {
3154 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3155 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3157 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3162 percent
= y_percent
* highx_float
;
3163 for (k
= 0, temp_index
= temp
; k
< components
;
3164 k
++, temp_index
+= element_size
) {
3166 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3167 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3169 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3173 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3174 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3175 for (k
= 0, temp_index
= temp
; k
< components
;
3176 k
++, temp_index
+= element_size
) {
3178 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3179 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3181 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3186 /* this is for the pixels in the body */
3187 temp0
= (const char *)datain
+ xindex
+ group_size
+
3189 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3191 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3192 for (k
= 0, temp_index
= temp
; k
< components
;
3193 k
++, temp_index
+= element_size
) {
3195 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3196 totals
[k
] += *(const GLfloat
*)&swapbuf
;
3198 totals
[k
] += *(const GLfloat
*)temp_index
;
3206 outindex
= (j
+ (i
* widthout
)) * components
;
3207 for (k
= 0; k
< components
; k
++) {
3208 dataout
[outindex
+ k
] = totals
[k
]/area
;
3209 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3211 lowx_int
= highx_int
;
3212 lowx_float
= highx_float
;
3213 highx_int
+= convx_int
;
3214 highx_float
+= convx_float
;
3215 if(highx_float
> 1) {
3220 lowy_int
= highy_int
;
3221 lowy_float
= highy_float
;
3222 highy_int
+= convy_int
;
3223 highy_float
+= convy_float
;
3224 if(highy_float
> 1) {
3231 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3233 if (!legalFormat(format
) || !legalType(type
)) {
3234 return GLU_INVALID_ENUM
;
3236 if (format
== GL_STENCIL_INDEX
) {
3237 return GLU_INVALID_ENUM
;
3240 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3241 return GLU_INVALID_OPERATION
;
3245 } /* checkMipmapArgs() */
3247 static GLboolean
legalFormat(GLenum format
)
3250 case GL_COLOR_INDEX
:
3251 case GL_STENCIL_INDEX
:
3252 case GL_DEPTH_COMPONENT
:
3260 case GL_LUMINANCE_ALPHA
:
3270 static GLboolean
legalType(GLenum type
)
3275 case GL_UNSIGNED_BYTE
:
3277 case GL_UNSIGNED_SHORT
:
3279 case GL_UNSIGNED_INT
:
3281 case GL_UNSIGNED_BYTE_3_3_2
:
3282 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3283 case GL_UNSIGNED_SHORT_5_6_5
:
3284 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3285 case GL_UNSIGNED_SHORT_4_4_4_4
:
3286 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3287 case GL_UNSIGNED_SHORT_5_5_5_1
:
3288 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3289 case GL_UNSIGNED_INT_8_8_8_8
:
3290 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3291 case GL_UNSIGNED_INT_10_10_10_2
:
3292 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3300 static GLboolean
isTypePackedPixel(GLenum type
)
3302 assert(legalType(type
));
3304 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3305 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3306 type
== GL_UNSIGNED_SHORT_5_6_5
||
3307 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3308 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3309 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3310 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3311 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3312 type
== GL_UNSIGNED_INT_8_8_8_8
||
3313 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3314 type
== GL_UNSIGNED_INT_10_10_10_2
||
3315 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3319 } /* isTypePackedPixel() */
3321 /* Determines if the packed pixel type is compatible with the format */
3322 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3324 /* if not a packed pixel type then return true */
3325 if (!isTypePackedPixel(type
)) {
3329 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3330 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3331 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3332 && format
!= GL_RGB
)
3335 /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
3336 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3338 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3339 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3340 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3341 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3342 type
== GL_UNSIGNED_INT_8_8_8_8
||
3343 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3344 type
== GL_UNSIGNED_INT_10_10_10_2
||
3345 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3346 (format
!= GL_RGBA
&&
3347 format
!= GL_BGRA
)) {
3352 } /* isLegalFormatForPackedPixelType() */
3354 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3357 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3358 totalLevels
< maxLevel
)
3360 else return GL_TRUE
;
3361 } /* isLegalLevels() */
3363 /* Given user requested texture size, determine if it fits. If it
3364 * doesn't then halve both sides and make the determination again
3365 * until it does fit (for IR only).
3366 * Note that proxy textures are not implemented in RE* even though
3367 * they advertise the texture extension.
3368 * Note that proxy textures are implemented but not according to spec in
3371 static void closestFit(GLenum target
, GLint width
, GLint height
,
3372 GLint internalFormat
, GLenum format
, GLenum type
,
3373 GLint
*newWidth
, GLint
*newHeight
)
3375 /* Use proxy textures if OpenGL version is >= 1.1 */
3376 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3378 GLint widthPowerOf2
= nearestPower(width
);
3379 GLint heightPowerOf2
= nearestPower(height
);
3383 /* compute level 1 width & height, clamping each at 1 */
3384 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3385 widthPowerOf2
>> 1 :
3387 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3388 heightPowerOf2
>> 1 :
3391 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3393 /* does width x height at level 1 & all their mipmaps fit? */
3394 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3395 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3396 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3398 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3400 #if defined(GL_ARB_texture_cube_map)
3401 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3402 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3403 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3404 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3405 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3406 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3407 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3408 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3410 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3412 #endif /* GL_ARB_texture_cube_map */
3414 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3415 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3416 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3417 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3419 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3420 /* does it fit??? */
3421 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3422 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3423 /* An 1x1 texture couldn't fit for some reason, so
3424 * break out. This should never happen. But things
3425 * happen. The disadvantage with this if-statement is
3426 * that we will never be aware of when this happens
3427 * since it will silently branch out.
3429 goto noProxyTextures
;
3431 widthPowerOf2
= widthAtLevelOne
;
3432 heightPowerOf2
= heightAtLevelOne
;
3434 /* else it does fit */
3435 } while (proxyWidth
== 0);
3436 /* loop must terminate! */
3438 /* return the width & height at level 0 that fits */
3439 *newWidth
= widthPowerOf2
;
3440 *newHeight
= heightPowerOf2
;
3441 /*printf("Proxy Textures\n");*/
3442 } /* if gluCheckExtension() */
3443 else { /* no texture extension, so do this instead */
3448 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3449 /* clamp user's texture sizes to maximum sizes, if necessary */
3450 *newWidth
= nearestPower(width
);
3451 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3452 *newHeight
= nearestPower(height
);
3453 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3454 /*printf("NO proxy textures\n");*/
3456 } /* closestFit() */
3459 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3460 GLenum typein
, const void *datain
,
3461 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3465 GLushort
*beforeImage
;
3466 GLushort
*afterImage
;
3467 PixelStorageModes psm
;
3469 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3472 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3473 return GLU_INVALID_VALUE
;
3475 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3476 return GLU_INVALID_ENUM
;
3478 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3479 return GLU_INVALID_OPERATION
;
3481 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3482 return GLU_INVALID_OPERATION
;
3485 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3486 if (beforeImage
== NULL
) {
3487 return GLU_OUT_OF_MEMORY
;
3491 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3492 if (afterImage
== NULL
) {
3494 return GLU_OUT_OF_MEMORY
;
3497 retrieveStoreModes(&psm
);
3498 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3499 datain
, beforeImage
);
3500 components
= elements_per_group(format
, 0);
3501 scale_internal(components
, widthin
, heightin
, beforeImage
,
3502 widthout
, heightout
, afterImage
);
3503 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3504 is_index(format
), afterImage
, dataout
);
3505 free((GLbyte
*) beforeImage
);
3506 free((GLbyte
*) afterImage
);
3511 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3513 GLsizei widthPowerOf2
,
3514 GLenum format
, GLenum type
,
3515 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3519 GLint level
, levels
;
3521 GLint newImage_width
;
3522 GLushort
*otherImage
;
3523 GLushort
*imageTemp
;
3526 PixelStorageModes psm
;
3528 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3533 newwidth
= widthPowerOf2
;
3534 levels
= computeLog(newwidth
);
3538 retrieveStoreModes(&psm
);
3539 newImage
= (GLushort
*)
3540 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3541 newImage_width
= width
;
3542 if (newImage
== NULL
) {
3543 return GLU_OUT_OF_MEMORY
;
3545 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3547 cmpts
= elements_per_group(format
,type
);
3548 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3549 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3550 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3551 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3553 ** If swap_bytes was set, swapping occurred in fill_image.
3555 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3557 for (level
= userLevel
; level
<= levels
; level
++) {
3558 if (newImage_width
== newwidth
) {
3559 /* Use newImage for this level */
3560 if (baseLevel
<= level
&& level
<= maxLevel
) {
3561 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3562 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3565 if (otherImage
== NULL
) {
3566 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3567 otherImage
= (GLushort
*) malloc(memreq
);
3568 if (otherImage
== NULL
) {
3569 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3570 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3571 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3572 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3573 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3574 return GLU_OUT_OF_MEMORY
;
3577 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3578 newwidth
, 1, otherImage
);
3579 /* Swap newImage and otherImage */
3580 imageTemp
= otherImage
;
3581 otherImage
= newImage
;
3582 newImage
= imageTemp
;
3584 newImage_width
= newwidth
;
3585 if (baseLevel
<= level
&& level
<= maxLevel
) {
3586 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3587 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3590 if (newwidth
> 1) newwidth
/= 2;
3592 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3593 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3594 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3595 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3596 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3598 free((GLbyte
*) newImage
);
3600 free((GLbyte
*) otherImage
);
3606 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3608 GLenum format
, GLenum type
,
3609 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3614 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3615 if (rc
!= 0) return rc
;
3618 return GLU_INVALID_VALUE
;
3621 levels
= computeLog(width
);
3624 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3625 return GLU_INVALID_VALUE
;
3627 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3630 userLevel
, baseLevel
, maxLevel
,
3632 } /* gluBuild1DMipmapLevels() */
3635 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3636 GLenum format
, GLenum type
,
3639 GLint widthPowerOf2
;
3643 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3644 if (rc
!= 0) return rc
;
3647 return GLU_INVALID_VALUE
;
3650 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3651 levels
= computeLog(widthPowerOf2
);
3653 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3656 format
,type
,0,0,levels
,data
);
3659 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3660 GLint width
, GLint height
, GLenum format
,
3661 GLenum type
, const void *data
)
3663 GLint newwidth
, newheight
;
3664 GLint level
, levels
;
3666 GLint newImage_width
;
3667 GLint newImage_height
;
3668 GLushort
*otherImage
;
3669 GLushort
*imageTemp
;
3672 PixelStorageModes psm
;
3674 retrieveStoreModes(&psm
);
3677 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3678 newwidth
= nearestPower(width
);
3679 if (newwidth
> maxsize
) newwidth
= maxsize
;
3680 newheight
= nearestPower(height
);
3681 if (newheight
> maxsize
) newheight
= maxsize
;
3683 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3684 &newwidth
,&newheight
);
3686 levels
= computeLog(newwidth
);
3687 level
= computeLog(newheight
);
3688 if (level
> levels
) levels
=level
;
3691 newImage
= (GLushort
*)
3692 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3693 newImage_width
= width
;
3694 newImage_height
= height
;
3695 if (newImage
== NULL
) {
3696 return GLU_OUT_OF_MEMORY
;
3699 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3702 cmpts
= elements_per_group(format
,type
);
3703 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3704 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3705 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3706 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3708 ** If swap_bytes was set, swapping occurred in fill_image.
3710 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3712 for (level
= 0; level
<= levels
; level
++) {
3713 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3714 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3715 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3718 if (otherImage
== NULL
) {
3720 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3721 otherImage
= (GLushort
*) malloc(memreq
);
3722 if (otherImage
== NULL
) {
3723 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3724 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3725 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3726 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3727 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3728 return GLU_OUT_OF_MEMORY
;
3731 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3732 newwidth
, newheight
, otherImage
);
3733 /* Swap newImage and otherImage */
3734 imageTemp
= otherImage
;
3735 otherImage
= newImage
;
3736 newImage
= imageTemp
;
3738 newImage_width
= newwidth
;
3739 newImage_height
= newheight
;
3740 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3741 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3744 if (newwidth
> 1) newwidth
/= 2;
3745 if (newheight
> 1) newheight
/= 2;
3747 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3748 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3749 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3750 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3751 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3753 free((GLbyte
*) newImage
);
3755 free((GLbyte
*) otherImage
);
3760 /* To make swapping images less error prone */
3761 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3762 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3764 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3765 GLsizei width
, GLsizei height
,
3766 GLsizei widthPowerOf2
,
3767 GLsizei heightPowerOf2
,
3768 GLenum format
, GLenum type
,
3770 GLint baseLevel
,GLint maxLevel
,
3773 GLint newwidth
, newheight
;
3774 GLint level
, levels
;
3775 const void *usersImage
; /* passed from user. Don't touch! */
3776 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3777 __GLU_INIT_SWAP_IMAGE
;
3781 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3782 GLint rowsize
, padding
;
3783 PixelStorageModes psm
;
3785 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3786 assert(width
>= 1 && height
>= 1);
3788 if(type
== GL_BITMAP
) {
3789 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3790 format
, type
, data
);
3793 srcImage
= dstImage
= NULL
;
3795 newwidth
= widthPowerOf2
;
3796 newheight
= heightPowerOf2
;
3797 levels
= computeLog(newwidth
);
3798 level
= computeLog(newheight
);
3799 if (level
> levels
) levels
=level
;
3803 retrieveStoreModes(&psm
);
3804 myswap_bytes
= psm
.unpack_swap_bytes
;
3805 cmpts
= elements_per_group(format
,type
);
3806 if (psm
.unpack_row_length
> 0) {
3807 groups_per_line
= psm
.unpack_row_length
;
3809 groups_per_line
= width
;
3812 element_size
= bytes_per_element(type
);
3813 group_size
= element_size
* cmpts
;
3814 if (element_size
== 1) myswap_bytes
= 0;
3816 rowsize
= groups_per_line
* group_size
;
3817 padding
= (rowsize
% psm
.unpack_alignment
);
3819 rowsize
+= psm
.unpack_alignment
- padding
;
3821 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3822 psm
.unpack_skip_pixels
* group_size
;
3824 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3825 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3826 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3830 /* already power-of-two square */
3831 if (width
== newwidth
&& height
== newheight
) {
3832 /* Use usersImage for level userLevel */
3833 if (baseLevel
<= level
&& level
<= maxLevel
) {
3834 glTexImage2D(target
, level
, internalFormat
, width
,
3835 height
, 0, format
, type
,
3838 if(levels
== 0) { /* we're done. clean up and return */
3839 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3840 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3841 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3842 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3843 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3847 int nextWidth
= newwidth
/2;
3848 int nextHeight
= newheight
/2;
3851 if (nextWidth
< 1) nextWidth
= 1;
3852 if (nextHeight
< 1) nextHeight
= 1;
3853 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3857 case GL_UNSIGNED_BYTE
:
3858 dstImage
= (GLubyte
*)malloc(memreq
);
3861 dstImage
= (GLbyte
*)malloc(memreq
);
3863 case GL_UNSIGNED_SHORT
:
3864 dstImage
= (GLushort
*)malloc(memreq
);
3867 dstImage
= (GLshort
*)malloc(memreq
);
3869 case GL_UNSIGNED_INT
:
3870 dstImage
= (GLuint
*)malloc(memreq
);
3873 dstImage
= (GLint
*)malloc(memreq
);
3876 dstImage
= (GLfloat
*)malloc(memreq
);
3878 case GL_UNSIGNED_BYTE_3_3_2
:
3879 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3880 dstImage
= (GLubyte
*)malloc(memreq
);
3882 case GL_UNSIGNED_SHORT_5_6_5
:
3883 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3884 case GL_UNSIGNED_SHORT_4_4_4_4
:
3885 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3886 case GL_UNSIGNED_SHORT_5_5_5_1
:
3887 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3888 dstImage
= (GLushort
*)malloc(memreq
);
3890 case GL_UNSIGNED_INT_8_8_8_8
:
3891 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3892 case GL_UNSIGNED_INT_10_10_10_2
:
3893 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3894 dstImage
= (GLuint
*)malloc(memreq
);
3897 return GLU_INVALID_ENUM
;
3899 if (dstImage
== NULL
) {
3900 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3901 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3902 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3903 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3904 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3905 return GLU_OUT_OF_MEMORY
;
3909 case GL_UNSIGNED_BYTE
:
3910 halveImage_ubyte(cmpts
, width
, height
,
3911 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3912 element_size
, rowsize
, group_size
);
3915 halveImage_byte(cmpts
, width
, height
,
3916 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3917 element_size
, rowsize
, group_size
);
3919 case GL_UNSIGNED_SHORT
:
3920 halveImage_ushort(cmpts
, width
, height
,
3921 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3922 element_size
, rowsize
, group_size
, myswap_bytes
);
3925 halveImage_short(cmpts
, width
, height
,
3926 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3927 element_size
, rowsize
, group_size
, myswap_bytes
);
3929 case GL_UNSIGNED_INT
:
3930 halveImage_uint(cmpts
, width
, height
,
3931 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3932 element_size
, rowsize
, group_size
, myswap_bytes
);
3935 halveImage_int(cmpts
, width
, height
,
3936 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3937 element_size
, rowsize
, group_size
, myswap_bytes
);
3940 halveImage_float(cmpts
, width
, height
,
3941 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3942 element_size
, rowsize
, group_size
, myswap_bytes
);
3944 case GL_UNSIGNED_BYTE_3_3_2
:
3945 assert(format
== GL_RGB
);
3946 halveImagePackedPixel(3,extract332
,shove332
,
3947 width
,height
,usersImage
,dstImage
,
3948 element_size
,rowsize
,myswap_bytes
);
3950 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3951 assert(format
== GL_RGB
);
3952 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3953 width
,height
,usersImage
,dstImage
,
3954 element_size
,rowsize
,myswap_bytes
);
3956 case GL_UNSIGNED_SHORT_5_6_5
:
3957 halveImagePackedPixel(3,extract565
,shove565
,
3958 width
,height
,usersImage
,dstImage
,
3959 element_size
,rowsize
,myswap_bytes
);
3961 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3962 halveImagePackedPixel(3,extract565rev
,shove565rev
,
3963 width
,height
,usersImage
,dstImage
,
3964 element_size
,rowsize
,myswap_bytes
);
3966 case GL_UNSIGNED_SHORT_4_4_4_4
:
3967 halveImagePackedPixel(4,extract4444
,shove4444
,
3968 width
,height
,usersImage
,dstImage
,
3969 element_size
,rowsize
,myswap_bytes
);
3971 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3972 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
3973 width
,height
,usersImage
,dstImage
,
3974 element_size
,rowsize
,myswap_bytes
);
3976 case GL_UNSIGNED_SHORT_5_5_5_1
:
3977 halveImagePackedPixel(4,extract5551
,shove5551
,
3978 width
,height
,usersImage
,dstImage
,
3979 element_size
,rowsize
,myswap_bytes
);
3981 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3982 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
3983 width
,height
,usersImage
,dstImage
,
3984 element_size
,rowsize
,myswap_bytes
);
3986 case GL_UNSIGNED_INT_8_8_8_8
:
3987 halveImagePackedPixel(4,extract8888
,shove8888
,
3988 width
,height
,usersImage
,dstImage
,
3989 element_size
,rowsize
,myswap_bytes
);
3991 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3992 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
3993 width
,height
,usersImage
,dstImage
,
3994 element_size
,rowsize
,myswap_bytes
);
3996 case GL_UNSIGNED_INT_10_10_10_2
:
3997 halveImagePackedPixel(4,extract1010102
,shove1010102
,
3998 width
,height
,usersImage
,dstImage
,
3999 element_size
,rowsize
,myswap_bytes
);
4001 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4002 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4003 width
,height
,usersImage
,dstImage
,
4004 element_size
,rowsize
,myswap_bytes
);
4011 newheight
= height
/2;
4013 if (newwidth
< 1) newwidth
= 1;
4014 if (newheight
< 1) newheight
= 1;
4017 rowsize
= newwidth
* group_size
;
4018 memreq
= image_size(newwidth
, newheight
, format
, type
);
4019 /* Swap srcImage and dstImage */
4020 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4022 case GL_UNSIGNED_BYTE
:
4023 dstImage
= (GLubyte
*)malloc(memreq
);
4026 dstImage
= (GLbyte
*)malloc(memreq
);
4028 case GL_UNSIGNED_SHORT
:
4029 dstImage
= (GLushort
*)malloc(memreq
);
4032 dstImage
= (GLshort
*)malloc(memreq
);
4034 case GL_UNSIGNED_INT
:
4035 dstImage
= (GLuint
*)malloc(memreq
);
4038 dstImage
= (GLint
*)malloc(memreq
);
4041 dstImage
= (GLfloat
*)malloc(memreq
);
4043 case GL_UNSIGNED_BYTE_3_3_2
:
4044 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4045 dstImage
= (GLubyte
*)malloc(memreq
);
4047 case GL_UNSIGNED_SHORT_5_6_5
:
4048 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4049 case GL_UNSIGNED_SHORT_4_4_4_4
:
4050 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4051 case GL_UNSIGNED_SHORT_5_5_5_1
:
4052 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4053 dstImage
= (GLushort
*)malloc(memreq
);
4055 case GL_UNSIGNED_INT_8_8_8_8
:
4056 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4057 case GL_UNSIGNED_INT_10_10_10_2
:
4058 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4059 dstImage
= (GLuint
*)malloc(memreq
);
4062 return GLU_INVALID_ENUM
;
4064 if (dstImage
== NULL
) {
4065 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4066 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4067 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4068 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4069 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4070 return GLU_OUT_OF_MEMORY
;
4072 /* level userLevel+1 is in srcImage; level userLevel already saved */
4073 level
= userLevel
+1;
4074 } else { /* user's image is *not* nice power-of-2 sized square */
4075 memreq
= image_size(newwidth
, newheight
, format
, type
);
4077 case GL_UNSIGNED_BYTE
:
4078 dstImage
= (GLubyte
*)malloc(memreq
);
4081 dstImage
= (GLbyte
*)malloc(memreq
);
4083 case GL_UNSIGNED_SHORT
:
4084 dstImage
= (GLushort
*)malloc(memreq
);
4087 dstImage
= (GLshort
*)malloc(memreq
);
4089 case GL_UNSIGNED_INT
:
4090 dstImage
= (GLuint
*)malloc(memreq
);
4093 dstImage
= (GLint
*)malloc(memreq
);
4096 dstImage
= (GLfloat
*)malloc(memreq
);
4098 case GL_UNSIGNED_BYTE_3_3_2
:
4099 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4100 dstImage
= (GLubyte
*)malloc(memreq
);
4102 case GL_UNSIGNED_SHORT_5_6_5
:
4103 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4104 case GL_UNSIGNED_SHORT_4_4_4_4
:
4105 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4106 case GL_UNSIGNED_SHORT_5_5_5_1
:
4107 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4108 dstImage
= (GLushort
*)malloc(memreq
);
4110 case GL_UNSIGNED_INT_8_8_8_8
:
4111 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4112 case GL_UNSIGNED_INT_10_10_10_2
:
4113 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4114 dstImage
= (GLuint
*)malloc(memreq
);
4117 return GLU_INVALID_ENUM
;
4120 if (dstImage
== NULL
) {
4121 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4122 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4123 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4124 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4125 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4126 return GLU_OUT_OF_MEMORY
;
4130 case GL_UNSIGNED_BYTE
:
4131 scale_internal_ubyte(cmpts
, width
, height
,
4132 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4133 (GLubyte
*)dstImage
, element_size
,
4134 rowsize
, group_size
);
4137 scale_internal_byte(cmpts
, width
, height
,
4138 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4139 (GLbyte
*)dstImage
, element_size
,
4140 rowsize
, group_size
);
4142 case GL_UNSIGNED_SHORT
:
4143 scale_internal_ushort(cmpts
, width
, height
,
4144 (const GLushort
*)usersImage
, newwidth
, newheight
,
4145 (GLushort
*)dstImage
, element_size
,
4146 rowsize
, group_size
, myswap_bytes
);
4149 scale_internal_short(cmpts
, width
, height
,
4150 (const GLshort
*)usersImage
, newwidth
, newheight
,
4151 (GLshort
*)dstImage
, element_size
,
4152 rowsize
, group_size
, myswap_bytes
);
4154 case GL_UNSIGNED_INT
:
4155 scale_internal_uint(cmpts
, width
, height
,
4156 (const GLuint
*)usersImage
, newwidth
, newheight
,
4157 (GLuint
*)dstImage
, element_size
,
4158 rowsize
, group_size
, myswap_bytes
);
4161 scale_internal_int(cmpts
, width
, height
,
4162 (const GLint
*)usersImage
, newwidth
, newheight
,
4163 (GLint
*)dstImage
, element_size
,
4164 rowsize
, group_size
, myswap_bytes
);
4167 scale_internal_float(cmpts
, width
, height
,
4168 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4169 (GLfloat
*)dstImage
, element_size
,
4170 rowsize
, group_size
, myswap_bytes
);
4172 case GL_UNSIGNED_BYTE_3_3_2
:
4173 scaleInternalPackedPixel(3,extract332
,shove332
,
4174 width
, height
,usersImage
,
4175 newwidth
,newheight
,(void *)dstImage
,
4176 element_size
,rowsize
,myswap_bytes
);
4178 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4179 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4180 width
, height
,usersImage
,
4181 newwidth
,newheight
,(void *)dstImage
,
4182 element_size
,rowsize
,myswap_bytes
);
4184 case GL_UNSIGNED_SHORT_5_6_5
:
4185 scaleInternalPackedPixel(3,extract565
,shove565
,
4186 width
, height
,usersImage
,
4187 newwidth
,newheight
,(void *)dstImage
,
4188 element_size
,rowsize
,myswap_bytes
);
4190 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4191 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4192 width
, height
,usersImage
,
4193 newwidth
,newheight
,(void *)dstImage
,
4194 element_size
,rowsize
,myswap_bytes
);
4196 case GL_UNSIGNED_SHORT_4_4_4_4
:
4197 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4198 width
, height
,usersImage
,
4199 newwidth
,newheight
,(void *)dstImage
,
4200 element_size
,rowsize
,myswap_bytes
);
4202 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4203 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4204 width
, height
,usersImage
,
4205 newwidth
,newheight
,(void *)dstImage
,
4206 element_size
,rowsize
,myswap_bytes
);
4208 case GL_UNSIGNED_SHORT_5_5_5_1
:
4209 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4210 width
, height
,usersImage
,
4211 newwidth
,newheight
,(void *)dstImage
,
4212 element_size
,rowsize
,myswap_bytes
);
4214 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4215 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4216 width
, height
,usersImage
,
4217 newwidth
,newheight
,(void *)dstImage
,
4218 element_size
,rowsize
,myswap_bytes
);
4220 case GL_UNSIGNED_INT_8_8_8_8
:
4221 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4222 width
, height
,usersImage
,
4223 newwidth
,newheight
,(void *)dstImage
,
4224 element_size
,rowsize
,myswap_bytes
);
4226 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4227 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4228 width
, height
,usersImage
,
4229 newwidth
,newheight
,(void *)dstImage
,
4230 element_size
,rowsize
,myswap_bytes
);
4232 case GL_UNSIGNED_INT_10_10_10_2
:
4233 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4234 width
, height
,usersImage
,
4235 newwidth
,newheight
,(void *)dstImage
,
4236 element_size
,rowsize
,myswap_bytes
);
4238 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4239 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4240 width
, height
,usersImage
,
4241 newwidth
,newheight
,(void *)dstImage
,
4242 element_size
,rowsize
,myswap_bytes
);
4249 rowsize
= newwidth
* group_size
;
4250 /* Swap dstImage and srcImage */
4251 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4253 if(levels
!= 0) { /* use as little memory as possible */
4255 int nextWidth
= newwidth
/2;
4256 int nextHeight
= newheight
/2;
4257 if (nextWidth
< 1) nextWidth
= 1;
4258 if (nextHeight
< 1) nextHeight
= 1;
4260 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4264 case GL_UNSIGNED_BYTE
:
4265 dstImage
= (GLubyte
*)malloc(memreq
);
4268 dstImage
= (GLbyte
*)malloc(memreq
);
4270 case GL_UNSIGNED_SHORT
:
4271 dstImage
= (GLushort
*)malloc(memreq
);
4274 dstImage
= (GLshort
*)malloc(memreq
);
4276 case GL_UNSIGNED_INT
:
4277 dstImage
= (GLuint
*)malloc(memreq
);
4280 dstImage
= (GLint
*)malloc(memreq
);
4283 dstImage
= (GLfloat
*)malloc(memreq
);
4285 case GL_UNSIGNED_BYTE_3_3_2
:
4286 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4287 dstImage
= (GLubyte
*)malloc(memreq
);
4289 case GL_UNSIGNED_SHORT_5_6_5
:
4290 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4291 case GL_UNSIGNED_SHORT_4_4_4_4
:
4292 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4293 case GL_UNSIGNED_SHORT_5_5_5_1
:
4294 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4295 dstImage
= (GLushort
*)malloc(memreq
);
4297 case GL_UNSIGNED_INT_8_8_8_8
:
4298 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4299 case GL_UNSIGNED_INT_10_10_10_2
:
4300 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4301 dstImage
= (GLuint
*)malloc(memreq
);
4304 return GLU_INVALID_ENUM
;
4306 if (dstImage
== NULL
) {
4307 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4308 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4309 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4310 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4311 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4312 return GLU_OUT_OF_MEMORY
;
4315 /* level userLevel is in srcImage; nothing saved yet */
4319 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4320 if (baseLevel
<= level
&& level
<= maxLevel
) {
4321 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4322 format
, type
, (void *)srcImage
);
4325 level
++; /* update current level for the loop */
4326 for (; level
<= levels
; level
++) {
4328 case GL_UNSIGNED_BYTE
:
4329 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4330 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4331 rowsize
, group_size
);
4334 halveImage_byte(cmpts
, newwidth
, newheight
,
4335 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4336 rowsize
, group_size
);
4338 case GL_UNSIGNED_SHORT
:
4339 halveImage_ushort(cmpts
, newwidth
, newheight
,
4340 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4341 rowsize
, group_size
, myswap_bytes
);
4344 halveImage_short(cmpts
, newwidth
, newheight
,
4345 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4346 rowsize
, group_size
, myswap_bytes
);
4348 case GL_UNSIGNED_INT
:
4349 halveImage_uint(cmpts
, newwidth
, newheight
,
4350 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4351 rowsize
, group_size
, myswap_bytes
);
4354 halveImage_int(cmpts
, newwidth
, newheight
,
4355 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4356 rowsize
, group_size
, myswap_bytes
);
4359 halveImage_float(cmpts
, newwidth
, newheight
,
4360 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4361 rowsize
, group_size
, myswap_bytes
);
4363 case GL_UNSIGNED_BYTE_3_3_2
:
4364 halveImagePackedPixel(3,extract332
,shove332
,
4366 srcImage
,dstImage
,element_size
,rowsize
,
4369 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4370 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4372 srcImage
,dstImage
,element_size
,rowsize
,
4375 case GL_UNSIGNED_SHORT_5_6_5
:
4376 halveImagePackedPixel(3,extract565
,shove565
,
4378 srcImage
,dstImage
,element_size
,rowsize
,
4381 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4382 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4384 srcImage
,dstImage
,element_size
,rowsize
,
4387 case GL_UNSIGNED_SHORT_4_4_4_4
:
4388 halveImagePackedPixel(4,extract4444
,shove4444
,
4390 srcImage
,dstImage
,element_size
,rowsize
,
4393 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4394 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4396 srcImage
,dstImage
,element_size
,rowsize
,
4399 case GL_UNSIGNED_SHORT_5_5_5_1
:
4400 halveImagePackedPixel(4,extract5551
,shove5551
,
4402 srcImage
,dstImage
,element_size
,rowsize
,
4405 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4406 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4408 srcImage
,dstImage
,element_size
,rowsize
,
4411 case GL_UNSIGNED_INT_8_8_8_8
:
4412 halveImagePackedPixel(4,extract8888
,shove8888
,
4414 srcImage
,dstImage
,element_size
,rowsize
,
4417 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4418 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4420 srcImage
,dstImage
,element_size
,rowsize
,
4423 case GL_UNSIGNED_INT_10_10_10_2
:
4424 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4426 srcImage
,dstImage
,element_size
,rowsize
,
4429 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4430 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4432 srcImage
,dstImage
,element_size
,rowsize
,
4440 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4442 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4443 if (newheight
> 1) newheight
/= 2;
4445 /* compute amount to pad per row, if any */
4446 int rowPad
= rowsize
% psm
.unpack_alignment
;
4448 /* should row be padded? */
4449 if (rowPad
== 0) { /* nope, row should not be padded */
4450 /* call tex image with srcImage untouched since it's not padded */
4451 if (baseLevel
<= level
&& level
<= maxLevel
) {
4452 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4453 format
, type
, (void *) srcImage
);
4456 else { /* yes, row should be padded */
4457 /* compute length of new row in bytes, including padding */
4458 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4459 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4461 /* allocate new image for mipmap of size newRowLength x newheight */
4462 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4463 if (newMipmapImage
== NULL
) {
4464 /* out of memory so return */
4465 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4466 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4467 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4468 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4469 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4470 return GLU_OUT_OF_MEMORY
;
4473 /* copy image from srcImage into newMipmapImage by rows */
4475 dstTrav
= (unsigned char *) newMipmapImage
,
4476 srcTrav
= (unsigned char *) srcImage
;
4479 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4480 srcTrav
+= rowsize
) { /* ...is skipped */
4481 memcpy(dstTrav
,srcTrav
,rowsize
);
4482 /* note that the pad bytes are not visited and will contain
4483 * garbage, which is ok.
4487 /* ...and use this new image for mipmapping instead */
4488 if (baseLevel
<= level
&& level
<= maxLevel
) {
4489 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4490 format
, type
, newMipmapImage
);
4492 free(newMipmapImage
); /* don't forget to free it! */
4496 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4497 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4498 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4499 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4500 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4502 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4503 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4507 } /* gluBuild2DMipmapLevelsCore() */
4510 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4511 GLsizei width
, GLsizei height
,
4512 GLenum format
, GLenum type
,
4513 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4518 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4519 if (rc
!= 0) return rc
;
4521 if (width
< 1 || height
< 1) {
4522 return GLU_INVALID_VALUE
;
4525 levels
= computeLog(width
);
4526 level
= computeLog(height
);
4527 if (level
> levels
) levels
=level
;
4530 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4531 return GLU_INVALID_VALUE
;
4533 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4537 userLevel
, baseLevel
, maxLevel
,
4539 } /* gluBuild2DMipmapLevels() */
4542 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4543 GLsizei width
, GLsizei height
,
4544 GLenum format
, GLenum type
,
4547 GLint widthPowerOf2
, heightPowerOf2
;
4550 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4551 if (rc
!= 0) return rc
;
4553 if (width
< 1 || height
< 1) {
4554 return GLU_INVALID_VALUE
;
4557 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4558 &widthPowerOf2
,&heightPowerOf2
);
4560 levels
= computeLog(widthPowerOf2
);
4561 level
= computeLog(heightPowerOf2
);
4562 if (level
> levels
) levels
=level
;
4564 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4566 widthPowerOf2
,heightPowerOf2
,
4569 } /* gluBuild2DMipmaps() */
4573 ** This routine is for the limited case in which
4574 ** type == GL_UNSIGNED_BYTE && format != index &&
4575 ** unpack_alignment = 1 && unpack_swap_bytes == false
4577 ** so all of the work data can be kept as ubytes instead of shorts.
4579 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4580 GLenum target
, GLint components
, GLint width
,
4581 GLint height
, GLenum format
,
4582 GLenum type
, void *data
)
4584 GLint newwidth
, newheight
;
4585 GLint level
, levels
;
4587 GLint newImage_width
;
4588 GLint newImage_height
;
4589 GLubyte
*otherImage
;
4596 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4597 newwidth
= nearestPower(width
);
4598 if (newwidth
> maxsize
) newwidth
= maxsize
;
4599 newheight
= nearestPower(height
);
4600 if (newheight
> maxsize
) newheight
= maxsize
;
4602 closestFit(target
,width
,height
,components
,format
,type
,
4603 &newwidth
,&newheight
);
4605 levels
= computeLog(newwidth
);
4606 level
= computeLog(newheight
);
4607 if (level
> levels
) levels
=level
;
4609 cmpts
= elements_per_group(format
,type
);
4613 ** No need to copy the user data if its in the packed correctly.
4614 ** Make sure that later routines don't change that data.
4616 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4617 newImage
= (GLubyte
*)data
;
4618 newImage_width
= width
;
4619 newImage_height
= height
;
4622 GLint groups_per_line
;
4623 GLint elements_per_line
;
4624 const GLubyte
*start
;
4625 const GLubyte
*iter
;
4629 newImage
= (GLubyte
*)
4630 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4631 newImage_width
= width
;
4632 newImage_height
= height
;
4633 if (newImage
== NULL
) {
4634 return GLU_OUT_OF_MEMORY
;
4638 ** Abbreviated version of fill_image for this restricted case.
4640 if (psm
->unpack_row_length
> 0) {
4641 groups_per_line
= psm
->unpack_row_length
;
4643 groups_per_line
= width
;
4645 rowsize
= groups_per_line
* cmpts
;
4646 elements_per_line
= width
* cmpts
;
4647 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4648 psm
->unpack_skip_pixels
* cmpts
;
4651 for (i
= 0; i
< height
; i
++) {
4653 for (j
= 0; j
< elements_per_line
; j
++) {
4663 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4664 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4665 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4666 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4667 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4669 for (level
= 0; level
<= levels
; level
++) {
4670 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4671 /* Use newImage for this level */
4672 glTexImage2D(target
, level
, components
, newImage_width
,
4673 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4676 if (otherImage
== NULL
) {
4678 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4679 otherImage
= (GLubyte
*) malloc(memreq
);
4680 if (otherImage
== NULL
) {
4681 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4682 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4683 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4684 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4685 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4686 return GLU_OUT_OF_MEMORY
;
4690 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4691 newImage, newwidth, newheight, otherImage);
4693 /* Swap newImage and otherImage */
4694 imageTemp
= otherImage
;
4695 otherImage
= newImage
;
4696 newImage
= imageTemp
;
4698 newImage_width
= newwidth
;
4699 newImage_height
= newheight
;
4700 glTexImage2D(target
, level
, components
, newImage_width
,
4701 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4704 if (newwidth
> 1) newwidth
/= 2;
4705 if (newheight
> 1) newheight
/= 2;
4707 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4708 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4709 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4710 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4711 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4713 if (newImage
!= (const GLubyte
*)data
) {
4714 free((GLbyte
*) newImage
);
4716 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4717 free((GLbyte
*) otherImage
);
4726 static GLint
elements_per_group(GLenum format
, GLenum type
)
4729 * Return the number of elements per group of a specified format
4732 /* If the type is packedpixels then answer is 1 (ignore format) */
4733 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4734 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4735 type
== GL_UNSIGNED_SHORT_5_6_5
||
4736 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4737 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4738 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4739 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4740 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4741 type
== GL_UNSIGNED_INT_8_8_8_8
||
4742 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4743 type
== GL_UNSIGNED_INT_10_10_10_2
||
4744 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4748 /* Types are not packed pixels, so get elements per group */
4753 case GL_LUMINANCE_ALPHA
:
4763 static GLfloat
bytes_per_element(GLenum type
)
4766 * Return the number of bytes per element, based on the element type
4771 case GL_UNSIGNED_SHORT
:
4772 return(sizeof(GLushort
));
4774 return(sizeof(GLshort
));
4775 case GL_UNSIGNED_BYTE
:
4776 return(sizeof(GLubyte
));
4778 return(sizeof(GLbyte
));
4780 return(sizeof(GLint
));
4781 case GL_UNSIGNED_INT
:
4782 return(sizeof(GLuint
));
4784 return(sizeof(GLfloat
));
4785 case GL_UNSIGNED_BYTE_3_3_2
:
4786 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4787 return(sizeof(GLubyte
));
4788 case GL_UNSIGNED_SHORT_5_6_5
:
4789 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4790 case GL_UNSIGNED_SHORT_4_4_4_4
:
4791 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4792 case GL_UNSIGNED_SHORT_5_5_5_1
:
4793 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4794 return(sizeof(GLushort
));
4795 case GL_UNSIGNED_INT_8_8_8_8
:
4796 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4797 case GL_UNSIGNED_INT_10_10_10_2
:
4798 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4799 return(sizeof(GLuint
));
4805 static GLint
is_index(GLenum format
)
4807 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4811 ** Compute memory required for internal packed array of data of given type
4814 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4821 components
= elements_per_group(format
,type
);
4822 if (type
== GL_BITMAP
) {
4823 bytes_per_row
= (width
+ 7) / 8;
4825 bytes_per_row
= bytes_per_element(type
) * width
;
4827 return bytes_per_row
* height
* components
;
4831 ** Extract array from user's data applying all pixel store modes.
4832 ** The internal format used is an array of unsigned shorts.
4834 static void fill_image(const PixelStorageModes
*psm
,
4835 GLint width
, GLint height
, GLenum format
,
4836 GLenum type
, GLboolean index_format
,
4837 const void *userdata
, GLushort
*newimage
)
4843 GLint groups_per_line
;
4845 GLint elements_per_line
;
4846 const GLubyte
*start
;
4847 const GLubyte
*iter
= NULL
;
4852 myswap_bytes
= psm
->unpack_swap_bytes
;
4853 components
= elements_per_group(format
,type
);
4854 if (psm
->unpack_row_length
> 0) {
4855 groups_per_line
= psm
->unpack_row_length
;
4857 groups_per_line
= width
;
4860 /* All formats except GL_BITMAP fall out trivially */
4861 if (type
== GL_BITMAP
) {
4865 rowsize
= (groups_per_line
* components
+ 7) / 8;
4866 padding
= (rowsize
% psm
->unpack_alignment
);
4868 rowsize
+= psm
->unpack_alignment
- padding
;
4871 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4872 (psm
->unpack_skip_pixels
* components
/ 8);
4873 elements_per_line
= width
* components
;
4875 for (i
= 0; i
< height
; i
++) {
4877 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4878 for (j
= 0; j
< elements_per_line
; j
++) {
4880 if (psm
->unpack_lsb_first
) {
4881 current_bit
= iter
[0] & (1 << bit_offset
);
4883 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4895 if (bit_offset
== 8) {
4904 element_size
= bytes_per_element(type
);
4905 group_size
= element_size
* components
;
4906 if (element_size
== 1) myswap_bytes
= 0;
4908 rowsize
= groups_per_line
* group_size
;
4909 padding
= (rowsize
% psm
->unpack_alignment
);
4911 rowsize
+= psm
->unpack_alignment
- padding
;
4913 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4914 psm
->unpack_skip_pixels
* group_size
;
4915 elements_per_line
= width
* components
;
4918 for (i
= 0; i
< height
; i
++) {
4920 for (j
= 0; j
< elements_per_line
; j
++) {
4922 float extractComponents
[4];
4925 case GL_UNSIGNED_BYTE_3_3_2
:
4926 extract332(0,iter
,extractComponents
);
4927 for (k
= 0; k
< 3; k
++) {
4928 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4931 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4932 extract233rev(0,iter
,extractComponents
);
4933 for (k
= 0; k
< 3; k
++) {
4934 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4937 case GL_UNSIGNED_BYTE
:
4941 *iter2
++ = (*iter
) * 257;
4946 *iter2
++ = *((const GLbyte
*) iter
);
4949 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4952 case GL_UNSIGNED_SHORT_5_6_5
:
4953 extract565(myswap_bytes
,iter
,extractComponents
);
4954 for (k
= 0; k
< 3; k
++) {
4955 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4958 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4959 extract565rev(myswap_bytes
,iter
,extractComponents
);
4960 for (k
= 0; k
< 3; k
++) {
4961 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4964 case GL_UNSIGNED_SHORT_4_4_4_4
:
4965 extract4444(myswap_bytes
,iter
,extractComponents
);
4966 for (k
= 0; k
< 4; k
++) {
4967 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4970 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4971 extract4444rev(myswap_bytes
,iter
,extractComponents
);
4972 for (k
= 0; k
< 4; k
++) {
4973 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4976 case GL_UNSIGNED_SHORT_5_5_5_1
:
4977 extract5551(myswap_bytes
,iter
,extractComponents
);
4978 for (k
= 0; k
< 4; k
++) {
4979 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4982 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4983 extract1555rev(myswap_bytes
,iter
,extractComponents
);
4984 for (k
= 0; k
< 4; k
++) {
4985 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4988 case GL_UNSIGNED_SHORT
:
4991 widget
.ub
[0] = iter
[1];
4992 widget
.ub
[1] = iter
[0];
4994 widget
.ub
[0] = iter
[0];
4995 widget
.ub
[1] = iter
[1];
4997 if (type
== GL_SHORT
) {
4999 *iter2
++ = widget
.s
[0];
5002 *iter2
++ = widget
.s
[0]*2;
5005 *iter2
++ = widget
.us
[0];
5008 case GL_UNSIGNED_INT_8_8_8_8
:
5009 extract8888(myswap_bytes
,iter
,extractComponents
);
5010 for (k
= 0; k
< 4; k
++) {
5011 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5014 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5015 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5016 for (k
= 0; k
< 4; k
++) {
5017 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5020 case GL_UNSIGNED_INT_10_10_10_2
:
5021 extract1010102(myswap_bytes
,iter
,extractComponents
);
5022 for (k
= 0; k
< 4; k
++) {
5023 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5026 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5027 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5028 for (k
= 0; k
< 4; k
++) {
5029 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5033 case GL_UNSIGNED_INT
:
5036 widget
.ub
[0] = iter
[3];
5037 widget
.ub
[1] = iter
[2];
5038 widget
.ub
[2] = iter
[1];
5039 widget
.ub
[3] = iter
[0];
5041 widget
.ub
[0] = iter
[0];
5042 widget
.ub
[1] = iter
[1];
5043 widget
.ub
[2] = iter
[2];
5044 widget
.ub
[3] = iter
[3];
5046 if (type
== GL_FLOAT
) {
5048 *iter2
++ = widget
.f
;
5050 *iter2
++ = 65535 * widget
.f
;
5052 } else if (type
== GL_UNSIGNED_INT
) {
5054 *iter2
++ = widget
.ui
;
5056 *iter2
++ = widget
.ui
>> 16;
5060 *iter2
++ = widget
.i
;
5062 *iter2
++ = widget
.i
>> 15;
5067 iter
+= element_size
;
5071 /* want 'iter' pointing at start, not within, row for assertion
5078 /* iterators should be one byte past end */
5079 if (!isTypePackedPixel(type
)) {
5080 assert(iter2
== &newimage
[width
*height
*components
]);
5083 assert(iter2
== &newimage
[width
*height
*
5084 elements_per_group(format
,0)]);
5086 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5087 psm
->unpack_skip_rows
* rowsize
+
5088 psm
->unpack_skip_pixels
* group_size
] );
5091 } /* fill_image() */
5094 ** Insert array into user's data applying all pixel store modes.
5095 ** The internal format is an array of unsigned shorts.
5096 ** empty_image() because it is the opposite of fill_image().
5098 static void empty_image(const PixelStorageModes
*psm
,
5099 GLint width
, GLint height
, GLenum format
,
5100 GLenum type
, GLboolean index_format
,
5101 const GLushort
*oldimage
, void *userdata
)
5107 GLint groups_per_line
;
5109 GLint elements_per_line
;
5111 GLubyte
*iter
= NULL
;
5112 const GLushort
*iter2
;
5116 myswap_bytes
= psm
->pack_swap_bytes
;
5117 components
= elements_per_group(format
,type
);
5118 if (psm
->pack_row_length
> 0) {
5119 groups_per_line
= psm
->pack_row_length
;
5121 groups_per_line
= width
;
5124 /* All formats except GL_BITMAP fall out trivially */
5125 if (type
== GL_BITMAP
) {
5129 rowsize
= (groups_per_line
* components
+ 7) / 8;
5130 padding
= (rowsize
% psm
->pack_alignment
);
5132 rowsize
+= psm
->pack_alignment
- padding
;
5134 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5135 (psm
->pack_skip_pixels
* components
/ 8);
5136 elements_per_line
= width
* components
;
5138 for (i
= 0; i
< height
; i
++) {
5140 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5141 for (j
= 0; j
< elements_per_line
; j
++) {
5143 current_bit
= iter2
[0] & 1;
5145 if (iter2
[0] > 32767) {
5153 if (psm
->pack_lsb_first
) {
5154 *iter
|= (1 << bit_offset
);
5156 *iter
|= (1 << (7 - bit_offset
));
5159 if (psm
->pack_lsb_first
) {
5160 *iter
&= ~(1 << bit_offset
);
5162 *iter
&= ~(1 << (7 - bit_offset
));
5167 if (bit_offset
== 8) {
5176 float shoveComponents
[4];
5178 element_size
= bytes_per_element(type
);
5179 group_size
= element_size
* components
;
5180 if (element_size
== 1) myswap_bytes
= 0;
5182 rowsize
= groups_per_line
* group_size
;
5183 padding
= (rowsize
% psm
->pack_alignment
);
5185 rowsize
+= psm
->pack_alignment
- padding
;
5187 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5188 psm
->pack_skip_pixels
* group_size
;
5189 elements_per_line
= width
* components
;
5192 for (i
= 0; i
< height
; i
++) {
5194 for (j
= 0; j
< elements_per_line
; j
++) {
5198 case GL_UNSIGNED_BYTE_3_3_2
:
5199 for (k
= 0; k
< 3; k
++) {
5200 shoveComponents
[k
]= *iter2
++ / 65535.0;
5202 shove332(shoveComponents
,0,(void *)iter
);
5204 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5205 for (k
= 0; k
< 3; k
++) {
5206 shoveComponents
[k
]= *iter2
++ / 65535.0;
5208 shove233rev(shoveComponents
,0,(void *)iter
);
5210 case GL_UNSIGNED_BYTE
:
5214 *iter
= *iter2
++ >> 8;
5219 *((GLbyte
*) iter
) = *iter2
++;
5221 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5224 case GL_UNSIGNED_SHORT_5_6_5
:
5225 for (k
= 0; k
< 3; k
++) {
5226 shoveComponents
[k
]= *iter2
++ / 65535.0;
5228 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5230 iter
[0] = widget
.ub
[1];
5231 iter
[1] = widget
.ub
[0];
5234 *(GLushort
*)iter
= widget
.us
[0];
5237 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5238 for (k
= 0; k
< 3; k
++) {
5239 shoveComponents
[k
]= *iter2
++ / 65535.0;
5241 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5243 iter
[0] = widget
.ub
[1];
5244 iter
[1] = widget
.ub
[0];
5247 *(GLushort
*)iter
= widget
.us
[0];
5250 case GL_UNSIGNED_SHORT_4_4_4_4
:
5251 for (k
= 0; k
< 4; k
++) {
5252 shoveComponents
[k
]= *iter2
++ / 65535.0;
5254 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5256 iter
[0] = widget
.ub
[1];
5257 iter
[1] = widget
.ub
[0];
5259 *(GLushort
*)iter
= widget
.us
[0];
5262 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5263 for (k
= 0; k
< 4; k
++) {
5264 shoveComponents
[k
]= *iter2
++ / 65535.0;
5266 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5268 iter
[0] = widget
.ub
[1];
5269 iter
[1] = widget
.ub
[0];
5271 *(GLushort
*)iter
= widget
.us
[0];
5274 case GL_UNSIGNED_SHORT_5_5_5_1
:
5275 for (k
= 0; k
< 4; k
++) {
5276 shoveComponents
[k
]= *iter2
++ / 65535.0;
5278 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5280 iter
[0] = widget
.ub
[1];
5281 iter
[1] = widget
.ub
[0];
5283 *(GLushort
*)iter
= widget
.us
[0];
5286 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5287 for (k
= 0; k
< 4; k
++) {
5288 shoveComponents
[k
]= *iter2
++ / 65535.0;
5290 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5292 iter
[0] = widget
.ub
[1];
5293 iter
[1] = widget
.ub
[0];
5295 *(GLushort
*)iter
= widget
.us
[0];
5298 case GL_UNSIGNED_SHORT
:
5300 if (type
== GL_SHORT
) {
5302 widget
.s
[0] = *iter2
++;
5304 widget
.s
[0] = *iter2
++ >> 1;
5307 widget
.us
[0] = *iter2
++;
5310 iter
[0] = widget
.ub
[1];
5311 iter
[1] = widget
.ub
[0];
5313 iter
[0] = widget
.ub
[0];
5314 iter
[1] = widget
.ub
[1];
5317 case GL_UNSIGNED_INT_8_8_8_8
:
5318 for (k
= 0; k
< 4; k
++) {
5319 shoveComponents
[k
]= *iter2
++ / 65535.0;
5321 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5323 iter
[3] = widget
.ub
[0];
5324 iter
[2] = widget
.ub
[1];
5325 iter
[1] = widget
.ub
[2];
5326 iter
[0] = widget
.ub
[3];
5328 *(GLuint
*)iter
= widget
.ui
;
5332 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5333 for (k
= 0; k
< 4; k
++) {
5334 shoveComponents
[k
]= *iter2
++ / 65535.0;
5336 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5338 iter
[3] = widget
.ub
[0];
5339 iter
[2] = widget
.ub
[1];
5340 iter
[1] = widget
.ub
[2];
5341 iter
[0] = widget
.ub
[3];
5343 *(GLuint
*)iter
= widget
.ui
;
5346 case GL_UNSIGNED_INT_10_10_10_2
:
5347 for (k
= 0; k
< 4; k
++) {
5348 shoveComponents
[k
]= *iter2
++ / 65535.0;
5350 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5352 iter
[3] = widget
.ub
[0];
5353 iter
[2] = widget
.ub
[1];
5354 iter
[1] = widget
.ub
[2];
5355 iter
[0] = widget
.ub
[3];
5357 *(GLuint
*)iter
= widget
.ui
;
5360 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5361 for (k
= 0; k
< 4; k
++) {
5362 shoveComponents
[k
]= *iter2
++ / 65535.0;
5364 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
5366 iter
[3] = widget
.ub
[0];
5367 iter
[2] = widget
.ub
[1];
5368 iter
[1] = widget
.ub
[2];
5369 iter
[0] = widget
.ub
[3];
5371 *(GLuint
*)iter
= widget
.ui
;
5375 case GL_UNSIGNED_INT
:
5377 if (type
== GL_FLOAT
) {
5379 widget
.f
= *iter2
++;
5381 widget
.f
= *iter2
++ / (float) 65535.0;
5383 } else if (type
== GL_UNSIGNED_INT
) {
5385 widget
.ui
= *iter2
++;
5387 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5391 widget
.i
= *iter2
++;
5393 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5397 iter
[3] = widget
.ub
[0];
5398 iter
[2] = widget
.ub
[1];
5399 iter
[1] = widget
.ub
[2];
5400 iter
[0] = widget
.ub
[3];
5402 iter
[0] = widget
.ub
[0];
5403 iter
[1] = widget
.ub
[1];
5404 iter
[2] = widget
.ub
[2];
5405 iter
[3] = widget
.ub
[3];
5409 iter
+= element_size
;
5413 /* want 'iter' pointing at start, not within, row for assertion
5420 /* iterators should be one byte past end */
5421 if (!isTypePackedPixel(type
)) {
5422 assert(iter2
== &oldimage
[width
*height
*components
]);
5425 assert(iter2
== &oldimage
[width
*height
*
5426 elements_per_group(format
,0)]);
5428 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5429 psm
->pack_skip_rows
* rowsize
+
5430 psm
->pack_skip_pixels
* group_size
] );
5433 } /* empty_image() */
5435 /*--------------------------------------------------------------------------
5436 * Decimation of packed pixel types
5437 *--------------------------------------------------------------------------
5439 static void extract332(int isSwap
,
5440 const void *packedPixel
, GLfloat extractComponents
[])
5442 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5444 isSwap
= isSwap
; /* turn off warnings */
5446 /* 11100000 == 0xe0 */
5447 /* 00011100 == 0x1c */
5448 /* 00000011 == 0x03 */
5450 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5451 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5452 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5453 } /* extract332() */
5455 static void shove332(const GLfloat shoveComponents
[],
5456 int index
, void *packedPixel
)
5458 /* 11100000 == 0xe0 */
5459 /* 00011100 == 0x1c */
5460 /* 00000011 == 0x03 */
5462 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5463 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5464 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5466 /* due to limited precision, need to round before shoving */
5467 ((GLubyte
*)packedPixel
)[index
] =
5468 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5469 ((GLubyte
*)packedPixel
)[index
] |=
5470 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5471 ((GLubyte
*)packedPixel
)[index
] |=
5472 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5475 static void extract233rev(int isSwap
,
5476 const void *packedPixel
, GLfloat extractComponents
[])
5478 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5480 isSwap
= isSwap
; /* turn off warnings */
5482 /* 0000,0111 == 0x07 */
5483 /* 0011,1000 == 0x38 */
5484 /* 1100,0000 == 0xC0 */
5486 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5487 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5488 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5489 } /* extract233rev() */
5491 static void shove233rev(const GLfloat shoveComponents
[],
5492 int index
, void *packedPixel
)
5494 /* 0000,0111 == 0x07 */
5495 /* 0011,1000 == 0x38 */
5496 /* 1100,0000 == 0xC0 */
5498 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5499 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5500 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5502 /* due to limited precision, need to round before shoving */
5503 ((GLubyte
*)packedPixel
)[index
] =
5504 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5505 ((GLubyte
*)packedPixel
)[index
]|=
5506 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5507 ((GLubyte
*)packedPixel
)[index
]|=
5508 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5509 } /* shove233rev() */
5511 static void extract565(int isSwap
,
5512 const void *packedPixel
, GLfloat extractComponents
[])
5514 GLushort ushort
= *(const GLushort
*)packedPixel
;
5517 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5520 ushort
= *(const GLushort
*)packedPixel
;
5523 /* 11111000,00000000 == 0xf800 */
5524 /* 00000111,11100000 == 0x07e0 */
5525 /* 00000000,00011111 == 0x001f */
5527 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5528 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5529 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5530 } /* extract565() */
5532 static void shove565(const GLfloat shoveComponents
[],
5533 int index
,void *packedPixel
)
5535 /* 11111000,00000000 == 0xf800 */
5536 /* 00000111,11100000 == 0x07e0 */
5537 /* 00000000,00011111 == 0x001f */
5539 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5540 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5541 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5543 /* due to limited precision, need to round before shoving */
5544 ((GLushort
*)packedPixel
)[index
] =
5545 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5546 ((GLushort
*)packedPixel
)[index
]|=
5547 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5548 ((GLushort
*)packedPixel
)[index
]|=
5549 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5552 static void extract565rev(int isSwap
,
5553 const void *packedPixel
, GLfloat extractComponents
[])
5555 GLushort ushort
= *(const GLushort
*)packedPixel
;
5558 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5561 ushort
= *(const GLushort
*)packedPixel
;
5564 /* 00000000,00011111 == 0x001f */
5565 /* 00000111,11100000 == 0x07e0 */
5566 /* 11111000,00000000 == 0xf800 */
5568 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5569 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5570 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5571 } /* extract565rev() */
5573 static void shove565rev(const GLfloat shoveComponents
[],
5574 int index
,void *packedPixel
)
5576 /* 00000000,00011111 == 0x001f */
5577 /* 00000111,11100000 == 0x07e0 */
5578 /* 11111000,00000000 == 0xf800 */
5580 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5581 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5582 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5584 /* due to limited precision, need to round before shoving */
5585 ((GLushort
*)packedPixel
)[index
] =
5586 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5587 ((GLushort
*)packedPixel
)[index
]|=
5588 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5589 ((GLushort
*)packedPixel
)[index
]|=
5590 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5591 } /* shove565rev() */
5593 static void extract4444(int isSwap
,const void *packedPixel
,
5594 GLfloat extractComponents
[])
5599 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5602 ushort
= *(const GLushort
*)packedPixel
;
5605 /* 11110000,00000000 == 0xf000 */
5606 /* 00001111,00000000 == 0x0f00 */
5607 /* 00000000,11110000 == 0x00f0 */
5608 /* 00000000,00001111 == 0x000f */
5610 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5611 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5612 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5613 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5614 } /* extract4444() */
5616 static void shove4444(const GLfloat shoveComponents
[],
5617 int index
,void *packedPixel
)
5619 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5620 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5621 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5622 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5624 /* due to limited precision, need to round before shoving */
5625 ((GLushort
*)packedPixel
)[index
] =
5626 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5627 ((GLushort
*)packedPixel
)[index
]|=
5628 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5629 ((GLushort
*)packedPixel
)[index
]|=
5630 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5631 ((GLushort
*)packedPixel
)[index
]|=
5632 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5635 static void extract4444rev(int isSwap
,const void *packedPixel
,
5636 GLfloat extractComponents
[])
5641 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5644 ushort
= *(const GLushort
*)packedPixel
;
5647 /* 00000000,00001111 == 0x000f */
5648 /* 00000000,11110000 == 0x00f0 */
5649 /* 00001111,00000000 == 0x0f00 */
5650 /* 11110000,00000000 == 0xf000 */
5653 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5654 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5655 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5656 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5657 } /* extract4444rev() */
5659 static void shove4444rev(const GLfloat shoveComponents
[],
5660 int index
,void *packedPixel
)
5662 /* 00000000,00001111 == 0x000f */
5663 /* 00000000,11110000 == 0x00f0 */
5664 /* 00001111,00000000 == 0x0f00 */
5665 /* 11110000,00000000 == 0xf000 */
5667 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5668 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5669 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5670 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5672 /* due to limited precision, need to round before shoving */
5673 ((GLushort
*)packedPixel
)[index
] =
5674 ((GLushort
)((shoveComponents
[0] * 15)+0.5) ) & 0x000F;
5675 ((GLushort
*)packedPixel
)[index
]|=
5676 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5677 ((GLushort
*)packedPixel
)[index
]|=
5678 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5679 ((GLushort
*)packedPixel
)[index
]|=
5680 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5681 } /* shove4444rev() */
5683 static void extract5551(int isSwap
,const void *packedPixel
,
5684 GLfloat extractComponents
[])
5689 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5692 ushort
= *(const GLushort
*)packedPixel
;
5695 /* 11111000,00000000 == 0xf800 */
5696 /* 00000111,11000000 == 0x07c0 */
5697 /* 00000000,00111110 == 0x003e */
5698 /* 00000000,00000001 == 0x0001 */
5700 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5701 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5702 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5703 extractComponents
[3]=(float)((ushort
& 0x0001) );
5704 } /* extract5551() */
5706 static void shove5551(const GLfloat shoveComponents
[],
5707 int index
,void *packedPixel
)
5709 /* 11111000,00000000 == 0xf800 */
5710 /* 00000111,11000000 == 0x07c0 */
5711 /* 00000000,00111110 == 0x003e */
5712 /* 00000000,00000001 == 0x0001 */
5714 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5715 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5716 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5717 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5719 /* due to limited precision, need to round before shoving */
5720 ((GLushort
*)packedPixel
)[index
] =
5721 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5722 ((GLushort
*)packedPixel
)[index
]|=
5723 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5724 ((GLushort
*)packedPixel
)[index
]|=
5725 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5726 ((GLushort
*)packedPixel
)[index
]|=
5727 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5730 static void extract1555rev(int isSwap
,const void *packedPixel
,
5731 GLfloat extractComponents
[])
5736 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5739 ushort
= *(const GLushort
*)packedPixel
;
5742 /* 00000000,00011111 == 0x001F */
5743 /* 00000011,11100000 == 0x03E0 */
5744 /* 01111100,00000000 == 0x7C00 */
5745 /* 10000000,00000000 == 0x8000 */
5748 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5749 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5750 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5751 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5752 } /* extract1555rev() */
5754 static void shove1555rev(const GLfloat shoveComponents
[],
5755 int index
,void *packedPixel
)
5757 /* 00000000,00011111 == 0x001F */
5758 /* 00000011,11100000 == 0x03E0 */
5759 /* 01111100,00000000 == 0x7C00 */
5760 /* 10000000,00000000 == 0x8000 */
5762 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5763 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5764 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5765 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5767 /* due to limited precision, need to round before shoving */
5768 ((GLushort
*)packedPixel
)[index
] =
5769 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5770 ((GLushort
*)packedPixel
)[index
]|=
5771 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5772 ((GLushort
*)packedPixel
)[index
]|=
5773 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5774 ((GLushort
*)packedPixel
)[index
]|=
5775 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5776 } /* shove1555rev() */
5778 static void extract8888(int isSwap
,
5779 const void *packedPixel
, GLfloat extractComponents
[])
5784 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5787 uint
= *(const GLuint
*)packedPixel
;
5790 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5791 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5792 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5793 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5796 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5797 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5798 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5799 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5800 } /* extract8888() */
5802 static void shove8888(const GLfloat shoveComponents
[],
5803 int index
,void *packedPixel
)
5805 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5806 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5807 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5808 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5810 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5811 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5812 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5813 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5815 /* due to limited precision, need to round before shoving */
5816 ((GLuint
*)packedPixel
)[index
] =
5817 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5818 ((GLuint
*)packedPixel
)[index
]|=
5819 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5820 ((GLuint
*)packedPixel
)[index
]|=
5821 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5822 ((GLuint
*)packedPixel
)[index
]|=
5823 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5826 static void extract8888rev(int isSwap
,
5827 const void *packedPixel
,GLfloat extractComponents
[])
5832 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5835 uint
= *(const GLuint
*)packedPixel
;
5838 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5839 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5840 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5841 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5844 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5845 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5846 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5847 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5848 } /* extract8888rev() */
5850 static void shove8888rev(const GLfloat shoveComponents
[],
5851 int index
,void *packedPixel
)
5853 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5854 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5855 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5856 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5858 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5859 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5860 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5861 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5863 /* due to limited precision, need to round before shoving */
5864 ((GLuint
*)packedPixel
)[index
] =
5865 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5866 ((GLuint
*)packedPixel
)[index
]|=
5867 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5868 ((GLuint
*)packedPixel
)[index
]|=
5869 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5870 ((GLuint
*)packedPixel
)[index
]|=
5871 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5872 } /* shove8888rev() */
5874 static void extract1010102(int isSwap
,
5875 const void *packedPixel
,GLfloat extractComponents
[])
5880 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5883 uint
= *(const GLuint
*)packedPixel
;
5886 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5887 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5888 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5889 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5892 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5893 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5894 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5895 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5896 } /* extract1010102() */
5898 static void shove1010102(const GLfloat shoveComponents
[],
5899 int index
,void *packedPixel
)
5901 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5902 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5903 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5904 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5906 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5907 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5908 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5909 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5911 /* due to limited precision, need to round before shoving */
5912 ((GLuint
*)packedPixel
)[index
] =
5913 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5914 ((GLuint
*)packedPixel
)[index
]|=
5915 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5916 ((GLuint
*)packedPixel
)[index
]|=
5917 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5918 ((GLuint
*)packedPixel
)[index
]|=
5919 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5920 } /* shove1010102() */
5922 static void extract2101010rev(int isSwap
,
5923 const void *packedPixel
,
5924 GLfloat extractComponents
[])
5929 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5932 uint
= *(const GLuint
*)packedPixel
;
5935 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5936 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5937 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5938 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5941 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5942 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5943 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5944 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5946 } /* extract2101010rev() */
5948 static void shove2101010rev(const GLfloat shoveComponents
[],
5949 int index
,void *packedPixel
)
5951 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5952 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5953 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5954 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5956 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5957 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5958 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5959 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5961 /* due to limited precision, need to round before shoving */
5962 ((GLuint
*)packedPixel
)[index
] =
5963 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
5964 ((GLuint
*)packedPixel
)[index
]|=
5965 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
5966 ((GLuint
*)packedPixel
)[index
]|=
5967 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
5968 ((GLuint
*)packedPixel
)[index
]|=
5969 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
5970 } /* shove2101010rev() */
5972 static void scaleInternalPackedPixel(int components
,
5973 void (*extractPackedPixel
)
5974 (int, const void *,GLfloat
[]),
5975 void (*shovePackedPixel
)
5976 (const GLfloat
[], int, void *),
5977 GLint widthIn
,GLint heightIn
,
5979 GLint widthOut
,GLint heightOut
,
5981 GLint pixelSizeInBytes
,
5982 GLint rowSizeInBytes
,GLint isSwap
)
5988 /* Max components in a format is 4, so... */
5990 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
5995 const char *temp
, *temp0
;
5998 int lowx_int
, highx_int
, lowy_int
, highy_int
;
5999 float x_percent
, y_percent
;
6000 float lowx_float
, highx_float
, lowy_float
, highy_float
;
6001 float convy_float
, convx_float
;
6002 int convy_int
, convx_int
;
6004 const char *left
, *right
;
6006 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
6007 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6008 widthIn
, heightIn
, dataIn
, dataOut
,
6009 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6012 convy
= (float) heightIn
/heightOut
;
6013 convx
= (float) widthIn
/widthOut
;
6014 convy_int
= floor(convy
);
6015 convy_float
= convy
- convy_int
;
6016 convx_int
= floor(convx
);
6017 convx_float
= convx
- convx_int
;
6019 area
= convx
* convy
;
6023 highy_int
= convy_int
;
6024 highy_float
= convy_float
;
6026 for (i
= 0; i
< heightOut
; i
++) {
6029 highx_int
= convx_int
;
6030 highx_float
= convx_float
;
6032 for (j
= 0; j
< widthOut
; j
++) {
6034 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6035 ** to (highx, highy) on input data into this pixel on output
6038 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6040 /* calculate the value for pixels in the 1st row */
6041 xindex
= lowx_int
*pixelSizeInBytes
;
6042 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6044 y_percent
= 1-lowy_float
;
6045 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6046 percent
= y_percent
* (1-lowx_float
);
6048 for (k
= 0, temp_index
= temp
; k
< components
;
6049 k
++, temp_index
+= element_size
) {
6051 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6053 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6057 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6058 for (k
= 0; k
< components
; k
++) {
6059 totals
[k
]+= extractTotals
[k
] * percent
;
6063 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6064 temp
+= pixelSizeInBytes
;
6066 for (k
= 0, temp_index
= temp
; k
< components
;
6067 k
++, temp_index
+= element_size
) {
6070 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6072 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6076 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6077 for (k
= 0; k
< components
; k
++) {
6078 totals
[k
]+= extractTotals
[k
] * y_percent
;
6082 temp
+= pixelSizeInBytes
;
6084 percent
= y_percent
* highx_float
;
6086 for (k
= 0, temp_index
= temp
; k
< components
;
6087 k
++, temp_index
+= element_size
) {
6089 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6091 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6095 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6096 for (k
= 0; k
< components
; k
++) {
6097 totals
[k
]+= extractTotals
[k
] * percent
;
6101 /* calculate the value for pixels in the last row */
6103 y_percent
= highy_float
;
6104 percent
= y_percent
* (1-lowx_float
);
6105 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6107 for (k
= 0, temp_index
= temp
; k
< components
;
6108 k
++, temp_index
+= element_size
) {
6110 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6112 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6116 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6117 for (k
= 0; k
< components
; k
++) {
6118 totals
[k
]+= extractTotals
[k
] * percent
;
6121 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6122 temp
+= pixelSizeInBytes
;
6124 for (k
= 0, temp_index
= temp
; k
< components
;
6125 k
++, temp_index
+= element_size
) {
6128 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6130 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6134 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6135 for (k
= 0; k
< components
; k
++) {
6136 totals
[k
]+= extractTotals
[k
] * y_percent
;
6141 temp
+= pixelSizeInBytes
;
6142 percent
= y_percent
* highx_float
;
6144 for (k
= 0, temp_index
= temp
; k
< components
;
6145 k
++, temp_index
+= element_size
) {
6147 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6149 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6153 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6154 for (k
= 0; k
< components
; k
++) {
6155 totals
[k
]+= extractTotals
[k
] * percent
;
6159 /* calculate the value for pixels in the 1st and last column */
6160 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6161 left
+= rowSizeInBytes
;
6162 right
+= rowSizeInBytes
;
6164 for (k
= 0; k
< components
;
6165 k
++, left
+= element_size
, right
+= element_size
) {
6168 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6169 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6171 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6172 + *(const GLushort
*)right
* highx_float
;
6176 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6177 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6178 for (k
= 0; k
< components
; k
++) {
6179 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6180 extractMoreTotals
[k
]*highx_float
);
6184 } else if (highy_int
> lowy_int
) {
6185 x_percent
= highx_float
- lowx_float
;
6186 percent
= (1-lowy_float
)*x_percent
;
6187 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6189 for (k
= 0, temp_index
= temp
; k
< components
;
6190 k
++, temp_index
+= element_size
) {
6192 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6194 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6198 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6199 for (k
= 0; k
< components
; k
++) {
6200 totals
[k
]+= extractTotals
[k
] * percent
;
6203 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6204 temp
+= rowSizeInBytes
;
6206 for (k
= 0, temp_index
= temp
; k
< components
;
6207 k
++, temp_index
+= element_size
) {
6210 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6212 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6216 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6217 for (k
= 0; k
< components
; k
++) {
6218 totals
[k
]+= extractTotals
[k
] * x_percent
;
6222 percent
= x_percent
* highy_float
;
6223 temp
+= rowSizeInBytes
;
6225 for (k
= 0, temp_index
= temp
; k
< components
;
6226 k
++, temp_index
+= element_size
) {
6228 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6230 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6234 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6235 for (k
= 0; k
< components
; k
++) {
6236 totals
[k
]+= extractTotals
[k
] * percent
;
6239 } else if (highx_int
> lowx_int
) {
6240 y_percent
= highy_float
- lowy_float
;
6241 percent
= (1-lowx_float
)*y_percent
;
6242 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6244 for (k
= 0, temp_index
= temp
; k
< components
;
6245 k
++, temp_index
+= element_size
) {
6247 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6249 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6253 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6254 for (k
= 0; k
< components
; k
++) {
6255 totals
[k
]+= extractTotals
[k
] * percent
;
6258 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6259 temp
+= pixelSizeInBytes
;
6261 for (k
= 0, temp_index
= temp
; k
< components
;
6262 k
++, temp_index
+= element_size
) {
6265 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6267 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6271 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6272 for (k
= 0; k
< components
; k
++) {
6273 totals
[k
]+= extractTotals
[k
] * y_percent
;
6277 temp
+= pixelSizeInBytes
;
6278 percent
= y_percent
* highx_float
;
6280 for (k
= 0, temp_index
= temp
; k
< components
;
6281 k
++, temp_index
+= element_size
) {
6283 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6285 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6289 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6290 for (k
= 0; k
< components
; k
++) {
6291 totals
[k
]+= extractTotals
[k
] * percent
;
6295 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6296 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6298 for (k
= 0, temp_index
= temp
; k
< components
;
6299 k
++, temp_index
+= element_size
) {
6301 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6303 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6307 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6308 for (k
= 0; k
< components
; k
++) {
6309 totals
[k
]+= extractTotals
[k
] * percent
;
6314 /* this is for the pixels in the body */
6315 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6316 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6318 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6320 for (k
= 0, temp_index
= temp
; k
< components
;
6321 k
++, temp_index
+= element_size
) {
6323 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6325 totals
[k
] += *(const GLushort
*)temp_index
;
6329 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6330 for (k
= 0; k
< components
; k
++) {
6331 totals
[k
]+= extractTotals
[k
];
6334 temp
+= pixelSizeInBytes
;
6336 temp0
+= rowSizeInBytes
;
6339 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6341 for (k
= 0; k
< components
; k
++) {
6342 dataout
[outindex
+ k
] = totals
[k
]/area
;
6343 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6346 for (k
= 0; k
< components
; k
++) {
6347 shoveTotals
[k
]= totals
[k
]/area
;
6349 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6351 lowx_int
= highx_int
;
6352 lowx_float
= highx_float
;
6353 highx_int
+= convx_int
;
6354 highx_float
+= convx_float
;
6355 if(highx_float
> 1) {
6360 lowy_int
= highy_int
;
6361 lowy_float
= highy_float
;
6362 highy_int
+= convy_int
;
6363 highy_float
+= convy_float
;
6364 if(highy_float
> 1) {
6370 assert(outindex
== (widthOut
*heightOut
- 1));
6371 } /* scaleInternalPackedPixel() */
6373 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6374 * inputs; not always equal. Output NEVER has row padding.
6376 static void halveImagePackedPixel(int components
,
6377 void (*extractPackedPixel
)
6378 (int, const void *,GLfloat
[]),
6379 void (*shovePackedPixel
)
6380 (const GLfloat
[],int, void *),
6381 GLint width
, GLint height
,
6382 const void *dataIn
, void *dataOut
,
6383 GLint pixelSizeInBytes
,
6384 GLint rowSizeInBytes
, GLint isSwap
)
6386 /* handle case where there is only 1 column/row */
6387 if (width
== 1 || height
== 1) {
6388 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6389 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6390 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6391 rowSizeInBytes
,isSwap
);
6398 int halfWidth
= width
/ 2;
6399 int halfHeight
= height
/ 2;
6400 const char *src
= (const char *) dataIn
;
6401 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6404 for (ii
= 0; ii
< halfHeight
; ii
++) {
6405 for (jj
= 0; jj
< halfWidth
; jj
++) {
6407 float totals
[4]; /* 4 is maximum components */
6408 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6411 (*extractPackedPixel
)(isSwap
,src
,
6412 &extractTotals
[0][0]);
6413 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6414 &extractTotals
[1][0]);
6415 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6416 &extractTotals
[2][0]);
6417 (*extractPackedPixel
)(isSwap
,
6418 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6419 &extractTotals
[3][0]);
6420 for (cc
= 0; cc
< components
; cc
++) {
6423 /* grab 4 pixels to average */
6425 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6426 * extractTotals[2][RED]+extractTotals[3][RED];
6427 * totals[RED]/= 4.0;
6429 for (kk
= 0; kk
< BOX4
; kk
++) {
6430 totals
[cc
]+= extractTotals
[kk
][cc
];
6432 totals
[cc
]/= (float)BOX4
;
6434 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6437 /* skip over to next square of 4 */
6438 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6440 /* skip past pad bytes, if any, to get to next row */
6443 /* src is at beginning of a row here, but it's the second row of
6444 * the square block of 4 pixels that we just worked on so we
6445 * need to go one more row.
6453 src
+= rowSizeInBytes
;
6456 /* both pointers must reach one byte after the end */
6457 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6458 assert(outIndex
== halfWidth
* halfHeight
);
6460 } /* halveImagePackedPixel() */
6462 static void halve1DimagePackedPixel(int components
,
6463 void (*extractPackedPixel
)
6464 (int, const void *,GLfloat
[]),
6465 void (*shovePackedPixel
)
6466 (const GLfloat
[],int, void *),
6467 GLint width
, GLint height
,
6468 const void *dataIn
, void *dataOut
,
6469 GLint pixelSizeInBytes
,
6470 GLint rowSizeInBytes
, GLint isSwap
)
6472 int halfWidth
= width
/ 2;
6473 int halfHeight
= height
/ 2;
6474 const char *src
= (const char *) dataIn
;
6477 assert(width
== 1 || height
== 1); /* must be 1D */
6478 assert(width
!= height
); /* can't be square */
6480 if (height
== 1) { /* 1 row */
6483 assert(width
!= 1); /* widthxheight can't be 1x1 */
6486 /* one horizontal row with possible pad bytes */
6488 for (jj
= 0; jj
< halfWidth
; jj
++) {
6490 float totals
[4]; /* 4 is maximum components */
6491 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6494 /* average two at a time, instead of four */
6495 (*extractPackedPixel
)(isSwap
,src
,
6496 &extractTotals
[0][0]);
6497 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6498 &extractTotals
[1][0]);
6499 for (cc
= 0; cc
< components
; cc
++) {
6502 /* grab 2 pixels to average */
6504 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6505 * totals[RED]/= 2.0;
6507 for (kk
= 0; kk
< BOX2
; kk
++) {
6508 totals
[cc
]+= extractTotals
[kk
][cc
];
6510 totals
[cc
]/= (float)BOX2
;
6512 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6515 /* skip over to next group of 2 */
6516 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6520 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6521 src
+= padBytes
; /* for assertion only */
6523 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6524 assert(outIndex
== halfWidth
* halfHeight
);
6526 else if (width
== 1) { /* 1 column */
6529 assert(height
!= 1); /* widthxheight can't be 1x1 */
6531 /* one vertical column with possible pad bytes per row */
6532 /* average two at a time */
6534 for (jj
= 0; jj
< halfHeight
; 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
+rowSizeInBytes
),
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 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6564 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6565 assert(outIndex
== halfWidth
* halfHeight
);
6567 } /* halve1DimagePackedPixel() */
6569 /*===========================================================================*/
6571 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6573 * This section ensures that GLU 1.3 will load and run on
6574 * a GL 1.1 implementation. It dynamically resolves the
6575 * call to glTexImage3D() which might not be available.
6576 * Or is it might be supported as an extension.
6577 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6580 typedef WINAPI
void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6581 GLenum internalFormat
,
6582 GLsizei width
, GLsizei height
,
6583 GLsizei depth
, GLint border
,
6584 GLenum format
, GLenum type
,
6585 const GLvoid
*pixels
);
6587 static TexImage3Dproc pTexImage3D
;
6591 # include <sys/types.h>
6593 # include <windows.h>
6594 PROC WINAPI
wglGetProcAddress(LPCSTR
);
6597 static void gluTexImage3D( GLenum target
, GLint level
,
6598 GLenum internalFormat
,
6599 GLsizei width
, GLsizei height
,
6600 GLsizei depth
, GLint border
,
6601 GLenum format
, GLenum type
,
6602 const GLvoid
*pixels
)
6606 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6608 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6610 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6611 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6613 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6618 /* Now call glTexImage3D */
6620 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6621 depth
, border
, format
, type
, pixels
);
6626 /* Only bind to a GL 1.2 implementation: */
6627 #define gluTexImage3D glTexImage3D
6631 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6632 GLenum format
, GLenum type
)
6634 int components
= elements_per_group(format
,type
);
6635 int bytes_per_row
= bytes_per_element(type
) * width
;
6637 assert(width
> 0 && height
> 0 && depth
> 0);
6638 assert(type
!= GL_BITMAP
);
6640 return bytes_per_row
* height
* depth
* components
;
6641 } /* imageSize3D() */
6643 static void fillImage3D(const PixelStorageModes
*psm
,
6644 GLint width
, GLint height
, GLint depth
, GLenum format
,
6645 GLenum type
, GLboolean indexFormat
,
6646 const void *userImage
, GLushort
*newImage
)
6655 int elementsPerLine
;
6658 const GLubyte
*start
, *rowStart
, *iter
= NULL
;
6662 myswapBytes
= psm
->unpack_swap_bytes
;
6663 components
= elements_per_group(format
,type
);
6664 if (psm
->unpack_row_length
> 0) {
6665 groupsPerLine
= psm
->unpack_row_length
;
6668 groupsPerLine
= width
;
6670 elementSize
= bytes_per_element(type
);
6671 groupSize
= elementSize
* components
;
6672 if (elementSize
== 1) myswapBytes
= 0;
6675 if (psm
->unpack_image_height
> 0) {
6676 rowsPerImage
= psm
->unpack_image_height
;
6679 rowsPerImage
= height
;
6683 rowSize
= groupsPerLine
* groupSize
;
6684 padding
= rowSize
% psm
->unpack_alignment
;
6686 rowSize
+= psm
->unpack_alignment
- padding
;
6689 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6691 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6692 psm
->unpack_skip_pixels
* groupSize
+
6694 psm
->unpack_skip_images
* imageSize
;
6695 elementsPerLine
= width
* components
;
6698 for (dd
= 0; dd
< depth
; dd
++) {
6701 for (hh
= 0; hh
< height
; hh
++) {
6704 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6706 float extractComponents
[4];
6709 case GL_UNSIGNED_BYTE
:
6713 *iter2
++ = (*iter
) * 257;
6718 *iter2
++ = *((const GLbyte
*) iter
);
6721 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6724 case GL_UNSIGNED_BYTE_3_3_2
:
6725 extract332(0,iter
,extractComponents
);
6726 for (k
= 0; k
< 3; k
++) {
6727 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6730 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6731 extract233rev(0,iter
,extractComponents
);
6732 for (k
= 0; k
< 3; k
++) {
6733 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6736 case GL_UNSIGNED_SHORT_5_6_5
:
6737 extract565(myswapBytes
,iter
,extractComponents
);
6738 for (k
= 0; k
< 3; k
++) {
6739 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6742 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6743 extract565rev(myswapBytes
,iter
,extractComponents
);
6744 for (k
= 0; k
< 3; k
++) {
6745 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6748 case GL_UNSIGNED_SHORT_4_4_4_4
:
6749 extract4444(myswapBytes
,iter
,extractComponents
);
6750 for (k
= 0; k
< 4; k
++) {
6751 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6754 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6755 extract4444rev(myswapBytes
,iter
,extractComponents
);
6756 for (k
= 0; k
< 4; k
++) {
6757 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6760 case GL_UNSIGNED_SHORT_5_5_5_1
:
6761 extract5551(myswapBytes
,iter
,extractComponents
);
6762 for (k
= 0; k
< 4; k
++) {
6763 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6766 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6767 extract1555rev(myswapBytes
,iter
,extractComponents
);
6768 for (k
= 0; k
< 4; k
++) {
6769 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6772 case GL_UNSIGNED_SHORT
:
6775 widget
.ub
[0] = iter
[1];
6776 widget
.ub
[1] = iter
[0];
6778 widget
.ub
[0] = iter
[0];
6779 widget
.ub
[1] = iter
[1];
6781 if (type
== GL_SHORT
) {
6783 *iter2
++ = widget
.s
[0];
6786 *iter2
++ = widget
.s
[0]*2;
6789 *iter2
++ = widget
.us
[0];
6792 case GL_UNSIGNED_INT_8_8_8_8
:
6793 extract8888(myswapBytes
,iter
,extractComponents
);
6794 for (k
= 0; k
< 4; k
++) {
6795 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6798 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6799 extract8888rev(myswapBytes
,iter
,extractComponents
);
6800 for (k
= 0; k
< 4; k
++) {
6801 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6804 case GL_UNSIGNED_INT_10_10_10_2
:
6805 extract1010102(myswapBytes
,iter
,extractComponents
);
6806 for (k
= 0; k
< 4; k
++) {
6807 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6810 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6811 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6812 for (k
= 0; k
< 4; k
++) {
6813 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6817 case GL_UNSIGNED_INT
:
6820 widget
.ub
[0] = iter
[3];
6821 widget
.ub
[1] = iter
[2];
6822 widget
.ub
[2] = iter
[1];
6823 widget
.ub
[3] = iter
[0];
6825 widget
.ub
[0] = iter
[0];
6826 widget
.ub
[1] = iter
[1];
6827 widget
.ub
[2] = iter
[2];
6828 widget
.ub
[3] = iter
[3];
6830 if (type
== GL_FLOAT
) {
6832 *iter2
++ = widget
.f
;
6834 *iter2
++ = 65535 * widget
.f
;
6836 } else if (type
== GL_UNSIGNED_INT
) {
6838 *iter2
++ = widget
.ui
;
6840 *iter2
++ = widget
.ui
>> 16;
6844 *iter2
++ = widget
.i
;
6846 *iter2
++ = widget
.i
>> 15;
6858 iter
= rowStart
; /* for assertion purposes */
6864 /* iterators should be one byte past end */
6865 if (!isTypePackedPixel(type
)) {
6866 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6869 assert(iter2
== &newImage
[width
*height
*depth
*
6870 elements_per_group(format
,0)]);
6872 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6873 psm
->unpack_skip_rows
* rowSize
+
6874 psm
->unpack_skip_pixels
* groupSize
+
6876 psm
->unpack_skip_images
* imageSize
] );
6877 } /* fillImage3D () */
6879 static void scaleInternal3D(GLint components
,
6880 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6881 const GLushort
*dataIn
,
6882 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6885 float x
, lowx
, highx
, convx
, halfconvx
;
6886 float y
, lowy
, highy
, convy
, halfconvy
;
6887 float z
, lowz
, highz
, convz
, halfconvz
;
6888 float xpercent
,ypercent
,zpercent
;
6890 /* Max components in a format is 4, so... */
6893 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6896 convz
= (float) depthIn
/depthOut
;
6897 convy
= (float) heightIn
/heightOut
;
6898 convx
= (float) widthIn
/widthOut
;
6899 halfconvx
= convx
/2;
6900 halfconvy
= convy
/2;
6901 halfconvz
= convz
/2;
6902 for (d
= 0; d
< depthOut
; d
++) {
6903 z
= convz
* (d
+0.5);
6904 if (depthIn
> depthOut
) {
6905 highz
= z
+ halfconvz
;
6906 lowz
= z
- halfconvz
;
6911 for (i
= 0; i
< heightOut
; i
++) {
6912 y
= convy
* (i
+0.5);
6913 if (heightIn
> heightOut
) {
6914 highy
= y
+ halfconvy
;
6915 lowy
= y
- halfconvy
;
6920 for (j
= 0; j
< widthOut
; j
++) {
6921 x
= convx
* (j
+0.5);
6922 if (widthIn
> widthOut
) {
6923 highx
= x
+ halfconvx
;
6924 lowx
= x
- halfconvx
;
6931 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6932 ** lowz) to (highx, highy, highz) on input data into this pixel
6935 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6941 zindex
= (zint
+ depthIn
) % depthIn
;
6942 if (highz
< zint
+1) {
6943 zpercent
= highz
- z
;
6945 zpercent
= zint
+1 - z
;
6951 yindex
= (yint
+ heightIn
) % heightIn
;
6952 if (highy
< yint
+1) {
6953 ypercent
= highy
- y
;
6955 ypercent
= yint
+1 - y
;
6962 xindex
= (xint
+ widthIn
) % widthIn
;
6963 if (highx
< xint
+1) {
6964 xpercent
= highx
- x
;
6966 xpercent
= xint
+1 - x
;
6969 percent
= xpercent
* ypercent
* zpercent
;
6972 temp
= (xindex
+ (yindex
*widthIn
) +
6973 (zindex
*widthIn
*heightIn
)) * components
;
6974 for (k
= 0; k
< components
; k
++) {
6975 assert(0 <= (temp
+k
) &&
6977 (widthIn
*heightIn
*depthIn
*components
));
6978 totals
[k
] += dataIn
[temp
+ k
] * percent
;
6993 temp
= (j
+ (i
* widthOut
) +
6994 (d
*widthOut
*heightOut
)) * components
;
6995 for (k
= 0; k
< components
; k
++) {
6996 /* totals[] should be rounded in the case of enlarging an
6997 * RGB ramp when the type is 332 or 4444
6999 assert(0 <= (temp
+k
) &&
7000 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
7001 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
7006 } /* scaleInternal3D() */
7008 static void emptyImage3D(const PixelStorageModes
*psm
,
7009 GLint width
, GLint height
, GLint depth
,
7010 GLenum format
, GLenum type
, GLboolean indexFormat
,
7011 const GLushort
*oldImage
, void *userImage
)
7020 GLubyte
*start
, *rowStart
, *iter
=NULL
;
7021 int elementsPerLine
;
7022 const GLushort
*iter2
;
7027 myswapBytes
= psm
->pack_swap_bytes
;
7028 components
= elements_per_group(format
,type
);
7029 if (psm
->pack_row_length
> 0) {
7030 groupsPerLine
= psm
->pack_row_length
;
7033 groupsPerLine
= width
;
7036 elementSize
= bytes_per_element(type
);
7037 groupSize
= elementSize
* components
;
7038 if (elementSize
== 1) myswapBytes
= 0;
7041 if (psm
->pack_image_height
> 0) {
7042 rowsPerImage
= psm
->pack_image_height
;
7045 rowsPerImage
= height
;
7050 rowSize
= groupsPerLine
* groupSize
;
7051 padding
= rowSize
% psm
->pack_alignment
;
7053 rowSize
+= psm
->pack_alignment
- padding
;
7056 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7058 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7059 psm
->pack_skip_pixels
* groupSize
+
7061 psm
->pack_skip_images
* imageSize
;
7062 elementsPerLine
= width
* components
;
7065 for (dd
= 0; dd
< depth
; dd
++) {
7068 for (ii
= 0; ii
< height
; ii
++) {
7071 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7073 float shoveComponents
[4];
7076 case GL_UNSIGNED_BYTE
:
7080 *iter
= *iter2
++ >> 8;
7085 *((GLbyte
*) iter
) = *iter2
++;
7087 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7090 case GL_UNSIGNED_BYTE_3_3_2
:
7091 for (k
= 0; k
< 3; k
++) {
7092 shoveComponents
[k
]= *iter2
++ / 65535.0;
7094 shove332(shoveComponents
,0,(void *)iter
);
7096 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7097 for (k
= 0; k
< 3; k
++) {
7098 shoveComponents
[k
]= *iter2
++ / 65535.0;
7100 shove233rev(shoveComponents
,0,(void *)iter
);
7102 case GL_UNSIGNED_SHORT_5_6_5
:
7103 for (k
= 0; k
< 3; k
++) {
7104 shoveComponents
[k
]= *iter2
++ / 65535.0;
7106 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7108 iter
[0] = widget
.ub
[1];
7109 iter
[1] = widget
.ub
[0];
7112 *(GLushort
*)iter
= widget
.us
[0];
7115 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7116 for (k
= 0; k
< 3; k
++) {
7117 shoveComponents
[k
]= *iter2
++ / 65535.0;
7119 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7121 iter
[0] = widget
.ub
[1];
7122 iter
[1] = widget
.ub
[0];
7125 *(GLushort
*)iter
= widget
.us
[0];
7128 case GL_UNSIGNED_SHORT_4_4_4_4
:
7129 for (k
= 0; k
< 4; k
++) {
7130 shoveComponents
[k
]= *iter2
++ / 65535.0;
7132 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7134 iter
[0] = widget
.ub
[1];
7135 iter
[1] = widget
.ub
[0];
7137 *(GLushort
*)iter
= widget
.us
[0];
7140 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7141 for (k
= 0; k
< 4; k
++) {
7142 shoveComponents
[k
]= *iter2
++ / 65535.0;
7144 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7146 iter
[0] = widget
.ub
[1];
7147 iter
[1] = widget
.ub
[0];
7149 *(GLushort
*)iter
= widget
.us
[0];
7152 case GL_UNSIGNED_SHORT_5_5_5_1
:
7153 for (k
= 0; k
< 4; k
++) {
7154 shoveComponents
[k
]= *iter2
++ / 65535.0;
7156 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7158 iter
[0] = widget
.ub
[1];
7159 iter
[1] = widget
.ub
[0];
7161 *(GLushort
*)iter
= widget
.us
[0];
7164 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7165 for (k
= 0; k
< 4; k
++) {
7166 shoveComponents
[k
]= *iter2
++ / 65535.0;
7168 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7170 iter
[0] = widget
.ub
[1];
7171 iter
[1] = widget
.ub
[0];
7173 *(GLushort
*)iter
= widget
.us
[0];
7176 case GL_UNSIGNED_SHORT
:
7178 if (type
== GL_SHORT
) {
7180 widget
.s
[0] = *iter2
++;
7182 widget
.s
[0] = *iter2
++ >> 1;
7185 widget
.us
[0] = *iter2
++;
7188 iter
[0] = widget
.ub
[1];
7189 iter
[1] = widget
.ub
[0];
7191 iter
[0] = widget
.ub
[0];
7192 iter
[1] = widget
.ub
[1];
7195 case GL_UNSIGNED_INT_8_8_8_8
:
7196 for (k
= 0; k
< 4; k
++) {
7197 shoveComponents
[k
]= *iter2
++ / 65535.0;
7199 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7201 iter
[3] = widget
.ub
[0];
7202 iter
[2] = widget
.ub
[1];
7203 iter
[1] = widget
.ub
[2];
7204 iter
[0] = widget
.ub
[3];
7206 *(GLuint
*)iter
= widget
.ui
;
7209 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7210 for (k
= 0; k
< 4; k
++) {
7211 shoveComponents
[k
]= *iter2
++ / 65535.0;
7213 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7215 iter
[3] = widget
.ub
[0];
7216 iter
[2] = widget
.ub
[1];
7217 iter
[1] = widget
.ub
[2];
7218 iter
[0] = widget
.ub
[3];
7220 *(GLuint
*)iter
= widget
.ui
;
7223 case GL_UNSIGNED_INT_10_10_10_2
:
7224 for (k
= 0; k
< 4; k
++) {
7225 shoveComponents
[k
]= *iter2
++ / 65535.0;
7227 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7229 iter
[3] = widget
.ub
[0];
7230 iter
[2] = widget
.ub
[1];
7231 iter
[1] = widget
.ub
[2];
7232 iter
[0] = widget
.ub
[3];
7234 *(GLuint
*)iter
= widget
.ui
;
7237 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7238 for (k
= 0; k
< 4; k
++) {
7239 shoveComponents
[k
]= *iter2
++ / 65535.0;
7241 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7243 iter
[3] = widget
.ub
[0];
7244 iter
[2] = widget
.ub
[1];
7245 iter
[1] = widget
.ub
[2];
7246 iter
[0] = widget
.ub
[3];
7248 *(GLuint
*)iter
= widget
.ui
;
7252 case GL_UNSIGNED_INT
:
7254 if (type
== GL_FLOAT
) {
7256 widget
.f
= *iter2
++;
7258 widget
.f
= *iter2
++ / (float) 65535.0;
7260 } else if (type
== GL_UNSIGNED_INT
) {
7262 widget
.ui
= *iter2
++;
7264 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7268 widget
.i
= *iter2
++;
7270 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
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 iter
[0] = widget
.ub
[0];
7280 iter
[1] = widget
.ub
[1];
7281 iter
[2] = widget
.ub
[2];
7282 iter
[3] = widget
.ub
[3];
7298 /* iterators should be one byte past end */
7299 if (!isTypePackedPixel(type
)) {
7300 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7303 assert(iter2
== &oldImage
[width
*height
*depth
*
7304 elements_per_group(format
,0)]);
7306 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7307 psm
->unpack_skip_rows
* rowSize
+
7308 psm
->unpack_skip_pixels
* groupSize
+
7310 psm
->unpack_skip_images
* imageSize
] );
7311 } /* emptyImage3D() */
7314 int gluScaleImage3D(GLenum format
,
7315 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7316 GLenum typeIn
, const void *dataIn
,
7317 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7318 GLenum typeOut
, void *dataOut
)
7321 GLushort
*beforeImage
, *afterImage
;
7322 PixelStorageModes psm
;
7324 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7325 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7329 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7330 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7331 return GLU_INVALID_VALUE
;
7334 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7335 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7336 return GLU_INVALID_ENUM
;
7338 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7339 return GLU_INVALID_OPERATION
;
7341 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7342 return GLU_INVALID_OPERATION
;
7345 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7346 GL_UNSIGNED_SHORT
));
7347 if (beforeImage
== NULL
) {
7348 return GLU_OUT_OF_MEMORY
;
7351 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7352 GL_UNSIGNED_SHORT
));
7353 if (afterImage
== NULL
) {
7355 return GLU_OUT_OF_MEMORY
;
7357 retrieveStoreModes3D(&psm
);
7359 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7360 dataIn
, beforeImage
);
7361 components
= elements_per_group(format
,0);
7362 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7363 widthOut
,heightOut
,depthOut
,afterImage
);
7364 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7365 is_index(format
),afterImage
, dataOut
);
7366 free((void *) beforeImage
);
7367 free((void *) afterImage
);
7370 } /* gluScaleImage3D() */
7373 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7374 GLint internalFormat
, GLenum format
, GLenum type
,
7375 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7377 GLint widthPowerOf2
= nearestPower(width
);
7378 GLint heightPowerOf2
= nearestPower(height
);
7379 GLint depthPowerOf2
= nearestPower(depth
);
7383 /* compute level 1 width & height & depth, clamping each at 1 */
7384 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7385 widthPowerOf2
>> 1 :
7387 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7388 heightPowerOf2
>> 1 :
7390 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7391 depthPowerOf2
>> 1 :
7393 GLenum proxyTarget
= 0;
7394 assert(widthAtLevelOne
> 0);
7395 assert(heightAtLevelOne
> 0);
7396 assert(depthAtLevelOne
> 0);
7398 /* does width x height x depth at level 1 & all their mipmaps fit? */
7399 if (target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
) {
7400 proxyTarget
= GL_PROXY_TEXTURE_3D
;
7401 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7403 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7404 0,format
,type
,NULL
);
7406 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7407 /* does it fit??? */
7408 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7409 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7410 depthPowerOf2
== 1) {
7411 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7414 widthPowerOf2
= widthAtLevelOne
;
7415 heightPowerOf2
= heightAtLevelOne
;
7416 depthPowerOf2
= depthAtLevelOne
;
7418 /* else it does fit */
7419 } while (proxyWidth
== 0);
7420 /* loop must terminate! */
7422 /* return the width & height at level 0 that fits */
7423 *newWidth
= widthPowerOf2
;
7424 *newHeight
= heightPowerOf2
;
7425 *newDepth
= depthPowerOf2
;
7426 /*printf("Proxy Textures\n");*/
7427 } /* closestFit3D() */
7429 static void halveImagePackedPixelSlice(int components
,
7430 void (*extractPackedPixel
)
7431 (int, const void *,GLfloat
[]),
7432 void (*shovePackedPixel
)
7433 (const GLfloat
[],int, void *),
7434 GLint width
, GLint height
, GLint depth
,
7435 const void *dataIn
, void *dataOut
,
7436 GLint pixelSizeInBytes
,
7437 GLint rowSizeInBytes
,
7438 GLint imageSizeInBytes
,
7442 int halfWidth
= width
/ 2;
7443 int halfHeight
= height
/ 2;
7444 int halfDepth
= depth
/ 2;
7445 const char *src
= (const char *)dataIn
;
7448 assert((width
== 1 || height
== 1) && depth
>= 2);
7450 if (width
== height
) { /* a 1-pixel column viewed from top */
7451 assert(width
== 1 && height
== 1);
7454 for (ii
= 0; ii
< halfDepth
; ii
++) {
7456 float extractTotals
[BOX2
][4];
7459 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7460 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7461 &extractTotals
[1][0]);
7462 for (cc
= 0; cc
< components
; cc
++) {
7465 /* average 2 pixels since only a column */
7467 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7468 * totals[RED]/= 2.0;
7470 for (kk
= 0; kk
< BOX2
; kk
++) {
7471 totals
[cc
]+= extractTotals
[kk
][cc
];
7473 totals
[cc
]/= (float)BOX2
;
7476 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7478 /* skip over to next group of 2 */
7479 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7482 else if (height
== 1) { /* horizontal slice viewed from top */
7485 for (ii
= 0; ii
< halfDepth
; ii
++) {
7486 for (jj
= 0; jj
< halfWidth
; jj
++) {
7488 float extractTotals
[BOX4
][4];
7491 (*extractPackedPixel
)(isSwap
,src
,
7492 &extractTotals
[0][0]);
7493 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7494 &extractTotals
[1][0]);
7495 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7496 &extractTotals
[2][0]);
7497 (*extractPackedPixel
)(isSwap
,
7498 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7499 &extractTotals
[3][0]);
7500 for (cc
= 0; cc
< components
; cc
++) {
7503 /* grab 4 pixels to average */
7505 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7506 * extractTotals[2][RED]+extractTotals[3][RED];
7507 * totals[RED]/= 4.0;
7509 for (kk
= 0; kk
< BOX4
; kk
++) {
7510 totals
[cc
]+= extractTotals
[kk
][cc
];
7512 totals
[cc
]/= (float)BOX4
;
7514 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7517 /* skip over to next horizontal square of 4 */
7518 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7524 else if (width
== 1) { /* vertical slice viewed from top */
7525 assert(height
!= 1);
7527 for (ii
= 0; ii
< halfDepth
; ii
++) {
7528 for (jj
= 0; jj
< halfHeight
; jj
++) {
7530 float extractTotals
[BOX4
][4];
7533 (*extractPackedPixel
)(isSwap
,src
,
7534 &extractTotals
[0][0]);
7535 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7536 &extractTotals
[1][0]);
7537 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7538 &extractTotals
[2][0]);
7539 (*extractPackedPixel
)(isSwap
,
7540 (src
+imageSizeInBytes
+rowSizeInBytes
),
7541 &extractTotals
[3][0]);
7542 for (cc
= 0; cc
< components
; cc
++) {
7545 /* grab 4 pixels to average */
7547 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7548 * extractTotals[2][RED]+extractTotals[3][RED];
7549 * totals[RED]/= 4.0;
7551 for (kk
= 0; kk
< BOX4
; kk
++) {
7552 totals
[cc
]+= extractTotals
[kk
][cc
];
7554 totals
[cc
]/= (float)BOX4
;
7556 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7560 /* skip over to next vertical square of 4 */
7561 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7567 } /* halveImagePackedPixelSlice() */
7569 static void halveImagePackedPixel3D(int components
,
7570 void (*extractPackedPixel
)
7571 (int, const void *,GLfloat
[]),
7572 void (*shovePackedPixel
)
7573 (const GLfloat
[],int, void *),
7574 GLint width
, GLint height
, GLint depth
,
7575 const void *dataIn
, void *dataOut
,
7576 GLint pixelSizeInBytes
,
7577 GLint rowSizeInBytes
,
7578 GLint imageSizeInBytes
,
7582 assert(1 <= width
&& 1 <= height
);
7584 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7585 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7586 rowSizeInBytes
,isSwap
);
7589 /* a horizontal or vertical slice viewed from top */
7590 else if (width
== 1 || height
== 1) {
7593 halveImagePackedPixelSlice(components
,
7594 extractPackedPixel
,shovePackedPixel
,
7595 width
, height
, depth
, dataIn
, dataOut
,
7596 pixelSizeInBytes
, rowSizeInBytes
,
7597 imageSizeInBytes
, isSwap
);
7603 int halfWidth
= width
/ 2;
7604 int halfHeight
= height
/ 2;
7605 int halfDepth
= depth
/ 2;
7606 const char *src
= (const char *) dataIn
;
7607 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7610 for (dd
= 0; dd
< halfDepth
; dd
++) {
7611 for (ii
= 0; ii
< halfHeight
; ii
++) {
7612 for (jj
= 0; jj
< halfWidth
; jj
++) {
7614 float totals
[4]; /* 4 is maximum components */
7615 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7618 (*extractPackedPixel
)(isSwap
,src
,
7619 &extractTotals
[0][0]);
7620 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7621 &extractTotals
[1][0]);
7622 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7623 &extractTotals
[2][0]);
7624 (*extractPackedPixel
)(isSwap
,
7625 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7626 &extractTotals
[3][0]);
7628 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7629 &extractTotals
[4][0]);
7630 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7631 &extractTotals
[5][0]);
7632 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7633 &extractTotals
[6][0]);
7634 (*extractPackedPixel
)(isSwap
,
7635 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7636 &extractTotals
[7][0]);
7637 for (cc
= 0; cc
< components
; cc
++) {
7640 /* grab 8 pixels to average */
7642 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7643 * extractTotals[2][RED]+extractTotals[3][RED]+
7644 * extractTotals[4][RED]+extractTotals[5][RED]+
7645 * extractTotals[6][RED]+extractTotals[7][RED];
7646 * totals[RED]/= 8.0;
7648 for (kk
= 0; kk
< BOX8
; kk
++) {
7649 totals
[cc
]+= extractTotals
[kk
][cc
];
7651 totals
[cc
]/= (float)BOX8
;
7653 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7656 /* skip over to next square of 4 */
7657 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7659 /* skip past pad bytes, if any, to get to next row */
7662 /* src is at beginning of a row here, but it's the second row of
7663 * the square block of 4 pixels that we just worked on so we
7664 * need to go one more row.
7672 src
+= rowSizeInBytes
;
7675 src
+= imageSizeInBytes
;
7678 /* both pointers must reach one byte after the end */
7679 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7680 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7683 } /* halveImagePackedPixel3D() */
7685 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7689 GLsizei widthPowerOf2
,
7690 GLsizei heightPowerOf2
,
7691 GLsizei depthPowerOf2
,
7692 GLenum format
, GLenum type
,
7694 GLint baseLevel
,GLint maxLevel
,
7697 GLint newWidth
, newHeight
, newDepth
;
7698 GLint level
, levels
;
7699 const void *usersImage
;
7700 void *srcImage
, *dstImage
;
7701 __GLU_INIT_SWAP_IMAGE
;
7705 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7706 GLint rowsPerImage
, imageSize
;
7707 GLint rowSize
, padding
;
7708 PixelStorageModes psm
;
7710 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7711 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7712 assert(type
!= GL_BITMAP
);
7714 srcImage
= dstImage
= NULL
;
7716 newWidth
= widthPowerOf2
;
7717 newHeight
= heightPowerOf2
;
7718 newDepth
= depthPowerOf2
;
7719 levels
= computeLog(newWidth
);
7720 level
= computeLog(newHeight
);
7721 if (level
> levels
) levels
=level
;
7722 level
= computeLog(newDepth
);
7723 if (level
> levels
) levels
=level
;
7727 retrieveStoreModes3D(&psm
);
7728 myswapBytes
= psm
.unpack_swap_bytes
;
7729 cmpts
= elements_per_group(format
,type
);
7730 if (psm
.unpack_row_length
> 0) {
7731 groupsPerLine
= psm
.unpack_row_length
;
7733 groupsPerLine
= width
;
7736 elementSize
= bytes_per_element(type
);
7737 groupSize
= elementSize
* cmpts
;
7738 if (elementSize
== 1) myswapBytes
= 0;
7741 if (psm
.unpack_image_height
> 0) {
7742 rowsPerImage
= psm
.unpack_image_height
;
7745 rowsPerImage
= height
;
7749 rowSize
= groupsPerLine
* groupSize
;
7750 padding
= (rowSize
% psm
.unpack_alignment
);
7752 rowSize
+= psm
.unpack_alignment
- padding
;
7755 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7757 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7758 psm
.unpack_skip_pixels
* groupSize
+
7760 psm
.unpack_skip_images
* imageSize
;
7762 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7763 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7764 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7765 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7766 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7770 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7771 /* Use usersImage for level userLevel */
7772 if (baseLevel
<= level
&& level
<= maxLevel
) {
7773 gluTexImage3D(target
, level
, internalFormat
, width
,
7774 height
, depth
, 0, format
, type
,
7777 if(levels
== 0) { /* we're done. clean up and return */
7778 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7779 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7780 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7781 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7782 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7783 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7784 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7788 int nextWidth
= newWidth
/2;
7789 int nextHeight
= newHeight
/2;
7790 int nextDepth
= newDepth
/2;
7793 if (nextWidth
< 1) nextWidth
= 1;
7794 if (nextHeight
< 1) nextHeight
= 1;
7795 if (nextDepth
< 1) nextDepth
= 1;
7796 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7799 case GL_UNSIGNED_BYTE
:
7800 dstImage
= (GLubyte
*)malloc(memReq
);
7803 dstImage
= (GLbyte
*)malloc(memReq
);
7805 case GL_UNSIGNED_SHORT
:
7806 dstImage
= (GLushort
*)malloc(memReq
);
7809 dstImage
= (GLshort
*)malloc(memReq
);
7811 case GL_UNSIGNED_INT
:
7812 dstImage
= (GLuint
*)malloc(memReq
);
7815 dstImage
= (GLint
*)malloc(memReq
);
7818 dstImage
= (GLfloat
*)malloc(memReq
);
7820 case GL_UNSIGNED_BYTE_3_3_2
:
7821 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7822 dstImage
= (GLubyte
*)malloc(memReq
);
7824 case GL_UNSIGNED_SHORT_5_6_5
:
7825 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7826 case GL_UNSIGNED_SHORT_4_4_4_4
:
7827 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7828 case GL_UNSIGNED_SHORT_5_5_5_1
:
7829 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7830 dstImage
= (GLushort
*)malloc(memReq
);
7832 case GL_UNSIGNED_INT_8_8_8_8
:
7833 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7834 case GL_UNSIGNED_INT_10_10_10_2
:
7835 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7836 dstImage
= (GLuint
*)malloc(memReq
);
7839 return GLU_INVALID_ENUM
; /* assertion */
7841 if (dstImage
== NULL
) {
7842 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7843 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7844 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7845 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7846 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7847 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7848 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7849 return GLU_OUT_OF_MEMORY
;
7853 case GL_UNSIGNED_BYTE
:
7855 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7857 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7858 imageSize
,myswapBytes
);
7861 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7862 elementSize
,rowSize
,groupSize
);
7867 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7869 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7870 imageSize
,myswapBytes
);
7873 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7874 elementSize
,rowSize
,groupSize
);
7877 case GL_UNSIGNED_SHORT
:
7879 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7881 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7882 imageSize
,myswapBytes
);
7885 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7886 elementSize
,rowSize
,groupSize
,myswapBytes
);
7891 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7893 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7894 imageSize
,myswapBytes
);
7897 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7898 elementSize
,rowSize
,groupSize
,myswapBytes
);
7901 case GL_UNSIGNED_INT
:
7903 halveImage3D(cmpts
,extractUint
,shoveUint
,
7905 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7906 imageSize
,myswapBytes
);
7909 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7910 elementSize
,rowSize
,groupSize
,myswapBytes
);
7915 halveImage3D(cmpts
,extractSint
,shoveSint
,
7917 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7918 imageSize
,myswapBytes
);
7921 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7922 elementSize
,rowSize
,groupSize
,myswapBytes
);
7927 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7929 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7930 imageSize
,myswapBytes
);
7933 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7934 elementSize
,rowSize
,groupSize
,myswapBytes
);
7937 case GL_UNSIGNED_BYTE_3_3_2
:
7938 assert(format
== GL_RGB
);
7939 halveImagePackedPixel3D(3,extract332
,shove332
,
7940 width
,height
,depth
,usersImage
,dstImage
,
7941 elementSize
,rowSize
,imageSize
,myswapBytes
);
7943 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7944 assert(format
== GL_RGB
);
7945 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7946 width
,height
,depth
,usersImage
,dstImage
,
7947 elementSize
,rowSize
,imageSize
,myswapBytes
);
7949 case GL_UNSIGNED_SHORT_5_6_5
:
7950 halveImagePackedPixel3D(3,extract565
,shove565
,
7951 width
,height
,depth
,usersImage
,dstImage
,
7952 elementSize
,rowSize
,imageSize
,myswapBytes
);
7954 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7955 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7956 width
,height
,depth
,usersImage
,dstImage
,
7957 elementSize
,rowSize
,imageSize
,myswapBytes
);
7959 case GL_UNSIGNED_SHORT_4_4_4_4
:
7960 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7961 width
,height
,depth
,usersImage
,dstImage
,
7962 elementSize
,rowSize
,imageSize
,myswapBytes
);
7964 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7965 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
7966 width
,height
,depth
,usersImage
,dstImage
,
7967 elementSize
,rowSize
,imageSize
,myswapBytes
);
7969 case GL_UNSIGNED_SHORT_5_5_5_1
:
7970 halveImagePackedPixel3D(4,extract5551
,shove5551
,
7971 width
,height
,depth
,usersImage
,dstImage
,
7972 elementSize
,rowSize
,imageSize
,myswapBytes
);
7974 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7975 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
7976 width
,height
,depth
,usersImage
,dstImage
,
7977 elementSize
,rowSize
,imageSize
,myswapBytes
);
7979 case GL_UNSIGNED_INT_8_8_8_8
:
7980 halveImagePackedPixel3D(4,extract8888
,shove8888
,
7981 width
,height
,depth
,usersImage
,dstImage
,
7982 elementSize
,rowSize
,imageSize
,myswapBytes
);
7984 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7985 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
7986 width
,height
,depth
,usersImage
,dstImage
,
7987 elementSize
,rowSize
,imageSize
,myswapBytes
);
7989 case GL_UNSIGNED_INT_10_10_10_2
:
7990 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
7991 width
,height
,depth
,usersImage
,dstImage
,
7992 elementSize
,rowSize
,imageSize
,myswapBytes
);
7994 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7995 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
7996 width
,height
,depth
,usersImage
,dstImage
,
7997 elementSize
,rowSize
,imageSize
,myswapBytes
);
8004 newHeight
= height
/2;
8007 if (newWidth
< 1) newWidth
= 1;
8008 if (newHeight
< 1) newHeight
= 1;
8009 if (newDepth
< 1) newDepth
= 1;
8012 rowSize
= newWidth
* groupSize
;
8013 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8014 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8015 /* Swap srcImage and dstImage */
8016 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8018 case GL_UNSIGNED_BYTE
:
8019 dstImage
= (GLubyte
*)malloc(memReq
);
8022 dstImage
= (GLbyte
*)malloc(memReq
);
8024 case GL_UNSIGNED_SHORT
:
8025 dstImage
= (GLushort
*)malloc(memReq
);
8028 dstImage
= (GLshort
*)malloc(memReq
);
8030 case GL_UNSIGNED_INT
:
8031 dstImage
= (GLuint
*)malloc(memReq
);
8034 dstImage
= (GLint
*)malloc(memReq
);
8037 dstImage
= (GLfloat
*)malloc(memReq
);
8039 case GL_UNSIGNED_BYTE_3_3_2
:
8040 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8041 dstImage
= (GLubyte
*)malloc(memReq
);
8043 case GL_UNSIGNED_SHORT_5_6_5
:
8044 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8045 case GL_UNSIGNED_SHORT_4_4_4_4
:
8046 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8047 case GL_UNSIGNED_SHORT_5_5_5_1
:
8048 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8049 dstImage
= (GLushort
*)malloc(memReq
);
8051 case GL_UNSIGNED_INT_8_8_8_8
:
8052 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8053 case GL_UNSIGNED_INT_10_10_10_2
:
8054 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8055 dstImage
= (GLuint
*)malloc(memReq
);
8058 return GLU_INVALID_ENUM
; /* assertion */
8060 if (dstImage
== NULL
) {
8061 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8062 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8063 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8064 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8065 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8066 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8067 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8068 return GLU_OUT_OF_MEMORY
;
8070 /* level userLevel+1 is in srcImage; level userLevel already saved */
8071 level
= userLevel
+1;
8072 } else {/* user's image is *not* nice power-of-2 sized square */
8073 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8075 case GL_UNSIGNED_BYTE
:
8076 dstImage
= (GLubyte
*)malloc(memReq
);
8079 dstImage
= (GLbyte
*)malloc(memReq
);
8081 case GL_UNSIGNED_SHORT
:
8082 dstImage
= (GLushort
*)malloc(memReq
);
8085 dstImage
= (GLshort
*)malloc(memReq
);
8087 case GL_UNSIGNED_INT
:
8088 dstImage
= (GLuint
*)malloc(memReq
);
8091 dstImage
= (GLint
*)malloc(memReq
);
8094 dstImage
= (GLfloat
*)malloc(memReq
);
8096 case GL_UNSIGNED_BYTE_3_3_2
:
8097 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8098 dstImage
= (GLubyte
*)malloc(memReq
);
8100 case GL_UNSIGNED_SHORT_5_6_5
:
8101 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8102 case GL_UNSIGNED_SHORT_4_4_4_4
:
8103 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8104 case GL_UNSIGNED_SHORT_5_5_5_1
:
8105 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8106 dstImage
= (GLushort
*)malloc(memReq
);
8108 case GL_UNSIGNED_INT_8_8_8_8
:
8109 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8110 case GL_UNSIGNED_INT_10_10_10_2
:
8111 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8112 dstImage
= (GLuint
*)malloc(memReq
);
8115 return GLU_INVALID_ENUM
; /* assertion */
8118 if (dstImage
== NULL
) {
8119 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8120 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8121 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8122 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8123 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8124 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8125 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8126 return GLU_OUT_OF_MEMORY
;
8128 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8129 width,height,depth,newWidth,newHeight,newDepth);*/
8131 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8132 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8135 rowSize
= newWidth
* groupSize
;
8136 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8137 /* Swap dstImage and srcImage */
8138 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8140 if(levels
!= 0) { /* use as little memory as possible */
8142 int nextWidth
= newWidth
/2;
8143 int nextHeight
= newHeight
/2;
8144 int nextDepth
= newDepth
/2;
8145 if (nextWidth
< 1) nextWidth
= 1;
8146 if (nextHeight
< 1) nextHeight
= 1;
8147 if (nextDepth
< 1) nextDepth
= 1;
8149 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8152 case GL_UNSIGNED_BYTE
:
8153 dstImage
= (GLubyte
*)malloc(memReq
);
8156 dstImage
= (GLbyte
*)malloc(memReq
);
8158 case GL_UNSIGNED_SHORT
:
8159 dstImage
= (GLushort
*)malloc(memReq
);
8162 dstImage
= (GLshort
*)malloc(memReq
);
8164 case GL_UNSIGNED_INT
:
8165 dstImage
= (GLuint
*)malloc(memReq
);
8168 dstImage
= (GLint
*)malloc(memReq
);
8171 dstImage
= (GLfloat
*)malloc(memReq
);
8173 case GL_UNSIGNED_BYTE_3_3_2
:
8174 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8175 dstImage
= (GLubyte
*)malloc(memReq
);
8177 case GL_UNSIGNED_SHORT_5_6_5
:
8178 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8179 case GL_UNSIGNED_SHORT_4_4_4_4
:
8180 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8181 case GL_UNSIGNED_SHORT_5_5_5_1
:
8182 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8183 dstImage
= (GLushort
*)malloc(memReq
);
8185 case GL_UNSIGNED_INT_8_8_8_8
:
8186 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8187 case GL_UNSIGNED_INT_10_10_10_2
:
8188 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8189 dstImage
= (GLuint
*)malloc(memReq
);
8192 return GLU_INVALID_ENUM
; /* assertion */
8194 if (dstImage
== NULL
) {
8195 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8196 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8197 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8198 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8199 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8200 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8201 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8202 return GLU_OUT_OF_MEMORY
;
8205 /* level userLevel is in srcImage; nothing saved yet */
8209 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8210 if (baseLevel
<= level
&& level
<= maxLevel
) {
8211 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8212 0,format
, type
, (void *)srcImage
);
8214 level
++; /* update current level for the loop */
8215 for (; level
<= levels
; level
++) {
8217 case GL_UNSIGNED_BYTE
:
8219 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8220 newWidth
,newHeight
,newDepth
,
8221 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8222 imageSize
,myswapBytes
);
8225 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8226 elementSize
,rowSize
,groupSize
);
8231 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8232 newWidth
,newHeight
,newDepth
,
8233 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8234 imageSize
,myswapBytes
);
8237 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8238 elementSize
,rowSize
,groupSize
);
8241 case GL_UNSIGNED_SHORT
:
8243 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8244 newWidth
,newHeight
,newDepth
,
8245 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8246 imageSize
,myswapBytes
);
8249 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8250 elementSize
,rowSize
,groupSize
,myswapBytes
);
8255 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8256 newWidth
,newHeight
,newDepth
,
8257 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8258 imageSize
,myswapBytes
);
8261 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8262 elementSize
,rowSize
,groupSize
,myswapBytes
);
8265 case GL_UNSIGNED_INT
:
8267 halveImage3D(cmpts
,extractUint
,shoveUint
,
8268 newWidth
,newHeight
,newDepth
,
8269 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8270 imageSize
,myswapBytes
);
8273 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8274 elementSize
,rowSize
,groupSize
,myswapBytes
);
8279 halveImage3D(cmpts
,extractSint
,shoveSint
,
8280 newWidth
,newHeight
,newDepth
,
8281 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8282 imageSize
,myswapBytes
);
8285 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8286 elementSize
,rowSize
,groupSize
,myswapBytes
);
8291 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8292 newWidth
,newHeight
,newDepth
,
8293 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8294 imageSize
,myswapBytes
);
8297 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8298 elementSize
,rowSize
,groupSize
,myswapBytes
);
8301 case GL_UNSIGNED_BYTE_3_3_2
:
8302 halveImagePackedPixel3D(3,extract332
,shove332
,
8303 newWidth
,newHeight
,newDepth
,
8304 srcImage
,dstImage
,elementSize
,rowSize
,
8305 imageSize
,myswapBytes
);
8307 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8308 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8309 newWidth
,newHeight
,newDepth
,
8310 srcImage
,dstImage
,elementSize
,rowSize
,
8311 imageSize
,myswapBytes
);
8313 case GL_UNSIGNED_SHORT_5_6_5
:
8314 halveImagePackedPixel3D(3,extract565
,shove565
,
8315 newWidth
,newHeight
,newDepth
,
8316 srcImage
,dstImage
,elementSize
,rowSize
,
8317 imageSize
,myswapBytes
);
8319 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8320 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8321 newWidth
,newHeight
,newDepth
,
8322 srcImage
,dstImage
,elementSize
,rowSize
,
8323 imageSize
,myswapBytes
);
8325 case GL_UNSIGNED_SHORT_4_4_4_4
:
8326 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8327 newWidth
,newHeight
,newDepth
,
8328 srcImage
,dstImage
,elementSize
,rowSize
,
8329 imageSize
,myswapBytes
);
8331 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8332 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8333 newWidth
,newHeight
,newDepth
,
8334 srcImage
,dstImage
,elementSize
,rowSize
,
8335 imageSize
,myswapBytes
);
8337 case GL_UNSIGNED_SHORT_5_5_5_1
:
8338 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8339 newWidth
,newHeight
,newDepth
,
8340 srcImage
,dstImage
,elementSize
,rowSize
,
8341 imageSize
,myswapBytes
);
8343 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8344 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8345 newWidth
,newHeight
,newDepth
,
8346 srcImage
,dstImage
,elementSize
,rowSize
,
8347 imageSize
,myswapBytes
);
8349 case GL_UNSIGNED_INT_8_8_8_8
:
8350 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8351 newWidth
,newHeight
,newDepth
,
8352 srcImage
,dstImage
,elementSize
,rowSize
,
8353 imageSize
,myswapBytes
);
8355 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8356 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8357 newWidth
,newHeight
,newDepth
,
8358 srcImage
,dstImage
,elementSize
,rowSize
,
8359 imageSize
,myswapBytes
);
8361 case GL_UNSIGNED_INT_10_10_10_2
:
8362 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8363 newWidth
,newHeight
,newDepth
,
8364 srcImage
,dstImage
,elementSize
,rowSize
,
8365 imageSize
,myswapBytes
);
8367 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8368 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8369 newWidth
,newHeight
,newDepth
,
8370 srcImage
,dstImage
,elementSize
,rowSize
,
8371 imageSize
,myswapBytes
);
8378 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8380 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8381 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8382 if (newDepth
> 1) newDepth
/= 2;
8384 /* call tex image with srcImage untouched since it's not padded */
8385 if (baseLevel
<= level
&& level
<= maxLevel
) {
8386 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8387 newDepth
,0, format
, type
, (void *) srcImage
);
8391 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8392 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8393 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8394 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8395 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8396 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8397 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8399 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8400 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8404 } /* gluBuild3DMipmapLevelsCore() */
8407 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8408 GLsizei width
, GLsizei height
, GLsizei depth
,
8409 GLenum format
, GLenum type
,
8410 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8415 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8416 if (rc
!= 0) return rc
;
8418 if (width
< 1 || height
< 1 || depth
< 1) {
8419 return GLU_INVALID_VALUE
;
8422 if(type
== GL_BITMAP
) {
8423 return GLU_INVALID_ENUM
;
8426 levels
= computeLog(width
);
8427 level
= computeLog(height
);
8428 if (level
> levels
) levels
=level
;
8429 level
= computeLog(depth
);
8430 if (level
> levels
) levels
=level
;
8433 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8434 return GLU_INVALID_VALUE
;
8436 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8437 width
, height
, depth
,
8438 width
, height
, depth
,
8440 userLevel
, baseLevel
, maxLevel
,
8442 } /* gluBuild3DMipmapLevels() */
8445 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8446 GLsizei width
, GLsizei height
, GLsizei depth
,
8447 GLenum format
, GLenum type
, const void *data
)
8449 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8452 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8453 if (rc
!= 0) return rc
;
8455 if (width
< 1 || height
< 1 || depth
< 1) {
8456 return GLU_INVALID_VALUE
;
8459 if(type
== GL_BITMAP
) {
8460 return GLU_INVALID_ENUM
;
8463 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8464 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8466 levels
= computeLog(widthPowerOf2
);
8467 level
= computeLog(heightPowerOf2
);
8468 if (level
> levels
) levels
=level
;
8469 level
= computeLog(depthPowerOf2
);
8470 if (level
> levels
) levels
=level
;
8472 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8473 width
, height
, depth
,
8474 widthPowerOf2
, heightPowerOf2
,
8476 format
, type
, 0, 0, levels
,
8478 } /* gluBuild3DMipmaps() */
8480 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8482 isSwap
= isSwap
; /* turn off warnings */
8484 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8485 } /* extractUbyte() */
8487 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8489 assert(0.0 <= value
&& value
< 256.0);
8491 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8492 } /* shoveUbyte() */
8494 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8496 isSwap
= isSwap
; /* turn off warnings */
8498 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8499 } /* extractSbyte() */
8501 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8503 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8504 } /* shoveSbyte() */
8506 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8511 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8514 ushort
= *(const GLushort
*)uitem
;
8517 return (GLdouble
)ushort
;
8518 } /* extractUshort() */
8520 static void shoveUshort(GLdouble value
, int index
, void *data
)
8522 assert(0.0 <= value
&& value
< 65536.0);
8524 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8525 } /* shoveUshort() */
8527 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8532 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8535 sshort
= *(const GLshort
*)sitem
;
8538 return (GLdouble
)sshort
;
8539 } /* extractSshort() */
8541 static void shoveSshort(GLdouble value
, int index
, void *data
)
8543 assert(0.0 <= value
&& value
< 32768.0);
8545 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8546 } /* shoveSshort() */
8548 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8553 uint
= __GLU_SWAP_4_BYTES(uitem
);
8556 uint
= *(const GLuint
*)uitem
;
8559 assert(uint
<= 0xffffffff);
8561 return (GLdouble
)uint
;
8562 } /* extractUint() */
8564 static void shoveUint(GLdouble value
, int index
, void *data
)
8566 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8568 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8571 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8576 sint
= __GLU_SWAP_4_BYTES(sitem
);
8579 sint
= *(const GLint
*)sitem
;
8582 assert(sint
<= 0x7fffffff);
8584 return (GLdouble
)sint
;
8585 } /* extractSint() */
8587 static void shoveSint(GLdouble value
, int index
, void *data
)
8589 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8591 ((GLint
*)data
)[index
]= (GLint
)value
;
8594 static GLdouble
extractFloat(int isSwap
, const void *item
)
8599 ffloat
= __GLU_SWAP_4_BYTES(item
);
8602 ffloat
= *(const GLfloat
*)item
;
8605 assert(ffloat
<= 1.0);
8607 return (GLdouble
)ffloat
;
8608 } /* extractFloat() */
8610 static void shoveFloat(GLdouble value
, int index
, void *data
)
8612 assert(0.0 <= value
&& value
<= 1.0);
8614 ((GLfloat
*)data
)[index
]= value
;
8615 } /* shoveFloat() */
8617 static void halveImageSlice(int components
,
8618 GLdouble (*extract
)(int, const void *),
8619 void (*shove
)(GLdouble
, int, void *),
8620 GLint width
, GLint height
, GLint depth
,
8621 const void *dataIn
, void *dataOut
,
8622 GLint elementSizeInBytes
,
8623 GLint groupSizeInBytes
,
8624 GLint rowSizeInBytes
,
8625 GLint imageSizeInBytes
,
8629 int halfWidth
= width
/ 2;
8630 int halfHeight
= height
/ 2;
8631 int halfDepth
= depth
/ 2;
8632 const char *src
= (const char *)dataIn
;
8633 int padBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8636 assert((width
== 1 || height
== 1) && depth
>= 2);
8638 if (width
== height
) { /* a 1-pixel column viewed from top */
8639 /* printf("1-column\n");*/
8640 assert(width
== 1 && height
== 1);
8643 for (ii
= 0; ii
< halfDepth
; ii
++) {
8646 for (cc
= 0; cc
< components
; cc
++) {
8648 double extractTotals
[BOX2
][4];
8651 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8652 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8654 /* average 2 pixels since only a column */
8656 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8657 * totals[RED]/= 2.0;
8659 for (kk
= 0; kk
< BOX2
; kk
++) {
8660 totals
[cc
]+= extractTotals
[kk
][cc
];
8662 totals
[cc
]/= (double)BOX2
;
8664 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8666 src
+= elementSizeInBytes
;
8669 /* skip over to next group of 2 */
8670 src
+= rowSizeInBytes
;
8673 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8674 assert(outIndex
== halfDepth
* components
);
8676 else if (height
== 1) { /* horizontal slice viewed from top */
8677 /* printf("horizontal slice\n"); */
8680 for (ii
= 0; ii
< halfDepth
; ii
++) {
8681 for (jj
= 0; jj
< halfWidth
; jj
++) {
8684 for (cc
= 0; cc
< components
; cc
++) {
8687 double extractTotals
[BOX4
][4];
8689 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8690 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8691 (src
+groupSizeInBytes
));
8692 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8693 (src
+imageSizeInBytes
));
8694 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8695 (src
+imageSizeInBytes
+groupSizeInBytes
));
8697 /* grab 4 pixels to average */
8699 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8700 * extractTotals[2][RED]+extractTotals[3][RED];
8701 * totals[RED]/= 4.0;
8703 for (kk
= 0; kk
< BOX4
; kk
++) {
8704 totals
[cc
]+= extractTotals
[kk
][cc
];
8706 totals
[cc
]/= (double)BOX4
;
8708 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8711 src
+= elementSizeInBytes
;
8714 /* skip over to next horizontal square of 4 */
8715 src
+= groupSizeInBytes
;
8719 src
+= rowSizeInBytes
;
8722 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8723 assert(outIndex
== halfWidth
* halfDepth
* components
);
8725 else if (width
== 1) { /* vertical slice viewed from top */
8726 /* printf("vertical slice\n"); */
8727 assert(height
!= 1);
8729 for (ii
= 0; ii
< halfDepth
; ii
++) {
8730 for (jj
= 0; jj
< halfHeight
; jj
++) {
8733 for (cc
= 0; cc
< components
; cc
++) {
8736 double extractTotals
[BOX4
][4];
8738 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8739 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8740 (src
+rowSizeInBytes
));
8741 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8742 (src
+imageSizeInBytes
));
8743 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8744 (src
+imageSizeInBytes
+rowSizeInBytes
));
8746 /* grab 4 pixels to average */
8748 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8749 * extractTotals[2][RED]+extractTotals[3][RED];
8750 * totals[RED]/= 4.0;
8752 for (kk
= 0; kk
< BOX4
; kk
++) {
8753 totals
[cc
]+= extractTotals
[kk
][cc
];
8755 totals
[cc
]/= (double)BOX4
;
8757 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8760 src
+= elementSizeInBytes
;
8764 /* skip over to next vertical square of 4 */
8765 src
+= rowSizeInBytes
;
8768 src
+= imageSizeInBytes
;
8771 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8772 assert(outIndex
== halfHeight
* halfDepth
* components
);
8775 } /* halveImageSlice() */
8777 static void halveImage3D(int components
,
8778 GLdouble (*extract
)(int, const void *),
8779 void (*shove
)(GLdouble
, int, void *),
8780 GLint width
, GLint height
, GLint depth
,
8781 const void *dataIn
, void *dataOut
,
8782 GLint elementSizeInBytes
,
8783 GLint groupSizeInBytes
,
8784 GLint rowSizeInBytes
,
8785 GLint imageSizeInBytes
,
8790 /* a horizontal/vertical/one-column slice viewed from top */
8791 if (width
== 1 || height
== 1) {
8794 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8795 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8796 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8802 int halfWidth
= width
/ 2;
8803 int halfHeight
= height
/ 2;
8804 int halfDepth
= depth
/ 2;
8805 const char *src
= (const char *) dataIn
;
8806 int padBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8809 for (dd
= 0; dd
< halfDepth
; dd
++) {
8810 for (ii
= 0; ii
< halfHeight
; ii
++) {
8811 for (jj
= 0; jj
< halfWidth
; jj
++) {
8814 for (cc
= 0; cc
< components
; cc
++) {
8817 double totals
[4]; /* 4 is maximum components */
8818 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8820 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8821 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8822 (src
+groupSizeInBytes
));
8823 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8824 (src
+rowSizeInBytes
));
8825 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8826 (src
+rowSizeInBytes
+groupSizeInBytes
));
8828 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8829 (src
+imageSizeInBytes
));
8831 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8832 (src
+groupSizeInBytes
+imageSizeInBytes
));
8833 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8834 (src
+rowSizeInBytes
+imageSizeInBytes
));
8835 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8836 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8840 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8841 * extractTotals[2][RED]+extractTotals[3][RED]+
8842 * extractTotals[4][RED]+extractTotals[5][RED]+
8843 * extractTotals[6][RED]+extractTotals[7][RED];
8844 * totals[RED]/= 8.0;
8846 for (kk
= 0; kk
< BOX8
; kk
++) {
8847 totals
[cc
]+= extractTotals
[kk
][cc
];
8849 totals
[cc
]/= (double)BOX8
;
8851 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8855 src
+= elementSizeInBytes
; /* go to next component */
8858 /* skip over to next square of 4 */
8859 src
+= groupSizeInBytes
;
8861 /* skip past pad bytes, if any, to get to next row */
8864 /* src is at beginning of a row here, but it's the second row of
8865 * the square block of 4 pixels that we just worked on so we
8866 * need to go one more row.
8874 src
+= rowSizeInBytes
;
8877 src
+= imageSizeInBytes
;
8880 /* both pointers must reach one byte after the end */
8881 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8882 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8884 } /* halveImage3D() */