2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
37 #include <limits.h> /* UINT_MAX */
50 /* Pixel storage modes */
53 GLint pack_row_length
;
55 GLint pack_skip_pixels
;
57 GLint pack_swap_bytes
;
58 GLint pack_skip_images
;
59 GLint pack_image_height
;
61 GLint unpack_alignment
;
62 GLint unpack_row_length
;
63 GLint unpack_skip_rows
;
64 GLint unpack_skip_pixels
;
65 GLint unpack_lsb_first
;
66 GLint unpack_swap_bytes
;
67 GLint unpack_skip_images
;
68 GLint unpack_image_height
;
71 static int gluBuild1DMipmapLevelsCore(GLenum
, GLint
,
74 GLenum
, GLenum
, GLint
, GLint
, GLint
,
76 static int gluBuild2DMipmapLevelsCore(GLenum
, GLint
,
79 GLenum
, GLenum
, GLint
, GLint
, GLint
,
81 static int gluBuild3DMipmapLevelsCore(GLenum
, GLint
,
82 GLsizei
, GLsizei
, GLsizei
,
83 GLsizei
, GLsizei
, GLsizei
,
84 GLenum
, GLenum
, GLint
, GLint
, GLint
,
88 * internal function declarations
90 static GLfloat
bytes_per_element(GLenum type
);
91 static GLint
elements_per_group(GLenum format
, GLenum type
);
92 static GLint
is_index(GLenum format
);
93 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
);
94 static void fill_image(const PixelStorageModes
*,
95 GLint width
, GLint height
, GLenum format
,
96 GLenum type
, GLboolean index_format
,
97 const void *userdata
, GLushort
*newimage
);
98 static void empty_image(const PixelStorageModes
*,
99 GLint width
, GLint height
, GLenum format
,
100 GLenum type
, GLboolean index_format
,
101 const GLushort
*oldimage
, void *userdata
);
102 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
103 const GLushort
*datain
,
104 GLint widthout
, GLint heightout
,
107 static void scale_internal_ubyte(GLint components
, GLint widthin
,
108 GLint heightin
, const GLubyte
*datain
,
109 GLint widthout
, GLint heightout
,
110 GLubyte
*dataout
, GLint element_size
,
111 GLint ysize
, GLint group_size
);
112 static void scale_internal_byte(GLint components
, GLint widthin
,
113 GLint heightin
, const GLbyte
*datain
,
114 GLint widthout
, GLint heightout
,
115 GLbyte
*dataout
, GLint element_size
,
116 GLint ysize
, GLint group_size
);
117 static void scale_internal_ushort(GLint components
, GLint widthin
,
118 GLint heightin
, const GLushort
*datain
,
119 GLint widthout
, GLint heightout
,
120 GLushort
*dataout
, GLint element_size
,
121 GLint ysize
, GLint group_size
,
123 static void scale_internal_short(GLint components
, GLint widthin
,
124 GLint heightin
, const GLshort
*datain
,
125 GLint widthout
, GLint heightout
,
126 GLshort
*dataout
, GLint element_size
,
127 GLint ysize
, GLint group_size
,
129 static void scale_internal_uint(GLint components
, GLint widthin
,
130 GLint heightin
, const GLuint
*datain
,
131 GLint widthout
, GLint heightout
,
132 GLuint
*dataout
, GLint element_size
,
133 GLint ysize
, GLint group_size
,
135 static void scale_internal_int(GLint components
, GLint widthin
,
136 GLint heightin
, const GLint
*datain
,
137 GLint widthout
, GLint heightout
,
138 GLint
*dataout
, GLint element_size
,
139 GLint ysize
, GLint group_size
,
141 static void scale_internal_float(GLint components
, GLint widthin
,
142 GLint heightin
, const GLfloat
*datain
,
143 GLint widthout
, GLint heightout
,
144 GLfloat
*dataout
, GLint element_size
,
145 GLint ysize
, GLint group_size
,
148 static int checkMipmapArgs(GLenum
, GLenum
, GLenum
);
149 static GLboolean
legalFormat(GLenum
);
150 static GLboolean
legalType(GLenum
);
151 static GLboolean
isTypePackedPixel(GLenum
);
152 static GLboolean
isLegalFormatForPackedPixelType(GLenum
, GLenum
);
153 static GLboolean
isLegalLevels(GLint
, GLint
, GLint
, GLint
);
154 static void closestFit(GLenum
, GLint
, GLint
, GLint
, GLenum
, GLenum
,
157 /* all extract/shove routines must return double to handle unsigned ints */
158 static GLdouble
extractUbyte(int, const void *);
159 static void shoveUbyte(GLdouble
, int, void *);
160 static GLdouble
extractSbyte(int, const void *);
161 static void shoveSbyte(GLdouble
, int, void *);
162 static GLdouble
extractUshort(int, const void *);
163 static void shoveUshort(GLdouble
, int, void *);
164 static GLdouble
extractSshort(int, const void *);
165 static void shoveSshort(GLdouble
, int, void *);
166 static GLdouble
extractUint(int, const void *);
167 static void shoveUint(GLdouble
, int, void *);
168 static GLdouble
extractSint(int, const void *);
169 static void shoveSint(GLdouble
, int, void *);
170 static GLdouble
extractFloat(int, const void *);
171 static void shoveFloat(GLdouble
, int, void *);
172 static void halveImageSlice(int, GLdouble (*)(int, const void *),
173 void (*)(GLdouble
, int, void *),
175 const void *, void *,
176 GLint
, GLint
, GLint
, GLint
, GLint
);
177 static void halveImage3D(int, GLdouble (*)(int, const void *),
178 void (*)(GLdouble
, int, void *),
180 const void *, void *,
181 GLint
, GLint
, GLint
, GLint
, GLint
);
183 /* packedpixel type scale routines */
184 static void extract332(int,const void *, GLfloat
[]);
185 static void shove332(const GLfloat
[],int ,void *);
186 static void extract233rev(int,const void *, GLfloat
[]);
187 static void shove233rev(const GLfloat
[],int ,void *);
188 static void extract565(int,const void *, GLfloat
[]);
189 static void shove565(const GLfloat
[],int ,void *);
190 static void extract565rev(int,const void *, GLfloat
[]);
191 static void shove565rev(const GLfloat
[],int ,void *);
192 static void extract4444(int,const void *, GLfloat
[]);
193 static void shove4444(const GLfloat
[],int ,void *);
194 static void extract4444rev(int,const void *, GLfloat
[]);
195 static void shove4444rev(const GLfloat
[],int ,void *);
196 static void extract5551(int,const void *, GLfloat
[]);
197 static void shove5551(const GLfloat
[],int ,void *);
198 static void extract1555rev(int,const void *, GLfloat
[]);
199 static void shove1555rev(const GLfloat
[],int ,void *);
200 static void extract8888(int,const void *, GLfloat
[]);
201 static void shove8888(const GLfloat
[],int ,void *);
202 static void extract8888rev(int,const void *, GLfloat
[]);
203 static void shove8888rev(const GLfloat
[],int ,void *);
204 static void extract1010102(int,const void *, GLfloat
[]);
205 static void shove1010102(const GLfloat
[],int ,void *);
206 static void extract2101010rev(int,const void *, GLfloat
[]);
207 static void shove2101010rev(const GLfloat
[],int ,void *);
208 static void scaleInternalPackedPixel(int,
209 void (*)(int, const void *,GLfloat
[]),
210 void (*)(const GLfloat
[],int, void *),
211 GLint
,GLint
, const void *,
212 GLint
,GLint
,void *,GLint
,GLint
,GLint
);
213 static void halveImagePackedPixel(int,
214 void (*)(int, const void *,GLfloat
[]),
215 void (*)(const GLfloat
[],int, void *),
216 GLint
, GLint
, const void *,
217 void *, GLint
, GLint
, GLint
);
218 static void halve1DimagePackedPixel(int,
219 void (*)(int, const void *,GLfloat
[]),
220 void (*)(const GLfloat
[],int, void *),
221 GLint
, GLint
, const void *,
222 void *, GLint
, GLint
, GLint
);
224 static void halve1Dimage_ubyte(GLint
, GLuint
, GLuint
,const GLubyte
*,
225 GLubyte
*, GLint
, GLint
, GLint
);
226 static void halve1Dimage_byte(GLint
, GLuint
, GLuint
,const GLbyte
*, GLbyte
*,
227 GLint
, GLint
, GLint
);
228 static void halve1Dimage_ushort(GLint
, GLuint
, GLuint
, const GLushort
*,
229 GLushort
*, GLint
, GLint
, GLint
, GLint
);
230 static void halve1Dimage_short(GLint
, GLuint
, GLuint
,const GLshort
*, GLshort
*,
231 GLint
, GLint
, GLint
, GLint
);
232 static void halve1Dimage_uint(GLint
, GLuint
, GLuint
, const GLuint
*, GLuint
*,
233 GLint
, GLint
, GLint
, GLint
);
234 static void halve1Dimage_int(GLint
, GLuint
, GLuint
, const GLint
*, GLint
*,
235 GLint
, GLint
, GLint
, GLint
);
236 static void halve1Dimage_float(GLint
, GLuint
, GLuint
, const GLfloat
*, GLfloat
*,
237 GLint
, GLint
, GLint
, GLint
);
239 static GLint
imageSize3D(GLint
, GLint
, GLint
, GLenum
,GLenum
);
240 static void fillImage3D(const PixelStorageModes
*, GLint
, GLint
, GLint
,GLenum
,
241 GLenum
, GLboolean
, const void *, GLushort
*);
242 static void emptyImage3D(const PixelStorageModes
*,
243 GLint
, GLint
, GLint
, GLenum
,
245 const GLushort
*, void *);
246 static void scaleInternal3D(GLint
, GLint
, GLint
, GLint
, const GLushort
*,
247 GLint
, GLint
, GLint
, GLushort
*);
249 static void retrieveStoreModes(PixelStorageModes
*psm
)
251 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
252 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
253 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
254 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
255 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
256 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
258 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
259 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
260 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
261 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
262 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
263 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
266 static void retrieveStoreModes3D(PixelStorageModes
*psm
)
268 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
269 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
270 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
271 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
272 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
273 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
274 glGetIntegerv(GL_UNPACK_SKIP_IMAGES
, &psm
->unpack_skip_images
);
275 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT
, &psm
->unpack_image_height
);
277 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
278 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
279 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
280 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
281 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
282 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
283 glGetIntegerv(GL_PACK_SKIP_IMAGES
, &psm
->pack_skip_images
);
284 glGetIntegerv(GL_PACK_IMAGE_HEIGHT
, &psm
->pack_image_height
);
287 static int computeLog(GLuint value
)
294 if (value
== 0) return -1;
299 if (value
!= 1) return -1;
308 ** Compute the nearest power of 2 number. This algorithm is a little
309 ** strange, but it works quite well.
311 static int nearestPower(GLuint value
)
318 if (value
== 0) return -1;
323 } else if (value
== 3) {
331 #define __GLU_SWAP_2_BYTES(s)\
332 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
334 #define __GLU_SWAP_4_BYTES(s)\
335 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
336 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
337 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
339 static void halveImage(GLint components
, GLuint width
, GLuint height
,
340 const GLushort
*datain
, GLushort
*dataout
)
343 int newwidth
, newheight
;
348 newwidth
= width
/ 2;
349 newheight
= height
/ 2;
350 delta
= width
* components
;
355 for (i
= 0; i
< newheight
; i
++) {
356 for (j
= 0; j
< newwidth
; j
++) {
357 for (k
= 0; k
< components
; k
++) {
358 s
[0] = (t
[0] + t
[components
] + t
[delta
] +
359 t
[delta
+components
] + 2) / 4;
368 static void halveImage_ubyte(GLint components
, GLuint width
, GLuint height
,
369 const GLubyte
*datain
, GLubyte
*dataout
,
370 GLint element_size
, GLint ysize
, GLint group_size
)
373 int newwidth
, newheight
;
378 /* handle case where there is only 1 column/row */
379 if (width
== 1 || height
== 1) {
380 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
381 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
382 element_size
,ysize
,group_size
);
386 newwidth
= width
/ 2;
387 newheight
= height
/ 2;
388 padBytes
= ysize
- (width
*group_size
);
390 t
= (const char *)datain
;
393 for (i
= 0; i
< newheight
; i
++) {
394 for (j
= 0; j
< newwidth
; j
++) {
395 for (k
= 0; k
< components
; k
++) {
396 s
[0] = (*(const GLubyte
*)t
+
397 *(const GLubyte
*)(t
+group_size
) +
398 *(const GLubyte
*)(t
+ysize
) +
399 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
400 s
++; t
+= element_size
;
410 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
411 const GLubyte
*dataIn
, GLubyte
*dataOut
,
412 GLint element_size
, GLint ysize
,
415 GLint halfWidth
= width
/ 2;
416 GLint halfHeight
= height
/ 2;
417 const char *src
= (const char *) dataIn
;
418 GLubyte
*dest
= dataOut
;
421 assert(width
== 1 || height
== 1); /* must be 1D */
422 assert(width
!= height
); /* can't be square */
424 if (height
== 1) { /* 1 row */
425 assert(width
!= 1); /* widthxheight can't be 1x1 */
428 for (jj
= 0; jj
< halfWidth
; jj
++) {
430 for (kk
= 0; kk
< components
; kk
++) {
431 *dest
= (*(const GLubyte
*)src
+
432 *(const GLubyte
*)(src
+group_size
)) / 2;
437 src
+= group_size
; /* skip to next 2 */
440 int padBytes
= ysize
- (width
*group_size
);
441 src
+= padBytes
; /* for assertion only */
444 else if (width
== 1) { /* 1 column */
445 int padBytes
= ysize
- (width
* group_size
);
446 assert(height
!= 1); /* widthxheight can't be 1x1 */
448 /* one vertical column with possible pad bytes per row */
449 /* average two at a time */
451 for (jj
= 0; jj
< halfHeight
; jj
++) {
453 for (kk
= 0; kk
< components
; kk
++) {
454 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
459 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
464 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
465 assert((char *)dest
== &((char *)dataOut
)
466 [components
* element_size
* halfWidth
* halfHeight
]);
467 } /* halve1Dimage_ubyte() */
469 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
470 const GLbyte
*datain
, GLbyte
*dataout
,
472 GLint ysize
, GLint group_size
)
475 int newwidth
, newheight
;
480 /* handle case where there is only 1 column/row */
481 if (width
== 1 || height
== 1) {
482 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
483 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
484 element_size
,ysize
,group_size
);
488 newwidth
= width
/ 2;
489 newheight
= height
/ 2;
490 padBytes
= ysize
- (width
*group_size
);
492 t
= (const char *)datain
;
495 for (i
= 0; i
< newheight
; i
++) {
496 for (j
= 0; j
< newwidth
; j
++) {
497 for (k
= 0; k
< components
; k
++) {
498 s
[0] = (*(const GLbyte
*)t
+
499 *(const GLbyte
*)(t
+group_size
) +
500 *(const GLbyte
*)(t
+ysize
) +
501 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
502 s
++; t
+= element_size
;
511 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
512 const GLbyte
*dataIn
, GLbyte
*dataOut
,
513 GLint element_size
,GLint ysize
, GLint group_size
)
515 GLint halfWidth
= width
/ 2;
516 GLint halfHeight
= height
/ 2;
517 const char *src
= (const char *) dataIn
;
518 GLbyte
*dest
= dataOut
;
521 assert(width
== 1 || height
== 1); /* must be 1D */
522 assert(width
!= height
); /* can't be square */
524 if (height
== 1) { /* 1 row */
525 assert(width
!= 1); /* widthxheight can't be 1x1 */
528 for (jj
= 0; jj
< halfWidth
; jj
++) {
530 for (kk
= 0; kk
< components
; kk
++) {
531 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
536 src
+= group_size
; /* skip to next 2 */
539 int padBytes
= ysize
- (width
*group_size
);
540 src
+= padBytes
; /* for assertion only */
543 else if (width
== 1) { /* 1 column */
544 int padBytes
= ysize
- (width
* group_size
);
545 assert(height
!= 1); /* widthxheight can't be 1x1 */
547 /* one vertical column with possible pad bytes per row */
548 /* average two at a time */
550 for (jj
= 0; jj
< halfHeight
; jj
++) {
552 for (kk
= 0; kk
< components
; kk
++) {
553 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
558 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
562 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
565 assert((char *)dest
== &((char *)dataOut
)
566 [components
* element_size
* halfWidth
* halfHeight
]);
567 } /* halve1Dimage_byte() */
569 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
570 const GLushort
*datain
, GLushort
*dataout
,
571 GLint element_size
, GLint ysize
, GLint group_size
,
575 int newwidth
, newheight
;
580 /* handle case where there is only 1 column/row */
581 if (width
== 1 || height
== 1) {
582 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
583 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
584 element_size
,ysize
,group_size
, myswap_bytes
);
588 newwidth
= width
/ 2;
589 newheight
= height
/ 2;
590 padBytes
= ysize
- (width
*group_size
);
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
;
611 for (i
= 0; i
< newheight
; i
++) {
612 for (j
= 0; j
< newwidth
; j
++) {
613 for (k
= 0; k
< components
; k
++) {
614 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
615 __GLU_SWAP_2_BYTES(t
+group_size
) +
616 __GLU_SWAP_2_BYTES(t
+ysize
) +
617 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
618 s
++; t
+= element_size
;
627 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
628 const GLushort
*dataIn
, GLushort
*dataOut
,
629 GLint element_size
, GLint ysize
,
630 GLint group_size
, GLint myswap_bytes
)
632 GLint halfWidth
= width
/ 2;
633 GLint halfHeight
= height
/ 2;
634 const char *src
= (const char *) dataIn
;
635 GLushort
*dest
= dataOut
;
638 assert(width
== 1 || height
== 1); /* must be 1D */
639 assert(width
!= height
); /* can't be square */
641 if (height
== 1) { /* 1 row */
642 assert(width
!= 1); /* widthxheight can't be 1x1 */
645 for (jj
= 0; jj
< halfWidth
; jj
++) {
647 for (kk
= 0; kk
< components
; kk
++) {
649 GLushort ushort
[BOX2
];
651 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
652 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
655 ushort
[0]= *(const GLushort
*)src
;
656 ushort
[1]= *(const GLushort
*)(src
+group_size
);
659 *dest
= (ushort
[0] + ushort
[1]) / 2;
663 src
+= group_size
; /* skip to next 2 */
666 int padBytes
= ysize
- (width
*group_size
);
667 src
+= padBytes
; /* for assertion only */
670 else if (width
== 1) { /* 1 column */
671 int padBytes
= ysize
- (width
* group_size
);
672 assert(height
!= 1); /* widthxheight can't be 1x1 */
674 /* one vertical column with possible pad bytes per row */
675 /* average two at a time */
677 for (jj
= 0; jj
< halfHeight
; jj
++) {
679 for (kk
= 0; kk
< components
; kk
++) {
681 GLushort ushort
[BOX2
];
683 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
684 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
687 ushort
[0]= *(const GLushort
*)src
;
688 ushort
[1]= *(const GLushort
*)(src
+ysize
);
690 *dest
= (ushort
[0] + ushort
[1]) / 2;
695 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
699 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
702 assert((char *)dest
== &((char *)dataOut
)
703 [components
* element_size
* halfWidth
* halfHeight
]);
705 } /* halve1Dimage_ushort() */
708 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
709 const GLshort
*datain
, GLshort
*dataout
,
710 GLint element_size
, GLint ysize
, GLint group_size
,
714 int newwidth
, newheight
;
719 /* handle case where there is only 1 column/row */
720 if (width
== 1 || height
== 1) {
721 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
722 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
723 element_size
,ysize
,group_size
, myswap_bytes
);
727 newwidth
= width
/ 2;
728 newheight
= height
/ 2;
729 padBytes
= ysize
- (width
*group_size
);
731 t
= (const char *)datain
;
735 for (i
= 0; i
< newheight
; i
++) {
736 for (j
= 0; j
< newwidth
; j
++) {
737 for (k
= 0; k
< components
; k
++) {
738 s
[0] = (*(const GLshort
*)t
+
739 *(const GLshort
*)(t
+group_size
) +
740 *(const GLshort
*)(t
+ysize
) +
741 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
742 s
++; t
+= element_size
;
750 for (i
= 0; i
< newheight
; i
++) {
751 for (j
= 0; j
< newwidth
; j
++) {
752 for (k
= 0; k
< components
; k
++) {
755 b
= __GLU_SWAP_2_BYTES(t
);
756 buf
= *(const GLshort
*)&b
;
757 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
758 buf
+= *(const GLshort
*)&b
;
759 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
760 buf
+= *(const GLshort
*)&b
;
761 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
762 buf
+= *(const GLshort
*)&b
;
763 s
[0] = (GLshort
)((buf
+2)/4);
764 s
++; t
+= element_size
;
773 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
774 const GLshort
*dataIn
, GLshort
*dataOut
,
775 GLint element_size
, GLint ysize
,
776 GLint group_size
, GLint myswap_bytes
)
778 GLint halfWidth
= width
/ 2;
779 GLint halfHeight
= height
/ 2;
780 const char *src
= (const char *) dataIn
;
781 GLshort
*dest
= dataOut
;
784 assert(width
== 1 || height
== 1); /* must be 1D */
785 assert(width
!= height
); /* can't be square */
787 if (height
== 1) { /* 1 row */
788 assert(width
!= 1); /* widthxheight can't be 1x1 */
791 for (jj
= 0; jj
< halfWidth
; jj
++) {
793 for (kk
= 0; kk
< components
; kk
++) {
795 GLshort sshort
[BOX2
];
797 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
798 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
801 sshort
[0]= *(const GLshort
*)src
;
802 sshort
[1]= *(const GLshort
*)(src
+group_size
);
805 *dest
= (sshort
[0] + sshort
[1]) / 2;
809 src
+= group_size
; /* skip to next 2 */
812 int padBytes
= ysize
- (width
*group_size
);
813 src
+= padBytes
; /* for assertion only */
816 else if (width
== 1) { /* 1 column */
817 int padBytes
= ysize
- (width
* group_size
);
818 assert(height
!= 1); /* widthxheight can't be 1x1 */
820 /* one vertical column with possible pad bytes per row */
821 /* average two at a time */
823 for (jj
= 0; jj
< halfHeight
; jj
++) {
825 for (kk
= 0; kk
< components
; kk
++) {
827 GLshort sshort
[BOX2
];
829 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
830 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
833 sshort
[0]= *(const GLshort
*)src
;
834 sshort
[1]= *(const GLshort
*)(src
+ysize
);
836 *dest
= (sshort
[0] + sshort
[1]) / 2;
841 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
845 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
848 assert((char *)dest
== &((char *)dataOut
)
849 [components
* element_size
* halfWidth
* halfHeight
]);
851 } /* halve1Dimage_short() */
854 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
855 const GLuint
*datain
, GLuint
*dataout
,
856 GLint element_size
, GLint ysize
, GLint group_size
,
860 int newwidth
, newheight
;
865 /* handle case where there is only 1 column/row */
866 if (width
== 1 || height
== 1) {
867 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
868 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
869 element_size
,ysize
,group_size
, myswap_bytes
);
873 newwidth
= width
/ 2;
874 newheight
= height
/ 2;
875 padBytes
= ysize
- (width
*group_size
);
877 t
= (const char *)datain
;
881 for (i
= 0; i
< newheight
; i
++) {
882 for (j
= 0; j
< newwidth
; j
++) {
883 for (k
= 0; k
< components
; k
++) {
884 /* need to cast to double to hold large unsigned ints */
885 s
[0] = ((double)*(const GLuint
*)t
+
886 (double)*(const GLuint
*)(t
+group_size
) +
887 (double)*(const GLuint
*)(t
+ysize
) +
888 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
889 s
++; t
+= element_size
;
898 for (i
= 0; i
< newheight
; i
++) {
899 for (j
= 0; j
< newwidth
; j
++) {
900 for (k
= 0; k
< components
; k
++) {
901 /* need to cast to double to hold large unsigned ints */
903 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
904 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
905 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
906 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
907 s
[0] = (GLuint
)(buf
/4 + 0.5);
909 s
++; t
+= element_size
;
919 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
920 const GLuint
*dataIn
, GLuint
*dataOut
,
921 GLint element_size
, GLint ysize
,
922 GLint group_size
, GLint myswap_bytes
)
924 GLint halfWidth
= width
/ 2;
925 GLint halfHeight
= height
/ 2;
926 const char *src
= (const char *) dataIn
;
927 GLuint
*dest
= dataOut
;
930 assert(width
== 1 || height
== 1); /* must be 1D */
931 assert(width
!= height
); /* can't be square */
933 if (height
== 1) { /* 1 row */
934 assert(width
!= 1); /* widthxheight can't be 1x1 */
937 for (jj
= 0; jj
< halfWidth
; jj
++) {
939 for (kk
= 0; kk
< components
; kk
++) {
943 uint
[0]= __GLU_SWAP_4_BYTES(src
);
944 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
947 uint
[0]= *(const GLuint
*)src
;
948 uint
[1]= *(const GLuint
*)(src
+group_size
);
950 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
955 src
+= group_size
; /* skip to next 2 */
958 int padBytes
= ysize
- (width
*group_size
);
959 src
+= padBytes
; /* for assertion only */
962 else if (width
== 1) { /* 1 column */
963 int padBytes
= ysize
- (width
* group_size
);
964 assert(height
!= 1); /* widthxheight can't be 1x1 */
966 /* one vertical column with possible pad bytes per row */
967 /* average two at a time */
969 for (jj
= 0; jj
< halfHeight
; jj
++) {
971 for (kk
= 0; kk
< components
; kk
++) {
975 uint
[0]= __GLU_SWAP_4_BYTES(src
);
976 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
979 uint
[0]= *(const GLuint
*)src
;
980 uint
[1]= *(const GLuint
*)(src
+ysize
);
982 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
987 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
991 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
994 assert((char *)dest
== &((char *)dataOut
)
995 [components
* element_size
* halfWidth
* halfHeight
]);
997 } /* halve1Dimage_uint() */
999 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
1000 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
1001 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
1004 int newwidth
, newheight
;
1009 /* handle case where there is only 1 column/row */
1010 if (width
== 1 || height
== 1) {
1011 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1012 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1013 element_size
,ysize
,group_size
, myswap_bytes
);
1017 newwidth
= width
/ 2;
1018 newheight
= height
/ 2;
1019 padBytes
= ysize
- (width
*group_size
);
1021 t
= (const char *)datain
;
1023 /* Piece o' cake! */
1025 for (i
= 0; i
< newheight
; i
++) {
1026 for (j
= 0; j
< newwidth
; j
++) {
1027 for (k
= 0; k
< components
; k
++) {
1028 s
[0] = ((float)*(const GLint
*)t
+
1029 (float)*(const GLint
*)(t
+group_size
) +
1030 (float)*(const GLint
*)(t
+ysize
) +
1031 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1032 s
++; t
+= element_size
;
1040 for (i
= 0; i
< newheight
; i
++) {
1041 for (j
= 0; j
< newwidth
; j
++) {
1042 for (k
= 0; k
< components
; k
++) {
1045 b
= __GLU_SWAP_4_BYTES(t
);
1047 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1049 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1051 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1053 s
[0] = (GLint
)(buf
/4 + 0.5);
1055 s
++; t
+= element_size
;
1065 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1066 const GLint
*dataIn
, GLint
*dataOut
,
1067 GLint element_size
, GLint ysize
,
1068 GLint group_size
, GLint myswap_bytes
)
1070 GLint halfWidth
= width
/ 2;
1071 GLint halfHeight
= height
/ 2;
1072 const char *src
= (const char *) dataIn
;
1073 GLint
*dest
= dataOut
;
1076 assert(width
== 1 || height
== 1); /* must be 1D */
1077 assert(width
!= height
); /* can't be square */
1079 if (height
== 1) { /* 1 row */
1080 assert(width
!= 1); /* widthxheight can't be 1x1 */
1083 for (jj
= 0; jj
< halfWidth
; jj
++) {
1085 for (kk
= 0; kk
< components
; kk
++) {
1089 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1090 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1093 uint
[0]= *(const GLuint
*)src
;
1094 uint
[1]= *(const GLuint
*)(src
+group_size
);
1096 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1101 src
+= group_size
; /* skip to next 2 */
1104 int padBytes
= ysize
- (width
*group_size
);
1105 src
+= padBytes
; /* for assertion only */
1108 else if (width
== 1) { /* 1 column */
1109 int padBytes
= ysize
- (width
* group_size
);
1110 assert(height
!= 1); /* widthxheight can't be 1x1 */
1112 /* one vertical column with possible pad bytes per row */
1113 /* average two at a time */
1115 for (jj
= 0; jj
< halfHeight
; jj
++) {
1117 for (kk
= 0; kk
< components
; kk
++) {
1121 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1122 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1125 uint
[0]= *(const GLuint
*)src
;
1126 uint
[1]= *(const GLuint
*)(src
+ysize
);
1128 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1133 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1137 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1140 assert((char *)dest
== &((char *)dataOut
)
1141 [components
* element_size
* halfWidth
* halfHeight
]);
1143 } /* halve1Dimage_int() */
1146 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1147 const GLfloat
*datain
, GLfloat
*dataout
,
1148 GLint element_size
, GLint ysize
, GLint group_size
,
1152 int newwidth
, newheight
;
1157 /* handle case where there is only 1 column/row */
1158 if (width
== 1 || height
== 1) {
1159 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1160 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1161 element_size
,ysize
,group_size
, myswap_bytes
);
1165 newwidth
= width
/ 2;
1166 newheight
= height
/ 2;
1167 padBytes
= ysize
- (width
*group_size
);
1169 t
= (const char *)datain
;
1171 /* Piece o' cake! */
1173 for (i
= 0; i
< newheight
; i
++) {
1174 for (j
= 0; j
< newwidth
; j
++) {
1175 for (k
= 0; k
< components
; k
++) {
1176 s
[0] = (*(const GLfloat
*)t
+
1177 *(const GLfloat
*)(t
+group_size
) +
1178 *(const GLfloat
*)(t
+ysize
) +
1179 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1180 s
++; t
+= element_size
;
1188 for (i
= 0; i
< newheight
; i
++) {
1189 for (j
= 0; j
< newwidth
; j
++) {
1190 for (k
= 0; k
< components
; k
++) {
1191 union { GLuint b
; GLfloat f
; } swapbuf
;
1192 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
);
1194 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1196 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1198 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1201 s
++; t
+= element_size
;
1211 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1212 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1213 GLint element_size
, GLint ysize
,
1214 GLint group_size
, GLint myswap_bytes
)
1216 GLint halfWidth
= width
/ 2;
1217 GLint halfHeight
= height
/ 2;
1218 const char *src
= (const char *) dataIn
;
1219 GLfloat
*dest
= dataOut
;
1222 assert(width
== 1 || height
== 1); /* must be 1D */
1223 assert(width
!= height
); /* can't be square */
1225 if (height
== 1) { /* 1 row */
1226 assert(width
!= 1); /* widthxheight can't be 1x1 */
1229 for (jj
= 0; jj
< halfWidth
; jj
++) {
1231 for (kk
= 0; kk
< components
; kk
++) {
1233 GLfloat sfloat
[BOX2
];
1235 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1236 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1239 sfloat
[0]= *(const GLfloat
*)src
;
1240 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1243 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1247 src
+= group_size
; /* skip to next 2 */
1250 int padBytes
= ysize
- (width
*group_size
);
1251 src
+= padBytes
; /* for assertion only */
1254 else if (width
== 1) { /* 1 column */
1255 int padBytes
= ysize
- (width
* group_size
);
1256 assert(height
!= 1); /* widthxheight can't be 1x1 */
1258 /* one vertical column with possible pad bytes per row */
1259 /* average two at a time */
1261 for (jj
= 0; jj
< halfHeight
; jj
++) {
1263 for (kk
= 0; kk
< components
; kk
++) {
1265 GLfloat sfloat
[BOX2
];
1267 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1268 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1271 sfloat
[0]= *(const GLfloat
*)src
;
1272 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1274 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1279 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1280 src
+= ysize
; /* skip to odd row */
1284 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1285 assert((char *)dest
== &((char *)dataOut
)
1286 [components
* element_size
* halfWidth
* halfHeight
]);
1287 } /* halve1Dimage_float() */
1289 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1290 const GLushort
*datain
,
1291 GLint widthout
, GLint heightout
,
1294 float x
, lowx
, highx
, convx
, halfconvx
;
1295 float y
, lowy
, highy
, convy
, halfconvy
;
1296 float xpercent
,ypercent
;
1298 /* Max components in a format is 4, so... */
1301 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1304 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1305 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1308 convy
= (float) heightin
/heightout
;
1309 convx
= (float) widthin
/widthout
;
1310 halfconvx
= convx
/2;
1311 halfconvy
= convy
/2;
1312 for (i
= 0; i
< heightout
; i
++) {
1313 y
= convy
* (i
+0.5);
1314 if (heightin
> heightout
) {
1315 highy
= y
+ halfconvy
;
1316 lowy
= y
- halfconvy
;
1321 for (j
= 0; j
< widthout
; j
++) {
1322 x
= convx
* (j
+0.5);
1323 if (widthin
> widthout
) {
1324 highx
= x
+ halfconvx
;
1325 lowx
= x
- halfconvx
;
1332 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1333 ** to (highx, highy) on input data into this pixel on output
1336 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1342 yindex
= (yint
+ heightin
) % heightin
;
1343 if (highy
< yint
+1) {
1344 ypercent
= highy
- y
;
1346 ypercent
= yint
+1 - y
;
1353 xindex
= (xint
+ widthin
) % widthin
;
1354 if (highx
< xint
+1) {
1355 xpercent
= highx
- x
;
1357 xpercent
= xint
+1 - x
;
1360 percent
= xpercent
* ypercent
;
1362 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1363 for (k
= 0; k
< components
; k
++) {
1364 totals
[k
] += datain
[temp
+ k
] * percent
;
1374 temp
= (j
+ (i
* widthout
)) * components
;
1375 for (k
= 0; k
< components
; k
++) {
1376 /* totals[] should be rounded in the case of enlarging an RGB
1377 * ramp when the type is 332 or 4444
1379 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1385 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1386 GLint heightin
, const GLubyte
*datain
,
1387 GLint widthout
, GLint heightout
,
1388 GLubyte
*dataout
, GLint element_size
,
1389 GLint ysize
, GLint group_size
)
1394 /* Max components in a format is 4, so... */
1399 const char *temp
, *temp0
;
1400 const char *temp_index
;
1403 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1404 float x_percent
, y_percent
;
1405 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1406 float convy_float
, convx_float
;
1407 int convy_int
, convx_int
;
1409 const char *left
, *right
;
1411 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1412 halveImage_ubyte(components
, widthin
, heightin
,
1413 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1414 element_size
, ysize
, group_size
);
1417 convy
= (float) heightin
/heightout
;
1418 convx
= (float) widthin
/widthout
;
1419 convy_int
= floor(convy
);
1420 convy_float
= convy
- convy_int
;
1421 convx_int
= floor(convx
);
1422 convx_float
= convx
- convx_int
;
1424 area
= convx
* convy
;
1428 highy_int
= convy_int
;
1429 highy_float
= convy_float
;
1431 for (i
= 0; i
< heightout
; i
++) {
1432 /* Clamp here to be sure we don't read beyond input buffer. */
1433 if (highy_int
>= heightin
)
1434 highy_int
= heightin
- 1;
1437 highx_int
= convx_int
;
1438 highx_float
= convx_float
;
1440 for (j
= 0; j
< widthout
; j
++) {
1443 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1444 ** to (highx, highy) on input data into this pixel on output
1447 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1449 /* calculate the value for pixels in the 1st row */
1450 xindex
= lowx_int
*group_size
;
1451 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1453 y_percent
= 1-lowy_float
;
1454 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1455 percent
= y_percent
* (1-lowx_float
);
1456 for (k
= 0, temp_index
= temp
; k
< components
;
1457 k
++, temp_index
+= element_size
) {
1458 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1461 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1463 for (k
= 0, temp_index
= temp
; k
< components
;
1464 k
++, temp_index
+= element_size
) {
1465 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1470 percent
= y_percent
* highx_float
;
1471 for (k
= 0, temp_index
= temp
; k
< components
;
1472 k
++, temp_index
+= element_size
) {
1473 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1476 /* calculate the value for pixels in the last row */
1477 y_percent
= highy_float
;
1478 percent
= y_percent
* (1-lowx_float
);
1479 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1480 for (k
= 0, temp_index
= temp
; k
< components
;
1481 k
++, temp_index
+= element_size
) {
1482 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1484 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1486 for (k
= 0, temp_index
= temp
; k
< components
;
1487 k
++, temp_index
+= element_size
) {
1488 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1492 percent
= y_percent
* highx_float
;
1493 for (k
= 0, temp_index
= temp
; k
< components
;
1494 k
++, temp_index
+= element_size
) {
1495 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1499 /* calculate the value for pixels in the 1st and last column */
1500 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1503 for (k
= 0; k
< components
;
1504 k
++, left
+= element_size
, right
+= element_size
) {
1505 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1506 +(GLubyte
)(*(right
))*highx_float
;
1509 } else if (highy_int
> lowy_int
) {
1510 x_percent
= highx_float
- lowx_float
;
1511 percent
= (1-lowy_float
)*x_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(m
= lowy_int
+1; m
< highy_int
; m
++) {
1519 for (k
= 0, temp_index
= temp
; k
< components
;
1520 k
++, temp_index
+= element_size
) {
1521 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1524 percent
= x_percent
* highy_float
;
1526 for (k
= 0, temp_index
= temp
; k
< components
;
1527 k
++, temp_index
+= element_size
) {
1528 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1530 } else if (highx_int
> lowx_int
) {
1531 y_percent
= highy_float
- lowy_float
;
1532 percent
= (1-lowx_float
)*y_percent
;
1533 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1534 for (k
= 0, temp_index
= temp
; k
< components
;
1535 k
++, temp_index
+= element_size
) {
1536 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1538 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1540 for (k
= 0, temp_index
= temp
; k
< components
;
1541 k
++, temp_index
+= element_size
) {
1542 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1546 percent
= y_percent
* highx_float
;
1547 for (k
= 0, temp_index
= temp
; k
< components
;
1548 k
++, temp_index
+= element_size
) {
1549 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1552 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1553 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1554 for (k
= 0, temp_index
= temp
; k
< components
;
1555 k
++, temp_index
+= element_size
) {
1556 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1562 /* this is for the pixels in the body */
1563 temp0
= (const char *)datain
+ xindex
+ group_size
+
1565 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1567 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1568 for (k
= 0, temp_index
= temp
; k
< components
;
1569 k
++, temp_index
+= element_size
) {
1570 totals
[k
] += (GLubyte
)(*(temp_index
));
1577 outindex
= (j
+ (i
* widthout
)) * components
;
1578 for (k
= 0; k
< components
; k
++) {
1579 dataout
[outindex
+ k
] = totals
[k
]/area
;
1580 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1582 lowx_int
= highx_int
;
1583 lowx_float
= highx_float
;
1584 highx_int
+= convx_int
;
1585 highx_float
+= convx_float
;
1586 if(highx_float
> 1) {
1591 lowy_int
= highy_int
;
1592 lowy_float
= highy_float
;
1593 highy_int
+= convy_int
;
1594 highy_float
+= convy_float
;
1595 if(highy_float
> 1) {
1602 static void scale_internal_byte(GLint components
, GLint widthin
,
1603 GLint heightin
, const GLbyte
*datain
,
1604 GLint widthout
, GLint heightout
,
1605 GLbyte
*dataout
, GLint element_size
,
1606 GLint ysize
, GLint group_size
)
1611 /* Max components in a format is 4, so... */
1616 const char *temp
, *temp0
;
1617 const char *temp_index
;
1620 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1621 float x_percent
, y_percent
;
1622 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1623 float convy_float
, convx_float
;
1624 int convy_int
, convx_int
;
1626 const char *left
, *right
;
1628 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1629 halveImage_byte(components
, widthin
, heightin
,
1630 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1631 element_size
, ysize
, group_size
);
1634 convy
= (float) heightin
/heightout
;
1635 convx
= (float) widthin
/widthout
;
1636 convy_int
= floor(convy
);
1637 convy_float
= convy
- convy_int
;
1638 convx_int
= floor(convx
);
1639 convx_float
= convx
- convx_int
;
1641 area
= convx
* convy
;
1645 highy_int
= convy_int
;
1646 highy_float
= convy_float
;
1648 for (i
= 0; i
< heightout
; i
++) {
1649 /* Clamp here to be sure we don't read beyond input buffer. */
1650 if (highy_int
>= heightin
)
1651 highy_int
= heightin
- 1;
1654 highx_int
= convx_int
;
1655 highx_float
= convx_float
;
1657 for (j
= 0; j
< widthout
; j
++) {
1660 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1661 ** to (highx, highy) on input data into this pixel on output
1664 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1666 /* calculate the value for pixels in the 1st row */
1667 xindex
= lowx_int
*group_size
;
1668 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1670 y_percent
= 1-lowy_float
;
1671 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1672 percent
= y_percent
* (1-lowx_float
);
1673 for (k
= 0, temp_index
= temp
; k
< components
;
1674 k
++, temp_index
+= element_size
) {
1675 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1678 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1680 for (k
= 0, temp_index
= temp
; k
< components
;
1681 k
++, temp_index
+= element_size
) {
1682 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1687 percent
= y_percent
* highx_float
;
1688 for (k
= 0, temp_index
= temp
; k
< components
;
1689 k
++, temp_index
+= element_size
) {
1690 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1693 /* calculate the value for pixels in the last row */
1694 y_percent
= highy_float
;
1695 percent
= y_percent
* (1-lowx_float
);
1696 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1697 for (k
= 0, temp_index
= temp
; k
< components
;
1698 k
++, temp_index
+= element_size
) {
1699 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1701 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1703 for (k
= 0, temp_index
= temp
; k
< components
;
1704 k
++, temp_index
+= element_size
) {
1705 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1709 percent
= y_percent
* highx_float
;
1710 for (k
= 0, temp_index
= temp
; k
< components
;
1711 k
++, temp_index
+= element_size
) {
1712 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1716 /* calculate the value for pixels in the 1st and last column */
1717 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1720 for (k
= 0; k
< components
;
1721 k
++, left
+= element_size
, right
+= element_size
) {
1722 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1723 +(GLbyte
)(*(right
))*highx_float
;
1726 } else if (highy_int
> lowy_int
) {
1727 x_percent
= highx_float
- lowx_float
;
1728 percent
= (1-lowy_float
)*x_percent
;
1729 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1730 for (k
= 0, temp_index
= temp
; k
< components
;
1731 k
++, temp_index
+= element_size
) {
1732 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1734 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1736 for (k
= 0, temp_index
= temp
; k
< components
;
1737 k
++, temp_index
+= element_size
) {
1738 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1741 percent
= x_percent
* highy_float
;
1743 for (k
= 0, temp_index
= temp
; k
< components
;
1744 k
++, temp_index
+= element_size
) {
1745 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1747 } else if (highx_int
> lowx_int
) {
1748 y_percent
= highy_float
- lowy_float
;
1749 percent
= (1-lowx_float
)*y_percent
;
1750 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1751 for (k
= 0, temp_index
= temp
; k
< components
;
1752 k
++, temp_index
+= element_size
) {
1753 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1755 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1757 for (k
= 0, temp_index
= temp
; k
< components
;
1758 k
++, temp_index
+= element_size
) {
1759 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1763 percent
= y_percent
* highx_float
;
1764 for (k
= 0, temp_index
= temp
; k
< components
;
1765 k
++, temp_index
+= element_size
) {
1766 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1769 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1770 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1771 for (k
= 0, temp_index
= temp
; k
< components
;
1772 k
++, temp_index
+= element_size
) {
1773 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1779 /* this is for the pixels in the body */
1780 temp0
= (const char *)datain
+ xindex
+ group_size
+
1782 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1784 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1785 for (k
= 0, temp_index
= temp
; k
< components
;
1786 k
++, temp_index
+= element_size
) {
1787 totals
[k
] += (GLbyte
)(*(temp_index
));
1794 outindex
= (j
+ (i
* widthout
)) * components
;
1795 for (k
= 0; k
< components
; k
++) {
1796 dataout
[outindex
+ k
] = totals
[k
]/area
;
1797 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1799 lowx_int
= highx_int
;
1800 lowx_float
= highx_float
;
1801 highx_int
+= convx_int
;
1802 highx_float
+= convx_float
;
1803 if(highx_float
> 1) {
1808 lowy_int
= highy_int
;
1809 lowy_float
= highy_float
;
1810 highy_int
+= convy_int
;
1811 highy_float
+= convy_float
;
1812 if(highy_float
> 1) {
1819 static void scale_internal_ushort(GLint components
, GLint widthin
,
1820 GLint heightin
, const GLushort
*datain
,
1821 GLint widthout
, GLint heightout
,
1822 GLushort
*dataout
, GLint element_size
,
1823 GLint ysize
, GLint group_size
,
1829 /* Max components in a format is 4, so... */
1834 const char *temp
, *temp0
;
1835 const char *temp_index
;
1838 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1839 float x_percent
, y_percent
;
1840 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1841 float convy_float
, convx_float
;
1842 int convy_int
, convx_int
;
1844 const char *left
, *right
;
1846 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1847 halveImage_ushort(components
, widthin
, heightin
,
1848 (const GLushort
*)datain
, (GLushort
*)dataout
,
1849 element_size
, ysize
, group_size
, myswap_bytes
);
1852 convy
= (float) heightin
/heightout
;
1853 convx
= (float) widthin
/widthout
;
1854 convy_int
= floor(convy
);
1855 convy_float
= convy
- convy_int
;
1856 convx_int
= floor(convx
);
1857 convx_float
= convx
- convx_int
;
1859 area
= convx
* convy
;
1863 highy_int
= convy_int
;
1864 highy_float
= convy_float
;
1866 for (i
= 0; i
< heightout
; i
++) {
1867 /* Clamp here to be sure we don't read beyond input buffer. */
1868 if (highy_int
>= heightin
)
1869 highy_int
= heightin
- 1;
1872 highx_int
= convx_int
;
1873 highx_float
= convx_float
;
1875 for (j
= 0; j
< widthout
; j
++) {
1877 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1878 ** to (highx, highy) on input data into this pixel on output
1881 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1883 /* calculate the value for pixels in the 1st row */
1884 xindex
= lowx_int
*group_size
;
1885 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1887 y_percent
= 1-lowy_float
;
1888 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1889 percent
= y_percent
* (1-lowx_float
);
1890 for (k
= 0, temp_index
= temp
; k
< components
;
1891 k
++, temp_index
+= element_size
) {
1893 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1895 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1899 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1901 for (k
= 0, temp_index
= temp
; k
< components
;
1902 k
++, temp_index
+= element_size
) {
1905 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1907 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1913 percent
= y_percent
* highx_float
;
1914 for (k
= 0, temp_index
= temp
; k
< components
;
1915 k
++, temp_index
+= element_size
) {
1917 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1919 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1923 /* calculate the value for pixels in the last row */
1924 y_percent
= highy_float
;
1925 percent
= y_percent
* (1-lowx_float
);
1926 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1927 for (k
= 0, temp_index
= temp
; k
< components
;
1928 k
++, temp_index
+= element_size
) {
1930 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1932 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1935 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1937 for (k
= 0, temp_index
= temp
; k
< components
;
1938 k
++, temp_index
+= element_size
) {
1941 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1943 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1948 percent
= y_percent
* highx_float
;
1949 for (k
= 0, temp_index
= temp
; k
< components
;
1950 k
++, temp_index
+= element_size
) {
1952 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1954 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1958 /* calculate the value for pixels in the 1st and last column */
1959 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1962 for (k
= 0; k
< components
;
1963 k
++, left
+= element_size
, right
+= element_size
) {
1966 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1967 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1969 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1970 + *(const GLushort
*)right
* highx_float
;
1974 } else if (highy_int
> lowy_int
) {
1975 x_percent
= highx_float
- lowx_float
;
1976 percent
= (1-lowy_float
)*x_percent
;
1977 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1978 for (k
= 0, temp_index
= temp
; k
< components
;
1979 k
++, temp_index
+= element_size
) {
1981 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1983 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1986 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1988 for (k
= 0, temp_index
= temp
; k
< components
;
1989 k
++, temp_index
+= element_size
) {
1992 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
1994 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
1998 percent
= x_percent
* highy_float
;
2000 for (k
= 0, temp_index
= temp
; k
< components
;
2001 k
++, temp_index
+= element_size
) {
2003 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2005 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2008 } else if (highx_int
> lowx_int
) {
2009 y_percent
= highy_float
- lowy_float
;
2010 percent
= (1-lowx_float
)*y_percent
;
2011 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2012 for (k
= 0, temp_index
= temp
; k
< components
;
2013 k
++, temp_index
+= element_size
) {
2015 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2017 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2020 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2022 for (k
= 0, temp_index
= temp
; k
< components
;
2023 k
++, temp_index
+= element_size
) {
2026 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2028 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2033 percent
= y_percent
* highx_float
;
2034 for (k
= 0, temp_index
= temp
; k
< components
;
2035 k
++, temp_index
+= element_size
) {
2037 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2039 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2043 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2044 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2045 for (k
= 0, temp_index
= temp
; k
< components
;
2046 k
++, temp_index
+= element_size
) {
2048 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2050 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2055 /* this is for the pixels in the body */
2056 temp0
= (const char *)datain
+ xindex
+ group_size
+
2058 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2060 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2061 for (k
= 0, temp_index
= temp
; k
< components
;
2062 k
++, temp_index
+= element_size
) {
2064 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2066 totals
[k
] += *(const GLushort
*)temp_index
;
2074 outindex
= (j
+ (i
* widthout
)) * components
;
2075 for (k
= 0; k
< components
; k
++) {
2076 dataout
[outindex
+ k
] = totals
[k
]/area
;
2077 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2079 lowx_int
= highx_int
;
2080 lowx_float
= highx_float
;
2081 highx_int
+= convx_int
;
2082 highx_float
+= convx_float
;
2083 if(highx_float
> 1) {
2088 lowy_int
= highy_int
;
2089 lowy_float
= highy_float
;
2090 highy_int
+= convy_int
;
2091 highy_float
+= convy_float
;
2092 if(highy_float
> 1) {
2099 static void scale_internal_short(GLint components
, GLint widthin
,
2100 GLint heightin
, const GLshort
*datain
,
2101 GLint widthout
, GLint heightout
,
2102 GLshort
*dataout
, GLint element_size
,
2103 GLint ysize
, GLint group_size
,
2109 /* Max components in a format is 4, so... */
2114 const char *temp
, *temp0
;
2115 const char *temp_index
;
2118 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2119 float x_percent
, y_percent
;
2120 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2121 float convy_float
, convx_float
;
2122 int convy_int
, convx_int
;
2124 const char *left
, *right
;
2126 GLushort swapbuf
; /* unsigned buffer */
2128 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2129 halveImage_short(components
, widthin
, heightin
,
2130 (const GLshort
*)datain
, (GLshort
*)dataout
,
2131 element_size
, ysize
, group_size
, myswap_bytes
);
2134 convy
= (float) heightin
/heightout
;
2135 convx
= (float) widthin
/widthout
;
2136 convy_int
= floor(convy
);
2137 convy_float
= convy
- convy_int
;
2138 convx_int
= floor(convx
);
2139 convx_float
= convx
- convx_int
;
2141 area
= convx
* convy
;
2145 highy_int
= convy_int
;
2146 highy_float
= convy_float
;
2148 for (i
= 0; i
< heightout
; i
++) {
2149 /* Clamp here to be sure we don't read beyond input buffer. */
2150 if (highy_int
>= heightin
)
2151 highy_int
= heightin
- 1;
2154 highx_int
= convx_int
;
2155 highx_float
= convx_float
;
2157 for (j
= 0; j
< widthout
; j
++) {
2159 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2160 ** to (highx, highy) on input data into this pixel on output
2163 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2165 /* calculate the value for pixels in the 1st row */
2166 xindex
= lowx_int
*group_size
;
2167 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2169 y_percent
= 1-lowy_float
;
2170 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2171 percent
= y_percent
* (1-lowx_float
);
2172 for (k
= 0, temp_index
= temp
; k
< components
;
2173 k
++, temp_index
+= element_size
) {
2175 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2176 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2178 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2182 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2184 for (k
= 0, temp_index
= temp
; k
< components
;
2185 k
++, temp_index
+= element_size
) {
2187 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2188 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2190 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2196 percent
= y_percent
* highx_float
;
2197 for (k
= 0, temp_index
= temp
; k
< components
;
2198 k
++, temp_index
+= element_size
) {
2200 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2201 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2203 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2207 /* calculate the value for pixels in the last row */
2208 y_percent
= highy_float
;
2209 percent
= y_percent
* (1-lowx_float
);
2210 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2211 for (k
= 0, temp_index
= temp
; k
< components
;
2212 k
++, temp_index
+= element_size
) {
2214 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2215 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2217 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2220 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2222 for (k
= 0, temp_index
= temp
; k
< components
;
2223 k
++, temp_index
+= element_size
) {
2225 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2226 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2228 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2233 percent
= y_percent
* highx_float
;
2234 for (k
= 0, temp_index
= temp
; k
< components
;
2235 k
++, temp_index
+= element_size
) {
2237 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2238 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2240 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2244 /* calculate the value for pixels in the 1st and last column */
2245 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2248 for (k
= 0; k
< components
;
2249 k
++, left
+= element_size
, right
+= element_size
) {
2251 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2252 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2253 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2254 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2256 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2257 + *(const GLshort
*)right
* highx_float
;
2261 } else if (highy_int
> lowy_int
) {
2262 x_percent
= highx_float
- lowx_float
;
2263 percent
= (1-lowy_float
)*x_percent
;
2264 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2265 for (k
= 0, temp_index
= temp
; k
< components
;
2266 k
++, temp_index
+= element_size
) {
2268 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2269 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2271 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2274 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2276 for (k
= 0, temp_index
= temp
; k
< components
;
2277 k
++, temp_index
+= element_size
) {
2279 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2280 totals
[k
] += *(const GLshort
*)&swapbuf
* x_percent
;
2282 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2286 percent
= x_percent
* highy_float
;
2288 for (k
= 0, temp_index
= temp
; k
< components
;
2289 k
++, temp_index
+= element_size
) {
2291 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2292 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2294 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2297 } else if (highx_int
> lowx_int
) {
2298 y_percent
= highy_float
- lowy_float
;
2299 percent
= (1-lowx_float
)*y_percent
;
2301 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2302 for (k
= 0, temp_index
= temp
; k
< components
;
2303 k
++, temp_index
+= element_size
) {
2305 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2306 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2308 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2311 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2313 for (k
= 0, temp_index
= temp
; k
< components
;
2314 k
++, temp_index
+= element_size
) {
2316 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2317 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2319 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2324 percent
= y_percent
* highx_float
;
2325 for (k
= 0, temp_index
= temp
; k
< components
;
2326 k
++, temp_index
+= element_size
) {
2328 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2329 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2331 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2335 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2336 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2337 for (k
= 0, temp_index
= temp
; k
< components
;
2338 k
++, temp_index
+= element_size
) {
2340 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2341 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2343 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2348 /* this is for the pixels in the body */
2349 temp0
= (const char *)datain
+ xindex
+ group_size
+
2351 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2353 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2354 for (k
= 0, temp_index
= temp
; k
< components
;
2355 k
++, temp_index
+= element_size
) {
2357 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2358 totals
[k
] += *(const GLshort
*)&swapbuf
;
2360 totals
[k
] += *(const GLshort
*)temp_index
;
2368 outindex
= (j
+ (i
* widthout
)) * components
;
2369 for (k
= 0; k
< components
; k
++) {
2370 dataout
[outindex
+ k
] = totals
[k
]/area
;
2371 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2373 lowx_int
= highx_int
;
2374 lowx_float
= highx_float
;
2375 highx_int
+= convx_int
;
2376 highx_float
+= convx_float
;
2377 if(highx_float
> 1) {
2382 lowy_int
= highy_int
;
2383 lowy_float
= highy_float
;
2384 highy_int
+= convy_int
;
2385 highy_float
+= convy_float
;
2386 if(highy_float
> 1) {
2393 static void scale_internal_uint(GLint components
, GLint widthin
,
2394 GLint heightin
, const GLuint
*datain
,
2395 GLint widthout
, GLint heightout
,
2396 GLuint
*dataout
, GLint element_size
,
2397 GLint ysize
, GLint group_size
,
2403 /* Max components in a format is 4, so... */
2408 const char *temp
, *temp0
;
2409 const char *temp_index
;
2412 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2413 float x_percent
, y_percent
;
2414 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2415 float convy_float
, convx_float
;
2416 int convy_int
, convx_int
;
2418 const char *left
, *right
;
2420 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2421 halveImage_uint(components
, widthin
, heightin
,
2422 (const GLuint
*)datain
, (GLuint
*)dataout
,
2423 element_size
, ysize
, group_size
, myswap_bytes
);
2426 convy
= (float) heightin
/heightout
;
2427 convx
= (float) widthin
/widthout
;
2428 convy_int
= floor(convy
);
2429 convy_float
= convy
- convy_int
;
2430 convx_int
= floor(convx
);
2431 convx_float
= convx
- convx_int
;
2433 area
= convx
* convy
;
2437 highy_int
= convy_int
;
2438 highy_float
= convy_float
;
2440 for (i
= 0; i
< heightout
; i
++) {
2441 /* Clamp here to be sure we don't read beyond input buffer. */
2442 if (highy_int
>= heightin
)
2443 highy_int
= heightin
- 1;
2446 highx_int
= convx_int
;
2447 highx_float
= convx_float
;
2449 for (j
= 0; j
< widthout
; j
++) {
2451 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2452 ** to (highx, highy) on input data into this pixel on output
2455 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2457 /* calculate the value for pixels in the 1st row */
2458 xindex
= lowx_int
*group_size
;
2459 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2461 y_percent
= 1-lowy_float
;
2462 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2463 percent
= y_percent
* (1-lowx_float
);
2464 for (k
= 0, temp_index
= temp
; k
< components
;
2465 k
++, temp_index
+= element_size
) {
2467 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2469 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2473 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2475 for (k
= 0, temp_index
= temp
; k
< components
;
2476 k
++, temp_index
+= element_size
) {
2479 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2481 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2487 percent
= y_percent
* highx_float
;
2488 for (k
= 0, temp_index
= temp
; k
< components
;
2489 k
++, temp_index
+= element_size
) {
2491 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2493 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2497 /* calculate the value for pixels in the last row */
2498 y_percent
= highy_float
;
2499 percent
= y_percent
* (1-lowx_float
);
2500 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2501 for (k
= 0, temp_index
= temp
; k
< components
;
2502 k
++, temp_index
+= element_size
) {
2504 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2506 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2509 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2511 for (k
= 0, temp_index
= temp
; k
< components
;
2512 k
++, temp_index
+= element_size
) {
2515 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2517 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2522 percent
= y_percent
* highx_float
;
2523 for (k
= 0, temp_index
= temp
; k
< components
;
2524 k
++, temp_index
+= element_size
) {
2526 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2528 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2532 /* calculate the value for pixels in the 1st and last column */
2533 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2536 for (k
= 0; k
< components
;
2537 k
++, left
+= element_size
, right
+= element_size
) {
2540 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2541 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2543 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2544 + *(const GLuint
*)right
* highx_float
;
2548 } else if (highy_int
> lowy_int
) {
2549 x_percent
= highx_float
- lowx_float
;
2550 percent
= (1-lowy_float
)*x_percent
;
2551 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2552 for (k
= 0, temp_index
= temp
; k
< components
;
2553 k
++, temp_index
+= element_size
) {
2555 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2557 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2560 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2562 for (k
= 0, temp_index
= temp
; k
< components
;
2563 k
++, temp_index
+= element_size
) {
2566 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2568 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2572 percent
= x_percent
* highy_float
;
2574 for (k
= 0, temp_index
= temp
; k
< components
;
2575 k
++, temp_index
+= element_size
) {
2577 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2579 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2582 } else if (highx_int
> lowx_int
) {
2583 y_percent
= highy_float
- lowy_float
;
2584 percent
= (1-lowx_float
)*y_percent
;
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
;
2595 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2597 for (k
= 0, temp_index
= temp
; k
< components
;
2598 k
++, temp_index
+= element_size
) {
2601 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2603 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2608 percent
= y_percent
* highx_float
;
2609 for (k
= 0, temp_index
= temp
; k
< components
;
2610 k
++, temp_index
+= element_size
) {
2612 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2614 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2618 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2619 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2620 for (k
= 0, temp_index
= temp
; k
< components
;
2621 k
++, temp_index
+= element_size
) {
2623 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2625 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2630 /* this is for the pixels in the body */
2631 temp0
= (const char *)datain
+ xindex
+ group_size
+
2633 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2635 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2636 for (k
= 0, temp_index
= temp
; k
< components
;
2637 k
++, temp_index
+= element_size
) {
2639 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2641 totals
[k
] += *(const GLuint
*)temp_index
;
2649 outindex
= (j
+ (i
* widthout
)) * components
;
2650 for (k
= 0; k
< components
; k
++) {
2651 /* clamp at UINT_MAX */
2652 float value
= totals
[k
]/area
;
2653 if (value
>= (float) UINT_MAX
) { /* need '=' */
2654 dataout
[outindex
+ k
] = UINT_MAX
;
2656 else dataout
[outindex
+ k
] = value
;
2658 lowx_int
= highx_int
;
2659 lowx_float
= highx_float
;
2660 highx_int
+= convx_int
;
2661 highx_float
+= convx_float
;
2662 if(highx_float
> 1) {
2667 lowy_int
= highy_int
;
2668 lowy_float
= highy_float
;
2669 highy_int
+= convy_int
;
2670 highy_float
+= convy_float
;
2671 if(highy_float
> 1) {
2680 static void scale_internal_int(GLint components
, GLint widthin
,
2681 GLint heightin
, const GLint
*datain
,
2682 GLint widthout
, GLint heightout
,
2683 GLint
*dataout
, GLint element_size
,
2684 GLint ysize
, GLint group_size
,
2690 /* Max components in a format is 4, so... */
2695 const char *temp
, *temp0
;
2696 const char *temp_index
;
2699 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2700 float x_percent
, y_percent
;
2701 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2702 float convy_float
, convx_float
;
2703 int convy_int
, convx_int
;
2705 const char *left
, *right
;
2707 GLuint swapbuf
; /* unsigned buffer */
2709 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2710 halveImage_int(components
, widthin
, heightin
,
2711 (const GLint
*)datain
, (GLint
*)dataout
,
2712 element_size
, ysize
, group_size
, myswap_bytes
);
2715 convy
= (float) heightin
/heightout
;
2716 convx
= (float) widthin
/widthout
;
2717 convy_int
= floor(convy
);
2718 convy_float
= convy
- convy_int
;
2719 convx_int
= floor(convx
);
2720 convx_float
= convx
- convx_int
;
2722 area
= convx
* convy
;
2726 highy_int
= convy_int
;
2727 highy_float
= convy_float
;
2729 for (i
= 0; i
< heightout
; i
++) {
2730 /* Clamp here to be sure we don't read beyond input buffer. */
2731 if (highy_int
>= heightin
)
2732 highy_int
= heightin
- 1;
2735 highx_int
= convx_int
;
2736 highx_float
= convx_float
;
2738 for (j
= 0; j
< widthout
; j
++) {
2740 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2741 ** to (highx, highy) on input data into this pixel on output
2744 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2746 /* calculate the value for pixels in the 1st row */
2747 xindex
= lowx_int
*group_size
;
2748 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2750 y_percent
= 1-lowy_float
;
2751 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2752 percent
= y_percent
* (1-lowx_float
);
2753 for (k
= 0, temp_index
= temp
; k
< components
;
2754 k
++, temp_index
+= element_size
) {
2756 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2757 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2759 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2763 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2765 for (k
= 0, temp_index
= temp
; k
< components
;
2766 k
++, temp_index
+= element_size
) {
2768 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2769 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2771 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2777 percent
= y_percent
* highx_float
;
2778 for (k
= 0, temp_index
= temp
; k
< components
;
2779 k
++, temp_index
+= element_size
) {
2781 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2782 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2784 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2788 /* calculate the value for pixels in the last row */
2789 y_percent
= highy_float
;
2790 percent
= y_percent
* (1-lowx_float
);
2791 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2792 for (k
= 0, temp_index
= temp
; k
< components
;
2793 k
++, temp_index
+= element_size
) {
2795 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2796 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2798 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2801 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2803 for (k
= 0, temp_index
= temp
; k
< components
;
2804 k
++, temp_index
+= element_size
) {
2806 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2807 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2809 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2814 percent
= y_percent
* highx_float
;
2815 for (k
= 0, temp_index
= temp
; k
< components
;
2816 k
++, temp_index
+= element_size
) {
2818 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2819 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2821 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2825 /* calculate the value for pixels in the 1st and last column */
2826 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2829 for (k
= 0; k
< components
;
2830 k
++, left
+= element_size
, right
+= element_size
) {
2832 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2833 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2834 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2835 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2837 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2838 + *(const GLint
*)right
* highx_float
;
2842 } else if (highy_int
> lowy_int
) {
2843 x_percent
= highx_float
- lowx_float
;
2844 percent
= (1-lowy_float
)*x_percent
;
2845 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2846 for (k
= 0, temp_index
= temp
; k
< components
;
2847 k
++, temp_index
+= element_size
) {
2849 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2850 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2852 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2855 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2857 for (k
= 0, temp_index
= temp
; k
< components
;
2858 k
++, temp_index
+= element_size
) {
2860 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2861 totals
[k
] += *(const GLint
*)&swapbuf
* x_percent
;
2863 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2867 percent
= x_percent
* highy_float
;
2869 for (k
= 0, temp_index
= temp
; k
< components
;
2870 k
++, temp_index
+= element_size
) {
2872 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2873 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2875 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2878 } else if (highx_int
> lowx_int
) {
2879 y_percent
= highy_float
- lowy_float
;
2880 percent
= (1-lowx_float
)*y_percent
;
2882 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2883 for (k
= 0, temp_index
= temp
; k
< components
;
2884 k
++, temp_index
+= element_size
) {
2886 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2887 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2889 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2892 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2894 for (k
= 0, temp_index
= temp
; k
< components
;
2895 k
++, temp_index
+= element_size
) {
2897 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2898 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2900 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2905 percent
= y_percent
* highx_float
;
2906 for (k
= 0, temp_index
= temp
; k
< components
;
2907 k
++, temp_index
+= element_size
) {
2909 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2910 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2912 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2916 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2917 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2918 for (k
= 0, temp_index
= temp
; k
< components
;
2919 k
++, temp_index
+= element_size
) {
2921 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2922 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2924 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2929 /* this is for the pixels in the body */
2930 temp0
= (const char *)datain
+ xindex
+ group_size
+
2932 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2934 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2935 for (k
= 0, temp_index
= temp
; k
< components
;
2936 k
++, temp_index
+= element_size
) {
2938 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2939 totals
[k
] += *(const GLint
*)&swapbuf
;
2941 totals
[k
] += *(const GLint
*)temp_index
;
2949 outindex
= (j
+ (i
* widthout
)) * components
;
2950 for (k
= 0; k
< components
; k
++) {
2951 dataout
[outindex
+ k
] = totals
[k
]/area
;
2952 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2954 lowx_int
= highx_int
;
2955 lowx_float
= highx_float
;
2956 highx_int
+= convx_int
;
2957 highx_float
+= convx_float
;
2958 if(highx_float
> 1) {
2963 lowy_int
= highy_int
;
2964 lowy_float
= highy_float
;
2965 highy_int
+= convy_int
;
2966 highy_float
+= convy_float
;
2967 if(highy_float
> 1) {
2976 static void scale_internal_float(GLint components
, GLint widthin
,
2977 GLint heightin
, const GLfloat
*datain
,
2978 GLint widthout
, GLint heightout
,
2979 GLfloat
*dataout
, GLint element_size
,
2980 GLint ysize
, GLint group_size
,
2986 /* Max components in a format is 4, so... */
2991 const char *temp
, *temp0
;
2992 const char *temp_index
;
2995 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2996 float x_percent
, y_percent
;
2997 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2998 float convy_float
, convx_float
;
2999 int convy_int
, convx_int
;
3001 const char *left
, *right
;
3003 union { GLuint b
; GLfloat f
; } swapbuf
;
3005 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
3006 halveImage_float(components
, widthin
, heightin
,
3007 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
3008 element_size
, ysize
, group_size
, myswap_bytes
);
3011 convy
= (float) heightin
/heightout
;
3012 convx
= (float) widthin
/widthout
;
3013 convy_int
= floor(convy
);
3014 convy_float
= convy
- convy_int
;
3015 convx_int
= floor(convx
);
3016 convx_float
= convx
- convx_int
;
3018 area
= convx
* convy
;
3022 highy_int
= convy_int
;
3023 highy_float
= convy_float
;
3025 for (i
= 0; i
< heightout
; i
++) {
3026 /* Clamp here to be sure we don't read beyond input buffer. */
3027 if (highy_int
>= heightin
)
3028 highy_int
= heightin
- 1;
3031 highx_int
= convx_int
;
3032 highx_float
= convx_float
;
3034 for (j
= 0; j
< widthout
; j
++) {
3036 ** Ok, now apply box filter to box that goes from (lowx, lowy)
3037 ** to (highx, highy) on input data into this pixel on output
3040 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3042 /* calculate the value for pixels in the 1st row */
3043 xindex
= lowx_int
*group_size
;
3044 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3046 y_percent
= 1-lowy_float
;
3047 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3048 percent
= y_percent
* (1-lowx_float
);
3049 for (k
= 0, temp_index
= temp
; k
< components
;
3050 k
++, temp_index
+= element_size
) {
3052 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3053 totals
[k
] += swapbuf
.f
* percent
;
3055 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3059 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3061 for (k
= 0, temp_index
= temp
; k
< components
;
3062 k
++, temp_index
+= element_size
) {
3064 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3065 totals
[k
] += swapbuf
.f
* y_percent
;
3067 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3073 percent
= y_percent
* highx_float
;
3074 for (k
= 0, temp_index
= temp
; k
< components
;
3075 k
++, temp_index
+= element_size
) {
3077 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3078 totals
[k
] += swapbuf
.f
* percent
;
3080 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3084 /* calculate the value for pixels in the last row */
3085 y_percent
= highy_float
;
3086 percent
= y_percent
* (1-lowx_float
);
3087 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3088 for (k
= 0, temp_index
= temp
; k
< components
;
3089 k
++, temp_index
+= element_size
) {
3091 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3092 totals
[k
] += swapbuf
.f
* percent
;
3094 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3097 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3099 for (k
= 0, temp_index
= temp
; k
< components
;
3100 k
++, temp_index
+= element_size
) {
3102 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3103 totals
[k
] += swapbuf
.f
* y_percent
;
3105 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3110 percent
= y_percent
* highx_float
;
3111 for (k
= 0, temp_index
= temp
; k
< components
;
3112 k
++, temp_index
+= element_size
) {
3114 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3115 totals
[k
] += swapbuf
.f
* percent
;
3117 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3121 /* calculate the value for pixels in the 1st and last column */
3122 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3125 for (k
= 0; k
< components
;
3126 k
++, left
+= element_size
, right
+= element_size
) {
3128 swapbuf
.b
= __GLU_SWAP_4_BYTES(left
);
3129 totals
[k
] += swapbuf
.f
* (1-lowx_float
);
3130 swapbuf
.b
= __GLU_SWAP_4_BYTES(right
);
3131 totals
[k
] += swapbuf
.f
* highx_float
;
3133 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3134 + *(const GLfloat
*)right
* highx_float
;
3138 } else if (highy_int
> lowy_int
) {
3139 x_percent
= highx_float
- lowx_float
;
3140 percent
= (1-lowy_float
)*x_percent
;
3141 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3142 for (k
= 0, temp_index
= temp
; k
< components
;
3143 k
++, temp_index
+= element_size
) {
3145 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3146 totals
[k
] += swapbuf
.f
* percent
;
3148 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3151 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3153 for (k
= 0, temp_index
= temp
; k
< components
;
3154 k
++, temp_index
+= element_size
) {
3156 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3157 totals
[k
] += swapbuf
.f
* x_percent
;
3159 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3163 percent
= x_percent
* highy_float
;
3165 for (k
= 0, temp_index
= temp
; k
< components
;
3166 k
++, temp_index
+= element_size
) {
3168 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3169 totals
[k
] += swapbuf
.f
* percent
;
3171 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3174 } else if (highx_int
> lowx_int
) {
3175 y_percent
= highy_float
- lowy_float
;
3176 percent
= (1-lowx_float
)*y_percent
;
3178 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3179 for (k
= 0, temp_index
= temp
; k
< components
;
3180 k
++, temp_index
+= element_size
) {
3182 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3183 totals
[k
] += swapbuf
.f
* percent
;
3185 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3188 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3190 for (k
= 0, temp_index
= temp
; k
< components
;
3191 k
++, temp_index
+= element_size
) {
3193 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3194 totals
[k
] += swapbuf
.f
* y_percent
;
3196 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3201 percent
= y_percent
* highx_float
;
3202 for (k
= 0, temp_index
= temp
; k
< components
;
3203 k
++, temp_index
+= element_size
) {
3205 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3206 totals
[k
] += swapbuf
.f
* percent
;
3208 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3212 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3213 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3214 for (k
= 0, temp_index
= temp
; k
< components
;
3215 k
++, temp_index
+= element_size
) {
3217 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3218 totals
[k
] += swapbuf
.f
* percent
;
3220 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3225 /* this is for the pixels in the body */
3226 temp0
= (const char *)datain
+ xindex
+ group_size
+
3228 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3230 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3231 for (k
= 0, temp_index
= temp
; k
< components
;
3232 k
++, temp_index
+= element_size
) {
3234 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3235 totals
[k
] += swapbuf
.f
;
3237 totals
[k
] += *(const GLfloat
*)temp_index
;
3245 outindex
= (j
+ (i
* widthout
)) * components
;
3246 for (k
= 0; k
< components
; k
++) {
3247 dataout
[outindex
+ k
] = totals
[k
]/area
;
3248 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3250 lowx_int
= highx_int
;
3251 lowx_float
= highx_float
;
3252 highx_int
+= convx_int
;
3253 highx_float
+= convx_float
;
3254 if(highx_float
> 1) {
3259 lowy_int
= highy_int
;
3260 lowy_float
= highy_float
;
3261 highy_int
+= convy_int
;
3262 highy_float
+= convy_float
;
3263 if(highy_float
> 1) {
3270 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3272 if (!legalFormat(format
) || !legalType(type
)) {
3273 return GLU_INVALID_ENUM
;
3275 if (format
== GL_STENCIL_INDEX
) {
3276 return GLU_INVALID_ENUM
;
3279 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3280 return GLU_INVALID_OPERATION
;
3284 } /* checkMipmapArgs() */
3286 static GLboolean
legalFormat(GLenum format
)
3289 case GL_COLOR_INDEX
:
3290 case GL_STENCIL_INDEX
:
3291 case GL_DEPTH_COMPONENT
:
3299 case GL_LUMINANCE_ALPHA
:
3309 static GLboolean
legalType(GLenum type
)
3314 case GL_UNSIGNED_BYTE
:
3316 case GL_UNSIGNED_SHORT
:
3318 case GL_UNSIGNED_INT
:
3320 case GL_UNSIGNED_BYTE_3_3_2
:
3321 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3322 case GL_UNSIGNED_SHORT_5_6_5
:
3323 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3324 case GL_UNSIGNED_SHORT_4_4_4_4
:
3325 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3326 case GL_UNSIGNED_SHORT_5_5_5_1
:
3327 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3328 case GL_UNSIGNED_INT_8_8_8_8
:
3329 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3330 case GL_UNSIGNED_INT_10_10_10_2
:
3331 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3339 static GLboolean
isTypePackedPixel(GLenum type
)
3341 assert(legalType(type
));
3343 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3344 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3345 type
== GL_UNSIGNED_SHORT_5_6_5
||
3346 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3347 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3348 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3349 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3350 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3351 type
== GL_UNSIGNED_INT_8_8_8_8
||
3352 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3353 type
== GL_UNSIGNED_INT_10_10_10_2
||
3354 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3358 } /* isTypePackedPixel() */
3360 /* Determines if the packed pixel type is compatible with the format */
3361 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3363 /* if not a packed pixel type then return true */
3364 if (!isTypePackedPixel(type
)) {
3368 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3369 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3370 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3371 && format
!= GL_RGB
)
3374 /* 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 &
3375 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3377 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3378 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3379 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3380 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3381 type
== GL_UNSIGNED_INT_8_8_8_8
||
3382 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3383 type
== GL_UNSIGNED_INT_10_10_10_2
||
3384 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3385 (format
!= GL_RGBA
&&
3386 format
!= GL_BGRA
)) {
3391 } /* isLegalFormatForPackedPixelType() */
3393 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3396 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3397 totalLevels
< maxLevel
)
3399 else return GL_TRUE
;
3400 } /* isLegalLevels() */
3402 /* Given user requested texture size, determine if it fits. If it
3403 * doesn't then halve both sides and make the determination again
3404 * until it does fit (for IR only).
3405 * Note that proxy textures are not implemented in RE* even though
3406 * they advertise the texture extension.
3407 * Note that proxy textures are implemented but not according to spec in
3410 static void closestFit(GLenum target
, GLint width
, GLint height
,
3411 GLint internalFormat
, GLenum format
, GLenum type
,
3412 GLint
*newWidth
, GLint
*newHeight
)
3414 /* Use proxy textures if OpenGL version is >= 1.1 */
3415 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3417 GLint widthPowerOf2
= nearestPower(width
);
3418 GLint heightPowerOf2
= nearestPower(height
);
3422 /* compute level 1 width & height, clamping each at 1 */
3423 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3424 widthPowerOf2
>> 1 :
3426 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3427 heightPowerOf2
>> 1 :
3430 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3432 /* does width x height at level 1 & all their mipmaps fit? */
3433 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3434 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3435 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3437 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3439 #if defined(GL_ARB_texture_cube_map)
3440 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3441 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3442 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3443 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3444 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3445 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3446 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3447 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3449 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3451 #endif /* GL_ARB_texture_cube_map */
3453 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3454 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3455 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3456 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3458 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3459 /* does it fit??? */
3460 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3461 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3462 /* An 1x1 texture couldn't fit for some reason, so
3463 * break out. This should never happen. But things
3464 * happen. The disadvantage with this if-statement is
3465 * that we will never be aware of when this happens
3466 * since it will silently branch out.
3468 goto noProxyTextures
;
3470 widthPowerOf2
= widthAtLevelOne
;
3471 heightPowerOf2
= heightAtLevelOne
;
3473 /* else it does fit */
3474 } while (proxyWidth
== 0);
3475 /* loop must terminate! */
3477 /* return the width & height at level 0 that fits */
3478 *newWidth
= widthPowerOf2
;
3479 *newHeight
= heightPowerOf2
;
3480 /*printf("Proxy Textures\n");*/
3481 } /* if gluCheckExtension() */
3482 else { /* no texture extension, so do this instead */
3487 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3488 /* clamp user's texture sizes to maximum sizes, if necessary */
3489 *newWidth
= nearestPower(width
);
3490 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3491 *newHeight
= nearestPower(height
);
3492 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3493 /*printf("NO proxy textures\n");*/
3495 } /* closestFit() */
3498 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3499 GLenum typein
, const void *datain
,
3500 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3504 GLushort
*beforeImage
;
3505 GLushort
*afterImage
;
3506 PixelStorageModes psm
;
3508 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3511 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3512 return GLU_INVALID_VALUE
;
3514 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3515 return GLU_INVALID_ENUM
;
3517 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3518 return GLU_INVALID_OPERATION
;
3520 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3521 return GLU_INVALID_OPERATION
;
3524 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3526 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3527 if (beforeImage
== NULL
|| afterImage
== NULL
) {
3530 return GLU_OUT_OF_MEMORY
;
3533 retrieveStoreModes(&psm
);
3534 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3535 datain
, beforeImage
);
3536 components
= elements_per_group(format
, 0);
3537 scale_internal(components
, widthin
, heightin
, beforeImage
,
3538 widthout
, heightout
, afterImage
);
3539 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3540 is_index(format
), afterImage
, dataout
);
3541 free((GLbyte
*) beforeImage
);
3542 free((GLbyte
*) afterImage
);
3547 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3549 GLsizei widthPowerOf2
,
3550 GLenum format
, GLenum type
,
3551 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3555 GLint level
, levels
;
3557 GLint newImage_width
;
3558 GLushort
*otherImage
;
3559 GLushort
*imageTemp
;
3562 PixelStorageModes psm
;
3564 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3569 newwidth
= widthPowerOf2
;
3570 levels
= computeLog(newwidth
);
3574 retrieveStoreModes(&psm
);
3575 newImage
= (GLushort
*)
3576 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3577 newImage_width
= width
;
3578 if (newImage
== NULL
) {
3579 return GLU_OUT_OF_MEMORY
;
3581 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3583 cmpts
= elements_per_group(format
,type
);
3584 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3585 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3586 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3587 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3589 ** If swap_bytes was set, swapping occurred in fill_image.
3591 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3593 for (level
= userLevel
; level
<= levels
; level
++) {
3594 if (newImage_width
== newwidth
) {
3595 /* Use newImage for this level */
3596 if (baseLevel
<= level
&& level
<= maxLevel
) {
3597 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3598 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3601 if (otherImage
== NULL
) {
3602 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3603 otherImage
= (GLushort
*) malloc(memreq
);
3604 if (otherImage
== NULL
) {
3605 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3606 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3607 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3608 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3609 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3611 return GLU_OUT_OF_MEMORY
;
3614 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3615 newwidth
, 1, otherImage
);
3616 /* Swap newImage and otherImage */
3617 imageTemp
= otherImage
;
3618 otherImage
= newImage
;
3619 newImage
= imageTemp
;
3621 newImage_width
= newwidth
;
3622 if (baseLevel
<= level
&& level
<= maxLevel
) {
3623 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3624 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3627 if (newwidth
> 1) newwidth
/= 2;
3629 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3630 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3631 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3632 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3633 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3635 free((GLbyte
*) newImage
);
3637 free((GLbyte
*) otherImage
);
3643 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3645 GLenum format
, GLenum type
,
3646 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3651 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3652 if (rc
!= 0) return rc
;
3655 return GLU_INVALID_VALUE
;
3658 levels
= computeLog(width
);
3661 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3662 return GLU_INVALID_VALUE
;
3664 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3667 userLevel
, baseLevel
, maxLevel
,
3669 } /* gluBuild1DMipmapLevels() */
3672 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3673 GLenum format
, GLenum type
,
3676 GLint widthPowerOf2
;
3680 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3681 if (rc
!= 0) return rc
;
3684 return GLU_INVALID_VALUE
;
3687 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3688 levels
= computeLog(widthPowerOf2
);
3690 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3693 format
,type
,0,0,levels
,data
);
3696 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3697 GLint width
, GLint height
, GLenum format
,
3698 GLenum type
, const void *data
)
3700 GLint newwidth
, newheight
;
3701 GLint level
, levels
;
3703 GLint newImage_width
;
3704 GLint newImage_height
;
3705 GLushort
*otherImage
;
3706 GLushort
*imageTemp
;
3709 PixelStorageModes psm
;
3711 retrieveStoreModes(&psm
);
3714 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3715 newwidth
= nearestPower(width
);
3716 if (newwidth
> maxsize
) newwidth
= maxsize
;
3717 newheight
= nearestPower(height
);
3718 if (newheight
> maxsize
) newheight
= maxsize
;
3720 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3721 &newwidth
,&newheight
);
3723 levels
= computeLog(newwidth
);
3724 level
= computeLog(newheight
);
3725 if (level
> levels
) levels
=level
;
3728 newImage
= (GLushort
*)
3729 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3730 newImage_width
= width
;
3731 newImage_height
= height
;
3732 if (newImage
== NULL
) {
3733 return GLU_OUT_OF_MEMORY
;
3736 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3739 cmpts
= elements_per_group(format
,type
);
3740 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3741 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3742 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3743 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3745 ** If swap_bytes was set, swapping occurred in fill_image.
3747 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3749 for (level
= 0; level
<= levels
; level
++) {
3750 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3751 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3752 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3755 if (otherImage
== NULL
) {
3757 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3758 otherImage
= (GLushort
*) malloc(memreq
);
3759 if (otherImage
== NULL
) {
3760 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3761 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3762 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3763 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3764 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3766 return GLU_OUT_OF_MEMORY
;
3769 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3770 newwidth
, newheight
, otherImage
);
3771 /* Swap newImage and otherImage */
3772 imageTemp
= otherImage
;
3773 otherImage
= newImage
;
3774 newImage
= imageTemp
;
3776 newImage_width
= newwidth
;
3777 newImage_height
= newheight
;
3778 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3779 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3782 if (newwidth
> 1) newwidth
/= 2;
3783 if (newheight
> 1) newheight
/= 2;
3785 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3786 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3787 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3788 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3789 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3791 free((GLbyte
*) newImage
);
3793 free((GLbyte
*) otherImage
);
3798 /* To make swapping images less error prone */
3799 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3800 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3802 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3803 GLsizei width
, GLsizei height
,
3804 GLsizei widthPowerOf2
,
3805 GLsizei heightPowerOf2
,
3806 GLenum format
, GLenum type
,
3808 GLint baseLevel
,GLint maxLevel
,
3811 GLint newwidth
, newheight
;
3812 GLint level
, levels
;
3813 const void *usersImage
; /* passed from user. Don't touch! */
3814 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3815 __GLU_INIT_SWAP_IMAGE
;
3819 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3820 GLint rowsize
, padding
;
3821 PixelStorageModes psm
;
3823 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3824 assert(width
>= 1 && height
>= 1);
3826 if(type
== GL_BITMAP
) {
3827 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3828 format
, type
, data
);
3831 srcImage
= dstImage
= NULL
;
3833 newwidth
= widthPowerOf2
;
3834 newheight
= heightPowerOf2
;
3835 levels
= computeLog(newwidth
);
3836 level
= computeLog(newheight
);
3837 if (level
> levels
) levels
=level
;
3841 retrieveStoreModes(&psm
);
3842 myswap_bytes
= psm
.unpack_swap_bytes
;
3843 cmpts
= elements_per_group(format
,type
);
3844 if (psm
.unpack_row_length
> 0) {
3845 groups_per_line
= psm
.unpack_row_length
;
3847 groups_per_line
= width
;
3850 element_size
= bytes_per_element(type
);
3851 group_size
= element_size
* cmpts
;
3852 if (element_size
== 1) myswap_bytes
= 0;
3854 rowsize
= groups_per_line
* group_size
;
3855 padding
= (rowsize
% psm
.unpack_alignment
);
3857 rowsize
+= psm
.unpack_alignment
- padding
;
3859 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3860 psm
.unpack_skip_pixels
* group_size
;
3862 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3863 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3864 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3868 /* already power-of-two square */
3869 if (width
== newwidth
&& height
== newheight
) {
3870 /* Use usersImage for level userLevel */
3871 if (baseLevel
<= level
&& level
<= maxLevel
) {
3872 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3873 glTexImage2D(target
, level
, internalFormat
, width
,
3874 height
, 0, format
, type
,
3877 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3878 if(levels
== 0) { /* we're done. clean up and return */
3879 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3880 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3881 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3882 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3883 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3887 int nextWidth
= newwidth
/2;
3888 int nextHeight
= newheight
/2;
3891 if (nextWidth
< 1) nextWidth
= 1;
3892 if (nextHeight
< 1) nextHeight
= 1;
3893 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3897 case GL_UNSIGNED_BYTE
:
3898 dstImage
= (GLubyte
*)malloc(memreq
);
3901 dstImage
= (GLbyte
*)malloc(memreq
);
3903 case GL_UNSIGNED_SHORT
:
3904 dstImage
= (GLushort
*)malloc(memreq
);
3907 dstImage
= (GLshort
*)malloc(memreq
);
3909 case GL_UNSIGNED_INT
:
3910 dstImage
= (GLuint
*)malloc(memreq
);
3913 dstImage
= (GLint
*)malloc(memreq
);
3916 dstImage
= (GLfloat
*)malloc(memreq
);
3918 case GL_UNSIGNED_BYTE_3_3_2
:
3919 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3920 dstImage
= (GLubyte
*)malloc(memreq
);
3922 case GL_UNSIGNED_SHORT_5_6_5
:
3923 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3924 case GL_UNSIGNED_SHORT_4_4_4_4
:
3925 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3926 case GL_UNSIGNED_SHORT_5_5_5_1
:
3927 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3928 dstImage
= (GLushort
*)malloc(memreq
);
3930 case GL_UNSIGNED_INT_8_8_8_8
:
3931 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3932 case GL_UNSIGNED_INT_10_10_10_2
:
3933 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3934 dstImage
= (GLuint
*)malloc(memreq
);
3937 return GLU_INVALID_ENUM
;
3939 if (dstImage
== NULL
) {
3940 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3941 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3942 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3943 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3944 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3945 return GLU_OUT_OF_MEMORY
;
3949 case GL_UNSIGNED_BYTE
:
3950 halveImage_ubyte(cmpts
, width
, height
,
3951 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3952 element_size
, rowsize
, group_size
);
3955 halveImage_byte(cmpts
, width
, height
,
3956 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3957 element_size
, rowsize
, group_size
);
3959 case GL_UNSIGNED_SHORT
:
3960 halveImage_ushort(cmpts
, width
, height
,
3961 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3962 element_size
, rowsize
, group_size
, myswap_bytes
);
3965 halveImage_short(cmpts
, width
, height
,
3966 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3967 element_size
, rowsize
, group_size
, myswap_bytes
);
3969 case GL_UNSIGNED_INT
:
3970 halveImage_uint(cmpts
, width
, height
,
3971 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3972 element_size
, rowsize
, group_size
, myswap_bytes
);
3975 halveImage_int(cmpts
, width
, height
,
3976 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3977 element_size
, rowsize
, group_size
, myswap_bytes
);
3980 halveImage_float(cmpts
, width
, height
,
3981 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3982 element_size
, rowsize
, group_size
, myswap_bytes
);
3984 case GL_UNSIGNED_BYTE_3_3_2
:
3985 assert(format
== GL_RGB
);
3986 halveImagePackedPixel(3,extract332
,shove332
,
3987 width
,height
,usersImage
,dstImage
,
3988 element_size
,rowsize
,myswap_bytes
);
3990 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3991 assert(format
== GL_RGB
);
3992 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3993 width
,height
,usersImage
,dstImage
,
3994 element_size
,rowsize
,myswap_bytes
);
3996 case GL_UNSIGNED_SHORT_5_6_5
:
3997 halveImagePackedPixel(3,extract565
,shove565
,
3998 width
,height
,usersImage
,dstImage
,
3999 element_size
,rowsize
,myswap_bytes
);
4001 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4002 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4003 width
,height
,usersImage
,dstImage
,
4004 element_size
,rowsize
,myswap_bytes
);
4006 case GL_UNSIGNED_SHORT_4_4_4_4
:
4007 halveImagePackedPixel(4,extract4444
,shove4444
,
4008 width
,height
,usersImage
,dstImage
,
4009 element_size
,rowsize
,myswap_bytes
);
4011 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4012 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4013 width
,height
,usersImage
,dstImage
,
4014 element_size
,rowsize
,myswap_bytes
);
4016 case GL_UNSIGNED_SHORT_5_5_5_1
:
4017 halveImagePackedPixel(4,extract5551
,shove5551
,
4018 width
,height
,usersImage
,dstImage
,
4019 element_size
,rowsize
,myswap_bytes
);
4021 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4022 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4023 width
,height
,usersImage
,dstImage
,
4024 element_size
,rowsize
,myswap_bytes
);
4026 case GL_UNSIGNED_INT_8_8_8_8
:
4027 halveImagePackedPixel(4,extract8888
,shove8888
,
4028 width
,height
,usersImage
,dstImage
,
4029 element_size
,rowsize
,myswap_bytes
);
4031 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4032 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4033 width
,height
,usersImage
,dstImage
,
4034 element_size
,rowsize
,myswap_bytes
);
4036 case GL_UNSIGNED_INT_10_10_10_2
:
4037 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4038 width
,height
,usersImage
,dstImage
,
4039 element_size
,rowsize
,myswap_bytes
);
4041 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4042 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4043 width
,height
,usersImage
,dstImage
,
4044 element_size
,rowsize
,myswap_bytes
);
4051 newheight
= height
/2;
4053 if (newwidth
< 1) newwidth
= 1;
4054 if (newheight
< 1) newheight
= 1;
4057 rowsize
= newwidth
* group_size
;
4058 memreq
= image_size(newwidth
, newheight
, format
, type
);
4059 /* Swap srcImage and dstImage */
4060 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4062 case GL_UNSIGNED_BYTE
:
4063 dstImage
= (GLubyte
*)malloc(memreq
);
4066 dstImage
= (GLbyte
*)malloc(memreq
);
4068 case GL_UNSIGNED_SHORT
:
4069 dstImage
= (GLushort
*)malloc(memreq
);
4072 dstImage
= (GLshort
*)malloc(memreq
);
4074 case GL_UNSIGNED_INT
:
4075 dstImage
= (GLuint
*)malloc(memreq
);
4078 dstImage
= (GLint
*)malloc(memreq
);
4081 dstImage
= (GLfloat
*)malloc(memreq
);
4083 case GL_UNSIGNED_BYTE_3_3_2
:
4084 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4085 dstImage
= (GLubyte
*)malloc(memreq
);
4087 case GL_UNSIGNED_SHORT_5_6_5
:
4088 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4089 case GL_UNSIGNED_SHORT_4_4_4_4
:
4090 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4091 case GL_UNSIGNED_SHORT_5_5_5_1
:
4092 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4093 dstImage
= (GLushort
*)malloc(memreq
);
4095 case GL_UNSIGNED_INT_8_8_8_8
:
4096 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4097 case GL_UNSIGNED_INT_10_10_10_2
:
4098 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4099 dstImage
= (GLuint
*)malloc(memreq
);
4102 return GLU_INVALID_ENUM
;
4104 if (dstImage
== NULL
) {
4105 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4106 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4107 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4108 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4109 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4111 return GLU_OUT_OF_MEMORY
;
4113 /* level userLevel+1 is in srcImage; level userLevel already saved */
4114 level
= userLevel
+1;
4115 } else { /* user's image is *not* nice power-of-2 sized square */
4116 memreq
= image_size(newwidth
, newheight
, format
, type
);
4118 case GL_UNSIGNED_BYTE
:
4119 dstImage
= (GLubyte
*)malloc(memreq
);
4122 dstImage
= (GLbyte
*)malloc(memreq
);
4124 case GL_UNSIGNED_SHORT
:
4125 dstImage
= (GLushort
*)malloc(memreq
);
4128 dstImage
= (GLshort
*)malloc(memreq
);
4130 case GL_UNSIGNED_INT
:
4131 dstImage
= (GLuint
*)malloc(memreq
);
4134 dstImage
= (GLint
*)malloc(memreq
);
4137 dstImage
= (GLfloat
*)malloc(memreq
);
4139 case GL_UNSIGNED_BYTE_3_3_2
:
4140 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4141 dstImage
= (GLubyte
*)malloc(memreq
);
4143 case GL_UNSIGNED_SHORT_5_6_5
:
4144 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4145 case GL_UNSIGNED_SHORT_4_4_4_4
:
4146 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4147 case GL_UNSIGNED_SHORT_5_5_5_1
:
4148 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4149 dstImage
= (GLushort
*)malloc(memreq
);
4151 case GL_UNSIGNED_INT_8_8_8_8
:
4152 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4153 case GL_UNSIGNED_INT_10_10_10_2
:
4154 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4155 dstImage
= (GLuint
*)malloc(memreq
);
4158 return GLU_INVALID_ENUM
;
4161 if (dstImage
== NULL
) {
4162 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4163 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4164 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4165 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4166 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4167 return GLU_OUT_OF_MEMORY
;
4171 case GL_UNSIGNED_BYTE
:
4172 scale_internal_ubyte(cmpts
, width
, height
,
4173 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4174 (GLubyte
*)dstImage
, element_size
,
4175 rowsize
, group_size
);
4178 scale_internal_byte(cmpts
, width
, height
,
4179 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4180 (GLbyte
*)dstImage
, element_size
,
4181 rowsize
, group_size
);
4183 case GL_UNSIGNED_SHORT
:
4184 scale_internal_ushort(cmpts
, width
, height
,
4185 (const GLushort
*)usersImage
, newwidth
, newheight
,
4186 (GLushort
*)dstImage
, element_size
,
4187 rowsize
, group_size
, myswap_bytes
);
4190 scale_internal_short(cmpts
, width
, height
,
4191 (const GLshort
*)usersImage
, newwidth
, newheight
,
4192 (GLshort
*)dstImage
, element_size
,
4193 rowsize
, group_size
, myswap_bytes
);
4195 case GL_UNSIGNED_INT
:
4196 scale_internal_uint(cmpts
, width
, height
,
4197 (const GLuint
*)usersImage
, newwidth
, newheight
,
4198 (GLuint
*)dstImage
, element_size
,
4199 rowsize
, group_size
, myswap_bytes
);
4202 scale_internal_int(cmpts
, width
, height
,
4203 (const GLint
*)usersImage
, newwidth
, newheight
,
4204 (GLint
*)dstImage
, element_size
,
4205 rowsize
, group_size
, myswap_bytes
);
4208 scale_internal_float(cmpts
, width
, height
,
4209 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4210 (GLfloat
*)dstImage
, element_size
,
4211 rowsize
, group_size
, myswap_bytes
);
4213 case GL_UNSIGNED_BYTE_3_3_2
:
4214 scaleInternalPackedPixel(3,extract332
,shove332
,
4215 width
, height
,usersImage
,
4216 newwidth
,newheight
,(void *)dstImage
,
4217 element_size
,rowsize
,myswap_bytes
);
4219 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4220 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4221 width
, height
,usersImage
,
4222 newwidth
,newheight
,(void *)dstImage
,
4223 element_size
,rowsize
,myswap_bytes
);
4225 case GL_UNSIGNED_SHORT_5_6_5
:
4226 scaleInternalPackedPixel(3,extract565
,shove565
,
4227 width
, height
,usersImage
,
4228 newwidth
,newheight
,(void *)dstImage
,
4229 element_size
,rowsize
,myswap_bytes
);
4231 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4232 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4233 width
, height
,usersImage
,
4234 newwidth
,newheight
,(void *)dstImage
,
4235 element_size
,rowsize
,myswap_bytes
);
4237 case GL_UNSIGNED_SHORT_4_4_4_4
:
4238 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4239 width
, height
,usersImage
,
4240 newwidth
,newheight
,(void *)dstImage
,
4241 element_size
,rowsize
,myswap_bytes
);
4243 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4244 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4245 width
, height
,usersImage
,
4246 newwidth
,newheight
,(void *)dstImage
,
4247 element_size
,rowsize
,myswap_bytes
);
4249 case GL_UNSIGNED_SHORT_5_5_5_1
:
4250 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4251 width
, height
,usersImage
,
4252 newwidth
,newheight
,(void *)dstImage
,
4253 element_size
,rowsize
,myswap_bytes
);
4255 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4256 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4257 width
, height
,usersImage
,
4258 newwidth
,newheight
,(void *)dstImage
,
4259 element_size
,rowsize
,myswap_bytes
);
4261 case GL_UNSIGNED_INT_8_8_8_8
:
4262 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4263 width
, height
,usersImage
,
4264 newwidth
,newheight
,(void *)dstImage
,
4265 element_size
,rowsize
,myswap_bytes
);
4267 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4268 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4269 width
, height
,usersImage
,
4270 newwidth
,newheight
,(void *)dstImage
,
4271 element_size
,rowsize
,myswap_bytes
);
4273 case GL_UNSIGNED_INT_10_10_10_2
:
4274 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4275 width
, height
,usersImage
,
4276 newwidth
,newheight
,(void *)dstImage
,
4277 element_size
,rowsize
,myswap_bytes
);
4279 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4280 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4281 width
, height
,usersImage
,
4282 newwidth
,newheight
,(void *)dstImage
,
4283 element_size
,rowsize
,myswap_bytes
);
4290 rowsize
= newwidth
* group_size
;
4291 /* Swap dstImage and srcImage */
4292 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4294 if(levels
!= 0) { /* use as little memory as possible */
4296 int nextWidth
= newwidth
/2;
4297 int nextHeight
= newheight
/2;
4298 if (nextWidth
< 1) nextWidth
= 1;
4299 if (nextHeight
< 1) nextHeight
= 1;
4301 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4305 case GL_UNSIGNED_BYTE
:
4306 dstImage
= (GLubyte
*)malloc(memreq
);
4309 dstImage
= (GLbyte
*)malloc(memreq
);
4311 case GL_UNSIGNED_SHORT
:
4312 dstImage
= (GLushort
*)malloc(memreq
);
4315 dstImage
= (GLshort
*)malloc(memreq
);
4317 case GL_UNSIGNED_INT
:
4318 dstImage
= (GLuint
*)malloc(memreq
);
4321 dstImage
= (GLint
*)malloc(memreq
);
4324 dstImage
= (GLfloat
*)malloc(memreq
);
4326 case GL_UNSIGNED_BYTE_3_3_2
:
4327 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4328 dstImage
= (GLubyte
*)malloc(memreq
);
4330 case GL_UNSIGNED_SHORT_5_6_5
:
4331 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4332 case GL_UNSIGNED_SHORT_4_4_4_4
:
4333 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4334 case GL_UNSIGNED_SHORT_5_5_5_1
:
4335 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4336 dstImage
= (GLushort
*)malloc(memreq
);
4338 case GL_UNSIGNED_INT_8_8_8_8
:
4339 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4340 case GL_UNSIGNED_INT_10_10_10_2
:
4341 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4342 dstImage
= (GLuint
*)malloc(memreq
);
4345 return GLU_INVALID_ENUM
;
4347 if (dstImage
== NULL
) {
4348 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4349 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4350 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4351 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4352 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4354 return GLU_OUT_OF_MEMORY
;
4357 /* level userLevel is in srcImage; nothing saved yet */
4361 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4362 if (baseLevel
<= level
&& level
<= maxLevel
) {
4363 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4364 format
, type
, (void *)srcImage
);
4367 level
++; /* update current level for the loop */
4368 for (; level
<= levels
; level
++) {
4370 case GL_UNSIGNED_BYTE
:
4371 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4372 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4373 rowsize
, group_size
);
4376 halveImage_byte(cmpts
, newwidth
, newheight
,
4377 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4378 rowsize
, group_size
);
4380 case GL_UNSIGNED_SHORT
:
4381 halveImage_ushort(cmpts
, newwidth
, newheight
,
4382 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4383 rowsize
, group_size
, myswap_bytes
);
4386 halveImage_short(cmpts
, newwidth
, newheight
,
4387 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4388 rowsize
, group_size
, myswap_bytes
);
4390 case GL_UNSIGNED_INT
:
4391 halveImage_uint(cmpts
, newwidth
, newheight
,
4392 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4393 rowsize
, group_size
, myswap_bytes
);
4396 halveImage_int(cmpts
, newwidth
, newheight
,
4397 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4398 rowsize
, group_size
, myswap_bytes
);
4401 halveImage_float(cmpts
, newwidth
, newheight
,
4402 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4403 rowsize
, group_size
, myswap_bytes
);
4405 case GL_UNSIGNED_BYTE_3_3_2
:
4406 halveImagePackedPixel(3,extract332
,shove332
,
4408 srcImage
,dstImage
,element_size
,rowsize
,
4411 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4412 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4414 srcImage
,dstImage
,element_size
,rowsize
,
4417 case GL_UNSIGNED_SHORT_5_6_5
:
4418 halveImagePackedPixel(3,extract565
,shove565
,
4420 srcImage
,dstImage
,element_size
,rowsize
,
4423 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4424 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4426 srcImage
,dstImage
,element_size
,rowsize
,
4429 case GL_UNSIGNED_SHORT_4_4_4_4
:
4430 halveImagePackedPixel(4,extract4444
,shove4444
,
4432 srcImage
,dstImage
,element_size
,rowsize
,
4435 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4436 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4438 srcImage
,dstImage
,element_size
,rowsize
,
4441 case GL_UNSIGNED_SHORT_5_5_5_1
:
4442 halveImagePackedPixel(4,extract5551
,shove5551
,
4444 srcImage
,dstImage
,element_size
,rowsize
,
4447 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4448 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4450 srcImage
,dstImage
,element_size
,rowsize
,
4453 case GL_UNSIGNED_INT_8_8_8_8
:
4454 halveImagePackedPixel(4,extract8888
,shove8888
,
4456 srcImage
,dstImage
,element_size
,rowsize
,
4459 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4460 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4462 srcImage
,dstImage
,element_size
,rowsize
,
4465 case GL_UNSIGNED_INT_10_10_10_2
:
4466 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4468 srcImage
,dstImage
,element_size
,rowsize
,
4471 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4472 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4474 srcImage
,dstImage
,element_size
,rowsize
,
4482 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4484 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4485 if (newheight
> 1) newheight
/= 2;
4487 /* compute amount to pad per row, if any */
4488 int rowPad
= rowsize
% psm
.unpack_alignment
;
4490 /* should row be padded? */
4491 if (rowPad
== 0) { /* nope, row should not be padded */
4492 /* call tex image with srcImage untouched since it's not padded */
4493 if (baseLevel
<= level
&& level
<= maxLevel
) {
4494 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4495 format
, type
, (void *) srcImage
);
4498 else { /* yes, row should be padded */
4499 /* compute length of new row in bytes, including padding */
4500 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4501 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4503 /* allocate new image for mipmap of size newRowLength x newheight */
4504 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4505 if (newMipmapImage
== NULL
) {
4506 /* out of memory so return */
4507 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4508 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4509 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4510 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4511 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4512 return GLU_OUT_OF_MEMORY
;
4515 /* copy image from srcImage into newMipmapImage by rows */
4517 dstTrav
= (unsigned char *) newMipmapImage
,
4518 srcTrav
= (unsigned char *) srcImage
;
4521 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4522 srcTrav
+= rowsize
) { /* ...is skipped */
4523 memcpy(dstTrav
,srcTrav
,rowsize
);
4524 /* note that the pad bytes are not visited and will contain
4525 * garbage, which is ok.
4529 /* ...and use this new image for mipmapping instead */
4530 if (baseLevel
<= level
&& level
<= maxLevel
) {
4531 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4532 format
, type
, newMipmapImage
);
4534 free(newMipmapImage
); /* don't forget to free it! */
4538 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4539 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4540 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4541 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4542 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4544 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4545 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4549 } /* gluBuild2DMipmapLevelsCore() */
4552 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4553 GLsizei width
, GLsizei height
,
4554 GLenum format
, GLenum type
,
4555 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4560 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4561 if (rc
!= 0) return rc
;
4563 if (width
< 1 || height
< 1) {
4564 return GLU_INVALID_VALUE
;
4567 levels
= computeLog(width
);
4568 level
= computeLog(height
);
4569 if (level
> levels
) levels
=level
;
4572 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4573 return GLU_INVALID_VALUE
;
4575 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4579 userLevel
, baseLevel
, maxLevel
,
4581 } /* gluBuild2DMipmapLevels() */
4584 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4585 GLsizei width
, GLsizei height
,
4586 GLenum format
, GLenum type
,
4589 GLint widthPowerOf2
, heightPowerOf2
;
4592 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4593 if (rc
!= 0) return rc
;
4595 if (width
< 1 || height
< 1) {
4596 return GLU_INVALID_VALUE
;
4599 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4600 &widthPowerOf2
,&heightPowerOf2
);
4602 levels
= computeLog(widthPowerOf2
);
4603 level
= computeLog(heightPowerOf2
);
4604 if (level
> levels
) levels
=level
;
4606 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4608 widthPowerOf2
,heightPowerOf2
,
4611 } /* gluBuild2DMipmaps() */
4615 ** This routine is for the limited case in which
4616 ** type == GL_UNSIGNED_BYTE && format != index &&
4617 ** unpack_alignment = 1 && unpack_swap_bytes == false
4619 ** so all of the work data can be kept as ubytes instead of shorts.
4621 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4622 GLenum target
, GLint components
, GLint width
,
4623 GLint height
, GLenum format
,
4624 GLenum type
, void *data
)
4626 GLint newwidth
, newheight
;
4627 GLint level
, levels
;
4629 GLint newImage_width
;
4630 GLint newImage_height
;
4631 GLubyte
*otherImage
;
4638 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4639 newwidth
= nearestPower(width
);
4640 if (newwidth
> maxsize
) newwidth
= maxsize
;
4641 newheight
= nearestPower(height
);
4642 if (newheight
> maxsize
) newheight
= maxsize
;
4644 closestFit(target
,width
,height
,components
,format
,type
,
4645 &newwidth
,&newheight
);
4647 levels
= computeLog(newwidth
);
4648 level
= computeLog(newheight
);
4649 if (level
> levels
) levels
=level
;
4651 cmpts
= elements_per_group(format
,type
);
4655 ** No need to copy the user data if its in the packed correctly.
4656 ** Make sure that later routines don't change that data.
4658 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4659 newImage
= (GLubyte
*)data
;
4660 newImage_width
= width
;
4661 newImage_height
= height
;
4664 GLint groups_per_line
;
4665 GLint elements_per_line
;
4666 const GLubyte
*start
;
4667 const GLubyte
*iter
;
4671 newImage
= (GLubyte
*)
4672 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4673 newImage_width
= width
;
4674 newImage_height
= height
;
4675 if (newImage
== NULL
) {
4676 return GLU_OUT_OF_MEMORY
;
4680 ** Abbreviated version of fill_image for this restricted case.
4682 if (psm
->unpack_row_length
> 0) {
4683 groups_per_line
= psm
->unpack_row_length
;
4685 groups_per_line
= width
;
4687 rowsize
= groups_per_line
* cmpts
;
4688 elements_per_line
= width
* cmpts
;
4689 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4690 psm
->unpack_skip_pixels
* cmpts
;
4693 for (i
= 0; i
< height
; i
++) {
4695 for (j
= 0; j
< elements_per_line
; j
++) {
4705 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4706 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4707 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4708 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4709 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4711 for (level
= 0; level
<= levels
; level
++) {
4712 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4713 /* Use newImage for this level */
4714 glTexImage2D(target
, level
, components
, newImage_width
,
4715 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4718 if (otherImage
== NULL
) {
4720 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4721 otherImage
= (GLubyte
*) malloc(memreq
);
4722 if (otherImage
== NULL
) {
4723 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4724 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4725 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4726 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4727 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4728 return GLU_OUT_OF_MEMORY
;
4732 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4733 newImage, newwidth, newheight, otherImage);
4735 /* Swap newImage and otherImage */
4736 imageTemp
= otherImage
;
4737 otherImage
= newImage
;
4738 newImage
= imageTemp
;
4740 newImage_width
= newwidth
;
4741 newImage_height
= newheight
;
4742 glTexImage2D(target
, level
, components
, newImage_width
,
4743 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4746 if (newwidth
> 1) newwidth
/= 2;
4747 if (newheight
> 1) newheight
/= 2;
4749 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4750 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4751 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4752 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4753 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4755 if (newImage
!= (const GLubyte
*)data
) {
4756 free((GLbyte
*) newImage
);
4758 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4759 free((GLbyte
*) otherImage
);
4768 static GLint
elements_per_group(GLenum format
, GLenum type
)
4771 * Return the number of elements per group of a specified format
4774 /* If the type is packedpixels then answer is 1 (ignore format) */
4775 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4776 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4777 type
== GL_UNSIGNED_SHORT_5_6_5
||
4778 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4779 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4780 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4781 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4782 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4783 type
== GL_UNSIGNED_INT_8_8_8_8
||
4784 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4785 type
== GL_UNSIGNED_INT_10_10_10_2
||
4786 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4790 /* Types are not packed pixels, so get elements per group */
4795 case GL_LUMINANCE_ALPHA
:
4805 static GLfloat
bytes_per_element(GLenum type
)
4808 * Return the number of bytes per element, based on the element type
4813 case GL_UNSIGNED_SHORT
:
4814 return(sizeof(GLushort
));
4816 return(sizeof(GLshort
));
4817 case GL_UNSIGNED_BYTE
:
4818 return(sizeof(GLubyte
));
4820 return(sizeof(GLbyte
));
4822 return(sizeof(GLint
));
4823 case GL_UNSIGNED_INT
:
4824 return(sizeof(GLuint
));
4826 return(sizeof(GLfloat
));
4827 case GL_UNSIGNED_BYTE_3_3_2
:
4828 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4829 return(sizeof(GLubyte
));
4830 case GL_UNSIGNED_SHORT_5_6_5
:
4831 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4832 case GL_UNSIGNED_SHORT_4_4_4_4
:
4833 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4834 case GL_UNSIGNED_SHORT_5_5_5_1
:
4835 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4836 return(sizeof(GLushort
));
4837 case GL_UNSIGNED_INT_8_8_8_8
:
4838 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4839 case GL_UNSIGNED_INT_10_10_10_2
:
4840 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4841 return(sizeof(GLuint
));
4847 static GLint
is_index(GLenum format
)
4849 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4853 ** Compute memory required for internal packed array of data of given type
4856 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4863 components
= elements_per_group(format
,type
);
4864 if (type
== GL_BITMAP
) {
4865 bytes_per_row
= (width
+ 7) / 8;
4867 bytes_per_row
= bytes_per_element(type
) * width
;
4869 return bytes_per_row
* height
* components
;
4873 ** Extract array from user's data applying all pixel store modes.
4874 ** The internal format used is an array of unsigned shorts.
4876 static void fill_image(const PixelStorageModes
*psm
,
4877 GLint width
, GLint height
, GLenum format
,
4878 GLenum type
, GLboolean index_format
,
4879 const void *userdata
, GLushort
*newimage
)
4885 GLint groups_per_line
;
4887 GLint elements_per_line
;
4888 const GLubyte
*start
;
4889 const GLubyte
*iter
;
4894 myswap_bytes
= psm
->unpack_swap_bytes
;
4895 components
= elements_per_group(format
,type
);
4896 if (psm
->unpack_row_length
> 0) {
4897 groups_per_line
= psm
->unpack_row_length
;
4899 groups_per_line
= width
;
4902 /* All formats except GL_BITMAP fall out trivially */
4903 if (type
== GL_BITMAP
) {
4907 rowsize
= (groups_per_line
* components
+ 7) / 8;
4908 padding
= (rowsize
% psm
->unpack_alignment
);
4910 rowsize
+= psm
->unpack_alignment
- padding
;
4912 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4913 (psm
->unpack_skip_pixels
* components
/ 8);
4914 elements_per_line
= width
* components
;
4916 for (i
= 0; i
< height
; i
++) {
4918 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4919 for (j
= 0; j
< elements_per_line
; j
++) {
4921 if (psm
->unpack_lsb_first
) {
4922 current_bit
= iter
[0] & (1 << bit_offset
);
4924 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4936 if (bit_offset
== 8) {
4945 element_size
= bytes_per_element(type
);
4946 group_size
= element_size
* components
;
4947 if (element_size
== 1) myswap_bytes
= 0;
4949 rowsize
= groups_per_line
* group_size
;
4950 padding
= (rowsize
% psm
->unpack_alignment
);
4952 rowsize
+= psm
->unpack_alignment
- padding
;
4954 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4955 psm
->unpack_skip_pixels
* group_size
;
4956 elements_per_line
= width
* components
;
4959 for (i
= 0; i
< height
; i
++) {
4961 for (j
= 0; j
< elements_per_line
; j
++) {
4963 float extractComponents
[4];
4966 case GL_UNSIGNED_BYTE_3_3_2
:
4967 extract332(0,iter
,extractComponents
);
4968 for (k
= 0; k
< 3; k
++) {
4969 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4972 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4973 extract233rev(0,iter
,extractComponents
);
4974 for (k
= 0; k
< 3; k
++) {
4975 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4978 case GL_UNSIGNED_BYTE
:
4982 *iter2
++ = (*iter
) * 257;
4987 *iter2
++ = *((const GLbyte
*) iter
);
4990 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4993 case GL_UNSIGNED_SHORT_5_6_5
:
4994 extract565(myswap_bytes
,iter
,extractComponents
);
4995 for (k
= 0; k
< 3; k
++) {
4996 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4999 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5000 extract565rev(myswap_bytes
,iter
,extractComponents
);
5001 for (k
= 0; k
< 3; k
++) {
5002 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5005 case GL_UNSIGNED_SHORT_4_4_4_4
:
5006 extract4444(myswap_bytes
,iter
,extractComponents
);
5007 for (k
= 0; k
< 4; k
++) {
5008 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5011 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5012 extract4444rev(myswap_bytes
,iter
,extractComponents
);
5013 for (k
= 0; k
< 4; k
++) {
5014 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5017 case GL_UNSIGNED_SHORT_5_5_5_1
:
5018 extract5551(myswap_bytes
,iter
,extractComponents
);
5019 for (k
= 0; k
< 4; k
++) {
5020 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5023 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5024 extract1555rev(myswap_bytes
,iter
,extractComponents
);
5025 for (k
= 0; k
< 4; k
++) {
5026 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5029 case GL_UNSIGNED_SHORT
:
5032 widget
.ub
[0] = iter
[1];
5033 widget
.ub
[1] = iter
[0];
5035 widget
.ub
[0] = iter
[0];
5036 widget
.ub
[1] = iter
[1];
5038 if (type
== GL_SHORT
) {
5040 *iter2
++ = widget
.s
[0];
5043 *iter2
++ = widget
.s
[0]*2;
5046 *iter2
++ = widget
.us
[0];
5049 case GL_UNSIGNED_INT_8_8_8_8
:
5050 extract8888(myswap_bytes
,iter
,extractComponents
);
5051 for (k
= 0; k
< 4; k
++) {
5052 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5055 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5056 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5057 for (k
= 0; k
< 4; k
++) {
5058 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5061 case GL_UNSIGNED_INT_10_10_10_2
:
5062 extract1010102(myswap_bytes
,iter
,extractComponents
);
5063 for (k
= 0; k
< 4; k
++) {
5064 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5067 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5068 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5069 for (k
= 0; k
< 4; k
++) {
5070 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5074 case GL_UNSIGNED_INT
:
5077 widget
.ub
[0] = iter
[3];
5078 widget
.ub
[1] = iter
[2];
5079 widget
.ub
[2] = iter
[1];
5080 widget
.ub
[3] = iter
[0];
5082 widget
.ub
[0] = iter
[0];
5083 widget
.ub
[1] = iter
[1];
5084 widget
.ub
[2] = iter
[2];
5085 widget
.ub
[3] = iter
[3];
5087 if (type
== GL_FLOAT
) {
5089 *iter2
++ = widget
.f
;
5091 *iter2
++ = 65535 * widget
.f
;
5093 } else if (type
== GL_UNSIGNED_INT
) {
5095 *iter2
++ = widget
.ui
;
5097 *iter2
++ = widget
.ui
>> 16;
5101 *iter2
++ = widget
.i
;
5103 *iter2
++ = widget
.i
>> 15;
5108 iter
+= element_size
;
5112 /* want 'iter' pointing at start, not within, row for assertion
5119 /* iterators should be one byte past end */
5120 if (!isTypePackedPixel(type
)) {
5121 assert(iter2
== &newimage
[width
*height
*components
]);
5124 assert(iter2
== &newimage
[width
*height
*
5125 elements_per_group(format
,0)]);
5127 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5128 psm
->unpack_skip_rows
* rowsize
+
5129 psm
->unpack_skip_pixels
* group_size
] );
5132 } /* fill_image() */
5135 ** Insert array into user's data applying all pixel store modes.
5136 ** The internal format is an array of unsigned shorts.
5137 ** empty_image() because it is the opposite of fill_image().
5139 static void empty_image(const PixelStorageModes
*psm
,
5140 GLint width
, GLint height
, GLenum format
,
5141 GLenum type
, GLboolean index_format
,
5142 const GLushort
*oldimage
, void *userdata
)
5148 GLint groups_per_line
;
5150 GLint elements_per_line
;
5153 const GLushort
*iter2
;
5157 myswap_bytes
= psm
->pack_swap_bytes
;
5158 components
= elements_per_group(format
,type
);
5159 if (psm
->pack_row_length
> 0) {
5160 groups_per_line
= psm
->pack_row_length
;
5162 groups_per_line
= width
;
5165 /* All formats except GL_BITMAP fall out trivially */
5166 if (type
== GL_BITMAP
) {
5170 rowsize
= (groups_per_line
* components
+ 7) / 8;
5171 padding
= (rowsize
% psm
->pack_alignment
);
5173 rowsize
+= psm
->pack_alignment
- padding
;
5175 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5176 (psm
->pack_skip_pixels
* components
/ 8);
5177 elements_per_line
= width
* components
;
5179 for (i
= 0; i
< height
; i
++) {
5181 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5182 for (j
= 0; j
< elements_per_line
; j
++) {
5184 current_bit
= iter2
[0] & 1;
5186 if (iter2
[0] > 32767) {
5194 if (psm
->pack_lsb_first
) {
5195 *iter
|= (1 << bit_offset
);
5197 *iter
|= (1 << (7 - bit_offset
));
5200 if (psm
->pack_lsb_first
) {
5201 *iter
&= ~(1 << bit_offset
);
5203 *iter
&= ~(1 << (7 - bit_offset
));
5208 if (bit_offset
== 8) {
5217 float shoveComponents
[4];
5219 element_size
= bytes_per_element(type
);
5220 group_size
= element_size
* components
;
5221 if (element_size
== 1) myswap_bytes
= 0;
5223 rowsize
= groups_per_line
* group_size
;
5224 padding
= (rowsize
% psm
->pack_alignment
);
5226 rowsize
+= psm
->pack_alignment
- padding
;
5228 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5229 psm
->pack_skip_pixels
* group_size
;
5230 elements_per_line
= width
* components
;
5233 for (i
= 0; i
< height
; i
++) {
5235 for (j
= 0; j
< elements_per_line
; j
++) {
5239 case GL_UNSIGNED_BYTE_3_3_2
:
5240 for (k
= 0; k
< 3; k
++) {
5241 shoveComponents
[k
]= *iter2
++ / 65535.0;
5243 shove332(shoveComponents
,0,(void *)iter
);
5245 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5246 for (k
= 0; k
< 3; k
++) {
5247 shoveComponents
[k
]= *iter2
++ / 65535.0;
5249 shove233rev(shoveComponents
,0,(void *)iter
);
5251 case GL_UNSIGNED_BYTE
:
5255 *iter
= *iter2
++ >> 8;
5260 *((GLbyte
*) iter
) = *iter2
++;
5262 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5265 case GL_UNSIGNED_SHORT_5_6_5
:
5266 for (k
= 0; k
< 3; k
++) {
5267 shoveComponents
[k
]= *iter2
++ / 65535.0;
5269 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5271 iter
[0] = widget
.ub
[1];
5272 iter
[1] = widget
.ub
[0];
5275 *(GLushort
*)iter
= widget
.us
[0];
5278 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5279 for (k
= 0; k
< 3; k
++) {
5280 shoveComponents
[k
]= *iter2
++ / 65535.0;
5282 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5284 iter
[0] = widget
.ub
[1];
5285 iter
[1] = widget
.ub
[0];
5288 *(GLushort
*)iter
= widget
.us
[0];
5291 case GL_UNSIGNED_SHORT_4_4_4_4
:
5292 for (k
= 0; k
< 4; k
++) {
5293 shoveComponents
[k
]= *iter2
++ / 65535.0;
5295 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5297 iter
[0] = widget
.ub
[1];
5298 iter
[1] = widget
.ub
[0];
5300 *(GLushort
*)iter
= widget
.us
[0];
5303 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5304 for (k
= 0; k
< 4; k
++) {
5305 shoveComponents
[k
]= *iter2
++ / 65535.0;
5307 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5309 iter
[0] = widget
.ub
[1];
5310 iter
[1] = widget
.ub
[0];
5312 *(GLushort
*)iter
= widget
.us
[0];
5315 case GL_UNSIGNED_SHORT_5_5_5_1
:
5316 for (k
= 0; k
< 4; k
++) {
5317 shoveComponents
[k
]= *iter2
++ / 65535.0;
5319 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5321 iter
[0] = widget
.ub
[1];
5322 iter
[1] = widget
.ub
[0];
5324 *(GLushort
*)iter
= widget
.us
[0];
5327 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5328 for (k
= 0; k
< 4; k
++) {
5329 shoveComponents
[k
]= *iter2
++ / 65535.0;
5331 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5333 iter
[0] = widget
.ub
[1];
5334 iter
[1] = widget
.ub
[0];
5336 *(GLushort
*)iter
= widget
.us
[0];
5339 case GL_UNSIGNED_SHORT
:
5341 if (type
== GL_SHORT
) {
5343 widget
.s
[0] = *iter2
++;
5345 widget
.s
[0] = *iter2
++ >> 1;
5348 widget
.us
[0] = *iter2
++;
5351 iter
[0] = widget
.ub
[1];
5352 iter
[1] = widget
.ub
[0];
5354 iter
[0] = widget
.ub
[0];
5355 iter
[1] = widget
.ub
[1];
5358 case GL_UNSIGNED_INT_8_8_8_8
:
5359 for (k
= 0; k
< 4; k
++) {
5360 shoveComponents
[k
]= *iter2
++ / 65535.0;
5362 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5364 iter
[3] = widget
.ub
[0];
5365 iter
[2] = widget
.ub
[1];
5366 iter
[1] = widget
.ub
[2];
5367 iter
[0] = widget
.ub
[3];
5369 *(GLuint
*)iter
= widget
.ui
;
5373 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5374 for (k
= 0; k
< 4; k
++) {
5375 shoveComponents
[k
]= *iter2
++ / 65535.0;
5377 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5379 iter
[3] = widget
.ub
[0];
5380 iter
[2] = widget
.ub
[1];
5381 iter
[1] = widget
.ub
[2];
5382 iter
[0] = widget
.ub
[3];
5384 *(GLuint
*)iter
= widget
.ui
;
5387 case GL_UNSIGNED_INT_10_10_10_2
:
5388 for (k
= 0; k
< 4; k
++) {
5389 shoveComponents
[k
]= *iter2
++ / 65535.0;
5391 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5393 iter
[3] = widget
.ub
[0];
5394 iter
[2] = widget
.ub
[1];
5395 iter
[1] = widget
.ub
[2];
5396 iter
[0] = widget
.ub
[3];
5398 *(GLuint
*)iter
= widget
.ui
;
5401 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5402 for (k
= 0; k
< 4; k
++) {
5403 shoveComponents
[k
]= *iter2
++ / 65535.0;
5405 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
5407 iter
[3] = widget
.ub
[0];
5408 iter
[2] = widget
.ub
[1];
5409 iter
[1] = widget
.ub
[2];
5410 iter
[0] = widget
.ub
[3];
5412 *(GLuint
*)iter
= widget
.ui
;
5416 case GL_UNSIGNED_INT
:
5418 if (type
== GL_FLOAT
) {
5420 widget
.f
= *iter2
++;
5422 widget
.f
= *iter2
++ / (float) 65535.0;
5424 } else if (type
== GL_UNSIGNED_INT
) {
5426 widget
.ui
= *iter2
++;
5428 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5432 widget
.i
= *iter2
++;
5434 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5438 iter
[3] = widget
.ub
[0];
5439 iter
[2] = widget
.ub
[1];
5440 iter
[1] = widget
.ub
[2];
5441 iter
[0] = widget
.ub
[3];
5443 iter
[0] = widget
.ub
[0];
5444 iter
[1] = widget
.ub
[1];
5445 iter
[2] = widget
.ub
[2];
5446 iter
[3] = widget
.ub
[3];
5450 iter
+= element_size
;
5454 /* want 'iter' pointing at start, not within, row for assertion
5461 /* iterators should be one byte past end */
5462 if (!isTypePackedPixel(type
)) {
5463 assert(iter2
== &oldimage
[width
*height
*components
]);
5466 assert(iter2
== &oldimage
[width
*height
*
5467 elements_per_group(format
,0)]);
5469 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5470 psm
->pack_skip_rows
* rowsize
+
5471 psm
->pack_skip_pixels
* group_size
] );
5474 } /* empty_image() */
5476 /*--------------------------------------------------------------------------
5477 * Decimation of packed pixel types
5478 *--------------------------------------------------------------------------
5480 static void extract332(int isSwap
,
5481 const void *packedPixel
, GLfloat extractComponents
[])
5483 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5485 isSwap
= isSwap
; /* turn off warnings */
5487 /* 11100000 == 0xe0 */
5488 /* 00011100 == 0x1c */
5489 /* 00000011 == 0x03 */
5491 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5492 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5493 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5494 } /* extract332() */
5496 static void shove332(const GLfloat shoveComponents
[],
5497 int index
, void *packedPixel
)
5499 /* 11100000 == 0xe0 */
5500 /* 00011100 == 0x1c */
5501 /* 00000011 == 0x03 */
5503 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5504 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5505 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5507 /* due to limited precision, need to round before shoving */
5508 ((GLubyte
*)packedPixel
)[index
] =
5509 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5510 ((GLubyte
*)packedPixel
)[index
] |=
5511 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5512 ((GLubyte
*)packedPixel
)[index
] |=
5513 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5516 static void extract233rev(int isSwap
,
5517 const void *packedPixel
, GLfloat extractComponents
[])
5519 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5521 isSwap
= isSwap
; /* turn off warnings */
5523 /* 0000,0111 == 0x07 */
5524 /* 0011,1000 == 0x38 */
5525 /* 1100,0000 == 0xC0 */
5527 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5528 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5529 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5530 } /* extract233rev() */
5532 static void shove233rev(const GLfloat shoveComponents
[],
5533 int index
, void *packedPixel
)
5535 /* 0000,0111 == 0x07 */
5536 /* 0011,1000 == 0x38 */
5537 /* 1100,0000 == 0xC0 */
5539 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5540 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5541 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5543 /* due to limited precision, need to round before shoving */
5544 ((GLubyte
*)packedPixel
)[index
] =
5545 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5546 ((GLubyte
*)packedPixel
)[index
]|=
5547 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5548 ((GLubyte
*)packedPixel
)[index
]|=
5549 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5550 } /* shove233rev() */
5552 static void extract565(int isSwap
,
5553 const void *packedPixel
, GLfloat extractComponents
[])
5558 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5561 ushort
= *(const GLushort
*)packedPixel
;
5564 /* 11111000,00000000 == 0xf800 */
5565 /* 00000111,11100000 == 0x07e0 */
5566 /* 00000000,00011111 == 0x001f */
5568 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5569 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5570 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5571 } /* extract565() */
5573 static void shove565(const GLfloat shoveComponents
[],
5574 int index
,void *packedPixel
)
5576 /* 11111000,00000000 == 0xf800 */
5577 /* 00000111,11100000 == 0x07e0 */
5578 /* 00000000,00011111 == 0x001f */
5580 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5581 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5582 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5584 /* due to limited precision, need to round before shoving */
5585 ((GLushort
*)packedPixel
)[index
] =
5586 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5587 ((GLushort
*)packedPixel
)[index
]|=
5588 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5589 ((GLushort
*)packedPixel
)[index
]|=
5590 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5593 static void extract565rev(int isSwap
,
5594 const void *packedPixel
, GLfloat extractComponents
[])
5596 GLushort ushort
= *(const GLushort
*)packedPixel
;
5599 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5602 ushort
= *(const GLushort
*)packedPixel
;
5605 /* 00000000,00011111 == 0x001f */
5606 /* 00000111,11100000 == 0x07e0 */
5607 /* 11111000,00000000 == 0xf800 */
5609 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5610 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5611 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5612 } /* extract565rev() */
5614 static void shove565rev(const GLfloat shoveComponents
[],
5615 int index
,void *packedPixel
)
5617 /* 00000000,00011111 == 0x001f */
5618 /* 00000111,11100000 == 0x07e0 */
5619 /* 11111000,00000000 == 0xf800 */
5621 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5622 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5623 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5625 /* due to limited precision, need to round before shoving */
5626 ((GLushort
*)packedPixel
)[index
] =
5627 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5628 ((GLushort
*)packedPixel
)[index
]|=
5629 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5630 ((GLushort
*)packedPixel
)[index
]|=
5631 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5632 } /* shove565rev() */
5634 static void extract4444(int isSwap
,const void *packedPixel
,
5635 GLfloat extractComponents
[])
5640 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5643 ushort
= *(const GLushort
*)packedPixel
;
5646 /* 11110000,00000000 == 0xf000 */
5647 /* 00001111,00000000 == 0x0f00 */
5648 /* 00000000,11110000 == 0x00f0 */
5649 /* 00000000,00001111 == 0x000f */
5651 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5652 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5653 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5654 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5655 } /* extract4444() */
5657 static void shove4444(const GLfloat shoveComponents
[],
5658 int index
,void *packedPixel
)
5660 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5661 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5662 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5663 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5665 /* due to limited precision, need to round before shoving */
5666 ((GLushort
*)packedPixel
)[index
] =
5667 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5668 ((GLushort
*)packedPixel
)[index
]|=
5669 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5670 ((GLushort
*)packedPixel
)[index
]|=
5671 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5672 ((GLushort
*)packedPixel
)[index
]|=
5673 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5676 static void extract4444rev(int isSwap
,const void *packedPixel
,
5677 GLfloat extractComponents
[])
5682 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5685 ushort
= *(const GLushort
*)packedPixel
;
5688 /* 00000000,00001111 == 0x000f */
5689 /* 00000000,11110000 == 0x00f0 */
5690 /* 00001111,00000000 == 0x0f00 */
5691 /* 11110000,00000000 == 0xf000 */
5694 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5695 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5696 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5697 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5698 } /* extract4444rev() */
5700 static void shove4444rev(const GLfloat shoveComponents
[],
5701 int index
,void *packedPixel
)
5703 /* 00000000,00001111 == 0x000f */
5704 /* 00000000,11110000 == 0x00f0 */
5705 /* 00001111,00000000 == 0x0f00 */
5706 /* 11110000,00000000 == 0xf000 */
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] * 15)+0.5) ) & 0x000F;
5716 ((GLushort
*)packedPixel
)[index
]|=
5717 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5718 ((GLushort
*)packedPixel
)[index
]|=
5719 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5720 ((GLushort
*)packedPixel
)[index
]|=
5721 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5722 } /* shove4444rev() */
5724 static void extract5551(int isSwap
,const void *packedPixel
,
5725 GLfloat extractComponents
[])
5730 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5733 ushort
= *(const GLushort
*)packedPixel
;
5736 /* 11111000,00000000 == 0xf800 */
5737 /* 00000111,11000000 == 0x07c0 */
5738 /* 00000000,00111110 == 0x003e */
5739 /* 00000000,00000001 == 0x0001 */
5741 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5742 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5743 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5744 extractComponents
[3]=(float)((ushort
& 0x0001) );
5745 } /* extract5551() */
5747 static void shove5551(const GLfloat shoveComponents
[],
5748 int index
,void *packedPixel
)
5750 /* 11111000,00000000 == 0xf800 */
5751 /* 00000111,11000000 == 0x07c0 */
5752 /* 00000000,00111110 == 0x003e */
5753 /* 00000000,00000001 == 0x0001 */
5755 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5756 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5757 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5758 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5760 /* due to limited precision, need to round before shoving */
5761 ((GLushort
*)packedPixel
)[index
] =
5762 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5763 ((GLushort
*)packedPixel
)[index
]|=
5764 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5765 ((GLushort
*)packedPixel
)[index
]|=
5766 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5767 ((GLushort
*)packedPixel
)[index
]|=
5768 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5771 static void extract1555rev(int isSwap
,const void *packedPixel
,
5772 GLfloat extractComponents
[])
5777 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5780 ushort
= *(const GLushort
*)packedPixel
;
5783 /* 00000000,00011111 == 0x001F */
5784 /* 00000011,11100000 == 0x03E0 */
5785 /* 01111100,00000000 == 0x7C00 */
5786 /* 10000000,00000000 == 0x8000 */
5789 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5790 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5791 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5792 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5793 } /* extract1555rev() */
5795 static void shove1555rev(const GLfloat shoveComponents
[],
5796 int index
,void *packedPixel
)
5798 /* 00000000,00011111 == 0x001F */
5799 /* 00000011,11100000 == 0x03E0 */
5800 /* 01111100,00000000 == 0x7C00 */
5801 /* 10000000,00000000 == 0x8000 */
5803 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5804 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5805 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5806 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5808 /* due to limited precision, need to round before shoving */
5809 ((GLushort
*)packedPixel
)[index
] =
5810 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5811 ((GLushort
*)packedPixel
)[index
]|=
5812 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5813 ((GLushort
*)packedPixel
)[index
]|=
5814 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5815 ((GLushort
*)packedPixel
)[index
]|=
5816 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5817 } /* shove1555rev() */
5819 static void extract8888(int isSwap
,
5820 const void *packedPixel
, GLfloat extractComponents
[])
5825 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5828 uint
= *(const GLuint
*)packedPixel
;
5831 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5832 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5833 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5834 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5837 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5838 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5839 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5840 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5841 } /* extract8888() */
5843 static void shove8888(const GLfloat shoveComponents
[],
5844 int index
,void *packedPixel
)
5846 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5847 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5848 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5849 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5851 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5852 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5853 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5854 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5856 /* due to limited precision, need to round before shoving */
5857 ((GLuint
*)packedPixel
)[index
] =
5858 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5859 ((GLuint
*)packedPixel
)[index
]|=
5860 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5861 ((GLuint
*)packedPixel
)[index
]|=
5862 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5863 ((GLuint
*)packedPixel
)[index
]|=
5864 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5867 static void extract8888rev(int isSwap
,
5868 const void *packedPixel
,GLfloat extractComponents
[])
5873 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5876 uint
= *(const GLuint
*)packedPixel
;
5879 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5880 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5881 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5882 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5885 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5886 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5887 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5888 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5889 } /* extract8888rev() */
5891 static void shove8888rev(const GLfloat shoveComponents
[],
5892 int index
,void *packedPixel
)
5894 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5895 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5896 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5897 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5899 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5900 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5901 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5902 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5904 /* due to limited precision, need to round before shoving */
5905 ((GLuint
*)packedPixel
)[index
] =
5906 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5907 ((GLuint
*)packedPixel
)[index
]|=
5908 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5909 ((GLuint
*)packedPixel
)[index
]|=
5910 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5911 ((GLuint
*)packedPixel
)[index
]|=
5912 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5913 } /* shove8888rev() */
5915 static void extract1010102(int isSwap
,
5916 const void *packedPixel
,GLfloat extractComponents
[])
5921 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5924 uint
= *(const GLuint
*)packedPixel
;
5927 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5928 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5929 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5930 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5933 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5934 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5935 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5936 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5937 } /* extract1010102() */
5939 static void shove1010102(const GLfloat shoveComponents
[],
5940 int index
,void *packedPixel
)
5942 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5943 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5944 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5945 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5947 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5948 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5949 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5950 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5952 /* due to limited precision, need to round before shoving */
5953 ((GLuint
*)packedPixel
)[index
] =
5954 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5955 ((GLuint
*)packedPixel
)[index
]|=
5956 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5957 ((GLuint
*)packedPixel
)[index
]|=
5958 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5959 ((GLuint
*)packedPixel
)[index
]|=
5960 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5961 } /* shove1010102() */
5963 static void extract2101010rev(int isSwap
,
5964 const void *packedPixel
,
5965 GLfloat extractComponents
[])
5970 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5973 uint
= *(const GLuint
*)packedPixel
;
5976 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5977 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5978 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5979 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5982 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5983 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5984 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5985 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5987 } /* extract2101010rev() */
5989 static void shove2101010rev(const GLfloat shoveComponents
[],
5990 int index
,void *packedPixel
)
5992 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5993 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5994 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5995 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5997 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5998 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5999 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
6000 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
6002 /* due to limited precision, need to round before shoving */
6003 ((GLuint
*)packedPixel
)[index
] =
6004 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
6005 ((GLuint
*)packedPixel
)[index
]|=
6006 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
6007 ((GLuint
*)packedPixel
)[index
]|=
6008 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
6009 ((GLuint
*)packedPixel
)[index
]|=
6010 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
6011 } /* shove2101010rev() */
6013 static void scaleInternalPackedPixel(int components
,
6014 void (*extractPackedPixel
)
6015 (int, const void *,GLfloat
[]),
6016 void (*shovePackedPixel
)
6017 (const GLfloat
[], int, void *),
6018 GLint widthIn
,GLint heightIn
,
6020 GLint widthOut
,GLint heightOut
,
6022 GLint pixelSizeInBytes
,
6023 GLint rowSizeInBytes
,GLint isSwap
)
6029 /* Max components in a format is 4, so... */
6031 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
6036 const char *temp
, *temp0
;
6039 int lowx_int
, highx_int
, lowy_int
, highy_int
;
6040 float x_percent
, y_percent
;
6041 float lowx_float
, highx_float
, lowy_float
, highy_float
;
6042 float convy_float
, convx_float
;
6043 int convy_int
, convx_int
;
6045 const char *left
, *right
;
6047 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
6048 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6049 widthIn
, heightIn
, dataIn
, dataOut
,
6050 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6053 convy
= (float) heightIn
/heightOut
;
6054 convx
= (float) widthIn
/widthOut
;
6055 convy_int
= floor(convy
);
6056 convy_float
= convy
- convy_int
;
6057 convx_int
= floor(convx
);
6058 convx_float
= convx
- convx_int
;
6060 area
= convx
* convy
;
6064 highy_int
= convy_int
;
6065 highy_float
= convy_float
;
6067 for (i
= 0; i
< heightOut
; i
++) {
6070 highx_int
= convx_int
;
6071 highx_float
= convx_float
;
6073 for (j
= 0; j
< widthOut
; j
++) {
6075 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6076 ** to (highx, highy) on input data into this pixel on output
6079 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6081 /* calculate the value for pixels in the 1st row */
6082 xindex
= lowx_int
*pixelSizeInBytes
;
6083 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6085 y_percent
= 1-lowy_float
;
6086 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6087 percent
= y_percent
* (1-lowx_float
);
6089 for (k
= 0, temp_index
= temp
; k
< components
;
6090 k
++, temp_index
+= element_size
) {
6092 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6094 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6098 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6099 for (k
= 0; k
< components
; k
++) {
6100 totals
[k
]+= extractTotals
[k
] * percent
;
6104 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6105 temp
+= pixelSizeInBytes
;
6107 for (k
= 0, temp_index
= temp
; k
< components
;
6108 k
++, temp_index
+= element_size
) {
6111 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6113 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6117 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6118 for (k
= 0; k
< components
; k
++) {
6119 totals
[k
]+= extractTotals
[k
] * y_percent
;
6123 temp
+= pixelSizeInBytes
;
6125 percent
= y_percent
* highx_float
;
6127 for (k
= 0, temp_index
= temp
; k
< components
;
6128 k
++, temp_index
+= element_size
) {
6130 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6132 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6136 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6137 for (k
= 0; k
< components
; k
++) {
6138 totals
[k
]+= extractTotals
[k
] * percent
;
6142 /* calculate the value for pixels in the last row */
6144 y_percent
= highy_float
;
6145 percent
= y_percent
* (1-lowx_float
);
6146 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6148 for (k
= 0, temp_index
= temp
; k
< components
;
6149 k
++, temp_index
+= element_size
) {
6151 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6153 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6157 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6158 for (k
= 0; k
< components
; k
++) {
6159 totals
[k
]+= extractTotals
[k
] * percent
;
6162 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6163 temp
+= pixelSizeInBytes
;
6165 for (k
= 0, temp_index
= temp
; k
< components
;
6166 k
++, temp_index
+= element_size
) {
6169 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6171 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6175 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6176 for (k
= 0; k
< components
; k
++) {
6177 totals
[k
]+= extractTotals
[k
] * y_percent
;
6182 temp
+= pixelSizeInBytes
;
6183 percent
= y_percent
* highx_float
;
6185 for (k
= 0, temp_index
= temp
; k
< components
;
6186 k
++, temp_index
+= element_size
) {
6188 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6190 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6194 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6195 for (k
= 0; k
< components
; k
++) {
6196 totals
[k
]+= extractTotals
[k
] * percent
;
6200 /* calculate the value for pixels in the 1st and last column */
6201 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6202 left
+= rowSizeInBytes
;
6203 right
+= rowSizeInBytes
;
6205 for (k
= 0; k
< components
;
6206 k
++, left
+= element_size
, right
+= element_size
) {
6209 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6210 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6212 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6213 + *(const GLushort
*)right
* highx_float
;
6217 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6218 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6219 for (k
= 0; k
< components
; k
++) {
6220 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6221 extractMoreTotals
[k
]*highx_float
);
6225 } else if (highy_int
> lowy_int
) {
6226 x_percent
= highx_float
- lowx_float
;
6227 percent
= (1-lowy_float
)*x_percent
;
6228 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6230 for (k
= 0, temp_index
= temp
; k
< components
;
6231 k
++, temp_index
+= element_size
) {
6233 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6235 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6239 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6240 for (k
= 0; k
< components
; k
++) {
6241 totals
[k
]+= extractTotals
[k
] * percent
;
6244 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6245 temp
+= rowSizeInBytes
;
6247 for (k
= 0, temp_index
= temp
; k
< components
;
6248 k
++, temp_index
+= element_size
) {
6251 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6253 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6257 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6258 for (k
= 0; k
< components
; k
++) {
6259 totals
[k
]+= extractTotals
[k
] * x_percent
;
6263 percent
= x_percent
* highy_float
;
6264 temp
+= rowSizeInBytes
;
6266 for (k
= 0, temp_index
= temp
; k
< components
;
6267 k
++, temp_index
+= element_size
) {
6269 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6271 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6275 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6276 for (k
= 0; k
< components
; k
++) {
6277 totals
[k
]+= extractTotals
[k
] * percent
;
6280 } else if (highx_int
> lowx_int
) {
6281 y_percent
= highy_float
- lowy_float
;
6282 percent
= (1-lowx_float
)*y_percent
;
6283 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6285 for (k
= 0, temp_index
= temp
; k
< components
;
6286 k
++, temp_index
+= element_size
) {
6288 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6290 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6294 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6295 for (k
= 0; k
< components
; k
++) {
6296 totals
[k
]+= extractTotals
[k
] * percent
;
6299 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6300 temp
+= pixelSizeInBytes
;
6302 for (k
= 0, temp_index
= temp
; k
< components
;
6303 k
++, temp_index
+= element_size
) {
6306 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6308 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6312 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6313 for (k
= 0; k
< components
; k
++) {
6314 totals
[k
]+= extractTotals
[k
] * y_percent
;
6318 temp
+= pixelSizeInBytes
;
6319 percent
= y_percent
* highx_float
;
6321 for (k
= 0, temp_index
= temp
; k
< components
;
6322 k
++, temp_index
+= element_size
) {
6324 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6326 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6330 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6331 for (k
= 0; k
< components
; k
++) {
6332 totals
[k
]+= extractTotals
[k
] * percent
;
6336 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6337 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6339 for (k
= 0, temp_index
= temp
; k
< components
;
6340 k
++, temp_index
+= element_size
) {
6342 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6344 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6348 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6349 for (k
= 0; k
< components
; k
++) {
6350 totals
[k
]+= extractTotals
[k
] * percent
;
6355 /* this is for the pixels in the body */
6356 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6357 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6359 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6361 for (k
= 0, temp_index
= temp
; k
< components
;
6362 k
++, temp_index
+= element_size
) {
6364 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6366 totals
[k
] += *(const GLushort
*)temp_index
;
6370 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6371 for (k
= 0; k
< components
; k
++) {
6372 totals
[k
]+= extractTotals
[k
];
6375 temp
+= pixelSizeInBytes
;
6377 temp0
+= rowSizeInBytes
;
6380 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6382 for (k
= 0; k
< components
; k
++) {
6383 dataout
[outindex
+ k
] = totals
[k
]/area
;
6384 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6387 for (k
= 0; k
< components
; k
++) {
6388 shoveTotals
[k
]= totals
[k
]/area
;
6390 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6392 lowx_int
= highx_int
;
6393 lowx_float
= highx_float
;
6394 highx_int
+= convx_int
;
6395 highx_float
+= convx_float
;
6396 if(highx_float
> 1) {
6401 lowy_int
= highy_int
;
6402 lowy_float
= highy_float
;
6403 highy_int
+= convy_int
;
6404 highy_float
+= convy_float
;
6405 if(highy_float
> 1) {
6411 assert(outindex
== (widthOut
*heightOut
- 1));
6412 } /* scaleInternalPackedPixel() */
6414 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6415 * inputs; not always equal. Output NEVER has row padding.
6417 static void halveImagePackedPixel(int components
,
6418 void (*extractPackedPixel
)
6419 (int, const void *,GLfloat
[]),
6420 void (*shovePackedPixel
)
6421 (const GLfloat
[],int, void *),
6422 GLint width
, GLint height
,
6423 const void *dataIn
, void *dataOut
,
6424 GLint pixelSizeInBytes
,
6425 GLint rowSizeInBytes
, GLint isSwap
)
6427 /* handle case where there is only 1 column/row */
6428 if (width
== 1 || height
== 1) {
6429 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6430 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6431 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6432 rowSizeInBytes
,isSwap
);
6439 int halfWidth
= width
/ 2;
6440 int halfHeight
= height
/ 2;
6441 const char *src
= (const char *) dataIn
;
6442 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6445 for (ii
= 0; ii
< halfHeight
; ii
++) {
6446 for (jj
= 0; jj
< halfWidth
; jj
++) {
6448 float totals
[4]; /* 4 is maximum components */
6449 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6452 (*extractPackedPixel
)(isSwap
,src
,
6453 &extractTotals
[0][0]);
6454 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6455 &extractTotals
[1][0]);
6456 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6457 &extractTotals
[2][0]);
6458 (*extractPackedPixel
)(isSwap
,
6459 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6460 &extractTotals
[3][0]);
6461 for (cc
= 0; cc
< components
; cc
++) {
6464 /* grab 4 pixels to average */
6466 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6467 * extractTotals[2][RED]+extractTotals[3][RED];
6468 * totals[RED]/= 4.0;
6470 for (kk
= 0; kk
< BOX4
; kk
++) {
6471 totals
[cc
]+= extractTotals
[kk
][cc
];
6473 totals
[cc
]/= (float)BOX4
;
6475 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6478 /* skip over to next square of 4 */
6479 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6481 /* skip past pad bytes, if any, to get to next row */
6484 /* src is at beginning of a row here, but it's the second row of
6485 * the square block of 4 pixels that we just worked on so we
6486 * need to go one more row.
6494 src
+= rowSizeInBytes
;
6497 /* both pointers must reach one byte after the end */
6498 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6499 assert(outIndex
== halfWidth
* halfHeight
);
6501 } /* halveImagePackedPixel() */
6503 static void halve1DimagePackedPixel(int components
,
6504 void (*extractPackedPixel
)
6505 (int, const void *,GLfloat
[]),
6506 void (*shovePackedPixel
)
6507 (const GLfloat
[],int, void *),
6508 GLint width
, GLint height
,
6509 const void *dataIn
, void *dataOut
,
6510 GLint pixelSizeInBytes
,
6511 GLint rowSizeInBytes
, GLint isSwap
)
6513 int halfWidth
= width
/ 2;
6514 int halfHeight
= height
/ 2;
6515 const char *src
= (const char *) dataIn
;
6518 assert(width
== 1 || height
== 1); /* must be 1D */
6519 assert(width
!= height
); /* can't be square */
6521 if (height
== 1) { /* 1 row */
6524 assert(width
!= 1); /* widthxheight can't be 1x1 */
6527 /* one horizontal row with possible pad bytes */
6529 for (jj
= 0; jj
< halfWidth
; jj
++) {
6531 float totals
[4]; /* 4 is maximum components */
6532 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6535 /* average two at a time, instead of four */
6536 (*extractPackedPixel
)(isSwap
,src
,
6537 &extractTotals
[0][0]);
6538 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6539 &extractTotals
[1][0]);
6540 for (cc
= 0; cc
< components
; cc
++) {
6543 /* grab 2 pixels to average */
6545 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6546 * totals[RED]/= 2.0;
6548 for (kk
= 0; kk
< BOX2
; kk
++) {
6549 totals
[cc
]+= extractTotals
[kk
][cc
];
6551 totals
[cc
]/= (float)BOX2
;
6553 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6556 /* skip over to next group of 2 */
6557 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6561 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6562 src
+= padBytes
; /* for assertion only */
6564 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6565 assert(outIndex
== halfWidth
* halfHeight
);
6567 else if (width
== 1) { /* 1 column */
6570 assert(height
!= 1); /* widthxheight can't be 1x1 */
6572 /* one vertical column with possible pad bytes per row */
6573 /* average two at a time */
6575 for (jj
= 0; jj
< halfHeight
; jj
++) {
6577 float totals
[4]; /* 4 is maximum components */
6578 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6581 /* average two at a time, instead of four */
6582 (*extractPackedPixel
)(isSwap
,src
,
6583 &extractTotals
[0][0]);
6584 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6585 &extractTotals
[1][0]);
6586 for (cc
= 0; cc
< components
; cc
++) {
6589 /* grab 2 pixels to average */
6591 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6592 * totals[RED]/= 2.0;
6594 for (kk
= 0; kk
< BOX2
; kk
++) {
6595 totals
[cc
]+= extractTotals
[kk
][cc
];
6597 totals
[cc
]/= (float)BOX2
;
6599 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6602 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6605 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6606 assert(outIndex
== halfWidth
* halfHeight
);
6608 } /* halve1DimagePackedPixel() */
6610 /*===========================================================================*/
6612 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6614 * This section ensures that GLU 1.3 will load and run on
6615 * a GL 1.1 implementation. It dynamically resolves the
6616 * call to glTexImage3D() which might not be available.
6617 * Or is it might be supported as an extension.
6618 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6621 typedef void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6622 GLenum internalFormat
,
6623 GLsizei width
, GLsizei height
,
6624 GLsizei depth
, GLint border
,
6625 GLenum format
, GLenum type
,
6626 const GLvoid
*pixels
);
6628 static TexImage3Dproc pTexImage3D
= 0;
6630 #if !defined(_WIN32) && !defined(__WIN32__)
6632 # include <sys/types.h>
6634 WINGDIAPI PROC WINAPI
wglGetProcAddress(LPCSTR
);
6637 static void gluTexImage3D( GLenum target
, GLint level
,
6638 GLenum internalFormat
,
6639 GLsizei width
, GLsizei height
,
6640 GLsizei depth
, GLint border
,
6641 GLenum format
, GLenum type
,
6642 const GLvoid
*pixels
)
6645 #if defined(_WIN32) || defined(__WIN32__)
6646 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6648 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6650 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6651 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6653 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6658 /* Now call glTexImage3D */
6660 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6661 depth
, border
, format
, type
, pixels
);
6666 /* Only bind to a GL 1.2 implementation: */
6667 #define gluTexImage3D glTexImage3D
6671 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6672 GLenum format
, GLenum type
)
6674 int components
= elements_per_group(format
,type
);
6675 int bytes_per_row
= bytes_per_element(type
) * width
;
6677 assert(width
> 0 && height
> 0 && depth
> 0);
6678 assert(type
!= GL_BITMAP
);
6680 return bytes_per_row
* height
* depth
* components
;
6681 } /* imageSize3D() */
6683 static void fillImage3D(const PixelStorageModes
*psm
,
6684 GLint width
, GLint height
, GLint depth
, GLenum format
,
6685 GLenum type
, GLboolean indexFormat
,
6686 const void *userImage
, GLushort
*newImage
)
6695 int elementsPerLine
;
6698 const GLubyte
*start
, *rowStart
, *iter
;
6702 myswapBytes
= psm
->unpack_swap_bytes
;
6703 components
= elements_per_group(format
,type
);
6704 if (psm
->unpack_row_length
> 0) {
6705 groupsPerLine
= psm
->unpack_row_length
;
6708 groupsPerLine
= width
;
6710 elementSize
= bytes_per_element(type
);
6711 groupSize
= elementSize
* components
;
6712 if (elementSize
== 1) myswapBytes
= 0;
6715 if (psm
->unpack_image_height
> 0) {
6716 rowsPerImage
= psm
->unpack_image_height
;
6719 rowsPerImage
= height
;
6723 rowSize
= groupsPerLine
* groupSize
;
6724 padding
= rowSize
% psm
->unpack_alignment
;
6726 rowSize
+= psm
->unpack_alignment
- padding
;
6729 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6731 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6732 psm
->unpack_skip_pixels
* groupSize
+
6734 psm
->unpack_skip_images
* imageSize
;
6735 elementsPerLine
= width
* components
;
6738 for (dd
= 0; dd
< depth
; dd
++) {
6741 for (hh
= 0; hh
< height
; hh
++) {
6744 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6746 float extractComponents
[4];
6749 case GL_UNSIGNED_BYTE
:
6753 *iter2
++ = (*iter
) * 257;
6758 *iter2
++ = *((const GLbyte
*) iter
);
6761 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6764 case GL_UNSIGNED_BYTE_3_3_2
:
6765 extract332(0,iter
,extractComponents
);
6766 for (k
= 0; k
< 3; k
++) {
6767 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6770 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6771 extract233rev(0,iter
,extractComponents
);
6772 for (k
= 0; k
< 3; k
++) {
6773 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6776 case GL_UNSIGNED_SHORT_5_6_5
:
6777 extract565(myswapBytes
,iter
,extractComponents
);
6778 for (k
= 0; k
< 3; k
++) {
6779 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6782 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6783 extract565rev(myswapBytes
,iter
,extractComponents
);
6784 for (k
= 0; k
< 3; k
++) {
6785 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6788 case GL_UNSIGNED_SHORT_4_4_4_4
:
6789 extract4444(myswapBytes
,iter
,extractComponents
);
6790 for (k
= 0; k
< 4; k
++) {
6791 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6794 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6795 extract4444rev(myswapBytes
,iter
,extractComponents
);
6796 for (k
= 0; k
< 4; k
++) {
6797 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6800 case GL_UNSIGNED_SHORT_5_5_5_1
:
6801 extract5551(myswapBytes
,iter
,extractComponents
);
6802 for (k
= 0; k
< 4; k
++) {
6803 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6806 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6807 extract1555rev(myswapBytes
,iter
,extractComponents
);
6808 for (k
= 0; k
< 4; k
++) {
6809 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6812 case GL_UNSIGNED_SHORT
:
6815 widget
.ub
[0] = iter
[1];
6816 widget
.ub
[1] = iter
[0];
6818 widget
.ub
[0] = iter
[0];
6819 widget
.ub
[1] = iter
[1];
6821 if (type
== GL_SHORT
) {
6823 *iter2
++ = widget
.s
[0];
6826 *iter2
++ = widget
.s
[0]*2;
6829 *iter2
++ = widget
.us
[0];
6832 case GL_UNSIGNED_INT_8_8_8_8
:
6833 extract8888(myswapBytes
,iter
,extractComponents
);
6834 for (k
= 0; k
< 4; k
++) {
6835 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6838 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6839 extract8888rev(myswapBytes
,iter
,extractComponents
);
6840 for (k
= 0; k
< 4; k
++) {
6841 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6844 case GL_UNSIGNED_INT_10_10_10_2
:
6845 extract1010102(myswapBytes
,iter
,extractComponents
);
6846 for (k
= 0; k
< 4; k
++) {
6847 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6850 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6851 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6852 for (k
= 0; k
< 4; k
++) {
6853 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6857 case GL_UNSIGNED_INT
:
6860 widget
.ub
[0] = iter
[3];
6861 widget
.ub
[1] = iter
[2];
6862 widget
.ub
[2] = iter
[1];
6863 widget
.ub
[3] = iter
[0];
6865 widget
.ub
[0] = iter
[0];
6866 widget
.ub
[1] = iter
[1];
6867 widget
.ub
[2] = iter
[2];
6868 widget
.ub
[3] = iter
[3];
6870 if (type
== GL_FLOAT
) {
6872 *iter2
++ = widget
.f
;
6874 *iter2
++ = 65535 * widget
.f
;
6876 } else if (type
== GL_UNSIGNED_INT
) {
6878 *iter2
++ = widget
.ui
;
6880 *iter2
++ = widget
.ui
>> 16;
6884 *iter2
++ = widget
.i
;
6886 *iter2
++ = widget
.i
>> 15;
6898 iter
= rowStart
; /* for assertion purposes */
6904 /* iterators should be one byte past end */
6905 if (!isTypePackedPixel(type
)) {
6906 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6909 assert(iter2
== &newImage
[width
*height
*depth
*
6910 elements_per_group(format
,0)]);
6912 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6913 psm
->unpack_skip_rows
* rowSize
+
6914 psm
->unpack_skip_pixels
* groupSize
+
6916 psm
->unpack_skip_images
* imageSize
] );
6917 } /* fillImage3D () */
6919 static void scaleInternal3D(GLint components
,
6920 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6921 const GLushort
*dataIn
,
6922 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6925 float x
, lowx
, highx
, convx
, halfconvx
;
6926 float y
, lowy
, highy
, convy
, halfconvy
;
6927 float z
, lowz
, highz
, convz
, halfconvz
;
6928 float xpercent
,ypercent
,zpercent
;
6930 /* Max components in a format is 4, so... */
6933 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6936 convz
= (float) depthIn
/depthOut
;
6937 convy
= (float) heightIn
/heightOut
;
6938 convx
= (float) widthIn
/widthOut
;
6939 halfconvx
= convx
/2;
6940 halfconvy
= convy
/2;
6941 halfconvz
= convz
/2;
6942 for (d
= 0; d
< depthOut
; d
++) {
6943 z
= convz
* (d
+0.5);
6944 if (depthIn
> depthOut
) {
6945 highz
= z
+ halfconvz
;
6946 lowz
= z
- halfconvz
;
6951 for (i
= 0; i
< heightOut
; i
++) {
6952 y
= convy
* (i
+0.5);
6953 if (heightIn
> heightOut
) {
6954 highy
= y
+ halfconvy
;
6955 lowy
= y
- halfconvy
;
6960 for (j
= 0; j
< widthOut
; j
++) {
6961 x
= convx
* (j
+0.5);
6962 if (widthIn
> widthOut
) {
6963 highx
= x
+ halfconvx
;
6964 lowx
= x
- halfconvx
;
6971 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6972 ** lowz) to (highx, highy, highz) on input data into this pixel
6975 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6981 zindex
= (zint
+ depthIn
) % depthIn
;
6982 if (highz
< zint
+1) {
6983 zpercent
= highz
- z
;
6985 zpercent
= zint
+1 - z
;
6991 yindex
= (yint
+ heightIn
) % heightIn
;
6992 if (highy
< yint
+1) {
6993 ypercent
= highy
- y
;
6995 ypercent
= yint
+1 - y
;
7002 xindex
= (xint
+ widthIn
) % widthIn
;
7003 if (highx
< xint
+1) {
7004 xpercent
= highx
- x
;
7006 xpercent
= xint
+1 - x
;
7009 percent
= xpercent
* ypercent
* zpercent
;
7012 temp
= (xindex
+ (yindex
*widthIn
) +
7013 (zindex
*widthIn
*heightIn
)) * components
;
7014 for (k
= 0; k
< components
; k
++) {
7015 assert(0 <= (temp
+k
) &&
7017 (widthIn
*heightIn
*depthIn
*components
));
7018 totals
[k
] += dataIn
[temp
+ k
] * percent
;
7033 temp
= (j
+ (i
* widthOut
) +
7034 (d
*widthOut
*heightOut
)) * components
;
7035 for (k
= 0; k
< components
; k
++) {
7036 /* totals[] should be rounded in the case of enlarging an
7037 * RGB ramp when the type is 332 or 4444
7039 assert(0 <= (temp
+k
) &&
7040 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
7041 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
7046 } /* scaleInternal3D() */
7048 static void emptyImage3D(const PixelStorageModes
*psm
,
7049 GLint width
, GLint height
, GLint depth
,
7050 GLenum format
, GLenum type
, GLboolean indexFormat
,
7051 const GLushort
*oldImage
, void *userImage
)
7060 GLubyte
*start
, *rowStart
, *iter
;
7061 int elementsPerLine
;
7062 const GLushort
*iter2
;
7067 myswapBytes
= psm
->pack_swap_bytes
;
7068 components
= elements_per_group(format
,type
);
7069 if (psm
->pack_row_length
> 0) {
7070 groupsPerLine
= psm
->pack_row_length
;
7073 groupsPerLine
= width
;
7076 elementSize
= bytes_per_element(type
);
7077 groupSize
= elementSize
* components
;
7078 if (elementSize
== 1) myswapBytes
= 0;
7081 if (psm
->pack_image_height
> 0) {
7082 rowsPerImage
= psm
->pack_image_height
;
7085 rowsPerImage
= height
;
7090 rowSize
= groupsPerLine
* groupSize
;
7091 padding
= rowSize
% psm
->pack_alignment
;
7093 rowSize
+= psm
->pack_alignment
- padding
;
7096 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7098 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7099 psm
->pack_skip_pixels
* groupSize
+
7101 psm
->pack_skip_images
* imageSize
;
7102 elementsPerLine
= width
* components
;
7105 for (dd
= 0; dd
< depth
; dd
++) {
7108 for (ii
= 0; ii
< height
; ii
++) {
7111 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7113 float shoveComponents
[4];
7116 case GL_UNSIGNED_BYTE
:
7120 *iter
= *iter2
++ >> 8;
7125 *((GLbyte
*) iter
) = *iter2
++;
7127 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7130 case GL_UNSIGNED_BYTE_3_3_2
:
7131 for (k
= 0; k
< 3; k
++) {
7132 shoveComponents
[k
]= *iter2
++ / 65535.0;
7134 shove332(shoveComponents
,0,(void *)iter
);
7136 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7137 for (k
= 0; k
< 3; k
++) {
7138 shoveComponents
[k
]= *iter2
++ / 65535.0;
7140 shove233rev(shoveComponents
,0,(void *)iter
);
7142 case GL_UNSIGNED_SHORT_5_6_5
:
7143 for (k
= 0; k
< 3; k
++) {
7144 shoveComponents
[k
]= *iter2
++ / 65535.0;
7146 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7148 iter
[0] = widget
.ub
[1];
7149 iter
[1] = widget
.ub
[0];
7152 *(GLushort
*)iter
= widget
.us
[0];
7155 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7156 for (k
= 0; k
< 3; k
++) {
7157 shoveComponents
[k
]= *iter2
++ / 65535.0;
7159 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7161 iter
[0] = widget
.ub
[1];
7162 iter
[1] = widget
.ub
[0];
7165 *(GLushort
*)iter
= widget
.us
[0];
7168 case GL_UNSIGNED_SHORT_4_4_4_4
:
7169 for (k
= 0; k
< 4; k
++) {
7170 shoveComponents
[k
]= *iter2
++ / 65535.0;
7172 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7174 iter
[0] = widget
.ub
[1];
7175 iter
[1] = widget
.ub
[0];
7177 *(GLushort
*)iter
= widget
.us
[0];
7180 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7181 for (k
= 0; k
< 4; k
++) {
7182 shoveComponents
[k
]= *iter2
++ / 65535.0;
7184 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7186 iter
[0] = widget
.ub
[1];
7187 iter
[1] = widget
.ub
[0];
7189 *(GLushort
*)iter
= widget
.us
[0];
7192 case GL_UNSIGNED_SHORT_5_5_5_1
:
7193 for (k
= 0; k
< 4; k
++) {
7194 shoveComponents
[k
]= *iter2
++ / 65535.0;
7196 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7198 iter
[0] = widget
.ub
[1];
7199 iter
[1] = widget
.ub
[0];
7201 *(GLushort
*)iter
= widget
.us
[0];
7204 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7205 for (k
= 0; k
< 4; k
++) {
7206 shoveComponents
[k
]= *iter2
++ / 65535.0;
7208 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7210 iter
[0] = widget
.ub
[1];
7211 iter
[1] = widget
.ub
[0];
7213 *(GLushort
*)iter
= widget
.us
[0];
7216 case GL_UNSIGNED_SHORT
:
7218 if (type
== GL_SHORT
) {
7220 widget
.s
[0] = *iter2
++;
7222 widget
.s
[0] = *iter2
++ >> 1;
7225 widget
.us
[0] = *iter2
++;
7228 iter
[0] = widget
.ub
[1];
7229 iter
[1] = widget
.ub
[0];
7231 iter
[0] = widget
.ub
[0];
7232 iter
[1] = widget
.ub
[1];
7235 case GL_UNSIGNED_INT_8_8_8_8
:
7236 for (k
= 0; k
< 4; k
++) {
7237 shoveComponents
[k
]= *iter2
++ / 65535.0;
7239 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7241 iter
[3] = widget
.ub
[0];
7242 iter
[2] = widget
.ub
[1];
7243 iter
[1] = widget
.ub
[2];
7244 iter
[0] = widget
.ub
[3];
7246 *(GLuint
*)iter
= widget
.ui
;
7249 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7250 for (k
= 0; k
< 4; k
++) {
7251 shoveComponents
[k
]= *iter2
++ / 65535.0;
7253 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7255 iter
[3] = widget
.ub
[0];
7256 iter
[2] = widget
.ub
[1];
7257 iter
[1] = widget
.ub
[2];
7258 iter
[0] = widget
.ub
[3];
7260 *(GLuint
*)iter
= widget
.ui
;
7263 case GL_UNSIGNED_INT_10_10_10_2
:
7264 for (k
= 0; k
< 4; k
++) {
7265 shoveComponents
[k
]= *iter2
++ / 65535.0;
7267 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7269 iter
[3] = widget
.ub
[0];
7270 iter
[2] = widget
.ub
[1];
7271 iter
[1] = widget
.ub
[2];
7272 iter
[0] = widget
.ub
[3];
7274 *(GLuint
*)iter
= widget
.ui
;
7277 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7278 for (k
= 0; k
< 4; k
++) {
7279 shoveComponents
[k
]= *iter2
++ / 65535.0;
7281 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7283 iter
[3] = widget
.ub
[0];
7284 iter
[2] = widget
.ub
[1];
7285 iter
[1] = widget
.ub
[2];
7286 iter
[0] = widget
.ub
[3];
7288 *(GLuint
*)iter
= widget
.ui
;
7292 case GL_UNSIGNED_INT
:
7294 if (type
== GL_FLOAT
) {
7296 widget
.f
= *iter2
++;
7298 widget
.f
= *iter2
++ / (float) 65535.0;
7300 } else if (type
== GL_UNSIGNED_INT
) {
7302 widget
.ui
= *iter2
++;
7304 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7308 widget
.i
= *iter2
++;
7310 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
7314 iter
[3] = widget
.ub
[0];
7315 iter
[2] = widget
.ub
[1];
7316 iter
[1] = widget
.ub
[2];
7317 iter
[0] = widget
.ub
[3];
7319 iter
[0] = widget
.ub
[0];
7320 iter
[1] = widget
.ub
[1];
7321 iter
[2] = widget
.ub
[2];
7322 iter
[3] = widget
.ub
[3];
7338 /* iterators should be one byte past end */
7339 if (!isTypePackedPixel(type
)) {
7340 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7343 assert(iter2
== &oldImage
[width
*height
*depth
*
7344 elements_per_group(format
,0)]);
7346 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7347 psm
->unpack_skip_rows
* rowSize
+
7348 psm
->unpack_skip_pixels
* groupSize
+
7350 psm
->unpack_skip_images
* imageSize
] );
7351 } /* emptyImage3D() */
7354 int gluScaleImage3D(GLenum format
,
7355 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7356 GLenum typeIn
, const void *dataIn
,
7357 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7358 GLenum typeOut
, void *dataOut
)
7361 GLushort
*beforeImage
, *afterImage
;
7362 PixelStorageModes psm
;
7364 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7365 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7369 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7370 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7371 return GLU_INVALID_VALUE
;
7374 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7375 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7376 return GLU_INVALID_ENUM
;
7378 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7379 return GLU_INVALID_OPERATION
;
7381 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7382 return GLU_INVALID_OPERATION
;
7385 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7386 GL_UNSIGNED_SHORT
));
7387 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7388 GL_UNSIGNED_SHORT
));
7389 if (beforeImage
== NULL
|| afterImage
== NULL
) {
7392 return GLU_OUT_OF_MEMORY
;
7394 retrieveStoreModes3D(&psm
);
7396 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7397 dataIn
, beforeImage
);
7398 components
= elements_per_group(format
,0);
7399 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7400 widthOut
,heightOut
,depthOut
,afterImage
);
7401 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7402 is_index(format
),afterImage
, dataOut
);
7403 free((void *) beforeImage
);
7404 free((void *) afterImage
);
7407 } /* gluScaleImage3D() */
7410 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7411 GLint internalFormat
, GLenum format
, GLenum type
,
7412 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7414 GLint widthPowerOf2
= nearestPower(width
);
7415 GLint heightPowerOf2
= nearestPower(height
);
7416 GLint depthPowerOf2
= nearestPower(depth
);
7420 /* compute level 1 width & height & depth, clamping each at 1 */
7421 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7422 widthPowerOf2
>> 1 :
7424 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7425 heightPowerOf2
>> 1 :
7427 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7428 depthPowerOf2
>> 1 :
7430 GLenum proxyTarget
= GL_PROXY_TEXTURE_3D
;
7431 assert(widthAtLevelOne
> 0);
7432 assert(heightAtLevelOne
> 0);
7433 assert(depthAtLevelOne
> 0);
7435 /* does width x height x depth at level 1 & all their mipmaps fit? */
7436 assert(target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
);
7437 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7439 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7440 0,format
,type
,NULL
);
7441 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7442 /* does it fit??? */
7443 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7444 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7445 depthPowerOf2
== 1) {
7446 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7449 widthPowerOf2
= widthAtLevelOne
;
7450 heightPowerOf2
= heightAtLevelOne
;
7451 depthPowerOf2
= depthAtLevelOne
;
7453 /* else it does fit */
7454 } while (proxyWidth
== 0);
7455 /* loop must terminate! */
7457 /* return the width & height at level 0 that fits */
7458 *newWidth
= widthPowerOf2
;
7459 *newHeight
= heightPowerOf2
;
7460 *newDepth
= depthPowerOf2
;
7461 /*printf("Proxy Textures\n");*/
7462 } /* closestFit3D() */
7464 static void halveImagePackedPixelSlice(int components
,
7465 void (*extractPackedPixel
)
7466 (int, const void *,GLfloat
[]),
7467 void (*shovePackedPixel
)
7468 (const GLfloat
[],int, void *),
7469 GLint width
, GLint height
, GLint depth
,
7470 const void *dataIn
, void *dataOut
,
7471 GLint pixelSizeInBytes
,
7472 GLint rowSizeInBytes
,
7473 GLint imageSizeInBytes
,
7477 int halfWidth
= width
/ 2;
7478 int halfHeight
= height
/ 2;
7479 int halfDepth
= depth
/ 2;
7480 const char *src
= (const char *)dataIn
;
7483 assert((width
== 1 || height
== 1) && depth
>= 2);
7485 if (width
== height
) { /* a 1-pixel column viewed from top */
7486 assert(width
== 1 && height
== 1);
7489 for (ii
= 0; ii
< halfDepth
; ii
++) {
7491 float extractTotals
[BOX2
][4];
7494 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7495 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7496 &extractTotals
[1][0]);
7497 for (cc
= 0; cc
< components
; cc
++) {
7500 /* average 2 pixels since only a column */
7502 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7503 * totals[RED]/= 2.0;
7505 for (kk
= 0; kk
< BOX2
; kk
++) {
7506 totals
[cc
]+= extractTotals
[kk
][cc
];
7508 totals
[cc
]/= (float)BOX2
;
7511 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7513 /* skip over to next group of 2 */
7514 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7517 else if (height
== 1) { /* horizontal slice viewed from top */
7520 for (ii
= 0; ii
< halfDepth
; ii
++) {
7521 for (jj
= 0; jj
< halfWidth
; jj
++) {
7523 float extractTotals
[BOX4
][4];
7526 (*extractPackedPixel
)(isSwap
,src
,
7527 &extractTotals
[0][0]);
7528 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7529 &extractTotals
[1][0]);
7530 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7531 &extractTotals
[2][0]);
7532 (*extractPackedPixel
)(isSwap
,
7533 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7534 &extractTotals
[3][0]);
7535 for (cc
= 0; cc
< components
; cc
++) {
7538 /* grab 4 pixels to average */
7540 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7541 * extractTotals[2][RED]+extractTotals[3][RED];
7542 * totals[RED]/= 4.0;
7544 for (kk
= 0; kk
< BOX4
; kk
++) {
7545 totals
[cc
]+= extractTotals
[kk
][cc
];
7547 totals
[cc
]/= (float)BOX4
;
7549 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7552 /* skip over to next horizontal square of 4 */
7553 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7559 else if (width
== 1) { /* vertical slice viewed from top */
7560 assert(height
!= 1);
7562 for (ii
= 0; ii
< halfDepth
; ii
++) {
7563 for (jj
= 0; jj
< halfHeight
; jj
++) {
7565 float extractTotals
[BOX4
][4];
7568 (*extractPackedPixel
)(isSwap
,src
,
7569 &extractTotals
[0][0]);
7570 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7571 &extractTotals
[1][0]);
7572 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7573 &extractTotals
[2][0]);
7574 (*extractPackedPixel
)(isSwap
,
7575 (src
+imageSizeInBytes
+rowSizeInBytes
),
7576 &extractTotals
[3][0]);
7577 for (cc
= 0; cc
< components
; cc
++) {
7580 /* grab 4 pixels to average */
7582 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7583 * extractTotals[2][RED]+extractTotals[3][RED];
7584 * totals[RED]/= 4.0;
7586 for (kk
= 0; kk
< BOX4
; kk
++) {
7587 totals
[cc
]+= extractTotals
[kk
][cc
];
7589 totals
[cc
]/= (float)BOX4
;
7591 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7595 /* skip over to next vertical square of 4 */
7596 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7602 } /* halveImagePackedPixelSlice() */
7604 static void halveImagePackedPixel3D(int components
,
7605 void (*extractPackedPixel
)
7606 (int, const void *,GLfloat
[]),
7607 void (*shovePackedPixel
)
7608 (const GLfloat
[],int, void *),
7609 GLint width
, GLint height
, GLint depth
,
7610 const void *dataIn
, void *dataOut
,
7611 GLint pixelSizeInBytes
,
7612 GLint rowSizeInBytes
,
7613 GLint imageSizeInBytes
,
7617 assert(1 <= width
&& 1 <= height
);
7619 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7620 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7621 rowSizeInBytes
,isSwap
);
7624 /* a horizontal or vertical slice viewed from top */
7625 else if (width
== 1 || height
== 1) {
7628 halveImagePackedPixelSlice(components
,
7629 extractPackedPixel
,shovePackedPixel
,
7630 width
, height
, depth
, dataIn
, dataOut
,
7631 pixelSizeInBytes
, rowSizeInBytes
,
7632 imageSizeInBytes
, isSwap
);
7638 int halfWidth
= width
/ 2;
7639 int halfHeight
= height
/ 2;
7640 int halfDepth
= depth
/ 2;
7641 const char *src
= (const char *) dataIn
;
7642 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7645 for (dd
= 0; dd
< halfDepth
; dd
++) {
7646 for (ii
= 0; ii
< halfHeight
; ii
++) {
7647 for (jj
= 0; jj
< halfWidth
; jj
++) {
7649 float totals
[4]; /* 4 is maximum components */
7650 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7653 (*extractPackedPixel
)(isSwap
,src
,
7654 &extractTotals
[0][0]);
7655 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7656 &extractTotals
[1][0]);
7657 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7658 &extractTotals
[2][0]);
7659 (*extractPackedPixel
)(isSwap
,
7660 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7661 &extractTotals
[3][0]);
7663 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7664 &extractTotals
[4][0]);
7665 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7666 &extractTotals
[5][0]);
7667 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7668 &extractTotals
[6][0]);
7669 (*extractPackedPixel
)(isSwap
,
7670 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7671 &extractTotals
[7][0]);
7672 for (cc
= 0; cc
< components
; cc
++) {
7675 /* grab 8 pixels to average */
7677 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7678 * extractTotals[2][RED]+extractTotals[3][RED]+
7679 * extractTotals[4][RED]+extractTotals[5][RED]+
7680 * extractTotals[6][RED]+extractTotals[7][RED];
7681 * totals[RED]/= 8.0;
7683 for (kk
= 0; kk
< BOX8
; kk
++) {
7684 totals
[cc
]+= extractTotals
[kk
][cc
];
7686 totals
[cc
]/= (float)BOX8
;
7688 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7691 /* skip over to next square of 4 */
7692 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7694 /* skip past pad bytes, if any, to get to next row */
7697 /* src is at beginning of a row here, but it's the second row of
7698 * the square block of 4 pixels that we just worked on so we
7699 * need to go one more row.
7707 src
+= rowSizeInBytes
;
7710 src
+= imageSizeInBytes
;
7713 /* both pointers must reach one byte after the end */
7714 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7715 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7718 } /* halveImagePackedPixel3D() */
7720 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7724 GLsizei widthPowerOf2
,
7725 GLsizei heightPowerOf2
,
7726 GLsizei depthPowerOf2
,
7727 GLenum format
, GLenum type
,
7729 GLint baseLevel
,GLint maxLevel
,
7732 GLint newWidth
, newHeight
, newDepth
;
7733 GLint level
, levels
;
7734 const void *usersImage
;
7735 void *srcImage
, *dstImage
;
7736 __GLU_INIT_SWAP_IMAGE
;
7740 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7741 GLint rowsPerImage
, imageSize
;
7742 GLint rowSize
, padding
;
7743 PixelStorageModes psm
;
7745 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7746 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7747 assert(type
!= GL_BITMAP
);
7749 srcImage
= dstImage
= NULL
;
7751 newWidth
= widthPowerOf2
;
7752 newHeight
= heightPowerOf2
;
7753 newDepth
= depthPowerOf2
;
7754 levels
= computeLog(newWidth
);
7755 level
= computeLog(newHeight
);
7756 if (level
> levels
) levels
=level
;
7757 level
= computeLog(newDepth
);
7758 if (level
> levels
) levels
=level
;
7762 retrieveStoreModes3D(&psm
);
7763 myswapBytes
= psm
.unpack_swap_bytes
;
7764 cmpts
= elements_per_group(format
,type
);
7765 if (psm
.unpack_row_length
> 0) {
7766 groupsPerLine
= psm
.unpack_row_length
;
7768 groupsPerLine
= width
;
7771 elementSize
= bytes_per_element(type
);
7772 groupSize
= elementSize
* cmpts
;
7773 if (elementSize
== 1) myswapBytes
= 0;
7776 if (psm
.unpack_image_height
> 0) {
7777 rowsPerImage
= psm
.unpack_image_height
;
7780 rowsPerImage
= height
;
7784 rowSize
= groupsPerLine
* groupSize
;
7785 padding
= (rowSize
% psm
.unpack_alignment
);
7787 rowSize
+= psm
.unpack_alignment
- padding
;
7790 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7792 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7793 psm
.unpack_skip_pixels
* groupSize
+
7795 psm
.unpack_skip_images
* imageSize
;
7797 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7798 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7799 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7800 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7801 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7805 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7806 /* Use usersImage for level userLevel */
7807 if (baseLevel
<= level
&& level
<= maxLevel
) {
7808 gluTexImage3D(target
, level
, internalFormat
, width
,
7809 height
, depth
, 0, format
, type
,
7812 if(levels
== 0) { /* we're done. clean up and return */
7813 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7814 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7815 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7816 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7817 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7818 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7819 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7823 int nextWidth
= newWidth
/2;
7824 int nextHeight
= newHeight
/2;
7825 int nextDepth
= newDepth
/2;
7828 if (nextWidth
< 1) nextWidth
= 1;
7829 if (nextHeight
< 1) nextHeight
= 1;
7830 if (nextDepth
< 1) nextDepth
= 1;
7831 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7834 case GL_UNSIGNED_BYTE
:
7835 dstImage
= (GLubyte
*)malloc(memReq
);
7838 dstImage
= (GLbyte
*)malloc(memReq
);
7840 case GL_UNSIGNED_SHORT
:
7841 dstImage
= (GLushort
*)malloc(memReq
);
7844 dstImage
= (GLshort
*)malloc(memReq
);
7846 case GL_UNSIGNED_INT
:
7847 dstImage
= (GLuint
*)malloc(memReq
);
7850 dstImage
= (GLint
*)malloc(memReq
);
7853 dstImage
= (GLfloat
*)malloc(memReq
);
7855 case GL_UNSIGNED_BYTE_3_3_2
:
7856 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7857 dstImage
= (GLubyte
*)malloc(memReq
);
7859 case GL_UNSIGNED_SHORT_5_6_5
:
7860 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7861 case GL_UNSIGNED_SHORT_4_4_4_4
:
7862 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7863 case GL_UNSIGNED_SHORT_5_5_5_1
:
7864 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7865 dstImage
= (GLushort
*)malloc(memReq
);
7867 case GL_UNSIGNED_INT_8_8_8_8
:
7868 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7869 case GL_UNSIGNED_INT_10_10_10_2
:
7870 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7871 dstImage
= (GLuint
*)malloc(memReq
);
7874 return GLU_INVALID_ENUM
; /* assertion */
7876 if (dstImage
== NULL
) {
7877 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7878 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7879 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7880 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7881 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7882 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7883 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7884 return GLU_OUT_OF_MEMORY
;
7888 case GL_UNSIGNED_BYTE
:
7890 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7892 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7893 imageSize
,myswapBytes
);
7896 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7897 elementSize
,rowSize
,groupSize
);
7902 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7904 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7905 imageSize
,myswapBytes
);
7908 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7909 elementSize
,rowSize
,groupSize
);
7912 case GL_UNSIGNED_SHORT
:
7914 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7916 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7917 imageSize
,myswapBytes
);
7920 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7921 elementSize
,rowSize
,groupSize
,myswapBytes
);
7926 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7928 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7929 imageSize
,myswapBytes
);
7932 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7933 elementSize
,rowSize
,groupSize
,myswapBytes
);
7936 case GL_UNSIGNED_INT
:
7938 halveImage3D(cmpts
,extractUint
,shoveUint
,
7940 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7941 imageSize
,myswapBytes
);
7944 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7945 elementSize
,rowSize
,groupSize
,myswapBytes
);
7950 halveImage3D(cmpts
,extractSint
,shoveSint
,
7952 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7953 imageSize
,myswapBytes
);
7956 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7957 elementSize
,rowSize
,groupSize
,myswapBytes
);
7962 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7964 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7965 imageSize
,myswapBytes
);
7968 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7969 elementSize
,rowSize
,groupSize
,myswapBytes
);
7972 case GL_UNSIGNED_BYTE_3_3_2
:
7973 assert(format
== GL_RGB
);
7974 halveImagePackedPixel3D(3,extract332
,shove332
,
7975 width
,height
,depth
,usersImage
,dstImage
,
7976 elementSize
,rowSize
,imageSize
,myswapBytes
);
7978 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7979 assert(format
== GL_RGB
);
7980 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7981 width
,height
,depth
,usersImage
,dstImage
,
7982 elementSize
,rowSize
,imageSize
,myswapBytes
);
7984 case GL_UNSIGNED_SHORT_5_6_5
:
7985 halveImagePackedPixel3D(3,extract565
,shove565
,
7986 width
,height
,depth
,usersImage
,dstImage
,
7987 elementSize
,rowSize
,imageSize
,myswapBytes
);
7989 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7990 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7991 width
,height
,depth
,usersImage
,dstImage
,
7992 elementSize
,rowSize
,imageSize
,myswapBytes
);
7994 case GL_UNSIGNED_SHORT_4_4_4_4
:
7995 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7996 width
,height
,depth
,usersImage
,dstImage
,
7997 elementSize
,rowSize
,imageSize
,myswapBytes
);
7999 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8000 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8001 width
,height
,depth
,usersImage
,dstImage
,
8002 elementSize
,rowSize
,imageSize
,myswapBytes
);
8004 case GL_UNSIGNED_SHORT_5_5_5_1
:
8005 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8006 width
,height
,depth
,usersImage
,dstImage
,
8007 elementSize
,rowSize
,imageSize
,myswapBytes
);
8009 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8010 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8011 width
,height
,depth
,usersImage
,dstImage
,
8012 elementSize
,rowSize
,imageSize
,myswapBytes
);
8014 case GL_UNSIGNED_INT_8_8_8_8
:
8015 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8016 width
,height
,depth
,usersImage
,dstImage
,
8017 elementSize
,rowSize
,imageSize
,myswapBytes
);
8019 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8020 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8021 width
,height
,depth
,usersImage
,dstImage
,
8022 elementSize
,rowSize
,imageSize
,myswapBytes
);
8024 case GL_UNSIGNED_INT_10_10_10_2
:
8025 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8026 width
,height
,depth
,usersImage
,dstImage
,
8027 elementSize
,rowSize
,imageSize
,myswapBytes
);
8029 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8030 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8031 width
,height
,depth
,usersImage
,dstImage
,
8032 elementSize
,rowSize
,imageSize
,myswapBytes
);
8039 newHeight
= height
/2;
8042 if (newWidth
< 1) newWidth
= 1;
8043 if (newHeight
< 1) newHeight
= 1;
8044 if (newDepth
< 1) newDepth
= 1;
8047 rowSize
= newWidth
* groupSize
;
8048 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8049 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8050 /* Swap srcImage and dstImage */
8051 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8053 case GL_UNSIGNED_BYTE
:
8054 dstImage
= (GLubyte
*)malloc(memReq
);
8057 dstImage
= (GLbyte
*)malloc(memReq
);
8059 case GL_UNSIGNED_SHORT
:
8060 dstImage
= (GLushort
*)malloc(memReq
);
8063 dstImage
= (GLshort
*)malloc(memReq
);
8065 case GL_UNSIGNED_INT
:
8066 dstImage
= (GLuint
*)malloc(memReq
);
8069 dstImage
= (GLint
*)malloc(memReq
);
8072 dstImage
= (GLfloat
*)malloc(memReq
);
8074 case GL_UNSIGNED_BYTE_3_3_2
:
8075 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8076 dstImage
= (GLubyte
*)malloc(memReq
);
8078 case GL_UNSIGNED_SHORT_5_6_5
:
8079 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8080 case GL_UNSIGNED_SHORT_4_4_4_4
:
8081 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8082 case GL_UNSIGNED_SHORT_5_5_5_1
:
8083 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8084 dstImage
= (GLushort
*)malloc(memReq
);
8086 case GL_UNSIGNED_INT_8_8_8_8
:
8087 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8088 case GL_UNSIGNED_INT_10_10_10_2
:
8089 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8090 dstImage
= (GLuint
*)malloc(memReq
);
8093 return GLU_INVALID_ENUM
; /* assertion */
8095 if (dstImage
== NULL
) {
8096 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8097 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8098 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8099 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8100 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8101 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8102 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8104 return GLU_OUT_OF_MEMORY
;
8106 /* level userLevel+1 is in srcImage; level userLevel already saved */
8107 level
= userLevel
+1;
8108 } else {/* user's image is *not* nice power-of-2 sized square */
8109 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8111 case GL_UNSIGNED_BYTE
:
8112 dstImage
= (GLubyte
*)malloc(memReq
);
8115 dstImage
= (GLbyte
*)malloc(memReq
);
8117 case GL_UNSIGNED_SHORT
:
8118 dstImage
= (GLushort
*)malloc(memReq
);
8121 dstImage
= (GLshort
*)malloc(memReq
);
8123 case GL_UNSIGNED_INT
:
8124 dstImage
= (GLuint
*)malloc(memReq
);
8127 dstImage
= (GLint
*)malloc(memReq
);
8130 dstImage
= (GLfloat
*)malloc(memReq
);
8132 case GL_UNSIGNED_BYTE_3_3_2
:
8133 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8134 dstImage
= (GLubyte
*)malloc(memReq
);
8136 case GL_UNSIGNED_SHORT_5_6_5
:
8137 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8138 case GL_UNSIGNED_SHORT_4_4_4_4
:
8139 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8140 case GL_UNSIGNED_SHORT_5_5_5_1
:
8141 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8142 dstImage
= (GLushort
*)malloc(memReq
);
8144 case GL_UNSIGNED_INT_8_8_8_8
:
8145 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8146 case GL_UNSIGNED_INT_10_10_10_2
:
8147 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8148 dstImage
= (GLuint
*)malloc(memReq
);
8151 return GLU_INVALID_ENUM
; /* assertion */
8154 if (dstImage
== NULL
) {
8155 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8156 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8157 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8158 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8159 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8160 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8161 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8162 return GLU_OUT_OF_MEMORY
;
8164 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8165 width,height,depth,newWidth,newHeight,newDepth);*/
8167 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8168 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8171 rowSize
= newWidth
* groupSize
;
8172 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8173 /* Swap dstImage and srcImage */
8174 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8176 if(levels
!= 0) { /* use as little memory as possible */
8178 int nextWidth
= newWidth
/2;
8179 int nextHeight
= newHeight
/2;
8180 int nextDepth
= newDepth
/2;
8181 if (nextWidth
< 1) nextWidth
= 1;
8182 if (nextHeight
< 1) nextHeight
= 1;
8183 if (nextDepth
< 1) nextDepth
= 1;
8185 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8188 case GL_UNSIGNED_BYTE
:
8189 dstImage
= (GLubyte
*)malloc(memReq
);
8192 dstImage
= (GLbyte
*)malloc(memReq
);
8194 case GL_UNSIGNED_SHORT
:
8195 dstImage
= (GLushort
*)malloc(memReq
);
8198 dstImage
= (GLshort
*)malloc(memReq
);
8200 case GL_UNSIGNED_INT
:
8201 dstImage
= (GLuint
*)malloc(memReq
);
8204 dstImage
= (GLint
*)malloc(memReq
);
8207 dstImage
= (GLfloat
*)malloc(memReq
);
8209 case GL_UNSIGNED_BYTE_3_3_2
:
8210 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8211 dstImage
= (GLubyte
*)malloc(memReq
);
8213 case GL_UNSIGNED_SHORT_5_6_5
:
8214 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8215 case GL_UNSIGNED_SHORT_4_4_4_4
:
8216 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8217 case GL_UNSIGNED_SHORT_5_5_5_1
:
8218 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8219 dstImage
= (GLushort
*)malloc(memReq
);
8221 case GL_UNSIGNED_INT_8_8_8_8
:
8222 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8223 case GL_UNSIGNED_INT_10_10_10_2
:
8224 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8225 dstImage
= (GLuint
*)malloc(memReq
);
8228 return GLU_INVALID_ENUM
; /* assertion */
8230 if (dstImage
== NULL
) {
8231 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8232 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8233 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8234 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8235 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8236 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8237 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8239 return GLU_OUT_OF_MEMORY
;
8242 /* level userLevel is in srcImage; nothing saved yet */
8246 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8247 if (baseLevel
<= level
&& level
<= maxLevel
) {
8248 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8249 0,format
, type
, (void *)srcImage
);
8251 level
++; /* update current level for the loop */
8252 for (; level
<= levels
; level
++) {
8254 case GL_UNSIGNED_BYTE
:
8256 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8257 newWidth
,newHeight
,newDepth
,
8258 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8259 imageSize
,myswapBytes
);
8262 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8263 elementSize
,rowSize
,groupSize
);
8268 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8269 newWidth
,newHeight
,newDepth
,
8270 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8271 imageSize
,myswapBytes
);
8274 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8275 elementSize
,rowSize
,groupSize
);
8278 case GL_UNSIGNED_SHORT
:
8280 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8281 newWidth
,newHeight
,newDepth
,
8282 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8283 imageSize
,myswapBytes
);
8286 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8287 elementSize
,rowSize
,groupSize
,myswapBytes
);
8292 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8293 newWidth
,newHeight
,newDepth
,
8294 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8295 imageSize
,myswapBytes
);
8298 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8299 elementSize
,rowSize
,groupSize
,myswapBytes
);
8302 case GL_UNSIGNED_INT
:
8304 halveImage3D(cmpts
,extractUint
,shoveUint
,
8305 newWidth
,newHeight
,newDepth
,
8306 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8307 imageSize
,myswapBytes
);
8310 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8311 elementSize
,rowSize
,groupSize
,myswapBytes
);
8316 halveImage3D(cmpts
,extractSint
,shoveSint
,
8317 newWidth
,newHeight
,newDepth
,
8318 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8319 imageSize
,myswapBytes
);
8322 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8323 elementSize
,rowSize
,groupSize
,myswapBytes
);
8328 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8329 newWidth
,newHeight
,newDepth
,
8330 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8331 imageSize
,myswapBytes
);
8334 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8335 elementSize
,rowSize
,groupSize
,myswapBytes
);
8338 case GL_UNSIGNED_BYTE_3_3_2
:
8339 halveImagePackedPixel3D(3,extract332
,shove332
,
8340 newWidth
,newHeight
,newDepth
,
8341 srcImage
,dstImage
,elementSize
,rowSize
,
8342 imageSize
,myswapBytes
);
8344 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8345 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8346 newWidth
,newHeight
,newDepth
,
8347 srcImage
,dstImage
,elementSize
,rowSize
,
8348 imageSize
,myswapBytes
);
8350 case GL_UNSIGNED_SHORT_5_6_5
:
8351 halveImagePackedPixel3D(3,extract565
,shove565
,
8352 newWidth
,newHeight
,newDepth
,
8353 srcImage
,dstImage
,elementSize
,rowSize
,
8354 imageSize
,myswapBytes
);
8356 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8357 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8358 newWidth
,newHeight
,newDepth
,
8359 srcImage
,dstImage
,elementSize
,rowSize
,
8360 imageSize
,myswapBytes
);
8362 case GL_UNSIGNED_SHORT_4_4_4_4
:
8363 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8364 newWidth
,newHeight
,newDepth
,
8365 srcImage
,dstImage
,elementSize
,rowSize
,
8366 imageSize
,myswapBytes
);
8368 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8369 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8370 newWidth
,newHeight
,newDepth
,
8371 srcImage
,dstImage
,elementSize
,rowSize
,
8372 imageSize
,myswapBytes
);
8374 case GL_UNSIGNED_SHORT_5_5_5_1
:
8375 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8376 newWidth
,newHeight
,newDepth
,
8377 srcImage
,dstImage
,elementSize
,rowSize
,
8378 imageSize
,myswapBytes
);
8380 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8381 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8382 newWidth
,newHeight
,newDepth
,
8383 srcImage
,dstImage
,elementSize
,rowSize
,
8384 imageSize
,myswapBytes
);
8386 case GL_UNSIGNED_INT_8_8_8_8
:
8387 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8388 newWidth
,newHeight
,newDepth
,
8389 srcImage
,dstImage
,elementSize
,rowSize
,
8390 imageSize
,myswapBytes
);
8392 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8393 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8394 newWidth
,newHeight
,newDepth
,
8395 srcImage
,dstImage
,elementSize
,rowSize
,
8396 imageSize
,myswapBytes
);
8398 case GL_UNSIGNED_INT_10_10_10_2
:
8399 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8400 newWidth
,newHeight
,newDepth
,
8401 srcImage
,dstImage
,elementSize
,rowSize
,
8402 imageSize
,myswapBytes
);
8404 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8405 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8406 newWidth
,newHeight
,newDepth
,
8407 srcImage
,dstImage
,elementSize
,rowSize
,
8408 imageSize
,myswapBytes
);
8415 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8417 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8418 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8419 if (newDepth
> 1) newDepth
/= 2;
8421 /* call tex image with srcImage untouched since it's not padded */
8422 if (baseLevel
<= level
&& level
<= maxLevel
) {
8423 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8424 newDepth
,0, format
, type
, (void *) srcImage
);
8428 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8429 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8430 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8431 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8432 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8433 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8434 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8436 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8437 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8441 } /* gluBuild3DMipmapLevelsCore() */
8444 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8445 GLsizei width
, GLsizei height
, GLsizei depth
,
8446 GLenum format
, GLenum type
,
8447 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8452 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8453 if (rc
!= 0) return rc
;
8455 if (width
< 1 || height
< 1 || depth
< 1) {
8456 return GLU_INVALID_VALUE
;
8459 if(type
== GL_BITMAP
) {
8460 return GLU_INVALID_ENUM
;
8463 levels
= computeLog(width
);
8464 level
= computeLog(height
);
8465 if (level
> levels
) levels
=level
;
8466 level
= computeLog(depth
);
8467 if (level
> levels
) levels
=level
;
8470 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8471 return GLU_INVALID_VALUE
;
8473 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8474 width
, height
, depth
,
8475 width
, height
, depth
,
8477 userLevel
, baseLevel
, maxLevel
,
8479 } /* gluBuild3DMipmapLevels() */
8482 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8483 GLsizei width
, GLsizei height
, GLsizei depth
,
8484 GLenum format
, GLenum type
, const void *data
)
8486 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8489 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8490 if (rc
!= 0) return rc
;
8492 if (width
< 1 || height
< 1 || depth
< 1) {
8493 return GLU_INVALID_VALUE
;
8496 if(type
== GL_BITMAP
) {
8497 return GLU_INVALID_ENUM
;
8500 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8501 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8503 levels
= computeLog(widthPowerOf2
);
8504 level
= computeLog(heightPowerOf2
);
8505 if (level
> levels
) levels
=level
;
8506 level
= computeLog(depthPowerOf2
);
8507 if (level
> levels
) levels
=level
;
8509 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8510 width
, height
, depth
,
8511 widthPowerOf2
, heightPowerOf2
,
8513 format
, type
, 0, 0, levels
,
8515 } /* gluBuild3DMipmaps() */
8517 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8519 isSwap
= isSwap
; /* turn off warnings */
8521 assert(*((const GLubyte
*)ubyte
) <= 255);
8523 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8524 } /* extractUbyte() */
8526 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8528 assert(0.0 <= value
&& value
< 256.0);
8530 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8531 } /* shoveUbyte() */
8533 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8535 isSwap
= isSwap
; /* turn off warnings */
8537 assert(*((const GLbyte
*)sbyte
) <= 127);
8539 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8540 } /* extractSbyte() */
8542 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8544 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8545 } /* shoveSbyte() */
8547 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8552 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8555 ushort
= *(const GLushort
*)uitem
;
8558 assert(ushort
<= 65535);
8560 return (GLdouble
)ushort
;
8561 } /* extractUshort() */
8563 static void shoveUshort(GLdouble value
, int index
, void *data
)
8565 assert(0.0 <= value
&& value
< 65536.0);
8567 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8568 } /* shoveUshort() */
8570 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8575 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8578 sshort
= *(const GLshort
*)sitem
;
8581 assert(sshort
<= 32767);
8583 return (GLdouble
)sshort
;
8584 } /* extractSshort() */
8586 static void shoveSshort(GLdouble value
, int index
, void *data
)
8588 assert(0.0 <= value
&& value
< 32768.0);
8590 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8591 } /* shoveSshort() */
8593 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8598 uint
= __GLU_SWAP_4_BYTES(uitem
);
8601 uint
= *(const GLuint
*)uitem
;
8604 assert(uint
<= 0xffffffff);
8606 return (GLdouble
)uint
;
8607 } /* extractUint() */
8609 static void shoveUint(GLdouble value
, int index
, void *data
)
8611 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8613 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8616 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8621 sint
= __GLU_SWAP_4_BYTES(sitem
);
8624 sint
= *(const GLint
*)sitem
;
8627 assert(sint
<= 0x7fffffff);
8629 return (GLdouble
)sint
;
8630 } /* extractSint() */
8632 static void shoveSint(GLdouble value
, int index
, void *data
)
8634 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8636 ((GLint
*)data
)[index
]= (GLint
)value
;
8639 static GLdouble
extractFloat(int isSwap
, const void *item
)
8644 ffloat
= __GLU_SWAP_4_BYTES(item
);
8647 ffloat
= *(const GLfloat
*)item
;
8650 assert(ffloat
<= 1.0);
8652 return (GLdouble
)ffloat
;
8653 } /* extractFloat() */
8655 static void shoveFloat(GLdouble value
, int index
, void *data
)
8657 assert(0.0 <= value
&& value
<= 1.0);
8659 ((GLfloat
*)data
)[index
]= value
;
8660 } /* shoveFloat() */
8662 static void halveImageSlice(int components
,
8663 GLdouble (*extract
)(int, const void *),
8664 void (*shove
)(GLdouble
, int, void *),
8665 GLint width
, GLint height
, GLint depth
,
8666 const void *dataIn
, void *dataOut
,
8667 GLint elementSizeInBytes
,
8668 GLint groupSizeInBytes
,
8669 GLint rowSizeInBytes
,
8670 GLint imageSizeInBytes
,
8674 int halfWidth
= width
/ 2;
8675 int halfHeight
= height
/ 2;
8676 int halfDepth
= depth
/ 2;
8677 const char *src
= (const char *)dataIn
;
8678 int rowPadBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8679 int imagePadBytes
= imageSizeInBytes
- (width
*height
*groupSizeInBytes
);
8682 assert((width
== 1 || height
== 1) && depth
>= 2);
8684 if (width
== height
) { /* a 1-pixel column viewed from top */
8685 /* printf("1-column\n");*/
8686 assert(width
== 1 && height
== 1);
8689 for (ii
= 0; ii
< halfDepth
; ii
++) {
8692 for (cc
= 0; cc
< components
; cc
++) {
8694 double extractTotals
[BOX2
][4];
8697 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8698 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8700 /* average 2 pixels since only a column */
8702 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8703 * totals[RED]/= 2.0;
8705 for (kk
= 0; kk
< BOX2
; kk
++) {
8706 totals
[cc
]+= extractTotals
[kk
][cc
];
8708 totals
[cc
]/= (double)BOX2
;
8710 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8712 src
+= elementSizeInBytes
;
8715 /* skip over to next group of 2 */
8716 src
+= rowSizeInBytes
;
8719 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8720 assert(outIndex
== halfDepth
* components
);
8722 else if (height
== 1) { /* horizontal slice viewed from top */
8723 /* printf("horizontal slice\n"); */
8726 for (ii
= 0; ii
< halfDepth
; ii
++) {
8727 for (jj
= 0; jj
< halfWidth
; jj
++) {
8730 for (cc
= 0; cc
< components
; cc
++) {
8733 double extractTotals
[BOX4
][4];
8735 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8736 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8737 (src
+groupSizeInBytes
));
8738 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8739 (src
+imageSizeInBytes
));
8740 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8741 (src
+imageSizeInBytes
+groupSizeInBytes
));
8743 /* grab 4 pixels to average */
8745 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8746 * extractTotals[2][RED]+extractTotals[3][RED];
8747 * totals[RED]/= 4.0;
8749 for (kk
= 0; kk
< BOX4
; kk
++) {
8750 totals
[cc
]+= extractTotals
[kk
][cc
];
8752 totals
[cc
]/= (double)BOX4
;
8754 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8757 src
+= elementSizeInBytes
;
8760 /* skip over to next horizontal square of 4 */
8761 src
+= groupSizeInBytes
;
8765 src
+= rowSizeInBytes
;
8768 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8769 assert(outIndex
== halfWidth
* halfDepth
* components
);
8771 else if (width
== 1) { /* vertical slice viewed from top */
8772 /* printf("vertical slice\n"); */
8773 assert(height
!= 1);
8775 for (ii
= 0; ii
< halfDepth
; ii
++) {
8776 for (jj
= 0; jj
< halfHeight
; jj
++) {
8779 for (cc
= 0; cc
< components
; cc
++) {
8782 double extractTotals
[BOX4
][4];
8784 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8785 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8786 (src
+rowSizeInBytes
));
8787 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8788 (src
+imageSizeInBytes
));
8789 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8790 (src
+imageSizeInBytes
+rowSizeInBytes
));
8792 /* grab 4 pixels to average */
8794 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8795 * extractTotals[2][RED]+extractTotals[3][RED];
8796 * totals[RED]/= 4.0;
8798 for (kk
= 0; kk
< BOX4
; kk
++) {
8799 totals
[cc
]+= extractTotals
[kk
][cc
];
8801 totals
[cc
]/= (double)BOX4
;
8803 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8806 src
+= elementSizeInBytes
;
8810 /* skip over to next vertical square of 4 */
8811 src
+= rowSizeInBytes
;
8813 src
+= imagePadBytes
;
8815 src
+= imageSizeInBytes
;
8818 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8819 assert(outIndex
== halfHeight
* halfDepth
* components
);
8822 } /* halveImageSlice() */
8824 static void halveImage3D(int components
,
8825 GLdouble (*extract
)(int, const void *),
8826 void (*shove
)(GLdouble
, int, void *),
8827 GLint width
, GLint height
, GLint depth
,
8828 const void *dataIn
, void *dataOut
,
8829 GLint elementSizeInBytes
,
8830 GLint groupSizeInBytes
,
8831 GLint rowSizeInBytes
,
8832 GLint imageSizeInBytes
,
8837 /* a horizontal/vertical/one-column slice viewed from top */
8838 if (width
== 1 || height
== 1) {
8841 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8842 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8843 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8849 int halfWidth
= width
/ 2;
8850 int halfHeight
= height
/ 2;
8851 int halfDepth
= depth
/ 2;
8852 const char *src
= (const char *) dataIn
;
8853 int rowPadBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8854 int imagePadBytes
= imageSizeInBytes
- (width
*height
*groupSizeInBytes
);
8857 for (dd
= 0; dd
< halfDepth
; dd
++) {
8858 for (ii
= 0; ii
< halfHeight
; ii
++) {
8859 for (jj
= 0; jj
< halfWidth
; jj
++) {
8862 for (cc
= 0; cc
< components
; cc
++) {
8865 double totals
[4]; /* 4 is maximum components */
8866 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8868 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8869 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8870 (src
+groupSizeInBytes
));
8871 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8872 (src
+rowSizeInBytes
));
8873 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8874 (src
+rowSizeInBytes
+groupSizeInBytes
));
8876 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8877 (src
+imageSizeInBytes
));
8879 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8880 (src
+groupSizeInBytes
+imageSizeInBytes
));
8881 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8882 (src
+rowSizeInBytes
+imageSizeInBytes
));
8883 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8884 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8888 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8889 * extractTotals[2][RED]+extractTotals[3][RED]+
8890 * extractTotals[4][RED]+extractTotals[5][RED]+
8891 * extractTotals[6][RED]+extractTotals[7][RED];
8892 * totals[RED]/= 8.0;
8894 for (kk
= 0; kk
< BOX8
; kk
++) {
8895 totals
[cc
]+= extractTotals
[kk
][cc
];
8897 totals
[cc
]/= (double)BOX8
;
8899 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8903 src
+= elementSizeInBytes
; /* go to next component */
8906 /* skip over to next square of 4 */
8907 src
+= groupSizeInBytes
;
8909 /* skip past pad bytes, if any, to get to next row */
8912 /* src is at beginning of a row here, but it's the second row of
8913 * the square block of 4 pixels that we just worked on so we
8914 * need to go one more row.
8922 src
+= rowSizeInBytes
;
8925 /* skip past pad bytes, if any, to get to next image */
8926 src
+= imagePadBytes
;
8928 src
+= imageSizeInBytes
;
8931 /* both pointers must reach one byte after the end */
8932 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8933 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8935 } /* halveImage3D() */