2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
34 ** $Date: 2003/10/14 23:48:58 $ $Revision: 1.4 $
35 ** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libutil/mipmap.c,v 1.4 2003/10/14 23:48:58 kendallb Exp $
44 #include <limits.h> /* UINT_MAX */
58 /* Pixel storage modes */
61 GLint pack_row_length
;
63 GLint pack_skip_pixels
;
65 GLint pack_swap_bytes
;
66 GLint pack_skip_images
;
67 GLint pack_image_height
;
69 GLint unpack_alignment
;
70 GLint unpack_row_length
;
71 GLint unpack_skip_rows
;
72 GLint unpack_skip_pixels
;
73 GLint unpack_lsb_first
;
74 GLint unpack_swap_bytes
;
75 GLint unpack_skip_images
;
76 GLint unpack_image_height
;
79 static int gluBuild1DMipmapLevelsCore(GLenum
, GLint
,
82 GLenum
, GLenum
, GLint
, GLint
, GLint
,
84 static int gluBuild2DMipmapLevelsCore(GLenum
, GLint
,
87 GLenum
, GLenum
, GLint
, GLint
, GLint
,
89 static int gluBuild3DMipmapLevelsCore(GLenum
, GLint
,
90 GLsizei
, GLsizei
, GLsizei
,
91 GLsizei
, GLsizei
, GLsizei
,
92 GLenum
, GLenum
, GLint
, GLint
, GLint
,
96 * internal function declarations
98 static GLfloat
bytes_per_element(GLenum type
);
99 static GLint
elements_per_group(GLenum format
, GLenum type
);
100 static GLint
is_index(GLenum format
);
101 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
);
102 static void fill_image(const PixelStorageModes
*,
103 GLint width
, GLint height
, GLenum format
,
104 GLenum type
, GLboolean index_format
,
105 const void *userdata
, GLushort
*newimage
);
106 static void empty_image(const PixelStorageModes
*,
107 GLint width
, GLint height
, GLenum format
,
108 GLenum type
, GLboolean index_format
,
109 const GLushort
*oldimage
, void *userdata
);
110 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
111 const GLushort
*datain
,
112 GLint widthout
, GLint heightout
,
115 static void scale_internal_ubyte(GLint components
, GLint widthin
,
116 GLint heightin
, const GLubyte
*datain
,
117 GLint widthout
, GLint heightout
,
118 GLubyte
*dataout
, GLint element_size
,
119 GLint ysize
, GLint group_size
);
120 static void scale_internal_byte(GLint components
, GLint widthin
,
121 GLint heightin
, const GLbyte
*datain
,
122 GLint widthout
, GLint heightout
,
123 GLbyte
*dataout
, GLint element_size
,
124 GLint ysize
, GLint group_size
);
125 static void scale_internal_ushort(GLint components
, GLint widthin
,
126 GLint heightin
, const GLushort
*datain
,
127 GLint widthout
, GLint heightout
,
128 GLushort
*dataout
, GLint element_size
,
129 GLint ysize
, GLint group_size
,
131 static void scale_internal_short(GLint components
, GLint widthin
,
132 GLint heightin
, const GLshort
*datain
,
133 GLint widthout
, GLint heightout
,
134 GLshort
*dataout
, GLint element_size
,
135 GLint ysize
, GLint group_size
,
137 static void scale_internal_uint(GLint components
, GLint widthin
,
138 GLint heightin
, const GLuint
*datain
,
139 GLint widthout
, GLint heightout
,
140 GLuint
*dataout
, GLint element_size
,
141 GLint ysize
, GLint group_size
,
143 static void scale_internal_int(GLint components
, GLint widthin
,
144 GLint heightin
, const GLint
*datain
,
145 GLint widthout
, GLint heightout
,
146 GLint
*dataout
, GLint element_size
,
147 GLint ysize
, GLint group_size
,
149 static void scale_internal_float(GLint components
, GLint widthin
,
150 GLint heightin
, const GLfloat
*datain
,
151 GLint widthout
, GLint heightout
,
152 GLfloat
*dataout
, GLint element_size
,
153 GLint ysize
, GLint group_size
,
156 static int checkMipmapArgs(GLenum
, GLenum
, GLenum
);
157 static GLboolean
legalFormat(GLenum
);
158 static GLboolean
legalType(GLenum
);
159 static GLboolean
isTypePackedPixel(GLenum
);
160 static GLboolean
isLegalFormatForPackedPixelType(GLenum
, GLenum
);
161 static GLboolean
isLegalLevels(GLint
, GLint
, GLint
, GLint
);
162 static void closestFit(GLenum
, GLint
, GLint
, GLint
, GLenum
, GLenum
,
165 /* all extract/shove routines must return double to handle unsigned ints */
166 static GLdouble
extractUbyte(int, const void *);
167 static void shoveUbyte(GLdouble
, int, void *);
168 static GLdouble
extractSbyte(int, const void *);
169 static void shoveSbyte(GLdouble
, int, void *);
170 static GLdouble
extractUshort(int, const void *);
171 static void shoveUshort(GLdouble
, int, void *);
172 static GLdouble
extractSshort(int, const void *);
173 static void shoveSshort(GLdouble
, int, void *);
174 static GLdouble
extractUint(int, const void *);
175 static void shoveUint(GLdouble
, int, void *);
176 static GLdouble
extractSint(int, const void *);
177 static void shoveSint(GLdouble
, int, void *);
178 static GLdouble
extractFloat(int, const void *);
179 static void shoveFloat(GLdouble
, int, void *);
180 static void halveImageSlice(int, GLdouble (*)(int, const void *),
181 void (*)(GLdouble
, int, void *),
183 const void *, void *,
184 GLint
, GLint
, GLint
, GLint
, GLint
);
185 static void halveImage3D(int, GLdouble (*)(int, const void *),
186 void (*)(GLdouble
, int, void *),
188 const void *, void *,
189 GLint
, GLint
, GLint
, GLint
, GLint
);
191 /* packedpixel type scale routines */
192 static void extract332(int,const void *, GLfloat
[]);
193 static void shove332(const GLfloat
[],int ,void *);
194 static void extract233rev(int,const void *, GLfloat
[]);
195 static void shove233rev(const GLfloat
[],int ,void *);
196 static void extract565(int,const void *, GLfloat
[]);
197 static void shove565(const GLfloat
[],int ,void *);
198 static void extract565rev(int,const void *, GLfloat
[]);
199 static void shove565rev(const GLfloat
[],int ,void *);
200 static void extract4444(int,const void *, GLfloat
[]);
201 static void shove4444(const GLfloat
[],int ,void *);
202 static void extract4444rev(int,const void *, GLfloat
[]);
203 static void shove4444rev(const GLfloat
[],int ,void *);
204 static void extract5551(int,const void *, GLfloat
[]);
205 static void shove5551(const GLfloat
[],int ,void *);
206 static void extract1555rev(int,const void *, GLfloat
[]);
207 static void shove1555rev(const GLfloat
[],int ,void *);
208 static void extract8888(int,const void *, GLfloat
[]);
209 static void shove8888(const GLfloat
[],int ,void *);
210 static void extract8888rev(int,const void *, GLfloat
[]);
211 static void shove8888rev(const GLfloat
[],int ,void *);
212 static void extract1010102(int,const void *, GLfloat
[]);
213 static void shove1010102(const GLfloat
[],int ,void *);
214 static void extract2101010rev(int,const void *, GLfloat
[]);
215 static void shove2101010rev(const GLfloat
[],int ,void *);
216 static void scaleInternalPackedPixel(int,
217 void (*)(int, const void *,GLfloat
[]),
218 void (*)(const GLfloat
[],int, void *),
219 GLint
,GLint
, const void *,
220 GLint
,GLint
,void *,GLint
,GLint
,GLint
);
221 static void halveImagePackedPixel(int,
222 void (*)(int, const void *,GLfloat
[]),
223 void (*)(const GLfloat
[],int, void *),
224 GLint
, GLint
, const void *,
225 void *, GLint
, GLint
, GLint
);
226 static void halve1DimagePackedPixel(int,
227 void (*)(int, const void *,GLfloat
[]),
228 void (*)(const GLfloat
[],int, void *),
229 GLint
, GLint
, const void *,
230 void *, GLint
, GLint
, GLint
);
232 static void halve1Dimage_ubyte(GLint
, GLuint
, GLuint
,const GLubyte
*,
233 GLubyte
*, GLint
, GLint
, GLint
);
234 static void halve1Dimage_byte(GLint
, GLuint
, GLuint
,const GLbyte
*, GLbyte
*,
235 GLint
, GLint
, GLint
);
236 static void halve1Dimage_ushort(GLint
, GLuint
, GLuint
, const GLushort
*,
237 GLushort
*, GLint
, GLint
, GLint
, GLint
);
238 static void halve1Dimage_short(GLint
, GLuint
, GLuint
,const GLshort
*, GLshort
*,
239 GLint
, GLint
, GLint
, GLint
);
240 static void halve1Dimage_uint(GLint
, GLuint
, GLuint
, const GLuint
*, GLuint
*,
241 GLint
, GLint
, GLint
, GLint
);
242 static void halve1Dimage_int(GLint
, GLuint
, GLuint
, const GLint
*, GLint
*,
243 GLint
, GLint
, GLint
, GLint
);
244 static void halve1Dimage_float(GLint
, GLuint
, GLuint
, const GLfloat
*, GLfloat
*,
245 GLint
, GLint
, GLint
, GLint
);
247 static GLint
imageSize3D(GLint
, GLint
, GLint
, GLenum
,GLenum
);
248 static void fillImage3D(const PixelStorageModes
*, GLint
, GLint
, GLint
,GLenum
,
249 GLenum
, GLboolean
, const void *, GLushort
*);
250 static void emptyImage3D(const PixelStorageModes
*,
251 GLint
, GLint
, GLint
, GLenum
,
253 const GLushort
*, void *);
254 static void scaleInternal3D(GLint
, GLint
, GLint
, GLint
, const GLushort
*,
255 GLint
, GLint
, GLint
, GLushort
*);
257 static void retrieveStoreModes(PixelStorageModes
*psm
)
259 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
260 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
261 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
262 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
263 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
264 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
266 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
267 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
268 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
269 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
270 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
271 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
274 static void retrieveStoreModes3D(PixelStorageModes
*psm
)
276 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
277 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
278 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
279 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
280 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
281 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
282 glGetIntegerv(GL_UNPACK_SKIP_IMAGES
, &psm
->unpack_skip_images
);
283 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT
, &psm
->unpack_image_height
);
285 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
286 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
287 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
288 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
289 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
290 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
291 glGetIntegerv(GL_PACK_SKIP_IMAGES
, &psm
->pack_skip_images
);
292 glGetIntegerv(GL_PACK_IMAGE_HEIGHT
, &psm
->pack_image_height
);
295 static int computeLog(GLuint value
)
302 if (value
== 0) return -1;
307 if (value
!= 1) return -1;
316 ** Compute the nearest power of 2 number. This algorithm is a little
317 ** strange, but it works quite well.
319 static int nearestPower(GLuint value
)
326 if (value
== 0) return -1;
331 } else if (value
== 3) {
339 #define __GLU_SWAP_2_BYTES(s)\
340 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
342 #define __GLU_SWAP_4_BYTES(s)\
343 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
344 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
345 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
347 static void halveImage(GLint components
, GLuint width
, GLuint height
,
348 const GLushort
*datain
, GLushort
*dataout
)
351 int newwidth
, newheight
;
356 newwidth
= width
/ 2;
357 newheight
= height
/ 2;
358 delta
= width
* components
;
363 for (i
= 0; i
< newheight
; i
++) {
364 for (j
= 0; j
< newwidth
; j
++) {
365 for (k
= 0; k
< components
; k
++) {
366 s
[0] = (t
[0] + t
[components
] + t
[delta
] +
367 t
[delta
+components
] + 2) / 4;
376 static void halveImage_ubyte(GLint components
, GLuint width
, GLuint height
,
377 const GLubyte
*datain
, GLubyte
*dataout
,
378 GLint element_size
, GLint ysize
, GLint group_size
)
381 int newwidth
, newheight
;
385 /* handle case where there is only 1 column/row */
386 if (width
== 1 || height
== 1) {
387 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
388 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
389 element_size
,ysize
,group_size
);
393 newwidth
= width
/ 2;
394 newheight
= height
/ 2;
396 t
= (const char *)datain
;
399 for (i
= 0; i
< newheight
; i
++) {
400 for (j
= 0; j
< newwidth
; j
++) {
401 for (k
= 0; k
< components
; k
++) {
402 s
[0] = (*(const GLubyte
*)t
+
403 *(const GLubyte
*)(t
+group_size
) +
404 *(const GLubyte
*)(t
+ysize
) +
405 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
406 s
++; t
+= element_size
;
415 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
416 const GLubyte
*dataIn
, GLubyte
*dataOut
,
417 GLint element_size
, GLint ysize
,
420 GLint halfWidth
= width
/ 2;
421 GLint halfHeight
= height
/ 2;
422 const char *src
= (const char *) dataIn
;
423 GLubyte
*dest
= dataOut
;
426 assert(width
== 1 || height
== 1); /* must be 1D */
427 assert(width
!= height
); /* can't be square */
429 if (height
== 1) { /* 1 row */
430 assert(width
!= 1); /* widthxheight can't be 1x1 */
433 for (jj
= 0; jj
< halfWidth
; jj
++) {
435 for (kk
= 0; kk
< components
; kk
++) {
436 *dest
= (*(const GLubyte
*)src
+
437 *(const GLubyte
*)(src
+group_size
)) / 2;
442 src
+= group_size
; /* skip to next 2 */
445 int padBytes
= ysize
- (width
*group_size
);
446 src
+= padBytes
; /* for assertion only */
449 else if (width
== 1) { /* 1 column */
450 int padBytes
= ysize
- (width
* group_size
);
451 assert(height
!= 1); /* widthxheight can't be 1x1 */
453 /* one vertical column with possible pad bytes per row */
454 /* average two at a time */
456 for (jj
= 0; jj
< halfHeight
; jj
++) {
458 for (kk
= 0; kk
< components
; kk
++) {
459 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
464 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
469 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
470 assert((char *)dest
== &((char *)dataOut
)
471 [components
* element_size
* halfWidth
* halfHeight
]);
472 } /* halve1Dimage_ubyte() */
474 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
475 const GLbyte
*datain
, GLbyte
*dataout
,
477 GLint ysize
, GLint group_size
)
480 int newwidth
, newheight
;
484 /* handle case where there is only 1 column/row */
485 if (width
== 1 || height
== 1) {
486 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
487 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
488 element_size
,ysize
,group_size
);
492 newwidth
= width
/ 2;
493 newheight
= height
/ 2;
495 t
= (const char *)datain
;
498 for (i
= 0; i
< newheight
; i
++) {
499 for (j
= 0; j
< newwidth
; j
++) {
500 for (k
= 0; k
< components
; k
++) {
501 s
[0] = (*(const GLbyte
*)t
+
502 *(const GLbyte
*)(t
+group_size
) +
503 *(const GLbyte
*)(t
+ysize
) +
504 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
505 s
++; t
+= element_size
;
513 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
514 const GLbyte
*dataIn
, GLbyte
*dataOut
,
515 GLint element_size
,GLint ysize
, GLint group_size
)
517 GLint halfWidth
= width
/ 2;
518 GLint halfHeight
= height
/ 2;
519 const char *src
= (const char *) dataIn
;
520 GLbyte
*dest
= dataOut
;
523 assert(width
== 1 || height
== 1); /* must be 1D */
524 assert(width
!= height
); /* can't be square */
526 if (height
== 1) { /* 1 row */
527 assert(width
!= 1); /* widthxheight can't be 1x1 */
530 for (jj
= 0; jj
< halfWidth
; jj
++) {
532 for (kk
= 0; kk
< components
; kk
++) {
533 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
538 src
+= group_size
; /* skip to next 2 */
541 int padBytes
= ysize
- (width
*group_size
);
542 src
+= padBytes
; /* for assertion only */
545 else if (width
== 1) { /* 1 column */
546 int padBytes
= ysize
- (width
* group_size
);
547 assert(height
!= 1); /* widthxheight can't be 1x1 */
549 /* one vertical column with possible pad bytes per row */
550 /* average two at a time */
552 for (jj
= 0; jj
< halfHeight
; jj
++) {
554 for (kk
= 0; kk
< components
; kk
++) {
555 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
560 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
564 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
567 assert((char *)dest
== &((char *)dataOut
)
568 [components
* element_size
* halfWidth
* halfHeight
]);
569 } /* halve1Dimage_byte() */
571 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
572 const GLushort
*datain
, GLushort
*dataout
,
573 GLint element_size
, GLint ysize
, GLint group_size
,
577 int newwidth
, newheight
;
581 /* handle case where there is only 1 column/row */
582 if (width
== 1 || height
== 1) {
583 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
584 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
585 element_size
,ysize
,group_size
, myswap_bytes
);
589 newwidth
= width
/ 2;
590 newheight
= height
/ 2;
592 t
= (const char *)datain
;
596 for (i
= 0; i
< newheight
; i
++) {
597 for (j
= 0; j
< newwidth
; j
++) {
598 for (k
= 0; k
< components
; k
++) {
599 s
[0] = (*(const GLushort
*)t
+
600 *(const GLushort
*)(t
+group_size
) +
601 *(const GLushort
*)(t
+ysize
) +
602 *(const GLushort
*)(t
+ysize
+group_size
) + 2) / 4;
603 s
++; t
+= element_size
;
610 for (i
= 0; i
< newheight
; i
++) {
611 for (j
= 0; j
< newwidth
; j
++) {
612 for (k
= 0; k
< components
; k
++) {
613 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
614 __GLU_SWAP_2_BYTES(t
+group_size
) +
615 __GLU_SWAP_2_BYTES(t
+ysize
) +
616 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
617 s
++; t
+= element_size
;
625 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
626 const GLushort
*dataIn
, GLushort
*dataOut
,
627 GLint element_size
, GLint ysize
,
628 GLint group_size
, GLint myswap_bytes
)
630 GLint halfWidth
= width
/ 2;
631 GLint halfHeight
= height
/ 2;
632 const char *src
= (const char *) dataIn
;
633 GLushort
*dest
= dataOut
;
636 assert(width
== 1 || height
== 1); /* must be 1D */
637 assert(width
!= height
); /* can't be square */
639 if (height
== 1) { /* 1 row */
640 assert(width
!= 1); /* widthxheight can't be 1x1 */
643 for (jj
= 0; jj
< halfWidth
; jj
++) {
645 for (kk
= 0; kk
< components
; kk
++) {
647 GLushort ushort
[BOX2
];
649 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
650 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
653 ushort
[0]= *(const GLushort
*)src
;
654 ushort
[1]= *(const GLushort
*)(src
+group_size
);
657 *dest
= (ushort
[0] + ushort
[1]) / 2;
661 src
+= group_size
; /* skip to next 2 */
664 int padBytes
= ysize
- (width
*group_size
);
665 src
+= padBytes
; /* for assertion only */
668 else if (width
== 1) { /* 1 column */
669 int padBytes
= ysize
- (width
* group_size
);
670 assert(height
!= 1); /* widthxheight can't be 1x1 */
672 /* one vertical column with possible pad bytes per row */
673 /* average two at a time */
675 for (jj
= 0; jj
< halfHeight
; jj
++) {
677 for (kk
= 0; kk
< components
; kk
++) {
679 GLushort ushort
[BOX2
];
681 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
682 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
685 ushort
[0]= *(const GLushort
*)src
;
686 ushort
[1]= *(const GLushort
*)(src
+ysize
);
688 *dest
= (ushort
[0] + ushort
[1]) / 2;
693 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
697 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
700 assert((char *)dest
== &((char *)dataOut
)
701 [components
* element_size
* halfWidth
* halfHeight
]);
703 } /* halve1Dimage_ushort() */
706 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
707 const GLshort
*datain
, GLshort
*dataout
,
708 GLint element_size
, GLint ysize
, GLint group_size
,
712 int newwidth
, newheight
;
716 /* handle case where there is only 1 column/row */
717 if (width
== 1 || height
== 1) {
718 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
719 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
720 element_size
,ysize
,group_size
, myswap_bytes
);
724 newwidth
= width
/ 2;
725 newheight
= height
/ 2;
727 t
= (const char *)datain
;
731 for (i
= 0; i
< newheight
; i
++) {
732 for (j
= 0; j
< newwidth
; j
++) {
733 for (k
= 0; k
< components
; k
++) {
734 s
[0] = (*(const GLshort
*)t
+
735 *(const GLshort
*)(t
+group_size
) +
736 *(const GLshort
*)(t
+ysize
) +
737 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
738 s
++; t
+= element_size
;
745 for (i
= 0; i
< newheight
; i
++) {
746 for (j
= 0; j
< newwidth
; j
++) {
747 for (k
= 0; k
< components
; k
++) {
750 b
= __GLU_SWAP_2_BYTES(t
);
751 buf
= *(const GLshort
*)&b
;
752 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
753 buf
+= *(const GLshort
*)&b
;
754 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
755 buf
+= *(const GLshort
*)&b
;
756 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
757 buf
+= *(const GLshort
*)&b
;
758 s
[0] = (GLshort
)((buf
+2)/4);
759 s
++; t
+= element_size
;
767 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
768 const GLshort
*dataIn
, GLshort
*dataOut
,
769 GLint element_size
, GLint ysize
,
770 GLint group_size
, GLint myswap_bytes
)
772 GLint halfWidth
= width
/ 2;
773 GLint halfHeight
= height
/ 2;
774 const char *src
= (const char *) dataIn
;
775 GLshort
*dest
= dataOut
;
778 assert(width
== 1 || height
== 1); /* must be 1D */
779 assert(width
!= height
); /* can't be square */
781 if (height
== 1) { /* 1 row */
782 assert(width
!= 1); /* widthxheight can't be 1x1 */
785 for (jj
= 0; jj
< halfWidth
; jj
++) {
787 for (kk
= 0; kk
< components
; kk
++) {
789 GLshort sshort
[BOX2
];
791 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
792 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
795 sshort
[0]= *(const GLshort
*)src
;
796 sshort
[1]= *(const GLshort
*)(src
+group_size
);
799 *dest
= (sshort
[0] + sshort
[1]) / 2;
803 src
+= group_size
; /* skip to next 2 */
806 int padBytes
= ysize
- (width
*group_size
);
807 src
+= padBytes
; /* for assertion only */
810 else if (width
== 1) { /* 1 column */
811 int padBytes
= ysize
- (width
* group_size
);
812 assert(height
!= 1); /* widthxheight can't be 1x1 */
814 /* one vertical column with possible pad bytes per row */
815 /* average two at a time */
817 for (jj
= 0; jj
< halfHeight
; jj
++) {
819 for (kk
= 0; kk
< components
; kk
++) {
821 GLshort sshort
[BOX2
];
823 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
824 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
827 sshort
[0]= *(const GLshort
*)src
;
828 sshort
[1]= *(const GLshort
*)(src
+ysize
);
830 *dest
= (sshort
[0] + sshort
[1]) / 2;
835 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
839 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
842 assert((char *)dest
== &((char *)dataOut
)
843 [components
* element_size
* halfWidth
* halfHeight
]);
845 } /* halve1Dimage_short() */
848 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
849 const GLuint
*datain
, GLuint
*dataout
,
850 GLint element_size
, GLint ysize
, GLint group_size
,
854 int newwidth
, newheight
;
858 /* handle case where there is only 1 column/row */
859 if (width
== 1 || height
== 1) {
860 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
861 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
862 element_size
,ysize
,group_size
, myswap_bytes
);
866 newwidth
= width
/ 2;
867 newheight
= height
/ 2;
869 t
= (const char *)datain
;
873 for (i
= 0; i
< newheight
; i
++) {
874 for (j
= 0; j
< newwidth
; j
++) {
875 for (k
= 0; k
< components
; k
++) {
876 /* need to cast to double to hold large unsigned ints */
877 s
[0] = ((double)*(const GLuint
*)t
+
878 (double)*(const GLuint
*)(t
+group_size
) +
879 (double)*(const GLuint
*)(t
+ysize
) +
880 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
881 s
++; t
+= element_size
;
889 for (i
= 0; i
< newheight
; i
++) {
890 for (j
= 0; j
< newwidth
; j
++) {
891 for (k
= 0; k
< components
; k
++) {
892 /* need to cast to double to hold large unsigned ints */
894 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
895 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
896 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
897 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
898 s
[0] = (GLuint
)(buf
/4 + 0.5);
900 s
++; t
+= element_size
;
909 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
910 const GLuint
*dataIn
, GLuint
*dataOut
,
911 GLint element_size
, GLint ysize
,
912 GLint group_size
, GLint myswap_bytes
)
914 GLint halfWidth
= width
/ 2;
915 GLint halfHeight
= height
/ 2;
916 const char *src
= (const char *) dataIn
;
917 GLuint
*dest
= dataOut
;
920 assert(width
== 1 || height
== 1); /* must be 1D */
921 assert(width
!= height
); /* can't be square */
923 if (height
== 1) { /* 1 row */
924 assert(width
!= 1); /* widthxheight can't be 1x1 */
927 for (jj
= 0; jj
< halfWidth
; jj
++) {
929 for (kk
= 0; kk
< components
; kk
++) {
933 uint
[0]= __GLU_SWAP_4_BYTES(src
);
934 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
937 uint
[0]= *(const GLuint
*)src
;
938 uint
[1]= *(const GLuint
*)(src
+group_size
);
940 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
945 src
+= group_size
; /* skip to next 2 */
948 int padBytes
= ysize
- (width
*group_size
);
949 src
+= padBytes
; /* for assertion only */
952 else if (width
== 1) { /* 1 column */
953 int padBytes
= ysize
- (width
* group_size
);
954 assert(height
!= 1); /* widthxheight can't be 1x1 */
956 /* one vertical column with possible pad bytes per row */
957 /* average two at a time */
959 for (jj
= 0; jj
< halfHeight
; jj
++) {
961 for (kk
= 0; kk
< components
; kk
++) {
965 uint
[0]= __GLU_SWAP_4_BYTES(src
);
966 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
969 uint
[0]= *(const GLuint
*)src
;
970 uint
[1]= *(const GLuint
*)(src
+ysize
);
972 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
977 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
981 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
984 assert((char *)dest
== &((char *)dataOut
)
985 [components
* element_size
* halfWidth
* halfHeight
]);
987 } /* halve1Dimage_uint() */
989 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
990 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
991 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
994 int newwidth
, newheight
;
998 /* handle case where there is only 1 column/row */
999 if (width
== 1 || height
== 1) {
1000 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1001 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1002 element_size
,ysize
,group_size
, myswap_bytes
);
1006 newwidth
= width
/ 2;
1007 newheight
= height
/ 2;
1009 t
= (const char *)datain
;
1011 /* Piece o' cake! */
1013 for (i
= 0; i
< newheight
; i
++) {
1014 for (j
= 0; j
< newwidth
; j
++) {
1015 for (k
= 0; k
< components
; k
++) {
1016 s
[0] = ((float)*(const GLint
*)t
+
1017 (float)*(const GLint
*)(t
+group_size
) +
1018 (float)*(const GLint
*)(t
+ysize
) +
1019 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1020 s
++; t
+= element_size
;
1027 for (i
= 0; i
< newheight
; i
++) {
1028 for (j
= 0; j
< newwidth
; j
++) {
1029 for (k
= 0; k
< components
; k
++) {
1032 b
= __GLU_SWAP_4_BYTES(t
);
1034 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1036 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1038 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1040 s
[0] = (GLint
)(buf
/4 + 0.5);
1042 s
++; t
+= element_size
;
1051 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1052 const GLint
*dataIn
, GLint
*dataOut
,
1053 GLint element_size
, GLint ysize
,
1054 GLint group_size
, GLint myswap_bytes
)
1056 GLint halfWidth
= width
/ 2;
1057 GLint halfHeight
= height
/ 2;
1058 const char *src
= (const char *) dataIn
;
1059 GLint
*dest
= dataOut
;
1062 assert(width
== 1 || height
== 1); /* must be 1D */
1063 assert(width
!= height
); /* can't be square */
1065 if (height
== 1) { /* 1 row */
1066 assert(width
!= 1); /* widthxheight can't be 1x1 */
1069 for (jj
= 0; jj
< halfWidth
; jj
++) {
1071 for (kk
= 0; kk
< components
; kk
++) {
1075 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1076 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1079 uint
[0]= *(const GLuint
*)src
;
1080 uint
[1]= *(const GLuint
*)(src
+group_size
);
1082 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1087 src
+= group_size
; /* skip to next 2 */
1090 int padBytes
= ysize
- (width
*group_size
);
1091 src
+= padBytes
; /* for assertion only */
1094 else if (width
== 1) { /* 1 column */
1095 int padBytes
= ysize
- (width
* group_size
);
1096 assert(height
!= 1); /* widthxheight can't be 1x1 */
1098 /* one vertical column with possible pad bytes per row */
1099 /* average two at a time */
1101 for (jj
= 0; jj
< halfHeight
; jj
++) {
1103 for (kk
= 0; kk
< components
; kk
++) {
1107 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1108 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1111 uint
[0]= *(const GLuint
*)src
;
1112 uint
[1]= *(const GLuint
*)(src
+ysize
);
1114 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1119 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1123 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1126 assert((char *)dest
== &((char *)dataOut
)
1127 [components
* element_size
* halfWidth
* halfHeight
]);
1129 } /* halve1Dimage_int() */
1132 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1133 const GLfloat
*datain
, GLfloat
*dataout
,
1134 GLint element_size
, GLint ysize
, GLint group_size
,
1138 int newwidth
, newheight
;
1142 /* handle case where there is only 1 column/row */
1143 if (width
== 1 || height
== 1) {
1144 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1145 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1146 element_size
,ysize
,group_size
, myswap_bytes
);
1150 newwidth
= width
/ 2;
1151 newheight
= height
/ 2;
1153 t
= (const char *)datain
;
1155 /* Piece o' cake! */
1157 for (i
= 0; i
< newheight
; i
++) {
1158 for (j
= 0; j
< newwidth
; j
++) {
1159 for (k
= 0; k
< components
; k
++) {
1160 s
[0] = (*(const GLfloat
*)t
+
1161 *(const GLfloat
*)(t
+group_size
) +
1162 *(const GLfloat
*)(t
+ysize
) +
1163 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1164 s
++; t
+= element_size
;
1171 for (i
= 0; i
< newheight
; i
++) {
1172 for (j
= 0; j
< newwidth
; j
++) {
1173 for (k
= 0; k
< components
; k
++) {
1175 b
= __GLU_SWAP_4_BYTES(t
);
1176 s
[0] = *(GLfloat
*)&b
;
1177 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1178 s
[0] += *(GLfloat
*)&b
;
1179 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1180 s
[0] += *(GLfloat
*)&b
;
1181 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1182 s
[0] += *(GLfloat
*)&b
;
1184 s
++; t
+= element_size
;
1193 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1194 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1195 GLint element_size
, GLint ysize
,
1196 GLint group_size
, GLint myswap_bytes
)
1198 GLint halfWidth
= width
/ 2;
1199 GLint halfHeight
= height
/ 2;
1200 const char *src
= (const char *) dataIn
;
1201 GLfloat
*dest
= dataOut
;
1204 assert(width
== 1 || height
== 1); /* must be 1D */
1205 assert(width
!= height
); /* can't be square */
1207 if (height
== 1) { /* 1 row */
1208 assert(width
!= 1); /* widthxheight can't be 1x1 */
1211 for (jj
= 0; jj
< halfWidth
; jj
++) {
1213 for (kk
= 0; kk
< components
; kk
++) {
1215 GLfloat sfloat
[BOX2
];
1217 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1218 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1221 sfloat
[0]= *(const GLfloat
*)src
;
1222 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1225 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1229 src
+= group_size
; /* skip to next 2 */
1232 int padBytes
= ysize
- (width
*group_size
);
1233 src
+= padBytes
; /* for assertion only */
1236 else if (width
== 1) { /* 1 column */
1237 int padBytes
= ysize
- (width
* group_size
);
1238 assert(height
!= 1); /* widthxheight can't be 1x1 */
1240 /* one vertical column with possible pad bytes per row */
1241 /* average two at a time */
1243 for (jj
= 0; jj
< halfHeight
; jj
++) {
1245 for (kk
= 0; kk
< components
; kk
++) {
1247 GLfloat sfloat
[BOX2
];
1249 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1250 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1253 sfloat
[0]= *(const GLfloat
*)src
;
1254 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1256 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1261 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1262 src
+= ysize
; /* skip to odd row */
1266 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1267 assert((char *)dest
== &((char *)dataOut
)
1268 [components
* element_size
* halfWidth
* halfHeight
]);
1269 } /* halve1Dimage_float() */
1271 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1272 const GLushort
*datain
,
1273 GLint widthout
, GLint heightout
,
1276 float x
, lowx
, highx
, convx
, halfconvx
;
1277 float y
, lowy
, highy
, convy
, halfconvy
;
1278 float xpercent
,ypercent
;
1280 /* Max components in a format is 4, so... */
1283 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1286 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1287 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1290 convy
= (float) heightin
/heightout
;
1291 convx
= (float) widthin
/widthout
;
1292 halfconvx
= convx
/2;
1293 halfconvy
= convy
/2;
1294 for (i
= 0; i
< heightout
; i
++) {
1295 y
= convy
* (i
+0.5);
1296 if (heightin
> heightout
) {
1297 highy
= y
+ halfconvy
;
1298 lowy
= y
- halfconvy
;
1303 for (j
= 0; j
< widthout
; j
++) {
1304 x
= convx
* (j
+0.5);
1305 if (widthin
> widthout
) {
1306 highx
= x
+ halfconvx
;
1307 lowx
= x
- halfconvx
;
1314 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1315 ** to (highx, highy) on input data into this pixel on output
1318 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1324 yindex
= (yint
+ heightin
) % heightin
;
1325 if (highy
< yint
+1) {
1326 ypercent
= highy
- y
;
1328 ypercent
= yint
+1 - y
;
1335 xindex
= (xint
+ widthin
) % widthin
;
1336 if (highx
< xint
+1) {
1337 xpercent
= highx
- x
;
1339 xpercent
= xint
+1 - x
;
1342 percent
= xpercent
* ypercent
;
1344 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1345 for (k
= 0; k
< components
; k
++) {
1346 totals
[k
] += datain
[temp
+ k
] * percent
;
1356 temp
= (j
+ (i
* widthout
)) * components
;
1357 for (k
= 0; k
< components
; k
++) {
1358 /* totals[] should be rounded in the case of enlarging an RGB
1359 * ramp when the type is 332 or 4444
1361 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1367 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1368 GLint heightin
, const GLubyte
*datain
,
1369 GLint widthout
, GLint heightout
,
1370 GLubyte
*dataout
, GLint element_size
,
1371 GLint ysize
, GLint group_size
)
1376 /* Max components in a format is 4, so... */
1381 const char *temp
, *temp0
;
1382 const char *temp_index
;
1385 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1386 float x_percent
, y_percent
;
1387 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1388 float convy_float
, convx_float
;
1389 int convy_int
, convx_int
;
1391 const char *left
, *right
;
1393 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1394 halveImage_ubyte(components
, widthin
, heightin
,
1395 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1396 element_size
, ysize
, group_size
);
1399 convy
= (float) heightin
/heightout
;
1400 convx
= (float) widthin
/widthout
;
1401 convy_int
= floor(convy
);
1402 convy_float
= convy
- convy_int
;
1403 convx_int
= floor(convx
);
1404 convx_float
= convx
- convx_int
;
1406 area
= convx
* convy
;
1410 highy_int
= convy_int
;
1411 highy_float
= convy_float
;
1413 for (i
= 0; i
< heightout
; i
++) {
1416 highx_int
= convx_int
;
1417 highx_float
= convx_float
;
1419 for (j
= 0; j
< widthout
; j
++) {
1422 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1423 ** to (highx, highy) on input data into this pixel on output
1426 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1428 /* calculate the value for pixels in the 1st row */
1429 xindex
= lowx_int
*group_size
;
1430 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1432 y_percent
= 1-lowy_float
;
1433 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1434 percent
= y_percent
* (1-lowx_float
);
1435 for (k
= 0, temp_index
= temp
; k
< components
;
1436 k
++, temp_index
+= element_size
) {
1437 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1440 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1442 for (k
= 0, temp_index
= temp
; k
< components
;
1443 k
++, temp_index
+= element_size
) {
1444 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1449 percent
= y_percent
* highx_float
;
1450 for (k
= 0, temp_index
= temp
; k
< components
;
1451 k
++, temp_index
+= element_size
) {
1452 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1455 /* calculate the value for pixels in the last row */
1456 y_percent
= highy_float
;
1457 percent
= y_percent
* (1-lowx_float
);
1458 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1459 for (k
= 0, temp_index
= temp
; k
< components
;
1460 k
++, temp_index
+= element_size
) {
1461 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1463 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1465 for (k
= 0, temp_index
= temp
; k
< components
;
1466 k
++, temp_index
+= element_size
) {
1467 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1471 percent
= y_percent
* highx_float
;
1472 for (k
= 0, temp_index
= temp
; k
< components
;
1473 k
++, temp_index
+= element_size
) {
1474 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1478 /* calculate the value for pixels in the 1st and last column */
1479 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1482 for (k
= 0; k
< components
;
1483 k
++, left
+= element_size
, right
+= element_size
) {
1484 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1485 +(GLubyte
)(*(right
))*highx_float
;
1488 } else if (highy_int
> lowy_int
) {
1489 x_percent
= highx_float
- lowx_float
;
1490 percent
= (1-lowy_float
)*x_percent
;
1491 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1492 for (k
= 0, temp_index
= temp
; k
< components
;
1493 k
++, temp_index
+= element_size
) {
1494 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1496 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1498 for (k
= 0, temp_index
= temp
; k
< components
;
1499 k
++, temp_index
+= element_size
) {
1500 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1503 percent
= x_percent
* highy_float
;
1505 for (k
= 0, temp_index
= temp
; k
< components
;
1506 k
++, temp_index
+= element_size
) {
1507 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1509 } else if (highx_int
> lowx_int
) {
1510 y_percent
= highy_float
- lowy_float
;
1511 percent
= (1-lowx_float
)*y_percent
;
1512 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1513 for (k
= 0, temp_index
= temp
; k
< components
;
1514 k
++, temp_index
+= element_size
) {
1515 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1517 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1519 for (k
= 0, temp_index
= temp
; k
< components
;
1520 k
++, temp_index
+= element_size
) {
1521 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1525 percent
= y_percent
* highx_float
;
1526 for (k
= 0, temp_index
= temp
; k
< components
;
1527 k
++, temp_index
+= element_size
) {
1528 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1531 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1532 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1533 for (k
= 0, temp_index
= temp
; k
< components
;
1534 k
++, temp_index
+= element_size
) {
1535 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1541 /* this is for the pixels in the body */
1542 temp0
= (const char *)datain
+ xindex
+ group_size
+
1544 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1546 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1547 for (k
= 0, temp_index
= temp
; k
< components
;
1548 k
++, temp_index
+= element_size
) {
1549 totals
[k
] += (GLubyte
)(*(temp_index
));
1556 outindex
= (j
+ (i
* widthout
)) * components
;
1557 for (k
= 0; k
< components
; k
++) {
1558 dataout
[outindex
+ k
] = totals
[k
]/area
;
1559 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1561 lowx_int
= highx_int
;
1562 lowx_float
= highx_float
;
1563 highx_int
+= convx_int
;
1564 highx_float
+= convx_float
;
1565 if(highx_float
> 1) {
1570 lowy_int
= highy_int
;
1571 lowy_float
= highy_float
;
1572 highy_int
+= convy_int
;
1573 highy_float
+= convy_float
;
1574 if(highy_float
> 1) {
1581 static void scale_internal_byte(GLint components
, GLint widthin
,
1582 GLint heightin
, const GLbyte
*datain
,
1583 GLint widthout
, GLint heightout
,
1584 GLbyte
*dataout
, GLint element_size
,
1585 GLint ysize
, GLint group_size
)
1590 /* Max components in a format is 4, so... */
1595 const char *temp
, *temp0
;
1596 const char *temp_index
;
1599 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1600 float x_percent
, y_percent
;
1601 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1602 float convy_float
, convx_float
;
1603 int convy_int
, convx_int
;
1605 const char *left
, *right
;
1607 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1608 halveImage_byte(components
, widthin
, heightin
,
1609 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1610 element_size
, ysize
, group_size
);
1613 convy
= (float) heightin
/heightout
;
1614 convx
= (float) widthin
/widthout
;
1615 convy_int
= floor(convy
);
1616 convy_float
= convy
- convy_int
;
1617 convx_int
= floor(convx
);
1618 convx_float
= convx
- convx_int
;
1620 area
= convx
* convy
;
1624 highy_int
= convy_int
;
1625 highy_float
= convy_float
;
1627 for (i
= 0; i
< heightout
; i
++) {
1630 highx_int
= convx_int
;
1631 highx_float
= convx_float
;
1633 for (j
= 0; j
< widthout
; j
++) {
1636 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1637 ** to (highx, highy) on input data into this pixel on output
1640 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1642 /* calculate the value for pixels in the 1st row */
1643 xindex
= lowx_int
*group_size
;
1644 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1646 y_percent
= 1-lowy_float
;
1647 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1648 percent
= y_percent
* (1-lowx_float
);
1649 for (k
= 0, temp_index
= temp
; k
< components
;
1650 k
++, temp_index
+= element_size
) {
1651 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1654 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1656 for (k
= 0, temp_index
= temp
; k
< components
;
1657 k
++, temp_index
+= element_size
) {
1658 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1663 percent
= y_percent
* highx_float
;
1664 for (k
= 0, temp_index
= temp
; k
< components
;
1665 k
++, temp_index
+= element_size
) {
1666 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1669 /* calculate the value for pixels in the last row */
1670 y_percent
= highy_float
;
1671 percent
= y_percent
* (1-lowx_float
);
1672 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1673 for (k
= 0, temp_index
= temp
; k
< components
;
1674 k
++, temp_index
+= element_size
) {
1675 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1677 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1679 for (k
= 0, temp_index
= temp
; k
< components
;
1680 k
++, temp_index
+= element_size
) {
1681 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1685 percent
= y_percent
* highx_float
;
1686 for (k
= 0, temp_index
= temp
; k
< components
;
1687 k
++, temp_index
+= element_size
) {
1688 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1692 /* calculate the value for pixels in the 1st and last column */
1693 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1696 for (k
= 0; k
< components
;
1697 k
++, left
+= element_size
, right
+= element_size
) {
1698 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1699 +(GLbyte
)(*(right
))*highx_float
;
1702 } else if (highy_int
> lowy_int
) {
1703 x_percent
= highx_float
- lowx_float
;
1704 percent
= (1-lowy_float
)*x_percent
;
1705 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1706 for (k
= 0, temp_index
= temp
; k
< components
;
1707 k
++, temp_index
+= element_size
) {
1708 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1710 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1712 for (k
= 0, temp_index
= temp
; k
< components
;
1713 k
++, temp_index
+= element_size
) {
1714 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1717 percent
= x_percent
* highy_float
;
1719 for (k
= 0, temp_index
= temp
; k
< components
;
1720 k
++, temp_index
+= element_size
) {
1721 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1723 } else if (highx_int
> lowx_int
) {
1724 y_percent
= highy_float
- lowy_float
;
1725 percent
= (1-lowx_float
)*y_percent
;
1726 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1727 for (k
= 0, temp_index
= temp
; k
< components
;
1728 k
++, temp_index
+= element_size
) {
1729 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1731 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1733 for (k
= 0, temp_index
= temp
; k
< components
;
1734 k
++, temp_index
+= element_size
) {
1735 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1739 percent
= y_percent
* highx_float
;
1740 for (k
= 0, temp_index
= temp
; k
< components
;
1741 k
++, temp_index
+= element_size
) {
1742 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1745 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1746 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1747 for (k
= 0, temp_index
= temp
; k
< components
;
1748 k
++, temp_index
+= element_size
) {
1749 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1755 /* this is for the pixels in the body */
1756 temp0
= (const char *)datain
+ xindex
+ group_size
+
1758 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1760 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1761 for (k
= 0, temp_index
= temp
; k
< components
;
1762 k
++, temp_index
+= element_size
) {
1763 totals
[k
] += (GLbyte
)(*(temp_index
));
1770 outindex
= (j
+ (i
* widthout
)) * components
;
1771 for (k
= 0; k
< components
; k
++) {
1772 dataout
[outindex
+ k
] = totals
[k
]/area
;
1773 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1775 lowx_int
= highx_int
;
1776 lowx_float
= highx_float
;
1777 highx_int
+= convx_int
;
1778 highx_float
+= convx_float
;
1779 if(highx_float
> 1) {
1784 lowy_int
= highy_int
;
1785 lowy_float
= highy_float
;
1786 highy_int
+= convy_int
;
1787 highy_float
+= convy_float
;
1788 if(highy_float
> 1) {
1795 static void scale_internal_ushort(GLint components
, GLint widthin
,
1796 GLint heightin
, const GLushort
*datain
,
1797 GLint widthout
, GLint heightout
,
1798 GLushort
*dataout
, GLint element_size
,
1799 GLint ysize
, GLint group_size
,
1805 /* Max components in a format is 4, so... */
1810 const char *temp
, *temp0
;
1811 const char *temp_index
;
1814 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1815 float x_percent
, y_percent
;
1816 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1817 float convy_float
, convx_float
;
1818 int convy_int
, convx_int
;
1820 const char *left
, *right
;
1822 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1823 halveImage_ushort(components
, widthin
, heightin
,
1824 (const GLushort
*)datain
, (GLushort
*)dataout
,
1825 element_size
, ysize
, group_size
, myswap_bytes
);
1828 convy
= (float) heightin
/heightout
;
1829 convx
= (float) widthin
/widthout
;
1830 convy_int
= floor(convy
);
1831 convy_float
= convy
- convy_int
;
1832 convx_int
= floor(convx
);
1833 convx_float
= convx
- convx_int
;
1835 area
= convx
* convy
;
1839 highy_int
= convy_int
;
1840 highy_float
= convy_float
;
1842 for (i
= 0; i
< heightout
; i
++) {
1845 highx_int
= convx_int
;
1846 highx_float
= convx_float
;
1848 for (j
= 0; j
< widthout
; j
++) {
1850 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1851 ** to (highx, highy) on input data into this pixel on output
1854 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1856 /* calculate the value for pixels in the 1st row */
1857 xindex
= lowx_int
*group_size
;
1858 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1860 y_percent
= 1-lowy_float
;
1861 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1862 percent
= y_percent
* (1-lowx_float
);
1863 for (k
= 0, temp_index
= temp
; k
< components
;
1864 k
++, temp_index
+= element_size
) {
1866 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1868 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1872 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1874 for (k
= 0, temp_index
= temp
; k
< components
;
1875 k
++, temp_index
+= element_size
) {
1878 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1880 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1886 percent
= y_percent
* highx_float
;
1887 for (k
= 0, temp_index
= temp
; k
< components
;
1888 k
++, temp_index
+= element_size
) {
1890 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1892 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1896 /* calculate the value for pixels in the last row */
1897 y_percent
= highy_float
;
1898 percent
= y_percent
* (1-lowx_float
);
1899 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1900 for (k
= 0, temp_index
= temp
; k
< components
;
1901 k
++, temp_index
+= element_size
) {
1903 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1905 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1908 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1910 for (k
= 0, temp_index
= temp
; k
< components
;
1911 k
++, temp_index
+= element_size
) {
1914 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1916 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1921 percent
= y_percent
* highx_float
;
1922 for (k
= 0, temp_index
= temp
; k
< components
;
1923 k
++, temp_index
+= element_size
) {
1925 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1927 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1931 /* calculate the value for pixels in the 1st and last column */
1932 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1935 for (k
= 0; k
< components
;
1936 k
++, left
+= element_size
, right
+= element_size
) {
1939 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1940 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1942 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1943 + *(const GLushort
*)right
* highx_float
;
1947 } else if (highy_int
> lowy_int
) {
1948 x_percent
= highx_float
- lowx_float
;
1949 percent
= (1-lowy_float
)*x_percent
;
1950 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1951 for (k
= 0, temp_index
= temp
; k
< components
;
1952 k
++, temp_index
+= element_size
) {
1954 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1956 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1959 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1961 for (k
= 0, temp_index
= temp
; k
< components
;
1962 k
++, temp_index
+= element_size
) {
1965 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
1967 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
1971 percent
= x_percent
* highy_float
;
1973 for (k
= 0, temp_index
= temp
; k
< components
;
1974 k
++, temp_index
+= element_size
) {
1976 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1978 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1981 } else if (highx_int
> lowx_int
) {
1982 y_percent
= highy_float
- lowy_float
;
1983 percent
= (1-lowx_float
)*y_percent
;
1984 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1985 for (k
= 0, temp_index
= temp
; k
< components
;
1986 k
++, temp_index
+= element_size
) {
1988 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1990 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1993 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1995 for (k
= 0, temp_index
= temp
; k
< components
;
1996 k
++, temp_index
+= element_size
) {
1999 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2001 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2006 percent
= y_percent
* highx_float
;
2007 for (k
= 0, temp_index
= temp
; k
< components
;
2008 k
++, temp_index
+= element_size
) {
2010 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2012 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2016 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2017 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2018 for (k
= 0, temp_index
= temp
; k
< components
;
2019 k
++, temp_index
+= element_size
) {
2021 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2023 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2028 /* this is for the pixels in the body */
2029 temp0
= (const char *)datain
+ xindex
+ group_size
+
2031 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2033 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2034 for (k
= 0, temp_index
= temp
; k
< components
;
2035 k
++, temp_index
+= element_size
) {
2037 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2039 totals
[k
] += *(const GLushort
*)temp_index
;
2047 outindex
= (j
+ (i
* widthout
)) * components
;
2048 for (k
= 0; k
< components
; k
++) {
2049 dataout
[outindex
+ k
] = totals
[k
]/area
;
2050 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2052 lowx_int
= highx_int
;
2053 lowx_float
= highx_float
;
2054 highx_int
+= convx_int
;
2055 highx_float
+= convx_float
;
2056 if(highx_float
> 1) {
2061 lowy_int
= highy_int
;
2062 lowy_float
= highy_float
;
2063 highy_int
+= convy_int
;
2064 highy_float
+= convy_float
;
2065 if(highy_float
> 1) {
2072 static void scale_internal_short(GLint components
, GLint widthin
,
2073 GLint heightin
, const GLshort
*datain
,
2074 GLint widthout
, GLint heightout
,
2075 GLshort
*dataout
, GLint element_size
,
2076 GLint ysize
, GLint group_size
,
2082 /* Max components in a format is 4, so... */
2087 const char *temp
, *temp0
;
2088 const char *temp_index
;
2091 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2092 float x_percent
, y_percent
;
2093 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2094 float convy_float
, convx_float
;
2095 int convy_int
, convx_int
;
2097 const char *left
, *right
;
2099 GLushort swapbuf
; /* unsigned buffer */
2101 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2102 halveImage_short(components
, widthin
, heightin
,
2103 (const GLshort
*)datain
, (GLshort
*)dataout
,
2104 element_size
, ysize
, group_size
, myswap_bytes
);
2107 convy
= (float) heightin
/heightout
;
2108 convx
= (float) widthin
/widthout
;
2109 convy_int
= floor(convy
);
2110 convy_float
= convy
- convy_int
;
2111 convx_int
= floor(convx
);
2112 convx_float
= convx
- convx_int
;
2114 area
= convx
* convy
;
2118 highy_int
= convy_int
;
2119 highy_float
= convy_float
;
2121 for (i
= 0; i
< heightout
; i
++) {
2124 highx_int
= convx_int
;
2125 highx_float
= convx_float
;
2127 for (j
= 0; j
< widthout
; j
++) {
2129 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2130 ** to (highx, highy) on input data into this pixel on output
2133 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2135 /* calculate the value for pixels in the 1st row */
2136 xindex
= lowx_int
*group_size
;
2137 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2139 y_percent
= 1-lowy_float
;
2140 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2141 percent
= y_percent
* (1-lowx_float
);
2142 for (k
= 0, temp_index
= temp
; k
< components
;
2143 k
++, temp_index
+= element_size
) {
2145 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2146 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2148 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2152 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2154 for (k
= 0, temp_index
= temp
; k
< components
;
2155 k
++, temp_index
+= element_size
) {
2157 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2158 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2160 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2166 percent
= y_percent
* highx_float
;
2167 for (k
= 0, temp_index
= temp
; k
< components
;
2168 k
++, temp_index
+= element_size
) {
2170 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2171 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2173 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2177 /* calculate the value for pixels in the last row */
2178 y_percent
= highy_float
;
2179 percent
= y_percent
* (1-lowx_float
);
2180 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2181 for (k
= 0, temp_index
= temp
; k
< components
;
2182 k
++, temp_index
+= element_size
) {
2184 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2185 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2187 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2190 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2192 for (k
= 0, temp_index
= temp
; k
< components
;
2193 k
++, temp_index
+= element_size
) {
2195 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2196 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2198 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2203 percent
= y_percent
* highx_float
;
2204 for (k
= 0, temp_index
= temp
; k
< components
;
2205 k
++, temp_index
+= element_size
) {
2207 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2208 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2210 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2214 /* calculate the value for pixels in the 1st and last column */
2215 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2218 for (k
= 0; k
< components
;
2219 k
++, left
+= element_size
, right
+= element_size
) {
2221 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2222 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2223 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2224 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2226 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2227 + *(const GLshort
*)right
* highx_float
;
2231 } else if (highy_int
> lowy_int
) {
2232 x_percent
= highx_float
- lowx_float
;
2233 percent
= (1-lowy_float
)*x_percent
;
2234 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2235 for (k
= 0, temp_index
= temp
; k
< components
;
2236 k
++, temp_index
+= element_size
) {
2238 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2239 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2241 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2244 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2246 for (k
= 0, temp_index
= temp
; k
< components
;
2247 k
++, temp_index
+= element_size
) {
2249 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2250 totals
[k
] += *(const GLshort
*)&swapbuf
* x_percent
;
2252 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2256 percent
= x_percent
* highy_float
;
2258 for (k
= 0, temp_index
= temp
; k
< components
;
2259 k
++, temp_index
+= element_size
) {
2261 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2262 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2264 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2267 } else if (highx_int
> lowx_int
) {
2268 y_percent
= highy_float
- lowy_float
;
2269 percent
= (1-lowx_float
)*y_percent
;
2271 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2272 for (k
= 0, temp_index
= temp
; k
< components
;
2273 k
++, temp_index
+= element_size
) {
2275 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2276 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2278 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2281 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2283 for (k
= 0, temp_index
= temp
; k
< components
;
2284 k
++, temp_index
+= element_size
) {
2286 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2287 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2289 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2294 percent
= y_percent
* highx_float
;
2295 for (k
= 0, temp_index
= temp
; k
< components
;
2296 k
++, temp_index
+= element_size
) {
2298 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2299 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2301 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2305 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2306 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2307 for (k
= 0, temp_index
= temp
; k
< components
;
2308 k
++, temp_index
+= element_size
) {
2310 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2311 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2313 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2318 /* this is for the pixels in the body */
2319 temp0
= (const char *)datain
+ xindex
+ group_size
+
2321 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2323 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2324 for (k
= 0, temp_index
= temp
; k
< components
;
2325 k
++, temp_index
+= element_size
) {
2327 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2328 totals
[k
] += *(const GLshort
*)&swapbuf
;
2330 totals
[k
] += *(const GLshort
*)temp_index
;
2338 outindex
= (j
+ (i
* widthout
)) * components
;
2339 for (k
= 0; k
< components
; k
++) {
2340 dataout
[outindex
+ k
] = totals
[k
]/area
;
2341 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2343 lowx_int
= highx_int
;
2344 lowx_float
= highx_float
;
2345 highx_int
+= convx_int
;
2346 highx_float
+= convx_float
;
2347 if(highx_float
> 1) {
2352 lowy_int
= highy_int
;
2353 lowy_float
= highy_float
;
2354 highy_int
+= convy_int
;
2355 highy_float
+= convy_float
;
2356 if(highy_float
> 1) {
2363 static void scale_internal_uint(GLint components
, GLint widthin
,
2364 GLint heightin
, const GLuint
*datain
,
2365 GLint widthout
, GLint heightout
,
2366 GLuint
*dataout
, GLint element_size
,
2367 GLint ysize
, GLint group_size
,
2373 /* Max components in a format is 4, so... */
2378 const char *temp
, *temp0
;
2379 const char *temp_index
;
2382 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2383 float x_percent
, y_percent
;
2384 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2385 float convy_float
, convx_float
;
2386 int convy_int
, convx_int
;
2388 const char *left
, *right
;
2390 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2391 halveImage_uint(components
, widthin
, heightin
,
2392 (const GLuint
*)datain
, (GLuint
*)dataout
,
2393 element_size
, ysize
, group_size
, myswap_bytes
);
2396 convy
= (float) heightin
/heightout
;
2397 convx
= (float) widthin
/widthout
;
2398 convy_int
= floor(convy
);
2399 convy_float
= convy
- convy_int
;
2400 convx_int
= floor(convx
);
2401 convx_float
= convx
- convx_int
;
2403 area
= convx
* convy
;
2407 highy_int
= convy_int
;
2408 highy_float
= convy_float
;
2410 for (i
= 0; i
< heightout
; i
++) {
2413 highx_int
= convx_int
;
2414 highx_float
= convx_float
;
2416 for (j
= 0; j
< widthout
; j
++) {
2418 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2419 ** to (highx, highy) on input data into this pixel on output
2422 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2424 /* calculate the value for pixels in the 1st row */
2425 xindex
= lowx_int
*group_size
;
2426 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2428 y_percent
= 1-lowy_float
;
2429 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2430 percent
= y_percent
* (1-lowx_float
);
2431 for (k
= 0, temp_index
= temp
; k
< components
;
2432 k
++, temp_index
+= element_size
) {
2434 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2436 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2440 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2442 for (k
= 0, temp_index
= temp
; k
< components
;
2443 k
++, temp_index
+= element_size
) {
2446 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2448 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2454 percent
= y_percent
* highx_float
;
2455 for (k
= 0, temp_index
= temp
; k
< components
;
2456 k
++, temp_index
+= element_size
) {
2458 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2460 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2464 /* calculate the value for pixels in the last row */
2465 y_percent
= highy_float
;
2466 percent
= y_percent
* (1-lowx_float
);
2467 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2468 for (k
= 0, temp_index
= temp
; k
< components
;
2469 k
++, temp_index
+= element_size
) {
2471 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2473 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2476 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2478 for (k
= 0, temp_index
= temp
; k
< components
;
2479 k
++, temp_index
+= element_size
) {
2482 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2484 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2489 percent
= y_percent
* highx_float
;
2490 for (k
= 0, temp_index
= temp
; k
< components
;
2491 k
++, temp_index
+= element_size
) {
2493 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2495 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2499 /* calculate the value for pixels in the 1st and last column */
2500 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2503 for (k
= 0; k
< components
;
2504 k
++, left
+= element_size
, right
+= element_size
) {
2507 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2508 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2510 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2511 + *(const GLuint
*)right
* highx_float
;
2515 } else if (highy_int
> lowy_int
) {
2516 x_percent
= highx_float
- lowx_float
;
2517 percent
= (1-lowy_float
)*x_percent
;
2518 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2519 for (k
= 0, temp_index
= temp
; k
< components
;
2520 k
++, temp_index
+= element_size
) {
2522 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2524 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2527 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2529 for (k
= 0, temp_index
= temp
; k
< components
;
2530 k
++, temp_index
+= element_size
) {
2533 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2535 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2539 percent
= x_percent
* highy_float
;
2541 for (k
= 0, temp_index
= temp
; k
< components
;
2542 k
++, temp_index
+= element_size
) {
2544 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2546 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2549 } else if (highx_int
> lowx_int
) {
2550 y_percent
= highy_float
- lowy_float
;
2551 percent
= (1-lowx_float
)*y_percent
;
2553 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2554 for (k
= 0, temp_index
= temp
; k
< components
;
2555 k
++, temp_index
+= element_size
) {
2557 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2559 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2562 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2564 for (k
= 0, temp_index
= temp
; k
< components
;
2565 k
++, temp_index
+= element_size
) {
2568 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2570 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2575 percent
= y_percent
* highx_float
;
2576 for (k
= 0, temp_index
= temp
; k
< components
;
2577 k
++, temp_index
+= element_size
) {
2579 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2581 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2585 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2586 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2587 for (k
= 0, temp_index
= temp
; k
< components
;
2588 k
++, temp_index
+= element_size
) {
2590 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2592 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2597 /* this is for the pixels in the body */
2598 temp0
= (const char *)datain
+ xindex
+ group_size
+
2600 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2602 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2603 for (k
= 0, temp_index
= temp
; k
< components
;
2604 k
++, temp_index
+= element_size
) {
2606 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2608 totals
[k
] += *(const GLuint
*)temp_index
;
2616 outindex
= (j
+ (i
* widthout
)) * components
;
2617 for (k
= 0; k
< components
; k
++) {
2618 /* clamp at UINT_MAX */
2619 float value
= totals
[k
]/area
;
2620 if (value
>= (float) UINT_MAX
) { /* need '=' */
2621 dataout
[outindex
+ k
] = UINT_MAX
;
2623 else dataout
[outindex
+ k
] = value
;
2625 lowx_int
= highx_int
;
2626 lowx_float
= highx_float
;
2627 highx_int
+= convx_int
;
2628 highx_float
+= convx_float
;
2629 if(highx_float
> 1) {
2634 lowy_int
= highy_int
;
2635 lowy_float
= highy_float
;
2636 highy_int
+= convy_int
;
2637 highy_float
+= convy_float
;
2638 if(highy_float
> 1) {
2647 static void scale_internal_int(GLint components
, GLint widthin
,
2648 GLint heightin
, const GLint
*datain
,
2649 GLint widthout
, GLint heightout
,
2650 GLint
*dataout
, GLint element_size
,
2651 GLint ysize
, GLint group_size
,
2657 /* Max components in a format is 4, so... */
2662 const char *temp
, *temp0
;
2663 const char *temp_index
;
2666 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2667 float x_percent
, y_percent
;
2668 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2669 float convy_float
, convx_float
;
2670 int convy_int
, convx_int
;
2672 const char *left
, *right
;
2674 GLuint swapbuf
; /* unsigned buffer */
2676 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2677 halveImage_int(components
, widthin
, heightin
,
2678 (const GLint
*)datain
, (GLint
*)dataout
,
2679 element_size
, ysize
, group_size
, myswap_bytes
);
2682 convy
= (float) heightin
/heightout
;
2683 convx
= (float) widthin
/widthout
;
2684 convy_int
= floor(convy
);
2685 convy_float
= convy
- convy_int
;
2686 convx_int
= floor(convx
);
2687 convx_float
= convx
- convx_int
;
2689 area
= convx
* convy
;
2693 highy_int
= convy_int
;
2694 highy_float
= convy_float
;
2696 for (i
= 0; i
< heightout
; i
++) {
2699 highx_int
= convx_int
;
2700 highx_float
= convx_float
;
2702 for (j
= 0; j
< widthout
; j
++) {
2704 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2705 ** to (highx, highy) on input data into this pixel on output
2708 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2710 /* calculate the value for pixels in the 1st row */
2711 xindex
= lowx_int
*group_size
;
2712 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2714 y_percent
= 1-lowy_float
;
2715 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2716 percent
= y_percent
* (1-lowx_float
);
2717 for (k
= 0, temp_index
= temp
; k
< components
;
2718 k
++, temp_index
+= element_size
) {
2720 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2721 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2723 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2727 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2729 for (k
= 0, temp_index
= temp
; k
< components
;
2730 k
++, temp_index
+= element_size
) {
2732 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2733 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2735 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2741 percent
= y_percent
* highx_float
;
2742 for (k
= 0, temp_index
= temp
; k
< components
;
2743 k
++, temp_index
+= element_size
) {
2745 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2746 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2748 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2752 /* calculate the value for pixels in the last row */
2753 y_percent
= highy_float
;
2754 percent
= y_percent
* (1-lowx_float
);
2755 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2756 for (k
= 0, temp_index
= temp
; k
< components
;
2757 k
++, temp_index
+= element_size
) {
2759 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2760 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2762 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2765 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2767 for (k
= 0, temp_index
= temp
; k
< components
;
2768 k
++, temp_index
+= element_size
) {
2770 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2771 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2773 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2778 percent
= y_percent
* highx_float
;
2779 for (k
= 0, temp_index
= temp
; k
< components
;
2780 k
++, temp_index
+= element_size
) {
2782 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2783 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2785 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2789 /* calculate the value for pixels in the 1st and last column */
2790 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2793 for (k
= 0; k
< components
;
2794 k
++, left
+= element_size
, right
+= element_size
) {
2796 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2797 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2798 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2799 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2801 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2802 + *(const GLint
*)right
* highx_float
;
2806 } else if (highy_int
> lowy_int
) {
2807 x_percent
= highx_float
- lowx_float
;
2808 percent
= (1-lowy_float
)*x_percent
;
2809 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2810 for (k
= 0, temp_index
= temp
; k
< components
;
2811 k
++, temp_index
+= element_size
) {
2813 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2814 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2816 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2819 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2821 for (k
= 0, temp_index
= temp
; k
< components
;
2822 k
++, temp_index
+= element_size
) {
2824 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2825 totals
[k
] += *(const GLint
*)&swapbuf
* x_percent
;
2827 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2831 percent
= x_percent
* highy_float
;
2833 for (k
= 0, temp_index
= temp
; k
< components
;
2834 k
++, temp_index
+= element_size
) {
2836 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2837 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2839 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2842 } else if (highx_int
> lowx_int
) {
2843 y_percent
= highy_float
- lowy_float
;
2844 percent
= (1-lowx_float
)*y_percent
;
2846 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2847 for (k
= 0, temp_index
= temp
; k
< components
;
2848 k
++, temp_index
+= element_size
) {
2850 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2851 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2853 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2856 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2858 for (k
= 0, temp_index
= temp
; k
< components
;
2859 k
++, temp_index
+= element_size
) {
2861 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2862 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2864 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2869 percent
= y_percent
* highx_float
;
2870 for (k
= 0, temp_index
= temp
; k
< components
;
2871 k
++, temp_index
+= element_size
) {
2873 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2874 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2876 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2880 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2881 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2882 for (k
= 0, temp_index
= temp
; k
< components
;
2883 k
++, temp_index
+= element_size
) {
2885 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2886 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2888 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2893 /* this is for the pixels in the body */
2894 temp0
= (const char *)datain
+ xindex
+ group_size
+
2896 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2898 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2899 for (k
= 0, temp_index
= temp
; k
< components
;
2900 k
++, temp_index
+= element_size
) {
2902 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2903 totals
[k
] += *(const GLint
*)&swapbuf
;
2905 totals
[k
] += *(const GLint
*)temp_index
;
2913 outindex
= (j
+ (i
* widthout
)) * components
;
2914 for (k
= 0; k
< components
; k
++) {
2915 dataout
[outindex
+ k
] = totals
[k
]/area
;
2916 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2918 lowx_int
= highx_int
;
2919 lowx_float
= highx_float
;
2920 highx_int
+= convx_int
;
2921 highx_float
+= convx_float
;
2922 if(highx_float
> 1) {
2927 lowy_int
= highy_int
;
2928 lowy_float
= highy_float
;
2929 highy_int
+= convy_int
;
2930 highy_float
+= convy_float
;
2931 if(highy_float
> 1) {
2940 static void scale_internal_float(GLint components
, GLint widthin
,
2941 GLint heightin
, const GLfloat
*datain
,
2942 GLint widthout
, GLint heightout
,
2943 GLfloat
*dataout
, GLint element_size
,
2944 GLint ysize
, GLint group_size
,
2950 /* Max components in a format is 4, so... */
2955 const char *temp
, *temp0
;
2956 const char *temp_index
;
2959 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2960 float x_percent
, y_percent
;
2961 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2962 float convy_float
, convx_float
;
2963 int convy_int
, convx_int
;
2965 const char *left
, *right
;
2967 GLuint swapbuf
; /* unsigned buffer */
2969 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2970 halveImage_float(components
, widthin
, heightin
,
2971 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
2972 element_size
, ysize
, group_size
, myswap_bytes
);
2975 convy
= (float) heightin
/heightout
;
2976 convx
= (float) widthin
/widthout
;
2977 convy_int
= floor(convy
);
2978 convy_float
= convy
- convy_int
;
2979 convx_int
= floor(convx
);
2980 convx_float
= convx
- convx_int
;
2982 area
= convx
* convy
;
2986 highy_int
= convy_int
;
2987 highy_float
= convy_float
;
2989 for (i
= 0; i
< heightout
; i
++) {
2992 highx_int
= convx_int
;
2993 highx_float
= convx_float
;
2995 for (j
= 0; j
< widthout
; j
++) {
2997 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2998 ** to (highx, highy) on input data into this pixel on output
3001 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3003 /* calculate the value for pixels in the 1st row */
3004 xindex
= lowx_int
*group_size
;
3005 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3007 y_percent
= 1-lowy_float
;
3008 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3009 percent
= y_percent
* (1-lowx_float
);
3010 for (k
= 0, temp_index
= temp
; k
< components
;
3011 k
++, temp_index
+= element_size
) {
3013 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3014 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3016 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3020 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3022 for (k
= 0, temp_index
= temp
; k
< components
;
3023 k
++, temp_index
+= element_size
) {
3025 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3026 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3028 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3034 percent
= y_percent
* highx_float
;
3035 for (k
= 0, temp_index
= temp
; k
< components
;
3036 k
++, temp_index
+= element_size
) {
3038 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3039 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3041 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3045 /* calculate the value for pixels in the last row */
3046 y_percent
= highy_float
;
3047 percent
= y_percent
* (1-lowx_float
);
3048 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3049 for (k
= 0, temp_index
= temp
; k
< components
;
3050 k
++, temp_index
+= element_size
) {
3052 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3053 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3055 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3058 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3060 for (k
= 0, temp_index
= temp
; k
< components
;
3061 k
++, temp_index
+= element_size
) {
3063 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3064 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3066 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3071 percent
= y_percent
* highx_float
;
3072 for (k
= 0, temp_index
= temp
; k
< components
;
3073 k
++, temp_index
+= element_size
) {
3075 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3076 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3078 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3082 /* calculate the value for pixels in the 1st and last column */
3083 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3086 for (k
= 0; k
< components
;
3087 k
++, left
+= element_size
, right
+= element_size
) {
3089 swapbuf
= __GLU_SWAP_4_BYTES(left
);
3090 totals
[k
] += *(const GLfloat
*)&swapbuf
* (1-lowx_float
);
3091 swapbuf
= __GLU_SWAP_4_BYTES(right
);
3092 totals
[k
] += *(const GLfloat
*)&swapbuf
* highx_float
;
3094 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3095 + *(const GLfloat
*)right
* highx_float
;
3099 } else if (highy_int
> lowy_int
) {
3100 x_percent
= highx_float
- lowx_float
;
3101 percent
= (1-lowy_float
)*x_percent
;
3102 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3103 for (k
= 0, temp_index
= temp
; k
< components
;
3104 k
++, temp_index
+= element_size
) {
3106 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3107 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3109 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3112 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3114 for (k
= 0, temp_index
= temp
; k
< components
;
3115 k
++, temp_index
+= element_size
) {
3117 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3118 totals
[k
] += *(const GLfloat
*)&swapbuf
* x_percent
;
3120 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3124 percent
= x_percent
* highy_float
;
3126 for (k
= 0, temp_index
= temp
; k
< components
;
3127 k
++, temp_index
+= element_size
) {
3129 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3130 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3132 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3135 } else if (highx_int
> lowx_int
) {
3136 y_percent
= highy_float
- lowy_float
;
3137 percent
= (1-lowx_float
)*y_percent
;
3139 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3140 for (k
= 0, temp_index
= temp
; k
< components
;
3141 k
++, temp_index
+= element_size
) {
3143 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3144 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3146 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3149 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3151 for (k
= 0, temp_index
= temp
; k
< components
;
3152 k
++, temp_index
+= element_size
) {
3154 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3155 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3157 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3162 percent
= y_percent
* highx_float
;
3163 for (k
= 0, temp_index
= temp
; k
< components
;
3164 k
++, temp_index
+= element_size
) {
3166 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3167 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3169 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3173 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3174 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3175 for (k
= 0, temp_index
= temp
; k
< components
;
3176 k
++, temp_index
+= element_size
) {
3178 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3179 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3181 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3186 /* this is for the pixels in the body */
3187 temp0
= (const char *)datain
+ xindex
+ group_size
+
3189 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3191 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3192 for (k
= 0, temp_index
= temp
; k
< components
;
3193 k
++, temp_index
+= element_size
) {
3195 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3196 totals
[k
] += *(const GLfloat
*)&swapbuf
;
3198 totals
[k
] += *(const GLfloat
*)temp_index
;
3206 outindex
= (j
+ (i
* widthout
)) * components
;
3207 for (k
= 0; k
< components
; k
++) {
3208 dataout
[outindex
+ k
] = totals
[k
]/area
;
3209 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3211 lowx_int
= highx_int
;
3212 lowx_float
= highx_float
;
3213 highx_int
+= convx_int
;
3214 highx_float
+= convx_float
;
3215 if(highx_float
> 1) {
3220 lowy_int
= highy_int
;
3221 lowy_float
= highy_float
;
3222 highy_int
+= convy_int
;
3223 highy_float
+= convy_float
;
3224 if(highy_float
> 1) {
3231 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3233 if (!legalFormat(format
) || !legalType(type
)) {
3234 return GLU_INVALID_ENUM
;
3236 if (format
== GL_STENCIL_INDEX
) {
3237 return GLU_INVALID_ENUM
;
3240 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3241 return GLU_INVALID_OPERATION
;
3245 } /* checkMipmapArgs() */
3247 static GLboolean
legalFormat(GLenum format
)
3250 case GL_COLOR_INDEX
:
3251 case GL_STENCIL_INDEX
:
3252 case GL_DEPTH_COMPONENT
:
3260 case GL_LUMINANCE_ALPHA
:
3270 static GLboolean
legalType(GLenum type
)
3275 case GL_UNSIGNED_BYTE
:
3277 case GL_UNSIGNED_SHORT
:
3279 case GL_UNSIGNED_INT
:
3281 case GL_UNSIGNED_BYTE_3_3_2
:
3282 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3283 case GL_UNSIGNED_SHORT_5_6_5
:
3284 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3285 case GL_UNSIGNED_SHORT_4_4_4_4
:
3286 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3287 case GL_UNSIGNED_SHORT_5_5_5_1
:
3288 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3289 case GL_UNSIGNED_INT_8_8_8_8
:
3290 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3291 case GL_UNSIGNED_INT_10_10_10_2
:
3292 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3300 static GLboolean
isTypePackedPixel(GLenum type
)
3302 assert(legalType(type
));
3304 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3305 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3306 type
== GL_UNSIGNED_SHORT_5_6_5
||
3307 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3308 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3309 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3310 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3311 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3312 type
== GL_UNSIGNED_INT_8_8_8_8
||
3313 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3314 type
== GL_UNSIGNED_INT_10_10_10_2
||
3315 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3319 } /* isTypePackedPixel() */
3321 /* Determines if the packed pixel type is compatible with the format */
3322 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3324 /* if not a packed pixel type then return true */
3325 if (!isTypePackedPixel(type
)) {
3329 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3330 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3331 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3332 && format
!= GL_RGB
)
3335 /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
3336 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3338 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3339 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3340 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3341 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3342 type
== GL_UNSIGNED_INT_8_8_8_8
||
3343 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3344 type
== GL_UNSIGNED_INT_10_10_10_2
||
3345 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3346 (format
!= GL_RGBA
&&
3347 format
!= GL_BGRA
)) {
3352 } /* isLegalFormatForPackedPixelType() */
3354 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3357 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3358 totalLevels
< maxLevel
)
3360 else return GL_TRUE
;
3361 } /* isLegalLevels() */
3363 /* Given user requested texture size, determine if it fits. If it
3364 * doesn't then halve both sides and make the determination again
3365 * until it does fit (for IR only).
3366 * Note that proxy textures are not implemented in RE* even though
3367 * they advertise the texture extension.
3368 * Note that proxy textures are implemented but not according to spec in
3371 static void closestFit(GLenum target
, GLint width
, GLint height
,
3372 GLint internalFormat
, GLenum format
, GLenum type
,
3373 GLint
*newWidth
, GLint
*newHeight
)
3375 /* Use proxy textures if OpenGL version is >= 1.1 */
3376 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3378 GLint widthPowerOf2
= nearestPower(width
);
3379 GLint heightPowerOf2
= nearestPower(height
);
3383 /* compute level 1 width & height, clamping each at 1 */
3384 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3385 widthPowerOf2
>> 1 :
3387 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3388 heightPowerOf2
>> 1 :
3391 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3393 /* does width x height at level 1 & all their mipmaps fit? */
3394 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3395 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3396 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3398 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3400 #if defined(GL_ARB_texture_cube_map)
3401 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3402 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3403 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3404 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3405 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3406 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3407 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3408 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3410 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3412 #endif /* GL_ARB_texture_cube_map */
3414 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3415 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3416 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3417 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3419 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3420 /* does it fit??? */
3421 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3422 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3423 /* An 1x1 texture couldn't fit for some reason, so
3424 * break out. This should never happen. But things
3425 * happen. The disadvantage with this if-statement is
3426 * that we will never be aware of when this happens
3427 * since it will silently branch out.
3429 goto noProxyTextures
;
3431 widthPowerOf2
= widthAtLevelOne
;
3432 heightPowerOf2
= heightAtLevelOne
;
3434 /* else it does fit */
3435 } while (proxyWidth
== 0);
3436 /* loop must terminate! */
3438 /* return the width & height at level 0 that fits */
3439 *newWidth
= widthPowerOf2
;
3440 *newHeight
= heightPowerOf2
;
3441 /*printf("Proxy Textures\n");*/
3442 } /* if gluCheckExtension() */
3443 else { /* no texture extension, so do this instead */
3448 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3449 /* clamp user's texture sizes to maximum sizes, if necessary */
3450 *newWidth
= nearestPower(width
);
3451 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3452 *newHeight
= nearestPower(height
);
3453 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3454 /*printf("NO proxy textures\n");*/
3456 } /* closestFit() */
3459 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3460 GLenum typein
, const void *datain
,
3461 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3465 GLushort
*beforeImage
;
3466 GLushort
*afterImage
;
3467 PixelStorageModes psm
;
3469 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3472 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3473 return GLU_INVALID_VALUE
;
3475 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3476 return GLU_INVALID_ENUM
;
3478 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3479 return GLU_INVALID_OPERATION
;
3481 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3482 return GLU_INVALID_OPERATION
;
3485 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3487 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3488 if (beforeImage
== NULL
|| afterImage
== NULL
) {
3489 return GLU_OUT_OF_MEMORY
;
3492 retrieveStoreModes(&psm
);
3493 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3494 datain
, beforeImage
);
3495 components
= elements_per_group(format
, 0);
3496 scale_internal(components
, widthin
, heightin
, beforeImage
,
3497 widthout
, heightout
, afterImage
);
3498 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3499 is_index(format
), afterImage
, dataout
);
3500 free((GLbyte
*) beforeImage
);
3501 free((GLbyte
*) afterImage
);
3506 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3508 GLsizei widthPowerOf2
,
3509 GLenum format
, GLenum type
,
3510 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3514 GLint level
, levels
;
3516 GLint newImage_width
;
3517 GLushort
*otherImage
;
3518 GLushort
*imageTemp
;
3521 PixelStorageModes psm
;
3523 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3528 newwidth
= widthPowerOf2
;
3529 levels
= computeLog(newwidth
);
3533 retrieveStoreModes(&psm
);
3534 newImage
= (GLushort
*)
3535 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3536 newImage_width
= width
;
3537 if (newImage
== NULL
) {
3538 return GLU_OUT_OF_MEMORY
;
3540 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3542 cmpts
= elements_per_group(format
,type
);
3543 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3544 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3545 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3546 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3548 ** If swap_bytes was set, swapping occurred in fill_image.
3550 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3552 for (level
= userLevel
; level
<= levels
; level
++) {
3553 if (newImage_width
== newwidth
) {
3554 /* Use newImage for this level */
3555 if (baseLevel
<= level
&& level
<= maxLevel
) {
3556 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3557 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3560 if (otherImage
== NULL
) {
3561 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3562 otherImage
= (GLushort
*) malloc(memreq
);
3563 if (otherImage
== NULL
) {
3564 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3565 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3566 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3567 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3568 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3569 return GLU_OUT_OF_MEMORY
;
3572 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3573 newwidth
, 1, otherImage
);
3574 /* Swap newImage and otherImage */
3575 imageTemp
= otherImage
;
3576 otherImage
= newImage
;
3577 newImage
= imageTemp
;
3579 newImage_width
= newwidth
;
3580 if (baseLevel
<= level
&& level
<= maxLevel
) {
3581 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3582 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3585 if (newwidth
> 1) newwidth
/= 2;
3587 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3588 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3589 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3590 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3591 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3593 free((GLbyte
*) newImage
);
3595 free((GLbyte
*) otherImage
);
3601 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3603 GLenum format
, GLenum type
,
3604 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3609 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3610 if (rc
!= 0) return rc
;
3613 return GLU_INVALID_VALUE
;
3616 levels
= computeLog(width
);
3619 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3620 return GLU_INVALID_VALUE
;
3622 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3625 userLevel
, baseLevel
, maxLevel
,
3627 } /* gluBuild1DMipmapLevels() */
3630 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3631 GLenum format
, GLenum type
,
3634 GLint widthPowerOf2
;
3638 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3639 if (rc
!= 0) return rc
;
3642 return GLU_INVALID_VALUE
;
3645 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3646 levels
= computeLog(widthPowerOf2
);
3648 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3651 format
,type
,0,0,levels
,data
);
3654 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3655 GLint width
, GLint height
, GLenum format
,
3656 GLenum type
, const void *data
)
3658 GLint newwidth
, newheight
;
3659 GLint level
, levels
;
3661 GLint newImage_width
;
3662 GLint newImage_height
;
3663 GLushort
*otherImage
;
3664 GLushort
*imageTemp
;
3667 PixelStorageModes psm
;
3669 retrieveStoreModes(&psm
);
3672 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3673 newwidth
= nearestPower(width
);
3674 if (newwidth
> maxsize
) newwidth
= maxsize
;
3675 newheight
= nearestPower(height
);
3676 if (newheight
> maxsize
) newheight
= maxsize
;
3678 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3679 &newwidth
,&newheight
);
3681 levels
= computeLog(newwidth
);
3682 level
= computeLog(newheight
);
3683 if (level
> levels
) levels
=level
;
3686 newImage
= (GLushort
*)
3687 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3688 newImage_width
= width
;
3689 newImage_height
= height
;
3690 if (newImage
== NULL
) {
3691 return GLU_OUT_OF_MEMORY
;
3694 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3697 cmpts
= elements_per_group(format
,type
);
3698 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3699 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3700 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3701 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3703 ** If swap_bytes was set, swapping occurred in fill_image.
3705 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3707 for (level
= 0; level
<= levels
; level
++) {
3708 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3709 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3710 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3713 if (otherImage
== NULL
) {
3715 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3716 otherImage
= (GLushort
*) malloc(memreq
);
3717 if (otherImage
== NULL
) {
3718 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3719 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3720 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3721 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3722 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3723 return GLU_OUT_OF_MEMORY
;
3726 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3727 newwidth
, newheight
, otherImage
);
3728 /* Swap newImage and otherImage */
3729 imageTemp
= otherImage
;
3730 otherImage
= newImage
;
3731 newImage
= imageTemp
;
3733 newImage_width
= newwidth
;
3734 newImage_height
= newheight
;
3735 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3736 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3739 if (newwidth
> 1) newwidth
/= 2;
3740 if (newheight
> 1) newheight
/= 2;
3742 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3743 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3744 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3745 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3746 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3748 free((GLbyte
*) newImage
);
3750 free((GLbyte
*) otherImage
);
3755 /* To make swapping images less error prone */
3756 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3757 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3759 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3760 GLsizei width
, GLsizei height
,
3761 GLsizei widthPowerOf2
,
3762 GLsizei heightPowerOf2
,
3763 GLenum format
, GLenum type
,
3765 GLint baseLevel
,GLint maxLevel
,
3768 GLint newwidth
, newheight
;
3769 GLint level
, levels
;
3770 const void *usersImage
; /* passed from user. Don't touch! */
3771 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3772 __GLU_INIT_SWAP_IMAGE
;
3776 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3777 GLint rowsize
, padding
;
3778 PixelStorageModes psm
;
3780 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3781 assert(width
>= 1 && height
>= 1);
3783 if(type
== GL_BITMAP
) {
3784 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3785 format
, type
, data
);
3788 srcImage
= dstImage
= NULL
;
3790 newwidth
= widthPowerOf2
;
3791 newheight
= heightPowerOf2
;
3792 levels
= computeLog(newwidth
);
3793 level
= computeLog(newheight
);
3794 if (level
> levels
) levels
=level
;
3798 retrieveStoreModes(&psm
);
3799 myswap_bytes
= psm
.unpack_swap_bytes
;
3800 cmpts
= elements_per_group(format
,type
);
3801 if (psm
.unpack_row_length
> 0) {
3802 groups_per_line
= psm
.unpack_row_length
;
3804 groups_per_line
= width
;
3807 element_size
= bytes_per_element(type
);
3808 group_size
= element_size
* cmpts
;
3809 if (element_size
== 1) myswap_bytes
= 0;
3811 rowsize
= groups_per_line
* group_size
;
3812 padding
= (rowsize
% psm
.unpack_alignment
);
3814 rowsize
+= psm
.unpack_alignment
- padding
;
3816 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3817 psm
.unpack_skip_pixels
* group_size
;
3819 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3820 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3821 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3825 /* already power-of-two square */
3826 if (width
== newwidth
&& height
== newheight
) {
3827 /* Use usersImage for level userLevel */
3828 if (baseLevel
<= level
&& level
<= maxLevel
) {
3829 glTexImage2D(target
, level
, internalFormat
, width
,
3830 height
, 0, format
, type
,
3833 if(levels
== 0) { /* we're done. clean up and return */
3834 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3835 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3836 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3837 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3838 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3842 int nextWidth
= newwidth
/2;
3843 int nextHeight
= newheight
/2;
3846 if (nextWidth
< 1) nextWidth
= 1;
3847 if (nextHeight
< 1) nextHeight
= 1;
3848 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3852 case GL_UNSIGNED_BYTE
:
3853 dstImage
= (GLubyte
*)malloc(memreq
);
3856 dstImage
= (GLbyte
*)malloc(memreq
);
3858 case GL_UNSIGNED_SHORT
:
3859 dstImage
= (GLushort
*)malloc(memreq
);
3862 dstImage
= (GLshort
*)malloc(memreq
);
3864 case GL_UNSIGNED_INT
:
3865 dstImage
= (GLuint
*)malloc(memreq
);
3868 dstImage
= (GLint
*)malloc(memreq
);
3871 dstImage
= (GLfloat
*)malloc(memreq
);
3873 case GL_UNSIGNED_BYTE_3_3_2
:
3874 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3875 dstImage
= (GLubyte
*)malloc(memreq
);
3877 case GL_UNSIGNED_SHORT_5_6_5
:
3878 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3879 case GL_UNSIGNED_SHORT_4_4_4_4
:
3880 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3881 case GL_UNSIGNED_SHORT_5_5_5_1
:
3882 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3883 dstImage
= (GLushort
*)malloc(memreq
);
3885 case GL_UNSIGNED_INT_8_8_8_8
:
3886 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3887 case GL_UNSIGNED_INT_10_10_10_2
:
3888 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3889 dstImage
= (GLuint
*)malloc(memreq
);
3892 return GLU_INVALID_ENUM
;
3894 if (dstImage
== NULL
) {
3895 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3896 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3897 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3898 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3899 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3900 return GLU_OUT_OF_MEMORY
;
3904 case GL_UNSIGNED_BYTE
:
3905 halveImage_ubyte(cmpts
, width
, height
,
3906 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3907 element_size
, rowsize
, group_size
);
3910 halveImage_byte(cmpts
, width
, height
,
3911 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3912 element_size
, rowsize
, group_size
);
3914 case GL_UNSIGNED_SHORT
:
3915 halveImage_ushort(cmpts
, width
, height
,
3916 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3917 element_size
, rowsize
, group_size
, myswap_bytes
);
3920 halveImage_short(cmpts
, width
, height
,
3921 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3922 element_size
, rowsize
, group_size
, myswap_bytes
);
3924 case GL_UNSIGNED_INT
:
3925 halveImage_uint(cmpts
, width
, height
,
3926 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3927 element_size
, rowsize
, group_size
, myswap_bytes
);
3930 halveImage_int(cmpts
, width
, height
,
3931 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3932 element_size
, rowsize
, group_size
, myswap_bytes
);
3935 halveImage_float(cmpts
, width
, height
,
3936 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3937 element_size
, rowsize
, group_size
, myswap_bytes
);
3939 case GL_UNSIGNED_BYTE_3_3_2
:
3940 assert(format
== GL_RGB
);
3941 halveImagePackedPixel(3,extract332
,shove332
,
3942 width
,height
,usersImage
,dstImage
,
3943 element_size
,rowsize
,myswap_bytes
);
3945 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3946 assert(format
== GL_RGB
);
3947 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3948 width
,height
,usersImage
,dstImage
,
3949 element_size
,rowsize
,myswap_bytes
);
3951 case GL_UNSIGNED_SHORT_5_6_5
:
3952 halveImagePackedPixel(3,extract565
,shove565
,
3953 width
,height
,usersImage
,dstImage
,
3954 element_size
,rowsize
,myswap_bytes
);
3956 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3957 halveImagePackedPixel(3,extract565rev
,shove565rev
,
3958 width
,height
,usersImage
,dstImage
,
3959 element_size
,rowsize
,myswap_bytes
);
3961 case GL_UNSIGNED_SHORT_4_4_4_4
:
3962 halveImagePackedPixel(4,extract4444
,shove4444
,
3963 width
,height
,usersImage
,dstImage
,
3964 element_size
,rowsize
,myswap_bytes
);
3966 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3967 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
3968 width
,height
,usersImage
,dstImage
,
3969 element_size
,rowsize
,myswap_bytes
);
3971 case GL_UNSIGNED_SHORT_5_5_5_1
:
3972 halveImagePackedPixel(4,extract5551
,shove5551
,
3973 width
,height
,usersImage
,dstImage
,
3974 element_size
,rowsize
,myswap_bytes
);
3976 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3977 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
3978 width
,height
,usersImage
,dstImage
,
3979 element_size
,rowsize
,myswap_bytes
);
3981 case GL_UNSIGNED_INT_8_8_8_8
:
3982 halveImagePackedPixel(4,extract8888
,shove8888
,
3983 width
,height
,usersImage
,dstImage
,
3984 element_size
,rowsize
,myswap_bytes
);
3986 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3987 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
3988 width
,height
,usersImage
,dstImage
,
3989 element_size
,rowsize
,myswap_bytes
);
3991 case GL_UNSIGNED_INT_10_10_10_2
:
3992 halveImagePackedPixel(4,extract1010102
,shove1010102
,
3993 width
,height
,usersImage
,dstImage
,
3994 element_size
,rowsize
,myswap_bytes
);
3996 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3997 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
3998 width
,height
,usersImage
,dstImage
,
3999 element_size
,rowsize
,myswap_bytes
);
4006 newheight
= height
/2;
4008 if (newwidth
< 1) newwidth
= 1;
4009 if (newheight
< 1) newheight
= 1;
4012 rowsize
= newwidth
* group_size
;
4013 memreq
= image_size(newwidth
, newheight
, format
, type
);
4014 /* Swap srcImage and dstImage */
4015 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4017 case GL_UNSIGNED_BYTE
:
4018 dstImage
= (GLubyte
*)malloc(memreq
);
4021 dstImage
= (GLbyte
*)malloc(memreq
);
4023 case GL_UNSIGNED_SHORT
:
4024 dstImage
= (GLushort
*)malloc(memreq
);
4027 dstImage
= (GLshort
*)malloc(memreq
);
4029 case GL_UNSIGNED_INT
:
4030 dstImage
= (GLuint
*)malloc(memreq
);
4033 dstImage
= (GLint
*)malloc(memreq
);
4036 dstImage
= (GLfloat
*)malloc(memreq
);
4038 case GL_UNSIGNED_BYTE_3_3_2
:
4039 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4040 dstImage
= (GLubyte
*)malloc(memreq
);
4042 case GL_UNSIGNED_SHORT_5_6_5
:
4043 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4044 case GL_UNSIGNED_SHORT_4_4_4_4
:
4045 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4046 case GL_UNSIGNED_SHORT_5_5_5_1
:
4047 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4048 dstImage
= (GLushort
*)malloc(memreq
);
4050 case GL_UNSIGNED_INT_8_8_8_8
:
4051 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4052 case GL_UNSIGNED_INT_10_10_10_2
:
4053 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4054 dstImage
= (GLuint
*)malloc(memreq
);
4057 return GLU_INVALID_ENUM
;
4059 if (dstImage
== NULL
) {
4060 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4061 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4062 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4063 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4064 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4065 return GLU_OUT_OF_MEMORY
;
4067 /* level userLevel+1 is in srcImage; level userLevel already saved */
4068 level
= userLevel
+1;
4069 } else { /* user's image is *not* nice power-of-2 sized square */
4070 memreq
= image_size(newwidth
, newheight
, format
, type
);
4072 case GL_UNSIGNED_BYTE
:
4073 dstImage
= (GLubyte
*)malloc(memreq
);
4076 dstImage
= (GLbyte
*)malloc(memreq
);
4078 case GL_UNSIGNED_SHORT
:
4079 dstImage
= (GLushort
*)malloc(memreq
);
4082 dstImage
= (GLshort
*)malloc(memreq
);
4084 case GL_UNSIGNED_INT
:
4085 dstImage
= (GLuint
*)malloc(memreq
);
4088 dstImage
= (GLint
*)malloc(memreq
);
4091 dstImage
= (GLfloat
*)malloc(memreq
);
4093 case GL_UNSIGNED_BYTE_3_3_2
:
4094 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4095 dstImage
= (GLubyte
*)malloc(memreq
);
4097 case GL_UNSIGNED_SHORT_5_6_5
:
4098 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4099 case GL_UNSIGNED_SHORT_4_4_4_4
:
4100 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4101 case GL_UNSIGNED_SHORT_5_5_5_1
:
4102 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4103 dstImage
= (GLushort
*)malloc(memreq
);
4105 case GL_UNSIGNED_INT_8_8_8_8
:
4106 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4107 case GL_UNSIGNED_INT_10_10_10_2
:
4108 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4109 dstImage
= (GLuint
*)malloc(memreq
);
4112 return GLU_INVALID_ENUM
;
4115 if (dstImage
== NULL
) {
4116 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4117 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4118 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4119 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4120 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4121 return GLU_OUT_OF_MEMORY
;
4125 case GL_UNSIGNED_BYTE
:
4126 scale_internal_ubyte(cmpts
, width
, height
,
4127 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4128 (GLubyte
*)dstImage
, element_size
,
4129 rowsize
, group_size
);
4132 scale_internal_byte(cmpts
, width
, height
,
4133 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4134 (GLbyte
*)dstImage
, element_size
,
4135 rowsize
, group_size
);
4137 case GL_UNSIGNED_SHORT
:
4138 scale_internal_ushort(cmpts
, width
, height
,
4139 (const GLushort
*)usersImage
, newwidth
, newheight
,
4140 (GLushort
*)dstImage
, element_size
,
4141 rowsize
, group_size
, myswap_bytes
);
4144 scale_internal_short(cmpts
, width
, height
,
4145 (const GLshort
*)usersImage
, newwidth
, newheight
,
4146 (GLshort
*)dstImage
, element_size
,
4147 rowsize
, group_size
, myswap_bytes
);
4149 case GL_UNSIGNED_INT
:
4150 scale_internal_uint(cmpts
, width
, height
,
4151 (const GLuint
*)usersImage
, newwidth
, newheight
,
4152 (GLuint
*)dstImage
, element_size
,
4153 rowsize
, group_size
, myswap_bytes
);
4156 scale_internal_int(cmpts
, width
, height
,
4157 (const GLint
*)usersImage
, newwidth
, newheight
,
4158 (GLint
*)dstImage
, element_size
,
4159 rowsize
, group_size
, myswap_bytes
);
4162 scale_internal_float(cmpts
, width
, height
,
4163 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4164 (GLfloat
*)dstImage
, element_size
,
4165 rowsize
, group_size
, myswap_bytes
);
4167 case GL_UNSIGNED_BYTE_3_3_2
:
4168 scaleInternalPackedPixel(3,extract332
,shove332
,
4169 width
, height
,usersImage
,
4170 newwidth
,newheight
,(void *)dstImage
,
4171 element_size
,rowsize
,myswap_bytes
);
4173 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4174 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4175 width
, height
,usersImage
,
4176 newwidth
,newheight
,(void *)dstImage
,
4177 element_size
,rowsize
,myswap_bytes
);
4179 case GL_UNSIGNED_SHORT_5_6_5
:
4180 scaleInternalPackedPixel(3,extract565
,shove565
,
4181 width
, height
,usersImage
,
4182 newwidth
,newheight
,(void *)dstImage
,
4183 element_size
,rowsize
,myswap_bytes
);
4185 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4186 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4187 width
, height
,usersImage
,
4188 newwidth
,newheight
,(void *)dstImage
,
4189 element_size
,rowsize
,myswap_bytes
);
4191 case GL_UNSIGNED_SHORT_4_4_4_4
:
4192 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4193 width
, height
,usersImage
,
4194 newwidth
,newheight
,(void *)dstImage
,
4195 element_size
,rowsize
,myswap_bytes
);
4197 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4198 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4199 width
, height
,usersImage
,
4200 newwidth
,newheight
,(void *)dstImage
,
4201 element_size
,rowsize
,myswap_bytes
);
4203 case GL_UNSIGNED_SHORT_5_5_5_1
:
4204 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4205 width
, height
,usersImage
,
4206 newwidth
,newheight
,(void *)dstImage
,
4207 element_size
,rowsize
,myswap_bytes
);
4209 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4210 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4211 width
, height
,usersImage
,
4212 newwidth
,newheight
,(void *)dstImage
,
4213 element_size
,rowsize
,myswap_bytes
);
4215 case GL_UNSIGNED_INT_8_8_8_8
:
4216 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4217 width
, height
,usersImage
,
4218 newwidth
,newheight
,(void *)dstImage
,
4219 element_size
,rowsize
,myswap_bytes
);
4221 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4222 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4223 width
, height
,usersImage
,
4224 newwidth
,newheight
,(void *)dstImage
,
4225 element_size
,rowsize
,myswap_bytes
);
4227 case GL_UNSIGNED_INT_10_10_10_2
:
4228 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4229 width
, height
,usersImage
,
4230 newwidth
,newheight
,(void *)dstImage
,
4231 element_size
,rowsize
,myswap_bytes
);
4233 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4234 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4235 width
, height
,usersImage
,
4236 newwidth
,newheight
,(void *)dstImage
,
4237 element_size
,rowsize
,myswap_bytes
);
4244 rowsize
= newwidth
* group_size
;
4245 /* Swap dstImage and srcImage */
4246 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4248 if(levels
!= 0) { /* use as little memory as possible */
4250 int nextWidth
= newwidth
/2;
4251 int nextHeight
= newheight
/2;
4252 if (nextWidth
< 1) nextWidth
= 1;
4253 if (nextHeight
< 1) nextHeight
= 1;
4255 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4259 case GL_UNSIGNED_BYTE
:
4260 dstImage
= (GLubyte
*)malloc(memreq
);
4263 dstImage
= (GLbyte
*)malloc(memreq
);
4265 case GL_UNSIGNED_SHORT
:
4266 dstImage
= (GLushort
*)malloc(memreq
);
4269 dstImage
= (GLshort
*)malloc(memreq
);
4271 case GL_UNSIGNED_INT
:
4272 dstImage
= (GLuint
*)malloc(memreq
);
4275 dstImage
= (GLint
*)malloc(memreq
);
4278 dstImage
= (GLfloat
*)malloc(memreq
);
4280 case GL_UNSIGNED_BYTE_3_3_2
:
4281 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4282 dstImage
= (GLubyte
*)malloc(memreq
);
4284 case GL_UNSIGNED_SHORT_5_6_5
:
4285 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4286 case GL_UNSIGNED_SHORT_4_4_4_4
:
4287 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4288 case GL_UNSIGNED_SHORT_5_5_5_1
:
4289 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4290 dstImage
= (GLushort
*)malloc(memreq
);
4292 case GL_UNSIGNED_INT_8_8_8_8
:
4293 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4294 case GL_UNSIGNED_INT_10_10_10_2
:
4295 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4296 dstImage
= (GLuint
*)malloc(memreq
);
4299 return GLU_INVALID_ENUM
;
4301 if (dstImage
== NULL
) {
4302 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4303 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4304 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4305 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4306 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4307 return GLU_OUT_OF_MEMORY
;
4310 /* level userLevel is in srcImage; nothing saved yet */
4314 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4315 if (baseLevel
<= level
&& level
<= maxLevel
) {
4316 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4317 format
, type
, (void *)srcImage
);
4320 level
++; /* update current level for the loop */
4321 for (; level
<= levels
; level
++) {
4323 case GL_UNSIGNED_BYTE
:
4324 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4325 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4326 rowsize
, group_size
);
4329 halveImage_byte(cmpts
, newwidth
, newheight
,
4330 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4331 rowsize
, group_size
);
4333 case GL_UNSIGNED_SHORT
:
4334 halveImage_ushort(cmpts
, newwidth
, newheight
,
4335 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4336 rowsize
, group_size
, myswap_bytes
);
4339 halveImage_short(cmpts
, newwidth
, newheight
,
4340 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4341 rowsize
, group_size
, myswap_bytes
);
4343 case GL_UNSIGNED_INT
:
4344 halveImage_uint(cmpts
, newwidth
, newheight
,
4345 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4346 rowsize
, group_size
, myswap_bytes
);
4349 halveImage_int(cmpts
, newwidth
, newheight
,
4350 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4351 rowsize
, group_size
, myswap_bytes
);
4354 halveImage_float(cmpts
, newwidth
, newheight
,
4355 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4356 rowsize
, group_size
, myswap_bytes
);
4358 case GL_UNSIGNED_BYTE_3_3_2
:
4359 halveImagePackedPixel(3,extract332
,shove332
,
4361 srcImage
,dstImage
,element_size
,rowsize
,
4364 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4365 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4367 srcImage
,dstImage
,element_size
,rowsize
,
4370 case GL_UNSIGNED_SHORT_5_6_5
:
4371 halveImagePackedPixel(3,extract565
,shove565
,
4373 srcImage
,dstImage
,element_size
,rowsize
,
4376 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4377 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4379 srcImage
,dstImage
,element_size
,rowsize
,
4382 case GL_UNSIGNED_SHORT_4_4_4_4
:
4383 halveImagePackedPixel(4,extract4444
,shove4444
,
4385 srcImage
,dstImage
,element_size
,rowsize
,
4388 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4389 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4391 srcImage
,dstImage
,element_size
,rowsize
,
4394 case GL_UNSIGNED_SHORT_5_5_5_1
:
4395 halveImagePackedPixel(4,extract5551
,shove5551
,
4397 srcImage
,dstImage
,element_size
,rowsize
,
4400 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4401 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4403 srcImage
,dstImage
,element_size
,rowsize
,
4406 case GL_UNSIGNED_INT_8_8_8_8
:
4407 halveImagePackedPixel(4,extract8888
,shove8888
,
4409 srcImage
,dstImage
,element_size
,rowsize
,
4412 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4413 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4415 srcImage
,dstImage
,element_size
,rowsize
,
4418 case GL_UNSIGNED_INT_10_10_10_2
:
4419 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4421 srcImage
,dstImage
,element_size
,rowsize
,
4424 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4425 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4427 srcImage
,dstImage
,element_size
,rowsize
,
4435 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4437 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4438 if (newheight
> 1) newheight
/= 2;
4440 /* compute amount to pad per row, if any */
4441 int rowPad
= rowsize
% psm
.unpack_alignment
;
4443 /* should row be padded? */
4444 if (rowPad
== 0) { /* nope, row should not be padded */
4445 /* call tex image with srcImage untouched since it's not padded */
4446 if (baseLevel
<= level
&& level
<= maxLevel
) {
4447 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4448 format
, type
, (void *) srcImage
);
4451 else { /* yes, row should be padded */
4452 /* compute length of new row in bytes, including padding */
4453 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4454 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4456 /* allocate new image for mipmap of size newRowLength x newheight */
4457 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4458 if (newMipmapImage
== NULL
) {
4459 /* out of memory so return */
4460 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4461 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4462 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4463 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4464 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4465 return GLU_OUT_OF_MEMORY
;
4468 /* copy image from srcImage into newMipmapImage by rows */
4470 dstTrav
= (unsigned char *) newMipmapImage
,
4471 srcTrav
= (unsigned char *) srcImage
;
4474 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4475 srcTrav
+= rowsize
) { /* ...is skipped */
4476 memcpy(dstTrav
,srcTrav
,rowsize
);
4477 /* note that the pad bytes are not visited and will contain
4478 * garbage, which is ok.
4482 /* ...and use this new image for mipmapping instead */
4483 if (baseLevel
<= level
&& level
<= maxLevel
) {
4484 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4485 format
, type
, newMipmapImage
);
4487 free(newMipmapImage
); /* don't forget to free it! */
4491 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4492 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4493 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4494 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4495 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4497 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4498 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4502 } /* gluBuild2DMipmapLevelsCore() */
4505 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4506 GLsizei width
, GLsizei height
,
4507 GLenum format
, GLenum type
,
4508 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4513 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4514 if (rc
!= 0) return rc
;
4516 if (width
< 1 || height
< 1) {
4517 return GLU_INVALID_VALUE
;
4520 levels
= computeLog(width
);
4521 level
= computeLog(height
);
4522 if (level
> levels
) levels
=level
;
4525 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4526 return GLU_INVALID_VALUE
;
4528 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4532 userLevel
, baseLevel
, maxLevel
,
4534 } /* gluBuild2DMipmapLevels() */
4537 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4538 GLsizei width
, GLsizei height
,
4539 GLenum format
, GLenum type
,
4542 GLint widthPowerOf2
, heightPowerOf2
;
4545 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4546 if (rc
!= 0) return rc
;
4548 if (width
< 1 || height
< 1) {
4549 return GLU_INVALID_VALUE
;
4552 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4553 &widthPowerOf2
,&heightPowerOf2
);
4555 levels
= computeLog(widthPowerOf2
);
4556 level
= computeLog(heightPowerOf2
);
4557 if (level
> levels
) levels
=level
;
4559 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4561 widthPowerOf2
,heightPowerOf2
,
4564 } /* gluBuild2DMipmaps() */
4568 ** This routine is for the limited case in which
4569 ** type == GL_UNSIGNED_BYTE && format != index &&
4570 ** unpack_alignment = 1 && unpack_swap_bytes == false
4572 ** so all of the work data can be kept as ubytes instead of shorts.
4574 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4575 GLenum target
, GLint components
, GLint width
,
4576 GLint height
, GLenum format
,
4577 GLenum type
, void *data
)
4579 GLint newwidth
, newheight
;
4580 GLint level
, levels
;
4582 GLint newImage_width
;
4583 GLint newImage_height
;
4584 GLubyte
*otherImage
;
4591 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4592 newwidth
= nearestPower(width
);
4593 if (newwidth
> maxsize
) newwidth
= maxsize
;
4594 newheight
= nearestPower(height
);
4595 if (newheight
> maxsize
) newheight
= maxsize
;
4597 closestFit(target
,width
,height
,components
,format
,type
,
4598 &newwidth
,&newheight
);
4600 levels
= computeLog(newwidth
);
4601 level
= computeLog(newheight
);
4602 if (level
> levels
) levels
=level
;
4604 cmpts
= elements_per_group(format
,type
);
4608 ** No need to copy the user data if its in the packed correctly.
4609 ** Make sure that later routines don't change that data.
4611 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4612 newImage
= (GLubyte
*)data
;
4613 newImage_width
= width
;
4614 newImage_height
= height
;
4617 GLint groups_per_line
;
4618 GLint elements_per_line
;
4619 const GLubyte
*start
;
4620 const GLubyte
*iter
;
4624 newImage
= (GLubyte
*)
4625 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4626 newImage_width
= width
;
4627 newImage_height
= height
;
4628 if (newImage
== NULL
) {
4629 return GLU_OUT_OF_MEMORY
;
4633 ** Abbreviated version of fill_image for this restricted case.
4635 if (psm
->unpack_row_length
> 0) {
4636 groups_per_line
= psm
->unpack_row_length
;
4638 groups_per_line
= width
;
4640 rowsize
= groups_per_line
* cmpts
;
4641 elements_per_line
= width
* cmpts
;
4642 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4643 psm
->unpack_skip_pixels
* cmpts
;
4646 for (i
= 0; i
< height
; i
++) {
4648 for (j
= 0; j
< elements_per_line
; j
++) {
4658 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4659 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4660 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4661 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4662 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4664 for (level
= 0; level
<= levels
; level
++) {
4665 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4666 /* Use newImage for this level */
4667 glTexImage2D(target
, level
, components
, newImage_width
,
4668 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4671 if (otherImage
== NULL
) {
4673 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4674 otherImage
= (GLubyte
*) malloc(memreq
);
4675 if (otherImage
== NULL
) {
4676 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4677 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4678 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4679 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4680 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4681 return GLU_OUT_OF_MEMORY
;
4685 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4686 newImage, newwidth, newheight, otherImage);
4688 /* Swap newImage and otherImage */
4689 imageTemp
= otherImage
;
4690 otherImage
= newImage
;
4691 newImage
= imageTemp
;
4693 newImage_width
= newwidth
;
4694 newImage_height
= newheight
;
4695 glTexImage2D(target
, level
, components
, newImage_width
,
4696 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4699 if (newwidth
> 1) newwidth
/= 2;
4700 if (newheight
> 1) newheight
/= 2;
4702 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4703 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4704 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4705 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4706 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4708 if (newImage
!= (const GLubyte
*)data
) {
4709 free((GLbyte
*) newImage
);
4711 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4712 free((GLbyte
*) otherImage
);
4721 static GLint
elements_per_group(GLenum format
, GLenum type
)
4724 * Return the number of elements per group of a specified format
4727 /* If the type is packedpixels then answer is 1 (ignore format) */
4728 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4729 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4730 type
== GL_UNSIGNED_SHORT_5_6_5
||
4731 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4732 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4733 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4734 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4735 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4736 type
== GL_UNSIGNED_INT_8_8_8_8
||
4737 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4738 type
== GL_UNSIGNED_INT_10_10_10_2
||
4739 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4743 /* Types are not packed pixels, so get elements per group */
4748 case GL_LUMINANCE_ALPHA
:
4758 static GLfloat
bytes_per_element(GLenum type
)
4761 * Return the number of bytes per element, based on the element type
4766 case GL_UNSIGNED_SHORT
:
4767 return(sizeof(GLushort
));
4769 return(sizeof(GLshort
));
4770 case GL_UNSIGNED_BYTE
:
4771 return(sizeof(GLubyte
));
4773 return(sizeof(GLbyte
));
4775 return(sizeof(GLint
));
4776 case GL_UNSIGNED_INT
:
4777 return(sizeof(GLuint
));
4779 return(sizeof(GLfloat
));
4780 case GL_UNSIGNED_BYTE_3_3_2
:
4781 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4782 return(sizeof(GLubyte
));
4783 case GL_UNSIGNED_SHORT_5_6_5
:
4784 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4785 case GL_UNSIGNED_SHORT_4_4_4_4
:
4786 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4787 case GL_UNSIGNED_SHORT_5_5_5_1
:
4788 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4789 return(sizeof(GLushort
));
4790 case GL_UNSIGNED_INT_8_8_8_8
:
4791 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4792 case GL_UNSIGNED_INT_10_10_10_2
:
4793 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4794 return(sizeof(GLuint
));
4800 static GLint
is_index(GLenum format
)
4802 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4806 ** Compute memory required for internal packed array of data of given type
4809 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4816 components
= elements_per_group(format
,type
);
4817 if (type
== GL_BITMAP
) {
4818 bytes_per_row
= (width
+ 7) / 8;
4820 bytes_per_row
= bytes_per_element(type
) * width
;
4822 return bytes_per_row
* height
* components
;
4826 ** Extract array from user's data applying all pixel store modes.
4827 ** The internal format used is an array of unsigned shorts.
4829 static void fill_image(const PixelStorageModes
*psm
,
4830 GLint width
, GLint height
, GLenum format
,
4831 GLenum type
, GLboolean index_format
,
4832 const void *userdata
, GLushort
*newimage
)
4838 GLint groups_per_line
;
4840 GLint elements_per_line
;
4841 const GLubyte
*start
;
4842 const GLubyte
*iter
;
4847 myswap_bytes
= psm
->unpack_swap_bytes
;
4848 components
= elements_per_group(format
,type
);
4849 if (psm
->unpack_row_length
> 0) {
4850 groups_per_line
= psm
->unpack_row_length
;
4852 groups_per_line
= width
;
4855 /* All formats except GL_BITMAP fall out trivially */
4856 if (type
== GL_BITMAP
) {
4860 rowsize
= (groups_per_line
* components
+ 7) / 8;
4861 padding
= (rowsize
% psm
->unpack_alignment
);
4863 rowsize
+= psm
->unpack_alignment
- padding
;
4865 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4866 (psm
->unpack_skip_pixels
* components
/ 8);
4867 elements_per_line
= width
* components
;
4869 for (i
= 0; i
< height
; i
++) {
4871 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4872 for (j
= 0; j
< elements_per_line
; j
++) {
4874 if (psm
->unpack_lsb_first
) {
4875 current_bit
= iter
[0] & (1 << bit_offset
);
4877 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4889 if (bit_offset
== 8) {
4898 element_size
= bytes_per_element(type
);
4899 group_size
= element_size
* components
;
4900 if (element_size
== 1) myswap_bytes
= 0;
4902 rowsize
= groups_per_line
* group_size
;
4903 padding
= (rowsize
% psm
->unpack_alignment
);
4905 rowsize
+= psm
->unpack_alignment
- padding
;
4907 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4908 psm
->unpack_skip_pixels
* group_size
;
4909 elements_per_line
= width
* components
;
4912 for (i
= 0; i
< height
; i
++) {
4914 for (j
= 0; j
< elements_per_line
; j
++) {
4916 float extractComponents
[4];
4919 case GL_UNSIGNED_BYTE_3_3_2
:
4920 extract332(0,iter
,extractComponents
);
4921 for (k
= 0; k
< 3; k
++) {
4922 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4925 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4926 extract233rev(0,iter
,extractComponents
);
4927 for (k
= 0; k
< 3; k
++) {
4928 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4931 case GL_UNSIGNED_BYTE
:
4935 *iter2
++ = (*iter
) * 257;
4940 *iter2
++ = *((const GLbyte
*) iter
);
4943 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4946 case GL_UNSIGNED_SHORT_5_6_5
:
4947 extract565(myswap_bytes
,iter
,extractComponents
);
4948 for (k
= 0; k
< 3; k
++) {
4949 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4952 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4953 extract565rev(myswap_bytes
,iter
,extractComponents
);
4954 for (k
= 0; k
< 3; k
++) {
4955 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4958 case GL_UNSIGNED_SHORT_4_4_4_4
:
4959 extract4444(myswap_bytes
,iter
,extractComponents
);
4960 for (k
= 0; k
< 4; k
++) {
4961 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4964 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4965 extract4444rev(myswap_bytes
,iter
,extractComponents
);
4966 for (k
= 0; k
< 4; k
++) {
4967 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4970 case GL_UNSIGNED_SHORT_5_5_5_1
:
4971 extract5551(myswap_bytes
,iter
,extractComponents
);
4972 for (k
= 0; k
< 4; k
++) {
4973 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4976 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4977 extract1555rev(myswap_bytes
,iter
,extractComponents
);
4978 for (k
= 0; k
< 4; k
++) {
4979 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4982 case GL_UNSIGNED_SHORT
:
4985 widget
.ub
[0] = iter
[1];
4986 widget
.ub
[1] = iter
[0];
4988 widget
.ub
[0] = iter
[0];
4989 widget
.ub
[1] = iter
[1];
4991 if (type
== GL_SHORT
) {
4993 *iter2
++ = widget
.s
[0];
4996 *iter2
++ = widget
.s
[0]*2;
4999 *iter2
++ = widget
.us
[0];
5002 case GL_UNSIGNED_INT_8_8_8_8
:
5003 extract8888(myswap_bytes
,iter
,extractComponents
);
5004 for (k
= 0; k
< 4; k
++) {
5005 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5008 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5009 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5010 for (k
= 0; k
< 4; k
++) {
5011 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5014 case GL_UNSIGNED_INT_10_10_10_2
:
5015 extract1010102(myswap_bytes
,iter
,extractComponents
);
5016 for (k
= 0; k
< 4; k
++) {
5017 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5020 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5021 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5022 for (k
= 0; k
< 4; k
++) {
5023 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5027 case GL_UNSIGNED_INT
:
5030 widget
.ub
[0] = iter
[3];
5031 widget
.ub
[1] = iter
[2];
5032 widget
.ub
[2] = iter
[1];
5033 widget
.ub
[3] = iter
[0];
5035 widget
.ub
[0] = iter
[0];
5036 widget
.ub
[1] = iter
[1];
5037 widget
.ub
[2] = iter
[2];
5038 widget
.ub
[3] = iter
[3];
5040 if (type
== GL_FLOAT
) {
5042 *iter2
++ = widget
.f
;
5044 *iter2
++ = 65535 * widget
.f
;
5046 } else if (type
== GL_UNSIGNED_INT
) {
5048 *iter2
++ = widget
.ui
;
5050 *iter2
++ = widget
.ui
>> 16;
5054 *iter2
++ = widget
.i
;
5056 *iter2
++ = widget
.i
>> 15;
5061 iter
+= element_size
;
5065 /* want 'iter' pointing at start, not within, row for assertion
5072 /* iterators should be one byte past end */
5073 if (!isTypePackedPixel(type
)) {
5074 assert(iter2
== &newimage
[width
*height
*components
]);
5077 assert(iter2
== &newimage
[width
*height
*
5078 elements_per_group(format
,0)]);
5080 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5081 psm
->unpack_skip_rows
* rowsize
+
5082 psm
->unpack_skip_pixels
* group_size
] );
5085 } /* fill_image() */
5088 ** Insert array into user's data applying all pixel store modes.
5089 ** The internal format is an array of unsigned shorts.
5090 ** empty_image() because it is the opposite of fill_image().
5092 static void empty_image(const PixelStorageModes
*psm
,
5093 GLint width
, GLint height
, GLenum format
,
5094 GLenum type
, GLboolean index_format
,
5095 const GLushort
*oldimage
, void *userdata
)
5101 GLint groups_per_line
;
5103 GLint elements_per_line
;
5106 const GLushort
*iter2
;
5110 myswap_bytes
= psm
->pack_swap_bytes
;
5111 components
= elements_per_group(format
,type
);
5112 if (psm
->pack_row_length
> 0) {
5113 groups_per_line
= psm
->pack_row_length
;
5115 groups_per_line
= width
;
5118 /* All formats except GL_BITMAP fall out trivially */
5119 if (type
== GL_BITMAP
) {
5123 rowsize
= (groups_per_line
* components
+ 7) / 8;
5124 padding
= (rowsize
% psm
->pack_alignment
);
5126 rowsize
+= psm
->pack_alignment
- padding
;
5128 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5129 (psm
->pack_skip_pixels
* components
/ 8);
5130 elements_per_line
= width
* components
;
5132 for (i
= 0; i
< height
; i
++) {
5134 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5135 for (j
= 0; j
< elements_per_line
; j
++) {
5137 current_bit
= iter2
[0] & 1;
5139 if (iter2
[0] > 32767) {
5147 if (psm
->pack_lsb_first
) {
5148 *iter
|= (1 << bit_offset
);
5150 *iter
|= (1 << (7 - bit_offset
));
5153 if (psm
->pack_lsb_first
) {
5154 *iter
&= ~(1 << bit_offset
);
5156 *iter
&= ~(1 << (7 - bit_offset
));
5161 if (bit_offset
== 8) {
5170 float shoveComponents
[4];
5172 element_size
= bytes_per_element(type
);
5173 group_size
= element_size
* components
;
5174 if (element_size
== 1) myswap_bytes
= 0;
5176 rowsize
= groups_per_line
* group_size
;
5177 padding
= (rowsize
% psm
->pack_alignment
);
5179 rowsize
+= psm
->pack_alignment
- padding
;
5181 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5182 psm
->pack_skip_pixels
* group_size
;
5183 elements_per_line
= width
* components
;
5186 for (i
= 0; i
< height
; i
++) {
5188 for (j
= 0; j
< elements_per_line
; j
++) {
5192 case GL_UNSIGNED_BYTE_3_3_2
:
5193 for (k
= 0; k
< 3; k
++) {
5194 shoveComponents
[k
]= *iter2
++ / 65535.0;
5196 shove332(shoveComponents
,0,(void *)iter
);
5198 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5199 for (k
= 0; k
< 3; k
++) {
5200 shoveComponents
[k
]= *iter2
++ / 65535.0;
5202 shove233rev(shoveComponents
,0,(void *)iter
);
5204 case GL_UNSIGNED_BYTE
:
5208 *iter
= *iter2
++ >> 8;
5213 *((GLbyte
*) iter
) = *iter2
++;
5215 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5218 case GL_UNSIGNED_SHORT_5_6_5
:
5219 for (k
= 0; k
< 3; k
++) {
5220 shoveComponents
[k
]= *iter2
++ / 65535.0;
5222 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5224 iter
[0] = widget
.ub
[1];
5225 iter
[1] = widget
.ub
[0];
5228 *(GLushort
*)iter
= widget
.us
[0];
5231 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5232 for (k
= 0; k
< 3; k
++) {
5233 shoveComponents
[k
]= *iter2
++ / 65535.0;
5235 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5237 iter
[0] = widget
.ub
[1];
5238 iter
[1] = widget
.ub
[0];
5241 *(GLushort
*)iter
= widget
.us
[0];
5244 case GL_UNSIGNED_SHORT_4_4_4_4
:
5245 for (k
= 0; k
< 4; k
++) {
5246 shoveComponents
[k
]= *iter2
++ / 65535.0;
5248 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5250 iter
[0] = widget
.ub
[1];
5251 iter
[1] = widget
.ub
[0];
5253 *(GLushort
*)iter
= widget
.us
[0];
5256 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5257 for (k
= 0; k
< 4; k
++) {
5258 shoveComponents
[k
]= *iter2
++ / 65535.0;
5260 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5262 iter
[0] = widget
.ub
[1];
5263 iter
[1] = widget
.ub
[0];
5265 *(GLushort
*)iter
= widget
.us
[0];
5268 case GL_UNSIGNED_SHORT_5_5_5_1
:
5269 for (k
= 0; k
< 4; k
++) {
5270 shoveComponents
[k
]= *iter2
++ / 65535.0;
5272 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5274 iter
[0] = widget
.ub
[1];
5275 iter
[1] = widget
.ub
[0];
5277 *(GLushort
*)iter
= widget
.us
[0];
5280 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5281 for (k
= 0; k
< 4; k
++) {
5282 shoveComponents
[k
]= *iter2
++ / 65535.0;
5284 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5286 iter
[0] = widget
.ub
[1];
5287 iter
[1] = widget
.ub
[0];
5289 *(GLushort
*)iter
= widget
.us
[0];
5292 case GL_UNSIGNED_SHORT
:
5294 if (type
== GL_SHORT
) {
5296 widget
.s
[0] = *iter2
++;
5298 widget
.s
[0] = *iter2
++ >> 1;
5301 widget
.us
[0] = *iter2
++;
5304 iter
[0] = widget
.ub
[1];
5305 iter
[1] = widget
.ub
[0];
5307 iter
[0] = widget
.ub
[0];
5308 iter
[1] = widget
.ub
[1];
5311 case GL_UNSIGNED_INT_8_8_8_8
:
5312 for (k
= 0; k
< 4; k
++) {
5313 shoveComponents
[k
]= *iter2
++ / 65535.0;
5315 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5317 iter
[3] = widget
.ub
[0];
5318 iter
[2] = widget
.ub
[1];
5319 iter
[1] = widget
.ub
[2];
5320 iter
[0] = widget
.ub
[3];
5322 *(GLuint
*)iter
= widget
.ui
;
5326 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5327 for (k
= 0; k
< 4; k
++) {
5328 shoveComponents
[k
]= *iter2
++ / 65535.0;
5330 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5332 iter
[3] = widget
.ub
[0];
5333 iter
[2] = widget
.ub
[1];
5334 iter
[1] = widget
.ub
[2];
5335 iter
[0] = widget
.ub
[3];
5337 *(GLuint
*)iter
= widget
.ui
;
5340 case GL_UNSIGNED_INT_10_10_10_2
:
5341 for (k
= 0; k
< 4; k
++) {
5342 shoveComponents
[k
]= *iter2
++ / 65535.0;
5344 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5346 iter
[3] = widget
.ub
[0];
5347 iter
[2] = widget
.ub
[1];
5348 iter
[1] = widget
.ub
[2];
5349 iter
[0] = widget
.ub
[3];
5351 *(GLuint
*)iter
= widget
.ui
;
5354 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5355 for (k
= 0; k
< 4; k
++) {
5356 shoveComponents
[k
]= *iter2
++ / 65535.0;
5358 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
5360 iter
[3] = widget
.ub
[0];
5361 iter
[2] = widget
.ub
[1];
5362 iter
[1] = widget
.ub
[2];
5363 iter
[0] = widget
.ub
[3];
5365 *(GLuint
*)iter
= widget
.ui
;
5369 case GL_UNSIGNED_INT
:
5371 if (type
== GL_FLOAT
) {
5373 widget
.f
= *iter2
++;
5375 widget
.f
= *iter2
++ / (float) 65535.0;
5377 } else if (type
== GL_UNSIGNED_INT
) {
5379 widget
.ui
= *iter2
++;
5381 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5385 widget
.i
= *iter2
++;
5387 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5391 iter
[3] = widget
.ub
[0];
5392 iter
[2] = widget
.ub
[1];
5393 iter
[1] = widget
.ub
[2];
5394 iter
[0] = widget
.ub
[3];
5396 iter
[0] = widget
.ub
[0];
5397 iter
[1] = widget
.ub
[1];
5398 iter
[2] = widget
.ub
[2];
5399 iter
[3] = widget
.ub
[3];
5403 iter
+= element_size
;
5407 /* want 'iter' pointing at start, not within, row for assertion
5414 /* iterators should be one byte past end */
5415 if (!isTypePackedPixel(type
)) {
5416 assert(iter2
== &oldimage
[width
*height
*components
]);
5419 assert(iter2
== &oldimage
[width
*height
*
5420 elements_per_group(format
,0)]);
5422 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5423 psm
->pack_skip_rows
* rowsize
+
5424 psm
->pack_skip_pixels
* group_size
] );
5427 } /* empty_image() */
5429 /*--------------------------------------------------------------------------
5430 * Decimation of packed pixel types
5431 *--------------------------------------------------------------------------
5433 static void extract332(int isSwap
,
5434 const void *packedPixel
, GLfloat extractComponents
[])
5436 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5438 isSwap
= isSwap
; /* turn off warnings */
5440 /* 11100000 == 0xe0 */
5441 /* 00011100 == 0x1c */
5442 /* 00000011 == 0x03 */
5444 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5445 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5446 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5447 } /* extract332() */
5449 static void shove332(const GLfloat shoveComponents
[],
5450 int index
, void *packedPixel
)
5452 /* 11100000 == 0xe0 */
5453 /* 00011100 == 0x1c */
5454 /* 00000011 == 0x03 */
5456 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5457 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5458 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5460 /* due to limited precision, need to round before shoving */
5461 ((GLubyte
*)packedPixel
)[index
] =
5462 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5463 ((GLubyte
*)packedPixel
)[index
] |=
5464 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5465 ((GLubyte
*)packedPixel
)[index
] |=
5466 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5469 static void extract233rev(int isSwap
,
5470 const void *packedPixel
, GLfloat extractComponents
[])
5472 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5474 isSwap
= isSwap
; /* turn off warnings */
5476 /* 0000,0111 == 0x07 */
5477 /* 0011,1000 == 0x38 */
5478 /* 1100,0000 == 0xC0 */
5480 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5481 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5482 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5483 } /* extract233rev() */
5485 static void shove233rev(const GLfloat shoveComponents
[],
5486 int index
, void *packedPixel
)
5488 /* 0000,0111 == 0x07 */
5489 /* 0011,1000 == 0x38 */
5490 /* 1100,0000 == 0xC0 */
5492 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5493 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5494 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5496 /* due to limited precision, need to round before shoving */
5497 ((GLubyte
*)packedPixel
)[index
] =
5498 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5499 ((GLubyte
*)packedPixel
)[index
]|=
5500 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5501 ((GLubyte
*)packedPixel
)[index
]|=
5502 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5503 } /* shove233rev() */
5505 static void extract565(int isSwap
,
5506 const void *packedPixel
, GLfloat extractComponents
[])
5508 GLushort ushort
= *(const GLushort
*)packedPixel
;
5511 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5514 ushort
= *(const GLushort
*)packedPixel
;
5517 /* 11111000,00000000 == 0xf800 */
5518 /* 00000111,11100000 == 0x07e0 */
5519 /* 00000000,00011111 == 0x001f */
5521 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5522 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5523 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5524 } /* extract565() */
5526 static void shove565(const GLfloat shoveComponents
[],
5527 int index
,void *packedPixel
)
5529 /* 11111000,00000000 == 0xf800 */
5530 /* 00000111,11100000 == 0x07e0 */
5531 /* 00000000,00011111 == 0x001f */
5533 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5534 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5535 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5537 /* due to limited precision, need to round before shoving */
5538 ((GLushort
*)packedPixel
)[index
] =
5539 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5540 ((GLushort
*)packedPixel
)[index
]|=
5541 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5542 ((GLushort
*)packedPixel
)[index
]|=
5543 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5546 static void extract565rev(int isSwap
,
5547 const void *packedPixel
, GLfloat extractComponents
[])
5549 GLushort ushort
= *(const GLushort
*)packedPixel
;
5552 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5555 ushort
= *(const GLushort
*)packedPixel
;
5558 /* 00000000,00011111 == 0x001f */
5559 /* 00000111,11100000 == 0x07e0 */
5560 /* 11111000,00000000 == 0xf800 */
5562 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5563 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5564 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5565 } /* extract565rev() */
5567 static void shove565rev(const GLfloat shoveComponents
[],
5568 int index
,void *packedPixel
)
5570 /* 00000000,00011111 == 0x001f */
5571 /* 00000111,11100000 == 0x07e0 */
5572 /* 11111000,00000000 == 0xf800 */
5574 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5575 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5576 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5578 /* due to limited precision, need to round before shoving */
5579 ((GLushort
*)packedPixel
)[index
] =
5580 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5581 ((GLushort
*)packedPixel
)[index
]|=
5582 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5583 ((GLushort
*)packedPixel
)[index
]|=
5584 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5585 } /* shove565rev() */
5587 static void extract4444(int isSwap
,const void *packedPixel
,
5588 GLfloat extractComponents
[])
5593 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5596 ushort
= *(const GLushort
*)packedPixel
;
5599 /* 11110000,00000000 == 0xf000 */
5600 /* 00001111,00000000 == 0x0f00 */
5601 /* 00000000,11110000 == 0x00f0 */
5602 /* 00000000,00001111 == 0x000f */
5604 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5605 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5606 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5607 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5608 } /* extract4444() */
5610 static void shove4444(const GLfloat shoveComponents
[],
5611 int index
,void *packedPixel
)
5613 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5614 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5615 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5616 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5618 /* due to limited precision, need to round before shoving */
5619 ((GLushort
*)packedPixel
)[index
] =
5620 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5621 ((GLushort
*)packedPixel
)[index
]|=
5622 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5623 ((GLushort
*)packedPixel
)[index
]|=
5624 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5625 ((GLushort
*)packedPixel
)[index
]|=
5626 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5629 static void extract4444rev(int isSwap
,const void *packedPixel
,
5630 GLfloat extractComponents
[])
5635 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5638 ushort
= *(const GLushort
*)packedPixel
;
5641 /* 00000000,00001111 == 0x000f */
5642 /* 00000000,11110000 == 0x00f0 */
5643 /* 00001111,00000000 == 0x0f00 */
5644 /* 11110000,00000000 == 0xf000 */
5647 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5648 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5649 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5650 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5651 } /* extract4444rev() */
5653 static void shove4444rev(const GLfloat shoveComponents
[],
5654 int index
,void *packedPixel
)
5656 /* 00000000,00001111 == 0x000f */
5657 /* 00000000,11110000 == 0x00f0 */
5658 /* 00001111,00000000 == 0x0f00 */
5659 /* 11110000,00000000 == 0xf000 */
5661 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5662 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5663 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5664 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5666 /* due to limited precision, need to round before shoving */
5667 ((GLushort
*)packedPixel
)[index
] =
5668 ((GLushort
)((shoveComponents
[0] * 15)+0.5) ) & 0x000F;
5669 ((GLushort
*)packedPixel
)[index
]|=
5670 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5671 ((GLushort
*)packedPixel
)[index
]|=
5672 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5673 ((GLushort
*)packedPixel
)[index
]|=
5674 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5675 } /* shove4444rev() */
5677 static void extract5551(int isSwap
,const void *packedPixel
,
5678 GLfloat extractComponents
[])
5683 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5686 ushort
= *(const GLushort
*)packedPixel
;
5689 /* 11111000,00000000 == 0xf800 */
5690 /* 00000111,11000000 == 0x07c0 */
5691 /* 00000000,00111110 == 0x003e */
5692 /* 00000000,00000001 == 0x0001 */
5694 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5695 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5696 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5697 extractComponents
[3]=(float)((ushort
& 0x0001) );
5698 } /* extract5551() */
5700 static void shove5551(const GLfloat shoveComponents
[],
5701 int index
,void *packedPixel
)
5703 /* 11111000,00000000 == 0xf800 */
5704 /* 00000111,11000000 == 0x07c0 */
5705 /* 00000000,00111110 == 0x003e */
5706 /* 00000000,00000001 == 0x0001 */
5708 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5709 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5710 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5711 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5713 /* due to limited precision, need to round before shoving */
5714 ((GLushort
*)packedPixel
)[index
] =
5715 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5716 ((GLushort
*)packedPixel
)[index
]|=
5717 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5718 ((GLushort
*)packedPixel
)[index
]|=
5719 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5720 ((GLushort
*)packedPixel
)[index
]|=
5721 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5724 static void extract1555rev(int isSwap
,const void *packedPixel
,
5725 GLfloat extractComponents
[])
5730 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5733 ushort
= *(const GLushort
*)packedPixel
;
5736 /* 00000000,00011111 == 0x001F */
5737 /* 00000011,11100000 == 0x03E0 */
5738 /* 01111100,00000000 == 0x7C00 */
5739 /* 10000000,00000000 == 0x8000 */
5742 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5743 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5744 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5745 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5746 } /* extract1555rev() */
5748 static void shove1555rev(const GLfloat shoveComponents
[],
5749 int index
,void *packedPixel
)
5751 /* 00000000,00011111 == 0x001F */
5752 /* 00000011,11100000 == 0x03E0 */
5753 /* 01111100,00000000 == 0x7C00 */
5754 /* 10000000,00000000 == 0x8000 */
5756 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5757 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5758 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5759 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5761 /* due to limited precision, need to round before shoving */
5762 ((GLushort
*)packedPixel
)[index
] =
5763 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5764 ((GLushort
*)packedPixel
)[index
]|=
5765 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5766 ((GLushort
*)packedPixel
)[index
]|=
5767 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5768 ((GLushort
*)packedPixel
)[index
]|=
5769 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5770 } /* shove1555rev() */
5772 static void extract8888(int isSwap
,
5773 const void *packedPixel
, GLfloat extractComponents
[])
5778 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5781 uint
= *(const GLuint
*)packedPixel
;
5784 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5785 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5786 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5787 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5790 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5791 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5792 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5793 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5794 } /* extract8888() */
5796 static void shove8888(const GLfloat shoveComponents
[],
5797 int index
,void *packedPixel
)
5799 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5800 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5801 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5802 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5804 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5805 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5806 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5807 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5809 /* due to limited precision, need to round before shoving */
5810 ((GLuint
*)packedPixel
)[index
] =
5811 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5812 ((GLuint
*)packedPixel
)[index
]|=
5813 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5814 ((GLuint
*)packedPixel
)[index
]|=
5815 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5816 ((GLuint
*)packedPixel
)[index
]|=
5817 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5820 static void extract8888rev(int isSwap
,
5821 const void *packedPixel
,GLfloat extractComponents
[])
5826 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5829 uint
= *(const GLuint
*)packedPixel
;
5832 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5833 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5834 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5835 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5838 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5839 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5840 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5841 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5842 } /* extract8888rev() */
5844 static void shove8888rev(const GLfloat shoveComponents
[],
5845 int index
,void *packedPixel
)
5847 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5848 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5849 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5850 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5852 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5853 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5854 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5855 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5857 /* due to limited precision, need to round before shoving */
5858 ((GLuint
*)packedPixel
)[index
] =
5859 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5860 ((GLuint
*)packedPixel
)[index
]|=
5861 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5862 ((GLuint
*)packedPixel
)[index
]|=
5863 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5864 ((GLuint
*)packedPixel
)[index
]|=
5865 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5866 } /* shove8888rev() */
5868 static void extract1010102(int isSwap
,
5869 const void *packedPixel
,GLfloat extractComponents
[])
5874 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5877 uint
= *(const GLuint
*)packedPixel
;
5880 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5881 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5882 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5883 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5886 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5887 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5888 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5889 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5890 } /* extract1010102() */
5892 static void shove1010102(const GLfloat shoveComponents
[],
5893 int index
,void *packedPixel
)
5895 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5896 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5897 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5898 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5900 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5901 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5902 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5903 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5905 /* due to limited precision, need to round before shoving */
5906 ((GLuint
*)packedPixel
)[index
] =
5907 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5908 ((GLuint
*)packedPixel
)[index
]|=
5909 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5910 ((GLuint
*)packedPixel
)[index
]|=
5911 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5912 ((GLuint
*)packedPixel
)[index
]|=
5913 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5914 } /* shove1010102() */
5916 static void extract2101010rev(int isSwap
,
5917 const void *packedPixel
,
5918 GLfloat extractComponents
[])
5923 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5926 uint
= *(const GLuint
*)packedPixel
;
5929 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5930 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5931 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5932 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5935 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5936 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5937 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5938 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5940 } /* extract2101010rev() */
5942 static void shove2101010rev(const GLfloat shoveComponents
[],
5943 int index
,void *packedPixel
)
5945 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5946 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5947 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5948 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5950 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5951 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5952 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5953 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5955 /* due to limited precision, need to round before shoving */
5956 ((GLuint
*)packedPixel
)[index
] =
5957 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
5958 ((GLuint
*)packedPixel
)[index
]|=
5959 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
5960 ((GLuint
*)packedPixel
)[index
]|=
5961 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
5962 ((GLuint
*)packedPixel
)[index
]|=
5963 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
5964 } /* shove2101010rev() */
5966 static void scaleInternalPackedPixel(int components
,
5967 void (*extractPackedPixel
)
5968 (int, const void *,GLfloat
[]),
5969 void (*shovePackedPixel
)
5970 (const GLfloat
[], int, void *),
5971 GLint widthIn
,GLint heightIn
,
5973 GLint widthOut
,GLint heightOut
,
5975 GLint pixelSizeInBytes
,
5976 GLint rowSizeInBytes
,GLint isSwap
)
5982 /* Max components in a format is 4, so... */
5984 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
5989 const char *temp
, *temp0
;
5992 int lowx_int
, highx_int
, lowy_int
, highy_int
;
5993 float x_percent
, y_percent
;
5994 float lowx_float
, highx_float
, lowy_float
, highy_float
;
5995 float convy_float
, convx_float
;
5996 int convy_int
, convx_int
;
5998 const char *left
, *right
;
6000 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
6001 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6002 widthIn
, heightIn
, dataIn
, dataOut
,
6003 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6006 convy
= (float) heightIn
/heightOut
;
6007 convx
= (float) widthIn
/widthOut
;
6008 convy_int
= floor(convy
);
6009 convy_float
= convy
- convy_int
;
6010 convx_int
= floor(convx
);
6011 convx_float
= convx
- convx_int
;
6013 area
= convx
* convy
;
6017 highy_int
= convy_int
;
6018 highy_float
= convy_float
;
6020 for (i
= 0; i
< heightOut
; i
++) {
6023 highx_int
= convx_int
;
6024 highx_float
= convx_float
;
6026 for (j
= 0; j
< widthOut
; j
++) {
6028 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6029 ** to (highx, highy) on input data into this pixel on output
6032 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6034 /* calculate the value for pixels in the 1st row */
6035 xindex
= lowx_int
*pixelSizeInBytes
;
6036 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6038 y_percent
= 1-lowy_float
;
6039 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6040 percent
= y_percent
* (1-lowx_float
);
6042 for (k
= 0, temp_index
= temp
; k
< components
;
6043 k
++, temp_index
+= element_size
) {
6045 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6047 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6051 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6052 for (k
= 0; k
< components
; k
++) {
6053 totals
[k
]+= extractTotals
[k
] * percent
;
6057 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6058 temp
+= pixelSizeInBytes
;
6060 for (k
= 0, temp_index
= temp
; k
< components
;
6061 k
++, temp_index
+= element_size
) {
6064 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6066 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6070 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6071 for (k
= 0; k
< components
; k
++) {
6072 totals
[k
]+= extractTotals
[k
] * y_percent
;
6076 temp
+= pixelSizeInBytes
;
6078 percent
= y_percent
* highx_float
;
6080 for (k
= 0, temp_index
= temp
; k
< components
;
6081 k
++, temp_index
+= element_size
) {
6083 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6085 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6089 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6090 for (k
= 0; k
< components
; k
++) {
6091 totals
[k
]+= extractTotals
[k
] * percent
;
6095 /* calculate the value for pixels in the last row */
6097 y_percent
= highy_float
;
6098 percent
= y_percent
* (1-lowx_float
);
6099 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6101 for (k
= 0, temp_index
= temp
; k
< components
;
6102 k
++, temp_index
+= element_size
) {
6104 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6106 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6110 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6111 for (k
= 0; k
< components
; k
++) {
6112 totals
[k
]+= extractTotals
[k
] * percent
;
6115 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6116 temp
+= pixelSizeInBytes
;
6118 for (k
= 0, temp_index
= temp
; k
< components
;
6119 k
++, temp_index
+= element_size
) {
6122 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6124 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6128 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6129 for (k
= 0; k
< components
; k
++) {
6130 totals
[k
]+= extractTotals
[k
] * y_percent
;
6135 temp
+= pixelSizeInBytes
;
6136 percent
= y_percent
* highx_float
;
6138 for (k
= 0, temp_index
= temp
; k
< components
;
6139 k
++, temp_index
+= element_size
) {
6141 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6143 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6147 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6148 for (k
= 0; k
< components
; k
++) {
6149 totals
[k
]+= extractTotals
[k
] * percent
;
6153 /* calculate the value for pixels in the 1st and last column */
6154 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6155 left
+= rowSizeInBytes
;
6156 right
+= rowSizeInBytes
;
6158 for (k
= 0; k
< components
;
6159 k
++, left
+= element_size
, right
+= element_size
) {
6162 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6163 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6165 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6166 + *(const GLushort
*)right
* highx_float
;
6170 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6171 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6172 for (k
= 0; k
< components
; k
++) {
6173 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6174 extractMoreTotals
[k
]*highx_float
);
6178 } else if (highy_int
> lowy_int
) {
6179 x_percent
= highx_float
- lowx_float
;
6180 percent
= (1-lowy_float
)*x_percent
;
6181 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6183 for (k
= 0, temp_index
= temp
; k
< components
;
6184 k
++, temp_index
+= element_size
) {
6186 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6188 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6192 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6193 for (k
= 0; k
< components
; k
++) {
6194 totals
[k
]+= extractTotals
[k
] * percent
;
6197 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6198 temp
+= rowSizeInBytes
;
6200 for (k
= 0, temp_index
= temp
; k
< components
;
6201 k
++, temp_index
+= element_size
) {
6204 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6206 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6210 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6211 for (k
= 0; k
< components
; k
++) {
6212 totals
[k
]+= extractTotals
[k
] * x_percent
;
6216 percent
= x_percent
* highy_float
;
6217 temp
+= rowSizeInBytes
;
6219 for (k
= 0, temp_index
= temp
; k
< components
;
6220 k
++, temp_index
+= element_size
) {
6222 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6224 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6228 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6229 for (k
= 0; k
< components
; k
++) {
6230 totals
[k
]+= extractTotals
[k
] * percent
;
6233 } else if (highx_int
> lowx_int
) {
6234 y_percent
= highy_float
- lowy_float
;
6235 percent
= (1-lowx_float
)*y_percent
;
6236 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6238 for (k
= 0, temp_index
= temp
; k
< components
;
6239 k
++, temp_index
+= element_size
) {
6241 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6243 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6247 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6248 for (k
= 0; k
< components
; k
++) {
6249 totals
[k
]+= extractTotals
[k
] * percent
;
6252 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6253 temp
+= pixelSizeInBytes
;
6255 for (k
= 0, temp_index
= temp
; k
< components
;
6256 k
++, temp_index
+= element_size
) {
6259 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6261 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6265 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6266 for (k
= 0; k
< components
; k
++) {
6267 totals
[k
]+= extractTotals
[k
] * y_percent
;
6271 temp
+= pixelSizeInBytes
;
6272 percent
= y_percent
* highx_float
;
6274 for (k
= 0, temp_index
= temp
; k
< components
;
6275 k
++, temp_index
+= element_size
) {
6277 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6279 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6283 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6284 for (k
= 0; k
< components
; k
++) {
6285 totals
[k
]+= extractTotals
[k
] * percent
;
6289 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6290 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6292 for (k
= 0, temp_index
= temp
; k
< components
;
6293 k
++, temp_index
+= element_size
) {
6295 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6297 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6301 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6302 for (k
= 0; k
< components
; k
++) {
6303 totals
[k
]+= extractTotals
[k
] * percent
;
6308 /* this is for the pixels in the body */
6309 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6310 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6312 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6314 for (k
= 0, temp_index
= temp
; k
< components
;
6315 k
++, temp_index
+= element_size
) {
6317 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6319 totals
[k
] += *(const GLushort
*)temp_index
;
6323 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6324 for (k
= 0; k
< components
; k
++) {
6325 totals
[k
]+= extractTotals
[k
];
6328 temp
+= pixelSizeInBytes
;
6330 temp0
+= rowSizeInBytes
;
6333 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6335 for (k
= 0; k
< components
; k
++) {
6336 dataout
[outindex
+ k
] = totals
[k
]/area
;
6337 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6340 for (k
= 0; k
< components
; k
++) {
6341 shoveTotals
[k
]= totals
[k
]/area
;
6343 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6345 lowx_int
= highx_int
;
6346 lowx_float
= highx_float
;
6347 highx_int
+= convx_int
;
6348 highx_float
+= convx_float
;
6349 if(highx_float
> 1) {
6354 lowy_int
= highy_int
;
6355 lowy_float
= highy_float
;
6356 highy_int
+= convy_int
;
6357 highy_float
+= convy_float
;
6358 if(highy_float
> 1) {
6364 assert(outindex
== (widthOut
*heightOut
- 1));
6365 } /* scaleInternalPackedPixel() */
6367 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6368 * inputs; not always equal. Output NEVER has row padding.
6370 static void halveImagePackedPixel(int components
,
6371 void (*extractPackedPixel
)
6372 (int, const void *,GLfloat
[]),
6373 void (*shovePackedPixel
)
6374 (const GLfloat
[],int, void *),
6375 GLint width
, GLint height
,
6376 const void *dataIn
, void *dataOut
,
6377 GLint pixelSizeInBytes
,
6378 GLint rowSizeInBytes
, GLint isSwap
)
6380 /* handle case where there is only 1 column/row */
6381 if (width
== 1 || height
== 1) {
6382 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6383 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6384 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6385 rowSizeInBytes
,isSwap
);
6392 int halfWidth
= width
/ 2;
6393 int halfHeight
= height
/ 2;
6394 const char *src
= (const char *) dataIn
;
6395 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6398 for (ii
= 0; ii
< halfHeight
; ii
++) {
6399 for (jj
= 0; jj
< halfWidth
; jj
++) {
6401 float totals
[4]; /* 4 is maximum components */
6402 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6405 (*extractPackedPixel
)(isSwap
,src
,
6406 &extractTotals
[0][0]);
6407 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6408 &extractTotals
[1][0]);
6409 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6410 &extractTotals
[2][0]);
6411 (*extractPackedPixel
)(isSwap
,
6412 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6413 &extractTotals
[3][0]);
6414 for (cc
= 0; cc
< components
; cc
++) {
6417 /* grab 4 pixels to average */
6419 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6420 * extractTotals[2][RED]+extractTotals[3][RED];
6421 * totals[RED]/= 4.0;
6423 for (kk
= 0; kk
< BOX4
; kk
++) {
6424 totals
[cc
]+= extractTotals
[kk
][cc
];
6426 totals
[cc
]/= (float)BOX4
;
6428 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6431 /* skip over to next square of 4 */
6432 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6434 /* skip past pad bytes, if any, to get to next row */
6437 /* src is at beginning of a row here, but it's the second row of
6438 * the square block of 4 pixels that we just worked on so we
6439 * need to go one more row.
6447 src
+= rowSizeInBytes
;
6450 /* both pointers must reach one byte after the end */
6451 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6452 assert(outIndex
== halfWidth
* halfHeight
);
6454 } /* halveImagePackedPixel() */
6456 static void halve1DimagePackedPixel(int components
,
6457 void (*extractPackedPixel
)
6458 (int, const void *,GLfloat
[]),
6459 void (*shovePackedPixel
)
6460 (const GLfloat
[],int, void *),
6461 GLint width
, GLint height
,
6462 const void *dataIn
, void *dataOut
,
6463 GLint pixelSizeInBytes
,
6464 GLint rowSizeInBytes
, GLint isSwap
)
6466 int halfWidth
= width
/ 2;
6467 int halfHeight
= height
/ 2;
6468 const char *src
= (const char *) dataIn
;
6471 assert(width
== 1 || height
== 1); /* must be 1D */
6472 assert(width
!= height
); /* can't be square */
6474 if (height
== 1) { /* 1 row */
6477 assert(width
!= 1); /* widthxheight can't be 1x1 */
6480 /* one horizontal row with possible pad bytes */
6482 for (jj
= 0; jj
< halfWidth
; jj
++) {
6484 float totals
[4]; /* 4 is maximum components */
6485 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6488 /* average two at a time, instead of four */
6489 (*extractPackedPixel
)(isSwap
,src
,
6490 &extractTotals
[0][0]);
6491 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6492 &extractTotals
[1][0]);
6493 for (cc
= 0; cc
< components
; cc
++) {
6496 /* grab 2 pixels to average */
6498 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6499 * totals[RED]/= 2.0;
6501 for (kk
= 0; kk
< BOX2
; kk
++) {
6502 totals
[cc
]+= extractTotals
[kk
][cc
];
6504 totals
[cc
]/= (float)BOX2
;
6506 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6509 /* skip over to next group of 2 */
6510 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6514 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6515 src
+= padBytes
; /* for assertion only */
6517 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6518 assert(outIndex
== halfWidth
* halfHeight
);
6520 else if (width
== 1) { /* 1 column */
6523 assert(height
!= 1); /* widthxheight can't be 1x1 */
6525 /* one vertical column with possible pad bytes per row */
6526 /* average two at a time */
6528 for (jj
= 0; jj
< halfHeight
; jj
++) {
6530 float totals
[4]; /* 4 is maximum components */
6531 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6534 /* average two at a time, instead of four */
6535 (*extractPackedPixel
)(isSwap
,src
,
6536 &extractTotals
[0][0]);
6537 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6538 &extractTotals
[1][0]);
6539 for (cc
= 0; cc
< components
; cc
++) {
6542 /* grab 2 pixels to average */
6544 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6545 * totals[RED]/= 2.0;
6547 for (kk
= 0; kk
< BOX2
; kk
++) {
6548 totals
[cc
]+= extractTotals
[kk
][cc
];
6550 totals
[cc
]/= (float)BOX2
;
6552 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6555 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6558 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6559 assert(outIndex
== halfWidth
* halfHeight
);
6561 } /* halve1DimagePackedPixel() */
6563 /*===========================================================================*/
6565 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6567 * This section ensures that GLU 1.3 will load and run on
6568 * a GL 1.1 implementation. It dynamically resolves the
6569 * call to glTexImage3D() which might not be available.
6570 * Or is it might be supported as an extension.
6571 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6574 typedef GLAPI
void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6575 GLenum internalFormat
,
6576 GLsizei width
, GLsizei height
,
6577 GLsizei depth
, GLint border
,
6578 GLenum format
, GLenum type
,
6579 const GLvoid
*pixels
);
6581 static TexImage3Dproc pTexImage3D
;
6585 # include <sys/types.h>
6587 WINGDIAPI PROC WINAPI
wglGetProcAddress(LPCSTR
);
6590 static void gluTexImage3D( GLenum target
, GLint level
,
6591 GLenum internalFormat
,
6592 GLsizei width
, GLsizei height
,
6593 GLsizei depth
, GLint border
,
6594 GLenum format
, GLenum type
,
6595 const GLvoid
*pixels
)
6599 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6601 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6603 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6604 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6606 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6611 /* Now call glTexImage3D */
6613 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6614 depth
, border
, format
, type
, pixels
);
6619 /* Only bind to a GL 1.2 implementation: */
6620 #define gluTexImage3D glTexImage3D
6624 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6625 GLenum format
, GLenum type
)
6627 int components
= elements_per_group(format
,type
);
6628 int bytes_per_row
= bytes_per_element(type
) * width
;
6630 assert(width
> 0 && height
> 0 && depth
> 0);
6631 assert(type
!= GL_BITMAP
);
6633 return bytes_per_row
* height
* depth
* components
;
6634 } /* imageSize3D() */
6636 static void fillImage3D(const PixelStorageModes
*psm
,
6637 GLint width
, GLint height
, GLint depth
, GLenum format
,
6638 GLenum type
, GLboolean indexFormat
,
6639 const void *userImage
, GLushort
*newImage
)
6648 int elementsPerLine
;
6651 const GLubyte
*start
, *rowStart
, *iter
;
6655 myswapBytes
= psm
->unpack_swap_bytes
;
6656 components
= elements_per_group(format
,type
);
6657 if (psm
->unpack_row_length
> 0) {
6658 groupsPerLine
= psm
->unpack_row_length
;
6661 groupsPerLine
= width
;
6663 elementSize
= bytes_per_element(type
);
6664 groupSize
= elementSize
* components
;
6665 if (elementSize
== 1) myswapBytes
= 0;
6668 if (psm
->unpack_image_height
> 0) {
6669 rowsPerImage
= psm
->unpack_image_height
;
6672 rowsPerImage
= height
;
6676 rowSize
= groupsPerLine
* groupSize
;
6677 padding
= rowSize
% psm
->unpack_alignment
;
6679 rowSize
+= psm
->unpack_alignment
- padding
;
6682 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6684 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6685 psm
->unpack_skip_pixels
* groupSize
+
6687 psm
->unpack_skip_images
* imageSize
;
6688 elementsPerLine
= width
* components
;
6691 for (dd
= 0; dd
< depth
; dd
++) {
6694 for (hh
= 0; hh
< height
; hh
++) {
6697 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6699 float extractComponents
[4];
6702 case GL_UNSIGNED_BYTE
:
6706 *iter2
++ = (*iter
) * 257;
6711 *iter2
++ = *((const GLbyte
*) iter
);
6714 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6717 case GL_UNSIGNED_BYTE_3_3_2
:
6718 extract332(0,iter
,extractComponents
);
6719 for (k
= 0; k
< 3; k
++) {
6720 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6723 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6724 extract233rev(0,iter
,extractComponents
);
6725 for (k
= 0; k
< 3; k
++) {
6726 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6729 case GL_UNSIGNED_SHORT_5_6_5
:
6730 extract565(myswapBytes
,iter
,extractComponents
);
6731 for (k
= 0; k
< 3; k
++) {
6732 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6735 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6736 extract565rev(myswapBytes
,iter
,extractComponents
);
6737 for (k
= 0; k
< 3; k
++) {
6738 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6741 case GL_UNSIGNED_SHORT_4_4_4_4
:
6742 extract4444(myswapBytes
,iter
,extractComponents
);
6743 for (k
= 0; k
< 4; k
++) {
6744 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6747 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6748 extract4444rev(myswapBytes
,iter
,extractComponents
);
6749 for (k
= 0; k
< 4; k
++) {
6750 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6753 case GL_UNSIGNED_SHORT_5_5_5_1
:
6754 extract5551(myswapBytes
,iter
,extractComponents
);
6755 for (k
= 0; k
< 4; k
++) {
6756 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6759 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6760 extract1555rev(myswapBytes
,iter
,extractComponents
);
6761 for (k
= 0; k
< 4; k
++) {
6762 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6765 case GL_UNSIGNED_SHORT
:
6768 widget
.ub
[0] = iter
[1];
6769 widget
.ub
[1] = iter
[0];
6771 widget
.ub
[0] = iter
[0];
6772 widget
.ub
[1] = iter
[1];
6774 if (type
== GL_SHORT
) {
6776 *iter2
++ = widget
.s
[0];
6779 *iter2
++ = widget
.s
[0]*2;
6782 *iter2
++ = widget
.us
[0];
6785 case GL_UNSIGNED_INT_8_8_8_8
:
6786 extract8888(myswapBytes
,iter
,extractComponents
);
6787 for (k
= 0; k
< 4; k
++) {
6788 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6791 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6792 extract8888rev(myswapBytes
,iter
,extractComponents
);
6793 for (k
= 0; k
< 4; k
++) {
6794 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6797 case GL_UNSIGNED_INT_10_10_10_2
:
6798 extract1010102(myswapBytes
,iter
,extractComponents
);
6799 for (k
= 0; k
< 4; k
++) {
6800 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6803 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6804 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6805 for (k
= 0; k
< 4; k
++) {
6806 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6810 case GL_UNSIGNED_INT
:
6813 widget
.ub
[0] = iter
[3];
6814 widget
.ub
[1] = iter
[2];
6815 widget
.ub
[2] = iter
[1];
6816 widget
.ub
[3] = iter
[0];
6818 widget
.ub
[0] = iter
[0];
6819 widget
.ub
[1] = iter
[1];
6820 widget
.ub
[2] = iter
[2];
6821 widget
.ub
[3] = iter
[3];
6823 if (type
== GL_FLOAT
) {
6825 *iter2
++ = widget
.f
;
6827 *iter2
++ = 65535 * widget
.f
;
6829 } else if (type
== GL_UNSIGNED_INT
) {
6831 *iter2
++ = widget
.ui
;
6833 *iter2
++ = widget
.ui
>> 16;
6837 *iter2
++ = widget
.i
;
6839 *iter2
++ = widget
.i
>> 15;
6851 iter
= rowStart
; /* for assertion purposes */
6857 /* iterators should be one byte past end */
6858 if (!isTypePackedPixel(type
)) {
6859 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6862 assert(iter2
== &newImage
[width
*height
*depth
*
6863 elements_per_group(format
,0)]);
6865 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6866 psm
->unpack_skip_rows
* rowSize
+
6867 psm
->unpack_skip_pixels
* groupSize
+
6869 psm
->unpack_skip_images
* imageSize
] );
6870 } /* fillImage3D () */
6872 static void scaleInternal3D(GLint components
,
6873 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6874 const GLushort
*dataIn
,
6875 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6878 float x
, lowx
, highx
, convx
, halfconvx
;
6879 float y
, lowy
, highy
, convy
, halfconvy
;
6880 float z
, lowz
, highz
, convz
, halfconvz
;
6881 float xpercent
,ypercent
,zpercent
;
6883 /* Max components in a format is 4, so... */
6886 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6889 convz
= (float) depthIn
/depthOut
;
6890 convy
= (float) heightIn
/heightOut
;
6891 convx
= (float) widthIn
/widthOut
;
6892 halfconvx
= convx
/2;
6893 halfconvy
= convy
/2;
6894 halfconvz
= convz
/2;
6895 for (d
= 0; d
< depthOut
; d
++) {
6896 z
= convz
* (d
+0.5);
6897 if (depthIn
> depthOut
) {
6898 highz
= z
+ halfconvz
;
6899 lowz
= z
- halfconvz
;
6904 for (i
= 0; i
< heightOut
; i
++) {
6905 y
= convy
* (i
+0.5);
6906 if (heightIn
> heightOut
) {
6907 highy
= y
+ halfconvy
;
6908 lowy
= y
- halfconvy
;
6913 for (j
= 0; j
< widthOut
; j
++) {
6914 x
= convx
* (j
+0.5);
6915 if (widthIn
> widthOut
) {
6916 highx
= x
+ halfconvx
;
6917 lowx
= x
- halfconvx
;
6924 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6925 ** lowz) to (highx, highy, highz) on input data into this pixel
6928 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6934 zindex
= (zint
+ depthIn
) % depthIn
;
6935 if (highz
< zint
+1) {
6936 zpercent
= highz
- z
;
6938 zpercent
= zint
+1 - z
;
6944 yindex
= (yint
+ heightIn
) % heightIn
;
6945 if (highy
< yint
+1) {
6946 ypercent
= highy
- y
;
6948 ypercent
= yint
+1 - y
;
6955 xindex
= (xint
+ widthIn
) % widthIn
;
6956 if (highx
< xint
+1) {
6957 xpercent
= highx
- x
;
6959 xpercent
= xint
+1 - x
;
6962 percent
= xpercent
* ypercent
* zpercent
;
6965 temp
= (xindex
+ (yindex
*widthIn
) +
6966 (zindex
*widthIn
*heightIn
)) * components
;
6967 for (k
= 0; k
< components
; k
++) {
6968 assert(0 <= (temp
+k
) &&
6970 (widthIn
*heightIn
*depthIn
*components
));
6971 totals
[k
] += dataIn
[temp
+ k
] * percent
;
6986 temp
= (j
+ (i
* widthOut
) +
6987 (d
*widthOut
*heightOut
)) * components
;
6988 for (k
= 0; k
< components
; k
++) {
6989 /* totals[] should be rounded in the case of enlarging an
6990 * RGB ramp when the type is 332 or 4444
6992 assert(0 <= (temp
+k
) &&
6993 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
6994 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
6999 } /* scaleInternal3D() */
7001 static void emptyImage3D(const PixelStorageModes
*psm
,
7002 GLint width
, GLint height
, GLint depth
,
7003 GLenum format
, GLenum type
, GLboolean indexFormat
,
7004 const GLushort
*oldImage
, void *userImage
)
7013 GLubyte
*start
, *rowStart
, *iter
;
7014 int elementsPerLine
;
7015 const GLushort
*iter2
;
7020 myswapBytes
= psm
->pack_swap_bytes
;
7021 components
= elements_per_group(format
,type
);
7022 if (psm
->pack_row_length
> 0) {
7023 groupsPerLine
= psm
->pack_row_length
;
7026 groupsPerLine
= width
;
7029 elementSize
= bytes_per_element(type
);
7030 groupSize
= elementSize
* components
;
7031 if (elementSize
== 1) myswapBytes
= 0;
7034 if (psm
->pack_image_height
> 0) {
7035 rowsPerImage
= psm
->pack_image_height
;
7038 rowsPerImage
= height
;
7043 rowSize
= groupsPerLine
* groupSize
;
7044 padding
= rowSize
% psm
->pack_alignment
;
7046 rowSize
+= psm
->pack_alignment
- padding
;
7049 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7051 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7052 psm
->pack_skip_pixels
* groupSize
+
7054 psm
->pack_skip_images
* imageSize
;
7055 elementsPerLine
= width
* components
;
7058 for (dd
= 0; dd
< depth
; dd
++) {
7061 for (ii
= 0; ii
< height
; ii
++) {
7064 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7066 float shoveComponents
[4];
7069 case GL_UNSIGNED_BYTE
:
7073 *iter
= *iter2
++ >> 8;
7078 *((GLbyte
*) iter
) = *iter2
++;
7080 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7083 case GL_UNSIGNED_BYTE_3_3_2
:
7084 for (k
= 0; k
< 3; k
++) {
7085 shoveComponents
[k
]= *iter2
++ / 65535.0;
7087 shove332(shoveComponents
,0,(void *)iter
);
7089 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7090 for (k
= 0; k
< 3; k
++) {
7091 shoveComponents
[k
]= *iter2
++ / 65535.0;
7093 shove233rev(shoveComponents
,0,(void *)iter
);
7095 case GL_UNSIGNED_SHORT_5_6_5
:
7096 for (k
= 0; k
< 3; k
++) {
7097 shoveComponents
[k
]= *iter2
++ / 65535.0;
7099 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7101 iter
[0] = widget
.ub
[1];
7102 iter
[1] = widget
.ub
[0];
7105 *(GLushort
*)iter
= widget
.us
[0];
7108 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7109 for (k
= 0; k
< 3; k
++) {
7110 shoveComponents
[k
]= *iter2
++ / 65535.0;
7112 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7114 iter
[0] = widget
.ub
[1];
7115 iter
[1] = widget
.ub
[0];
7118 *(GLushort
*)iter
= widget
.us
[0];
7121 case GL_UNSIGNED_SHORT_4_4_4_4
:
7122 for (k
= 0; k
< 4; k
++) {
7123 shoveComponents
[k
]= *iter2
++ / 65535.0;
7125 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7127 iter
[0] = widget
.ub
[1];
7128 iter
[1] = widget
.ub
[0];
7130 *(GLushort
*)iter
= widget
.us
[0];
7133 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7134 for (k
= 0; k
< 4; k
++) {
7135 shoveComponents
[k
]= *iter2
++ / 65535.0;
7137 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7139 iter
[0] = widget
.ub
[1];
7140 iter
[1] = widget
.ub
[0];
7142 *(GLushort
*)iter
= widget
.us
[0];
7145 case GL_UNSIGNED_SHORT_5_5_5_1
:
7146 for (k
= 0; k
< 4; k
++) {
7147 shoveComponents
[k
]= *iter2
++ / 65535.0;
7149 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7151 iter
[0] = widget
.ub
[1];
7152 iter
[1] = widget
.ub
[0];
7154 *(GLushort
*)iter
= widget
.us
[0];
7157 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7158 for (k
= 0; k
< 4; k
++) {
7159 shoveComponents
[k
]= *iter2
++ / 65535.0;
7161 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7163 iter
[0] = widget
.ub
[1];
7164 iter
[1] = widget
.ub
[0];
7166 *(GLushort
*)iter
= widget
.us
[0];
7169 case GL_UNSIGNED_SHORT
:
7171 if (type
== GL_SHORT
) {
7173 widget
.s
[0] = *iter2
++;
7175 widget
.s
[0] = *iter2
++ >> 1;
7178 widget
.us
[0] = *iter2
++;
7181 iter
[0] = widget
.ub
[1];
7182 iter
[1] = widget
.ub
[0];
7184 iter
[0] = widget
.ub
[0];
7185 iter
[1] = widget
.ub
[1];
7188 case GL_UNSIGNED_INT_8_8_8_8
:
7189 for (k
= 0; k
< 4; k
++) {
7190 shoveComponents
[k
]= *iter2
++ / 65535.0;
7192 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7194 iter
[3] = widget
.ub
[0];
7195 iter
[2] = widget
.ub
[1];
7196 iter
[1] = widget
.ub
[2];
7197 iter
[0] = widget
.ub
[3];
7199 *(GLuint
*)iter
= widget
.ui
;
7202 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7203 for (k
= 0; k
< 4; k
++) {
7204 shoveComponents
[k
]= *iter2
++ / 65535.0;
7206 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7208 iter
[3] = widget
.ub
[0];
7209 iter
[2] = widget
.ub
[1];
7210 iter
[1] = widget
.ub
[2];
7211 iter
[0] = widget
.ub
[3];
7213 *(GLuint
*)iter
= widget
.ui
;
7216 case GL_UNSIGNED_INT_10_10_10_2
:
7217 for (k
= 0; k
< 4; k
++) {
7218 shoveComponents
[k
]= *iter2
++ / 65535.0;
7220 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7222 iter
[3] = widget
.ub
[0];
7223 iter
[2] = widget
.ub
[1];
7224 iter
[1] = widget
.ub
[2];
7225 iter
[0] = widget
.ub
[3];
7227 *(GLuint
*)iter
= widget
.ui
;
7230 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7231 for (k
= 0; k
< 4; k
++) {
7232 shoveComponents
[k
]= *iter2
++ / 65535.0;
7234 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7236 iter
[3] = widget
.ub
[0];
7237 iter
[2] = widget
.ub
[1];
7238 iter
[1] = widget
.ub
[2];
7239 iter
[0] = widget
.ub
[3];
7241 *(GLuint
*)iter
= widget
.ui
;
7245 case GL_UNSIGNED_INT
:
7247 if (type
== GL_FLOAT
) {
7249 widget
.f
= *iter2
++;
7251 widget
.f
= *iter2
++ / (float) 65535.0;
7253 } else if (type
== GL_UNSIGNED_INT
) {
7255 widget
.ui
= *iter2
++;
7257 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7261 widget
.i
= *iter2
++;
7263 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
7267 iter
[3] = widget
.ub
[0];
7268 iter
[2] = widget
.ub
[1];
7269 iter
[1] = widget
.ub
[2];
7270 iter
[0] = widget
.ub
[3];
7272 iter
[0] = widget
.ub
[0];
7273 iter
[1] = widget
.ub
[1];
7274 iter
[2] = widget
.ub
[2];
7275 iter
[3] = widget
.ub
[3];
7291 /* iterators should be one byte past end */
7292 if (!isTypePackedPixel(type
)) {
7293 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7296 assert(iter2
== &oldImage
[width
*height
*depth
*
7297 elements_per_group(format
,0)]);
7299 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7300 psm
->unpack_skip_rows
* rowSize
+
7301 psm
->unpack_skip_pixels
* groupSize
+
7303 psm
->unpack_skip_images
* imageSize
] );
7304 } /* emptyImage3D() */
7307 int gluScaleImage3D(GLenum format
,
7308 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7309 GLenum typeIn
, const void *dataIn
,
7310 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7311 GLenum typeOut
, void *dataOut
)
7314 GLushort
*beforeImage
, *afterImage
;
7315 PixelStorageModes psm
;
7317 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7318 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7322 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7323 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7324 return GLU_INVALID_VALUE
;
7327 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7328 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7329 return GLU_INVALID_ENUM
;
7331 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7332 return GLU_INVALID_OPERATION
;
7334 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7335 return GLU_INVALID_OPERATION
;
7338 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7339 GL_UNSIGNED_SHORT
));
7340 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7341 GL_UNSIGNED_SHORT
));
7342 if (beforeImage
== NULL
|| afterImage
== NULL
) {
7343 return GLU_OUT_OF_MEMORY
;
7345 retrieveStoreModes3D(&psm
);
7347 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7348 dataIn
, beforeImage
);
7349 components
= elements_per_group(format
,0);
7350 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7351 widthOut
,heightOut
,depthOut
,afterImage
);
7352 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7353 is_index(format
),afterImage
, dataOut
);
7354 free((void *) beforeImage
);
7355 free((void *) afterImage
);
7358 } /* gluScaleImage3D() */
7361 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7362 GLint internalFormat
, GLenum format
, GLenum type
,
7363 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7365 GLint widthPowerOf2
= nearestPower(width
);
7366 GLint heightPowerOf2
= nearestPower(height
);
7367 GLint depthPowerOf2
= nearestPower(depth
);
7371 /* compute level 1 width & height & depth, clamping each at 1 */
7372 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7373 widthPowerOf2
>> 1 :
7375 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7376 heightPowerOf2
>> 1 :
7378 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7379 depthPowerOf2
>> 1 :
7382 assert(widthAtLevelOne
> 0);
7383 assert(heightAtLevelOne
> 0);
7384 assert(depthAtLevelOne
> 0);
7386 /* does width x height x depth at level 1 & all their mipmaps fit? */
7387 if (target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
) {
7388 proxyTarget
= GL_PROXY_TEXTURE_3D
;
7389 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7391 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7392 0,format
,type
,NULL
);
7394 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7395 /* does it fit??? */
7396 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7397 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7398 depthPowerOf2
== 1) {
7399 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7402 widthPowerOf2
= widthAtLevelOne
;
7403 heightPowerOf2
= heightAtLevelOne
;
7404 depthPowerOf2
= depthAtLevelOne
;
7406 /* else it does fit */
7407 } while (proxyWidth
== 0);
7408 /* loop must terminate! */
7410 /* return the width & height at level 0 that fits */
7411 *newWidth
= widthPowerOf2
;
7412 *newHeight
= heightPowerOf2
;
7413 *newDepth
= depthPowerOf2
;
7414 /*printf("Proxy Textures\n");*/
7415 } /* closestFit3D() */
7417 static void halveImagePackedPixelSlice(int components
,
7418 void (*extractPackedPixel
)
7419 (int, const void *,GLfloat
[]),
7420 void (*shovePackedPixel
)
7421 (const GLfloat
[],int, void *),
7422 GLint width
, GLint height
, GLint depth
,
7423 const void *dataIn
, void *dataOut
,
7424 GLint pixelSizeInBytes
,
7425 GLint rowSizeInBytes
,
7426 GLint imageSizeInBytes
,
7430 int halfWidth
= width
/ 2;
7431 int halfHeight
= height
/ 2;
7432 int halfDepth
= depth
/ 2;
7433 const char *src
= (const char *)dataIn
;
7436 assert((width
== 1 || height
== 1) && depth
>= 2);
7438 if (width
== height
) { /* a 1-pixel column viewed from top */
7439 assert(width
== 1 && height
== 1);
7442 for (ii
= 0; ii
< halfDepth
; ii
++) {
7444 float extractTotals
[BOX2
][4];
7447 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7448 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7449 &extractTotals
[1][0]);
7450 for (cc
= 0; cc
< components
; cc
++) {
7453 /* average 2 pixels since only a column */
7455 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7456 * totals[RED]/= 2.0;
7458 for (kk
= 0; kk
< BOX2
; kk
++) {
7459 totals
[cc
]+= extractTotals
[kk
][cc
];
7461 totals
[cc
]/= (float)BOX2
;
7464 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7466 /* skip over to next group of 2 */
7467 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7470 else if (height
== 1) { /* horizontal slice viewed from top */
7473 for (ii
= 0; ii
< halfDepth
; ii
++) {
7474 for (jj
= 0; jj
< halfWidth
; jj
++) {
7476 float extractTotals
[BOX4
][4];
7479 (*extractPackedPixel
)(isSwap
,src
,
7480 &extractTotals
[0][0]);
7481 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7482 &extractTotals
[1][0]);
7483 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7484 &extractTotals
[2][0]);
7485 (*extractPackedPixel
)(isSwap
,
7486 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7487 &extractTotals
[3][0]);
7488 for (cc
= 0; cc
< components
; cc
++) {
7491 /* grab 4 pixels to average */
7493 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7494 * extractTotals[2][RED]+extractTotals[3][RED];
7495 * totals[RED]/= 4.0;
7497 for (kk
= 0; kk
< BOX4
; kk
++) {
7498 totals
[cc
]+= extractTotals
[kk
][cc
];
7500 totals
[cc
]/= (float)BOX4
;
7502 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7505 /* skip over to next horizontal square of 4 */
7506 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7512 else if (width
== 1) { /* vertical slice viewed from top */
7513 assert(height
!= 1);
7515 for (ii
= 0; ii
< halfDepth
; ii
++) {
7516 for (jj
= 0; jj
< halfHeight
; jj
++) {
7518 float extractTotals
[BOX4
][4];
7521 (*extractPackedPixel
)(isSwap
,src
,
7522 &extractTotals
[0][0]);
7523 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7524 &extractTotals
[1][0]);
7525 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7526 &extractTotals
[2][0]);
7527 (*extractPackedPixel
)(isSwap
,
7528 (src
+imageSizeInBytes
+rowSizeInBytes
),
7529 &extractTotals
[3][0]);
7530 for (cc
= 0; cc
< components
; cc
++) {
7533 /* grab 4 pixels to average */
7535 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7536 * extractTotals[2][RED]+extractTotals[3][RED];
7537 * totals[RED]/= 4.0;
7539 for (kk
= 0; kk
< BOX4
; kk
++) {
7540 totals
[cc
]+= extractTotals
[kk
][cc
];
7542 totals
[cc
]/= (float)BOX4
;
7544 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7548 /* skip over to next vertical square of 4 */
7549 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7555 } /* halveImagePackedPixelSlice() */
7557 static void halveImagePackedPixel3D(int components
,
7558 void (*extractPackedPixel
)
7559 (int, const void *,GLfloat
[]),
7560 void (*shovePackedPixel
)
7561 (const GLfloat
[],int, void *),
7562 GLint width
, GLint height
, GLint depth
,
7563 const void *dataIn
, void *dataOut
,
7564 GLint pixelSizeInBytes
,
7565 GLint rowSizeInBytes
,
7566 GLint imageSizeInBytes
,
7570 assert(1 <= width
&& 1 <= height
);
7572 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7573 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7574 rowSizeInBytes
,isSwap
);
7577 /* a horizontal or vertical slice viewed from top */
7578 else if (width
== 1 || height
== 1) {
7581 halveImagePackedPixelSlice(components
,
7582 extractPackedPixel
,shovePackedPixel
,
7583 width
, height
, depth
, dataIn
, dataOut
,
7584 pixelSizeInBytes
, rowSizeInBytes
,
7585 imageSizeInBytes
, isSwap
);
7591 int halfWidth
= width
/ 2;
7592 int halfHeight
= height
/ 2;
7593 int halfDepth
= depth
/ 2;
7594 const char *src
= (const char *) dataIn
;
7595 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7598 for (dd
= 0; dd
< halfDepth
; dd
++) {
7599 for (ii
= 0; ii
< halfHeight
; ii
++) {
7600 for (jj
= 0; jj
< halfWidth
; jj
++) {
7602 float totals
[4]; /* 4 is maximum components */
7603 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7606 (*extractPackedPixel
)(isSwap
,src
,
7607 &extractTotals
[0][0]);
7608 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7609 &extractTotals
[1][0]);
7610 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7611 &extractTotals
[2][0]);
7612 (*extractPackedPixel
)(isSwap
,
7613 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7614 &extractTotals
[3][0]);
7616 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7617 &extractTotals
[4][0]);
7618 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7619 &extractTotals
[5][0]);
7620 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7621 &extractTotals
[6][0]);
7622 (*extractPackedPixel
)(isSwap
,
7623 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7624 &extractTotals
[7][0]);
7625 for (cc
= 0; cc
< components
; cc
++) {
7628 /* grab 8 pixels to average */
7630 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7631 * extractTotals[2][RED]+extractTotals[3][RED]+
7632 * extractTotals[4][RED]+extractTotals[5][RED]+
7633 * extractTotals[6][RED]+extractTotals[7][RED];
7634 * totals[RED]/= 8.0;
7636 for (kk
= 0; kk
< BOX8
; kk
++) {
7637 totals
[cc
]+= extractTotals
[kk
][cc
];
7639 totals
[cc
]/= (float)BOX8
;
7641 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7644 /* skip over to next square of 4 */
7645 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7647 /* skip past pad bytes, if any, to get to next row */
7650 /* src is at beginning of a row here, but it's the second row of
7651 * the square block of 4 pixels that we just worked on so we
7652 * need to go one more row.
7660 src
+= rowSizeInBytes
;
7663 src
+= imageSizeInBytes
;
7666 /* both pointers must reach one byte after the end */
7667 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7668 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7671 } /* halveImagePackedPixel3D() */
7673 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7677 GLsizei widthPowerOf2
,
7678 GLsizei heightPowerOf2
,
7679 GLsizei depthPowerOf2
,
7680 GLenum format
, GLenum type
,
7682 GLint baseLevel
,GLint maxLevel
,
7685 GLint newWidth
, newHeight
, newDepth
;
7686 GLint level
, levels
;
7687 const void *usersImage
;
7688 void *srcImage
, *dstImage
;
7689 __GLU_INIT_SWAP_IMAGE
;
7693 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7694 GLint rowsPerImage
, imageSize
;
7695 GLint rowSize
, padding
;
7696 PixelStorageModes psm
;
7698 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7699 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7700 assert(type
!= GL_BITMAP
);
7702 srcImage
= dstImage
= NULL
;
7704 newWidth
= widthPowerOf2
;
7705 newHeight
= heightPowerOf2
;
7706 newDepth
= depthPowerOf2
;
7707 levels
= computeLog(newWidth
);
7708 level
= computeLog(newHeight
);
7709 if (level
> levels
) levels
=level
;
7710 level
= computeLog(newDepth
);
7711 if (level
> levels
) levels
=level
;
7715 retrieveStoreModes3D(&psm
);
7716 myswapBytes
= psm
.unpack_swap_bytes
;
7717 cmpts
= elements_per_group(format
,type
);
7718 if (psm
.unpack_row_length
> 0) {
7719 groupsPerLine
= psm
.unpack_row_length
;
7721 groupsPerLine
= width
;
7724 elementSize
= bytes_per_element(type
);
7725 groupSize
= elementSize
* cmpts
;
7726 if (elementSize
== 1) myswapBytes
= 0;
7729 if (psm
.unpack_image_height
> 0) {
7730 rowsPerImage
= psm
.unpack_image_height
;
7733 rowsPerImage
= height
;
7737 rowSize
= groupsPerLine
* groupSize
;
7738 padding
= (rowSize
% psm
.unpack_alignment
);
7740 rowSize
+= psm
.unpack_alignment
- padding
;
7743 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7745 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7746 psm
.unpack_skip_pixels
* groupSize
+
7748 psm
.unpack_skip_images
* imageSize
;
7750 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7751 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7752 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7753 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7754 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7758 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7759 /* Use usersImage for level userLevel */
7760 if (baseLevel
<= level
&& level
<= maxLevel
) {
7761 gluTexImage3D(target
, level
, internalFormat
, width
,
7762 height
, depth
, 0, format
, type
,
7765 if(levels
== 0) { /* we're done. clean up and return */
7766 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7767 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7768 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7769 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7770 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7771 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7772 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7776 int nextWidth
= newWidth
/2;
7777 int nextHeight
= newHeight
/2;
7778 int nextDepth
= newDepth
/2;
7781 if (nextWidth
< 1) nextWidth
= 1;
7782 if (nextHeight
< 1) nextHeight
= 1;
7783 if (nextDepth
< 1) nextDepth
= 1;
7784 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7787 case GL_UNSIGNED_BYTE
:
7788 dstImage
= (GLubyte
*)malloc(memReq
);
7791 dstImage
= (GLbyte
*)malloc(memReq
);
7793 case GL_UNSIGNED_SHORT
:
7794 dstImage
= (GLushort
*)malloc(memReq
);
7797 dstImage
= (GLshort
*)malloc(memReq
);
7799 case GL_UNSIGNED_INT
:
7800 dstImage
= (GLuint
*)malloc(memReq
);
7803 dstImage
= (GLint
*)malloc(memReq
);
7806 dstImage
= (GLfloat
*)malloc(memReq
);
7808 case GL_UNSIGNED_BYTE_3_3_2
:
7809 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7810 dstImage
= (GLubyte
*)malloc(memReq
);
7812 case GL_UNSIGNED_SHORT_5_6_5
:
7813 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7814 case GL_UNSIGNED_SHORT_4_4_4_4
:
7815 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7816 case GL_UNSIGNED_SHORT_5_5_5_1
:
7817 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7818 dstImage
= (GLushort
*)malloc(memReq
);
7820 case GL_UNSIGNED_INT_8_8_8_8
:
7821 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7822 case GL_UNSIGNED_INT_10_10_10_2
:
7823 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7824 dstImage
= (GLuint
*)malloc(memReq
);
7827 return GLU_INVALID_ENUM
; /* assertion */
7829 if (dstImage
== NULL
) {
7830 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7831 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7832 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7833 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7834 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7835 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7836 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7837 return GLU_OUT_OF_MEMORY
;
7841 case GL_UNSIGNED_BYTE
:
7843 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7845 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7846 imageSize
,myswapBytes
);
7849 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7850 elementSize
,rowSize
,groupSize
);
7855 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7857 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7858 imageSize
,myswapBytes
);
7861 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7862 elementSize
,rowSize
,groupSize
);
7865 case GL_UNSIGNED_SHORT
:
7867 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7869 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7870 imageSize
,myswapBytes
);
7873 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7874 elementSize
,rowSize
,groupSize
,myswapBytes
);
7879 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7881 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7882 imageSize
,myswapBytes
);
7885 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7886 elementSize
,rowSize
,groupSize
,myswapBytes
);
7889 case GL_UNSIGNED_INT
:
7891 halveImage3D(cmpts
,extractUint
,shoveUint
,
7893 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7894 imageSize
,myswapBytes
);
7897 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7898 elementSize
,rowSize
,groupSize
,myswapBytes
);
7903 halveImage3D(cmpts
,extractSint
,shoveSint
,
7905 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7906 imageSize
,myswapBytes
);
7909 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7910 elementSize
,rowSize
,groupSize
,myswapBytes
);
7915 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7917 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7918 imageSize
,myswapBytes
);
7921 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7922 elementSize
,rowSize
,groupSize
,myswapBytes
);
7925 case GL_UNSIGNED_BYTE_3_3_2
:
7926 assert(format
== GL_RGB
);
7927 halveImagePackedPixel3D(3,extract332
,shove332
,
7928 width
,height
,depth
,usersImage
,dstImage
,
7929 elementSize
,rowSize
,imageSize
,myswapBytes
);
7931 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7932 assert(format
== GL_RGB
);
7933 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7934 width
,height
,depth
,usersImage
,dstImage
,
7935 elementSize
,rowSize
,imageSize
,myswapBytes
);
7937 case GL_UNSIGNED_SHORT_5_6_5
:
7938 halveImagePackedPixel3D(3,extract565
,shove565
,
7939 width
,height
,depth
,usersImage
,dstImage
,
7940 elementSize
,rowSize
,imageSize
,myswapBytes
);
7942 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7943 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7944 width
,height
,depth
,usersImage
,dstImage
,
7945 elementSize
,rowSize
,imageSize
,myswapBytes
);
7947 case GL_UNSIGNED_SHORT_4_4_4_4
:
7948 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7949 width
,height
,depth
,usersImage
,dstImage
,
7950 elementSize
,rowSize
,imageSize
,myswapBytes
);
7952 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7953 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
7954 width
,height
,depth
,usersImage
,dstImage
,
7955 elementSize
,rowSize
,imageSize
,myswapBytes
);
7957 case GL_UNSIGNED_SHORT_5_5_5_1
:
7958 halveImagePackedPixel3D(4,extract5551
,shove5551
,
7959 width
,height
,depth
,usersImage
,dstImage
,
7960 elementSize
,rowSize
,imageSize
,myswapBytes
);
7962 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7963 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
7964 width
,height
,depth
,usersImage
,dstImage
,
7965 elementSize
,rowSize
,imageSize
,myswapBytes
);
7967 case GL_UNSIGNED_INT_8_8_8_8
:
7968 halveImagePackedPixel3D(4,extract8888
,shove8888
,
7969 width
,height
,depth
,usersImage
,dstImage
,
7970 elementSize
,rowSize
,imageSize
,myswapBytes
);
7972 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7973 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
7974 width
,height
,depth
,usersImage
,dstImage
,
7975 elementSize
,rowSize
,imageSize
,myswapBytes
);
7977 case GL_UNSIGNED_INT_10_10_10_2
:
7978 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
7979 width
,height
,depth
,usersImage
,dstImage
,
7980 elementSize
,rowSize
,imageSize
,myswapBytes
);
7982 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7983 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
7984 width
,height
,depth
,usersImage
,dstImage
,
7985 elementSize
,rowSize
,imageSize
,myswapBytes
);
7992 newHeight
= height
/2;
7995 if (newWidth
< 1) newWidth
= 1;
7996 if (newHeight
< 1) newHeight
= 1;
7997 if (newDepth
< 1) newDepth
= 1;
8000 rowSize
= newWidth
* groupSize
;
8001 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8002 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8003 /* Swap srcImage and dstImage */
8004 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8006 case GL_UNSIGNED_BYTE
:
8007 dstImage
= (GLubyte
*)malloc(memReq
);
8010 dstImage
= (GLbyte
*)malloc(memReq
);
8012 case GL_UNSIGNED_SHORT
:
8013 dstImage
= (GLushort
*)malloc(memReq
);
8016 dstImage
= (GLshort
*)malloc(memReq
);
8018 case GL_UNSIGNED_INT
:
8019 dstImage
= (GLuint
*)malloc(memReq
);
8022 dstImage
= (GLint
*)malloc(memReq
);
8025 dstImage
= (GLfloat
*)malloc(memReq
);
8027 case GL_UNSIGNED_BYTE_3_3_2
:
8028 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8029 dstImage
= (GLubyte
*)malloc(memReq
);
8031 case GL_UNSIGNED_SHORT_5_6_5
:
8032 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8033 case GL_UNSIGNED_SHORT_4_4_4_4
:
8034 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8035 case GL_UNSIGNED_SHORT_5_5_5_1
:
8036 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8037 dstImage
= (GLushort
*)malloc(memReq
);
8039 case GL_UNSIGNED_INT_8_8_8_8
:
8040 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8041 case GL_UNSIGNED_INT_10_10_10_2
:
8042 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8043 dstImage
= (GLuint
*)malloc(memReq
);
8046 return GLU_INVALID_ENUM
; /* assertion */
8048 if (dstImage
== NULL
) {
8049 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8050 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8051 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8052 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8053 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8054 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8055 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8056 return GLU_OUT_OF_MEMORY
;
8058 /* level userLevel+1 is in srcImage; level userLevel already saved */
8059 level
= userLevel
+1;
8060 } else {/* user's image is *not* nice power-of-2 sized square */
8061 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8063 case GL_UNSIGNED_BYTE
:
8064 dstImage
= (GLubyte
*)malloc(memReq
);
8067 dstImage
= (GLbyte
*)malloc(memReq
);
8069 case GL_UNSIGNED_SHORT
:
8070 dstImage
= (GLushort
*)malloc(memReq
);
8073 dstImage
= (GLshort
*)malloc(memReq
);
8075 case GL_UNSIGNED_INT
:
8076 dstImage
= (GLuint
*)malloc(memReq
);
8079 dstImage
= (GLint
*)malloc(memReq
);
8082 dstImage
= (GLfloat
*)malloc(memReq
);
8084 case GL_UNSIGNED_BYTE_3_3_2
:
8085 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8086 dstImage
= (GLubyte
*)malloc(memReq
);
8088 case GL_UNSIGNED_SHORT_5_6_5
:
8089 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8090 case GL_UNSIGNED_SHORT_4_4_4_4
:
8091 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8092 case GL_UNSIGNED_SHORT_5_5_5_1
:
8093 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8094 dstImage
= (GLushort
*)malloc(memReq
);
8096 case GL_UNSIGNED_INT_8_8_8_8
:
8097 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8098 case GL_UNSIGNED_INT_10_10_10_2
:
8099 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8100 dstImage
= (GLuint
*)malloc(memReq
);
8103 return GLU_INVALID_ENUM
; /* assertion */
8106 if (dstImage
== NULL
) {
8107 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8108 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8109 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8110 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8111 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8112 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8113 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8114 return GLU_OUT_OF_MEMORY
;
8116 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8117 width,height,depth,newWidth,newHeight,newDepth);*/
8119 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8120 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8123 rowSize
= newWidth
* groupSize
;
8124 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8125 /* Swap dstImage and srcImage */
8126 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8128 if(levels
!= 0) { /* use as little memory as possible */
8130 int nextWidth
= newWidth
/2;
8131 int nextHeight
= newHeight
/2;
8132 int nextDepth
= newDepth
/2;
8133 if (nextWidth
< 1) nextWidth
= 1;
8134 if (nextHeight
< 1) nextHeight
= 1;
8135 if (nextDepth
< 1) nextDepth
= 1;
8137 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8140 case GL_UNSIGNED_BYTE
:
8141 dstImage
= (GLubyte
*)malloc(memReq
);
8144 dstImage
= (GLbyte
*)malloc(memReq
);
8146 case GL_UNSIGNED_SHORT
:
8147 dstImage
= (GLushort
*)malloc(memReq
);
8150 dstImage
= (GLshort
*)malloc(memReq
);
8152 case GL_UNSIGNED_INT
:
8153 dstImage
= (GLuint
*)malloc(memReq
);
8156 dstImage
= (GLint
*)malloc(memReq
);
8159 dstImage
= (GLfloat
*)malloc(memReq
);
8161 case GL_UNSIGNED_BYTE_3_3_2
:
8162 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8163 dstImage
= (GLubyte
*)malloc(memReq
);
8165 case GL_UNSIGNED_SHORT_5_6_5
:
8166 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8167 case GL_UNSIGNED_SHORT_4_4_4_4
:
8168 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8169 case GL_UNSIGNED_SHORT_5_5_5_1
:
8170 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8171 dstImage
= (GLushort
*)malloc(memReq
);
8173 case GL_UNSIGNED_INT_8_8_8_8
:
8174 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8175 case GL_UNSIGNED_INT_10_10_10_2
:
8176 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8177 dstImage
= (GLuint
*)malloc(memReq
);
8180 return GLU_INVALID_ENUM
; /* assertion */
8182 if (dstImage
== NULL
) {
8183 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8184 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8185 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8186 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8187 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8188 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8189 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8190 return GLU_OUT_OF_MEMORY
;
8193 /* level userLevel is in srcImage; nothing saved yet */
8197 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8198 if (baseLevel
<= level
&& level
<= maxLevel
) {
8199 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8200 0,format
, type
, (void *)srcImage
);
8202 level
++; /* update current level for the loop */
8203 for (; level
<= levels
; level
++) {
8205 case GL_UNSIGNED_BYTE
:
8207 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8208 newWidth
,newHeight
,newDepth
,
8209 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8210 imageSize
,myswapBytes
);
8213 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8214 elementSize
,rowSize
,groupSize
);
8219 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8220 newWidth
,newHeight
,newDepth
,
8221 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8222 imageSize
,myswapBytes
);
8225 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8226 elementSize
,rowSize
,groupSize
);
8229 case GL_UNSIGNED_SHORT
:
8231 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8232 newWidth
,newHeight
,newDepth
,
8233 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8234 imageSize
,myswapBytes
);
8237 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8238 elementSize
,rowSize
,groupSize
,myswapBytes
);
8243 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8244 newWidth
,newHeight
,newDepth
,
8245 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8246 imageSize
,myswapBytes
);
8249 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8250 elementSize
,rowSize
,groupSize
,myswapBytes
);
8253 case GL_UNSIGNED_INT
:
8255 halveImage3D(cmpts
,extractUint
,shoveUint
,
8256 newWidth
,newHeight
,newDepth
,
8257 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8258 imageSize
,myswapBytes
);
8261 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8262 elementSize
,rowSize
,groupSize
,myswapBytes
);
8267 halveImage3D(cmpts
,extractSint
,shoveSint
,
8268 newWidth
,newHeight
,newDepth
,
8269 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8270 imageSize
,myswapBytes
);
8273 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8274 elementSize
,rowSize
,groupSize
,myswapBytes
);
8279 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8280 newWidth
,newHeight
,newDepth
,
8281 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8282 imageSize
,myswapBytes
);
8285 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8286 elementSize
,rowSize
,groupSize
,myswapBytes
);
8289 case GL_UNSIGNED_BYTE_3_3_2
:
8290 halveImagePackedPixel3D(3,extract332
,shove332
,
8291 newWidth
,newHeight
,newDepth
,
8292 srcImage
,dstImage
,elementSize
,rowSize
,
8293 imageSize
,myswapBytes
);
8295 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8296 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8297 newWidth
,newHeight
,newDepth
,
8298 srcImage
,dstImage
,elementSize
,rowSize
,
8299 imageSize
,myswapBytes
);
8301 case GL_UNSIGNED_SHORT_5_6_5
:
8302 halveImagePackedPixel3D(3,extract565
,shove565
,
8303 newWidth
,newHeight
,newDepth
,
8304 srcImage
,dstImage
,elementSize
,rowSize
,
8305 imageSize
,myswapBytes
);
8307 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8308 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8309 newWidth
,newHeight
,newDepth
,
8310 srcImage
,dstImage
,elementSize
,rowSize
,
8311 imageSize
,myswapBytes
);
8313 case GL_UNSIGNED_SHORT_4_4_4_4
:
8314 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8315 newWidth
,newHeight
,newDepth
,
8316 srcImage
,dstImage
,elementSize
,rowSize
,
8317 imageSize
,myswapBytes
);
8319 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8320 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8321 newWidth
,newHeight
,newDepth
,
8322 srcImage
,dstImage
,elementSize
,rowSize
,
8323 imageSize
,myswapBytes
);
8325 case GL_UNSIGNED_SHORT_5_5_5_1
:
8326 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8327 newWidth
,newHeight
,newDepth
,
8328 srcImage
,dstImage
,elementSize
,rowSize
,
8329 imageSize
,myswapBytes
);
8331 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8332 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8333 newWidth
,newHeight
,newDepth
,
8334 srcImage
,dstImage
,elementSize
,rowSize
,
8335 imageSize
,myswapBytes
);
8337 case GL_UNSIGNED_INT_8_8_8_8
:
8338 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8339 newWidth
,newHeight
,newDepth
,
8340 srcImage
,dstImage
,elementSize
,rowSize
,
8341 imageSize
,myswapBytes
);
8343 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8344 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8345 newWidth
,newHeight
,newDepth
,
8346 srcImage
,dstImage
,elementSize
,rowSize
,
8347 imageSize
,myswapBytes
);
8349 case GL_UNSIGNED_INT_10_10_10_2
:
8350 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8351 newWidth
,newHeight
,newDepth
,
8352 srcImage
,dstImage
,elementSize
,rowSize
,
8353 imageSize
,myswapBytes
);
8355 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8356 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8357 newWidth
,newHeight
,newDepth
,
8358 srcImage
,dstImage
,elementSize
,rowSize
,
8359 imageSize
,myswapBytes
);
8366 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8368 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8369 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8370 if (newDepth
> 1) newDepth
/= 2;
8372 /* call tex image with srcImage untouched since it's not padded */
8373 if (baseLevel
<= level
&& level
<= maxLevel
) {
8374 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8375 newDepth
,0, format
, type
, (void *) srcImage
);
8379 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8380 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8381 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8382 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8383 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8384 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8385 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8387 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8388 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8392 } /* gluBuild3DMipmapLevelsCore() */
8395 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8396 GLsizei width
, GLsizei height
, GLsizei depth
,
8397 GLenum format
, GLenum type
,
8398 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8403 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8404 if (rc
!= 0) return rc
;
8406 if (width
< 1 || height
< 1 || depth
< 1) {
8407 return GLU_INVALID_VALUE
;
8410 if(type
== GL_BITMAP
) {
8411 return GLU_INVALID_ENUM
;
8414 levels
= computeLog(width
);
8415 level
= computeLog(height
);
8416 if (level
> levels
) levels
=level
;
8417 level
= computeLog(depth
);
8418 if (level
> levels
) levels
=level
;
8421 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8422 return GLU_INVALID_VALUE
;
8424 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8425 width
, height
, depth
,
8426 width
, height
, depth
,
8428 userLevel
, baseLevel
, maxLevel
,
8430 } /* gluBuild3DMipmapLevels() */
8433 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8434 GLsizei width
, GLsizei height
, GLsizei depth
,
8435 GLenum format
, GLenum type
, const void *data
)
8437 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8440 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8441 if (rc
!= 0) return rc
;
8443 if (width
< 1 || height
< 1 || depth
< 1) {
8444 return GLU_INVALID_VALUE
;
8447 if(type
== GL_BITMAP
) {
8448 return GLU_INVALID_ENUM
;
8451 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8452 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8454 levels
= computeLog(widthPowerOf2
);
8455 level
= computeLog(heightPowerOf2
);
8456 if (level
> levels
) levels
=level
;
8457 level
= computeLog(depthPowerOf2
);
8458 if (level
> levels
) levels
=level
;
8460 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8461 width
, height
, depth
,
8462 widthPowerOf2
, heightPowerOf2
,
8464 format
, type
, 0, 0, levels
,
8466 } /* gluBuild3DMipmaps() */
8468 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8470 isSwap
= isSwap
; /* turn off warnings */
8472 assert(*((const GLubyte
*)ubyte
) <= 255);
8474 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8475 } /* extractUbyte() */
8477 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8479 assert(0.0 <= value
&& value
< 256.0);
8481 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8482 } /* shoveUbyte() */
8484 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8486 isSwap
= isSwap
; /* turn off warnings */
8488 assert(*((const GLbyte
*)sbyte
) <= 127);
8490 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8491 } /* extractSbyte() */
8493 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8495 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8496 } /* shoveSbyte() */
8498 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8503 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8506 ushort
= *(const GLushort
*)uitem
;
8509 assert(ushort
<= 65535);
8511 return (GLdouble
)ushort
;
8512 } /* extractUshort() */
8514 static void shoveUshort(GLdouble value
, int index
, void *data
)
8516 assert(0.0 <= value
&& value
< 65536.0);
8518 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8519 } /* shoveUshort() */
8521 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8526 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8529 sshort
= *(const GLshort
*)sitem
;
8532 assert(sshort
<= 32767);
8534 return (GLdouble
)sshort
;
8535 } /* extractSshort() */
8537 static void shoveSshort(GLdouble value
, int index
, void *data
)
8539 assert(0.0 <= value
&& value
< 32768.0);
8541 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8542 } /* shoveSshort() */
8544 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8549 uint
= __GLU_SWAP_4_BYTES(uitem
);
8552 uint
= *(const GLuint
*)uitem
;
8555 assert(uint
<= 0xffffffff);
8557 return (GLdouble
)uint
;
8558 } /* extractUint() */
8560 static void shoveUint(GLdouble value
, int index
, void *data
)
8562 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8564 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8567 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8572 sint
= __GLU_SWAP_4_BYTES(sitem
);
8575 sint
= *(const GLint
*)sitem
;
8578 assert(sint
<= 0x7fffffff);
8580 return (GLdouble
)sint
;
8581 } /* extractSint() */
8583 static void shoveSint(GLdouble value
, int index
, void *data
)
8585 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8587 ((GLint
*)data
)[index
]= (GLint
)value
;
8590 static GLdouble
extractFloat(int isSwap
, const void *item
)
8595 ffloat
= __GLU_SWAP_4_BYTES(item
);
8598 ffloat
= *(const GLfloat
*)item
;
8601 assert(ffloat
<= 1.0);
8603 return (GLdouble
)ffloat
;
8604 } /* extractFloat() */
8606 static void shoveFloat(GLdouble value
, int index
, void *data
)
8608 assert(0.0 <= value
&& value
<= 1.0);
8610 ((GLfloat
*)data
)[index
]= value
;
8611 } /* shoveFloat() */
8613 static void halveImageSlice(int components
,
8614 GLdouble (*extract
)(int, const void *),
8615 void (*shove
)(GLdouble
, int, void *),
8616 GLint width
, GLint height
, GLint depth
,
8617 const void *dataIn
, void *dataOut
,
8618 GLint elementSizeInBytes
,
8619 GLint groupSizeInBytes
,
8620 GLint rowSizeInBytes
,
8621 GLint imageSizeInBytes
,
8625 int halfWidth
= width
/ 2;
8626 int halfHeight
= height
/ 2;
8627 int halfDepth
= depth
/ 2;
8628 const char *src
= (const char *)dataIn
;
8629 int padBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8632 assert((width
== 1 || height
== 1) && depth
>= 2);
8634 if (width
== height
) { /* a 1-pixel column viewed from top */
8635 /* printf("1-column\n");*/
8636 assert(width
== 1 && height
== 1);
8639 for (ii
= 0; ii
< halfDepth
; ii
++) {
8642 for (cc
= 0; cc
< components
; cc
++) {
8644 double extractTotals
[BOX2
][4];
8647 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8648 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8650 /* average 2 pixels since only a column */
8652 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8653 * totals[RED]/= 2.0;
8655 for (kk
= 0; kk
< BOX2
; kk
++) {
8656 totals
[cc
]+= extractTotals
[kk
][cc
];
8658 totals
[cc
]/= (double)BOX2
;
8660 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8662 src
+= elementSizeInBytes
;
8665 /* skip over to next group of 2 */
8666 src
+= rowSizeInBytes
;
8669 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8670 assert(outIndex
== halfDepth
* components
);
8672 else if (height
== 1) { /* horizontal slice viewed from top */
8673 /* printf("horizontal slice\n"); */
8676 for (ii
= 0; ii
< halfDepth
; ii
++) {
8677 for (jj
= 0; jj
< halfWidth
; jj
++) {
8680 for (cc
= 0; cc
< components
; cc
++) {
8683 double extractTotals
[BOX4
][4];
8685 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8686 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8687 (src
+groupSizeInBytes
));
8688 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8689 (src
+imageSizeInBytes
));
8690 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8691 (src
+imageSizeInBytes
+groupSizeInBytes
));
8693 /* grab 4 pixels to average */
8695 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8696 * extractTotals[2][RED]+extractTotals[3][RED];
8697 * totals[RED]/= 4.0;
8699 for (kk
= 0; kk
< BOX4
; kk
++) {
8700 totals
[cc
]+= extractTotals
[kk
][cc
];
8702 totals
[cc
]/= (double)BOX4
;
8704 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8707 src
+= elementSizeInBytes
;
8710 /* skip over to next horizontal square of 4 */
8711 src
+= groupSizeInBytes
;
8715 src
+= rowSizeInBytes
;
8718 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8719 assert(outIndex
== halfWidth
* halfDepth
* components
);
8721 else if (width
== 1) { /* vertical slice viewed from top */
8722 /* printf("vertical slice\n"); */
8723 assert(height
!= 1);
8725 for (ii
= 0; ii
< halfDepth
; ii
++) {
8726 for (jj
= 0; jj
< halfHeight
; jj
++) {
8729 for (cc
= 0; cc
< components
; cc
++) {
8732 double extractTotals
[BOX4
][4];
8734 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8735 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8736 (src
+rowSizeInBytes
));
8737 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8738 (src
+imageSizeInBytes
));
8739 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8740 (src
+imageSizeInBytes
+rowSizeInBytes
));
8742 /* grab 4 pixels to average */
8744 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8745 * extractTotals[2][RED]+extractTotals[3][RED];
8746 * totals[RED]/= 4.0;
8748 for (kk
= 0; kk
< BOX4
; kk
++) {
8749 totals
[cc
]+= extractTotals
[kk
][cc
];
8751 totals
[cc
]/= (double)BOX4
;
8753 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8756 src
+= elementSizeInBytes
;
8760 /* skip over to next vertical square of 4 */
8761 src
+= rowSizeInBytes
;
8764 src
+= imageSizeInBytes
;
8767 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8768 assert(outIndex
== halfHeight
* halfDepth
* components
);
8771 } /* halveImageSlice() */
8773 static void halveImage3D(int components
,
8774 GLdouble (*extract
)(int, const void *),
8775 void (*shove
)(GLdouble
, int, void *),
8776 GLint width
, GLint height
, GLint depth
,
8777 const void *dataIn
, void *dataOut
,
8778 GLint elementSizeInBytes
,
8779 GLint groupSizeInBytes
,
8780 GLint rowSizeInBytes
,
8781 GLint imageSizeInBytes
,
8786 /* a horizontal/vertical/one-column slice viewed from top */
8787 if (width
== 1 || height
== 1) {
8790 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8791 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8792 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8798 int halfWidth
= width
/ 2;
8799 int halfHeight
= height
/ 2;
8800 int halfDepth
= depth
/ 2;
8801 const char *src
= (const char *) dataIn
;
8802 int padBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8805 for (dd
= 0; dd
< halfDepth
; dd
++) {
8806 for (ii
= 0; ii
< halfHeight
; ii
++) {
8807 for (jj
= 0; jj
< halfWidth
; jj
++) {
8810 for (cc
= 0; cc
< components
; cc
++) {
8813 double totals
[4]; /* 4 is maximum components */
8814 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8816 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8817 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8818 (src
+groupSizeInBytes
));
8819 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8820 (src
+rowSizeInBytes
));
8821 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8822 (src
+rowSizeInBytes
+groupSizeInBytes
));
8824 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8825 (src
+imageSizeInBytes
));
8827 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8828 (src
+groupSizeInBytes
+imageSizeInBytes
));
8829 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8830 (src
+rowSizeInBytes
+imageSizeInBytes
));
8831 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8832 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8836 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8837 * extractTotals[2][RED]+extractTotals[3][RED]+
8838 * extractTotals[4][RED]+extractTotals[5][RED]+
8839 * extractTotals[6][RED]+extractTotals[7][RED];
8840 * totals[RED]/= 8.0;
8842 for (kk
= 0; kk
< BOX8
; kk
++) {
8843 totals
[cc
]+= extractTotals
[kk
][cc
];
8845 totals
[cc
]/= (double)BOX8
;
8847 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8851 src
+= elementSizeInBytes
; /* go to next component */
8854 /* skip over to next square of 4 */
8855 src
+= groupSizeInBytes
;
8857 /* skip past pad bytes, if any, to get to next row */
8860 /* src is at beginning of a row here, but it's the second row of
8861 * the square block of 4 pixels that we just worked on so we
8862 * need to go one more row.
8870 src
+= rowSizeInBytes
;
8873 src
+= imageSizeInBytes
;
8876 /* both pointers must reach one byte after the end */
8877 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8878 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8880 } /* halveImage3D() */