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 */
51 /* Pixel storage modes */
54 GLint pack_row_length
;
56 GLint pack_skip_pixels
;
58 GLint pack_swap_bytes
;
59 GLint pack_skip_images
;
60 GLint pack_image_height
;
62 GLint unpack_alignment
;
63 GLint unpack_row_length
;
64 GLint unpack_skip_rows
;
65 GLint unpack_skip_pixels
;
66 GLint unpack_lsb_first
;
67 GLint unpack_swap_bytes
;
68 GLint unpack_skip_images
;
69 GLint unpack_image_height
;
72 static int gluBuild1DMipmapLevelsCore(GLenum
, GLint
,
75 GLenum
, GLenum
, GLint
, GLint
, GLint
,
77 static int gluBuild2DMipmapLevelsCore(GLenum
, GLint
,
80 GLenum
, GLenum
, GLint
, GLint
, GLint
,
82 static int gluBuild3DMipmapLevelsCore(GLenum
, GLint
,
83 GLsizei
, GLsizei
, GLsizei
,
84 GLsizei
, GLsizei
, GLsizei
,
85 GLenum
, GLenum
, GLint
, GLint
, GLint
,
89 * internal function declarations
91 static GLfloat
bytes_per_element(GLenum type
);
92 static GLint
elements_per_group(GLenum format
, GLenum type
);
93 static GLint
is_index(GLenum format
);
94 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
);
95 static void fill_image(const PixelStorageModes
*,
96 GLint width
, GLint height
, GLenum format
,
97 GLenum type
, GLboolean index_format
,
98 const void *userdata
, GLushort
*newimage
);
99 static void empty_image(const PixelStorageModes
*,
100 GLint width
, GLint height
, GLenum format
,
101 GLenum type
, GLboolean index_format
,
102 const GLushort
*oldimage
, void *userdata
);
103 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
104 const GLushort
*datain
,
105 GLint widthout
, GLint heightout
,
108 static void scale_internal_ubyte(GLint components
, GLint widthin
,
109 GLint heightin
, const GLubyte
*datain
,
110 GLint widthout
, GLint heightout
,
111 GLubyte
*dataout
, GLint element_size
,
112 GLint ysize
, GLint group_size
);
113 static void scale_internal_byte(GLint components
, GLint widthin
,
114 GLint heightin
, const GLbyte
*datain
,
115 GLint widthout
, GLint heightout
,
116 GLbyte
*dataout
, GLint element_size
,
117 GLint ysize
, GLint group_size
);
118 static void scale_internal_ushort(GLint components
, GLint widthin
,
119 GLint heightin
, const GLushort
*datain
,
120 GLint widthout
, GLint heightout
,
121 GLushort
*dataout
, GLint element_size
,
122 GLint ysize
, GLint group_size
,
124 static void scale_internal_short(GLint components
, GLint widthin
,
125 GLint heightin
, const GLshort
*datain
,
126 GLint widthout
, GLint heightout
,
127 GLshort
*dataout
, GLint element_size
,
128 GLint ysize
, GLint group_size
,
130 static void scale_internal_uint(GLint components
, GLint widthin
,
131 GLint heightin
, const GLuint
*datain
,
132 GLint widthout
, GLint heightout
,
133 GLuint
*dataout
, GLint element_size
,
134 GLint ysize
, GLint group_size
,
136 static void scale_internal_int(GLint components
, GLint widthin
,
137 GLint heightin
, const GLint
*datain
,
138 GLint widthout
, GLint heightout
,
139 GLint
*dataout
, GLint element_size
,
140 GLint ysize
, GLint group_size
,
142 static void scale_internal_float(GLint components
, GLint widthin
,
143 GLint heightin
, const GLfloat
*datain
,
144 GLint widthout
, GLint heightout
,
145 GLfloat
*dataout
, GLint element_size
,
146 GLint ysize
, GLint group_size
,
149 static int checkMipmapArgs(GLenum
, GLenum
, GLenum
);
150 static GLboolean
legalFormat(GLenum
);
151 static GLboolean
legalType(GLenum
);
152 static GLboolean
isTypePackedPixel(GLenum
);
153 static GLboolean
isLegalFormatForPackedPixelType(GLenum
, GLenum
);
154 static GLboolean
isLegalLevels(GLint
, GLint
, GLint
, GLint
);
155 static void closestFit(GLenum
, GLint
, GLint
, GLint
, GLenum
, GLenum
,
158 /* all extract/shove routines must return double to handle unsigned ints */
159 static GLdouble
extractUbyte(int, const void *);
160 static void shoveUbyte(GLdouble
, int, void *);
161 static GLdouble
extractSbyte(int, const void *);
162 static void shoveSbyte(GLdouble
, int, void *);
163 static GLdouble
extractUshort(int, const void *);
164 static void shoveUshort(GLdouble
, int, void *);
165 static GLdouble
extractSshort(int, const void *);
166 static void shoveSshort(GLdouble
, int, void *);
167 static GLdouble
extractUint(int, const void *);
168 static void shoveUint(GLdouble
, int, void *);
169 static GLdouble
extractSint(int, const void *);
170 static void shoveSint(GLdouble
, int, void *);
171 static GLdouble
extractFloat(int, const void *);
172 static void shoveFloat(GLdouble
, int, void *);
173 static void halveImageSlice(int, GLdouble (*)(int, const void *),
174 void (*)(GLdouble
, int, void *),
176 const void *, void *,
177 GLint
, GLint
, GLint
, GLint
, GLint
);
178 static void halveImage3D(int, GLdouble (*)(int, const void *),
179 void (*)(GLdouble
, int, void *),
181 const void *, void *,
182 GLint
, GLint
, GLint
, GLint
, GLint
);
184 /* packedpixel type scale routines */
185 static void extract332(int,const void *, GLfloat
[]);
186 static void shove332(const GLfloat
[],int ,void *);
187 static void extract233rev(int,const void *, GLfloat
[]);
188 static void shove233rev(const GLfloat
[],int ,void *);
189 static void extract565(int,const void *, GLfloat
[]);
190 static void shove565(const GLfloat
[],int ,void *);
191 static void extract565rev(int,const void *, GLfloat
[]);
192 static void shove565rev(const GLfloat
[],int ,void *);
193 static void extract4444(int,const void *, GLfloat
[]);
194 static void shove4444(const GLfloat
[],int ,void *);
195 static void extract4444rev(int,const void *, GLfloat
[]);
196 static void shove4444rev(const GLfloat
[],int ,void *);
197 static void extract5551(int,const void *, GLfloat
[]);
198 static void shove5551(const GLfloat
[],int ,void *);
199 static void extract1555rev(int,const void *, GLfloat
[]);
200 static void shove1555rev(const GLfloat
[],int ,void *);
201 static void extract8888(int,const void *, GLfloat
[]);
202 static void shove8888(const GLfloat
[],int ,void *);
203 static void extract8888rev(int,const void *, GLfloat
[]);
204 static void shove8888rev(const GLfloat
[],int ,void *);
205 static void extract1010102(int,const void *, GLfloat
[]);
206 static void shove1010102(const GLfloat
[],int ,void *);
207 static void extract2101010rev(int,const void *, GLfloat
[]);
208 static void shove2101010rev(const GLfloat
[],int ,void *);
209 static void scaleInternalPackedPixel(int,
210 void (*)(int, const void *,GLfloat
[]),
211 void (*)(const GLfloat
[],int, void *),
212 GLint
,GLint
, const void *,
213 GLint
,GLint
,void *,GLint
,GLint
,GLint
);
214 static void halveImagePackedPixel(int,
215 void (*)(int, const void *,GLfloat
[]),
216 void (*)(const GLfloat
[],int, void *),
217 GLint
, GLint
, const void *,
218 void *, GLint
, GLint
, GLint
);
219 static void halve1DimagePackedPixel(int,
220 void (*)(int, const void *,GLfloat
[]),
221 void (*)(const GLfloat
[],int, void *),
222 GLint
, GLint
, const void *,
223 void *, GLint
, GLint
, GLint
);
225 static void halve1Dimage_ubyte(GLint
, GLuint
, GLuint
,const GLubyte
*,
226 GLubyte
*, GLint
, GLint
, GLint
);
227 static void halve1Dimage_byte(GLint
, GLuint
, GLuint
,const GLbyte
*, GLbyte
*,
228 GLint
, GLint
, GLint
);
229 static void halve1Dimage_ushort(GLint
, GLuint
, GLuint
, const GLushort
*,
230 GLushort
*, GLint
, GLint
, GLint
, GLint
);
231 static void halve1Dimage_short(GLint
, GLuint
, GLuint
,const GLshort
*, GLshort
*,
232 GLint
, GLint
, GLint
, GLint
);
233 static void halve1Dimage_uint(GLint
, GLuint
, GLuint
, const GLuint
*, GLuint
*,
234 GLint
, GLint
, GLint
, GLint
);
235 static void halve1Dimage_int(GLint
, GLuint
, GLuint
, const GLint
*, GLint
*,
236 GLint
, GLint
, GLint
, GLint
);
237 static void halve1Dimage_float(GLint
, GLuint
, GLuint
, const GLfloat
*, GLfloat
*,
238 GLint
, GLint
, GLint
, GLint
);
240 static GLint
imageSize3D(GLint
, GLint
, GLint
, GLenum
,GLenum
);
241 static void fillImage3D(const PixelStorageModes
*, GLint
, GLint
, GLint
,GLenum
,
242 GLenum
, GLboolean
, const void *, GLushort
*);
243 static void emptyImage3D(const PixelStorageModes
*,
244 GLint
, GLint
, GLint
, GLenum
,
246 const GLushort
*, void *);
247 static void scaleInternal3D(GLint
, GLint
, GLint
, GLint
, const GLushort
*,
248 GLint
, GLint
, GLint
, GLushort
*);
250 static void retrieveStoreModes(PixelStorageModes
*psm
)
252 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
253 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
254 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
255 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
256 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
257 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
259 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
260 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
261 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
262 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
263 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
264 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
267 static void retrieveStoreModes3D(PixelStorageModes
*psm
)
269 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
270 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
271 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
272 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
273 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
274 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
275 glGetIntegerv(GL_UNPACK_SKIP_IMAGES
, &psm
->unpack_skip_images
);
276 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT
, &psm
->unpack_image_height
);
278 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
279 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
280 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
281 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
282 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
283 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
284 glGetIntegerv(GL_PACK_SKIP_IMAGES
, &psm
->pack_skip_images
);
285 glGetIntegerv(GL_PACK_IMAGE_HEIGHT
, &psm
->pack_image_height
);
288 static int computeLog(GLuint value
)
295 if (value
== 0) return -1;
300 if (value
!= 1) return -1;
309 ** Compute the nearest power of 2 number. This algorithm is a little
310 ** strange, but it works quite well.
312 static int nearestPower(GLuint value
)
319 if (value
== 0) return -1;
324 } else if (value
== 3) {
332 #define __GLU_SWAP_2_BYTES(s)\
333 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
335 #define __GLU_SWAP_4_BYTES(s)\
336 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
337 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
338 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
340 static void halveImage(GLint components
, GLuint width
, GLuint height
,
341 const GLushort
*datain
, GLushort
*dataout
)
344 int newwidth
, newheight
;
349 newwidth
= width
/ 2;
350 newheight
= height
/ 2;
351 delta
= width
* components
;
356 for (i
= 0; i
< newheight
; i
++) {
357 for (j
= 0; j
< newwidth
; j
++) {
358 for (k
= 0; k
< components
; k
++) {
359 s
[0] = (t
[0] + t
[components
] + t
[delta
] +
360 t
[delta
+components
] + 2) / 4;
369 static void halveImage_ubyte(GLint components
, GLuint width
, GLuint height
,
370 const GLubyte
*datain
, GLubyte
*dataout
,
371 GLint element_size
, GLint ysize
, GLint group_size
)
374 int newwidth
, newheight
;
379 /* handle case where there is only 1 column/row */
380 if (width
== 1 || height
== 1) {
381 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
382 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
383 element_size
,ysize
,group_size
);
387 newwidth
= width
/ 2;
388 newheight
= height
/ 2;
389 padBytes
= ysize
- (width
*group_size
);
391 t
= (const char *)datain
;
394 for (i
= 0; i
< newheight
; i
++) {
395 for (j
= 0; j
< newwidth
; j
++) {
396 for (k
= 0; k
< components
; k
++) {
397 s
[0] = (*(const GLubyte
*)t
+
398 *(const GLubyte
*)(t
+group_size
) +
399 *(const GLubyte
*)(t
+ysize
) +
400 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
401 s
++; t
+= element_size
;
411 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
412 const GLubyte
*dataIn
, GLubyte
*dataOut
,
413 GLint element_size
, GLint ysize
,
416 GLint halfWidth
= width
/ 2;
417 GLint halfHeight
= height
/ 2;
418 const char *src
= (const char *) dataIn
;
419 GLubyte
*dest
= dataOut
;
422 assert(width
== 1 || height
== 1); /* must be 1D */
423 assert(width
!= height
); /* can't be square */
425 if (height
== 1) { /* 1 row */
426 assert(width
!= 1); /* widthxheight can't be 1x1 */
429 for (jj
= 0; jj
< halfWidth
; jj
++) {
431 for (kk
= 0; kk
< components
; kk
++) {
432 *dest
= (*(const GLubyte
*)src
+
433 *(const GLubyte
*)(src
+group_size
)) / 2;
438 src
+= group_size
; /* skip to next 2 */
441 int padBytes
= ysize
- (width
*group_size
);
442 src
+= padBytes
; /* for assertion only */
445 else if (width
== 1) { /* 1 column */
446 int padBytes
= ysize
- (width
* group_size
);
447 assert(height
!= 1); /* widthxheight can't be 1x1 */
449 /* one vertical column with possible pad bytes per row */
450 /* average two at a time */
452 for (jj
= 0; jj
< halfHeight
; jj
++) {
454 for (kk
= 0; kk
< components
; kk
++) {
455 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
460 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
465 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
466 assert((char *)dest
== &((char *)dataOut
)
467 [components
* element_size
* halfWidth
* halfHeight
]);
468 } /* halve1Dimage_ubyte() */
470 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
471 const GLbyte
*datain
, GLbyte
*dataout
,
473 GLint ysize
, GLint group_size
)
476 int newwidth
, newheight
;
481 /* handle case where there is only 1 column/row */
482 if (width
== 1 || height
== 1) {
483 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
484 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
485 element_size
,ysize
,group_size
);
489 newwidth
= width
/ 2;
490 newheight
= height
/ 2;
491 padBytes
= ysize
- (width
*group_size
);
493 t
= (const char *)datain
;
496 for (i
= 0; i
< newheight
; i
++) {
497 for (j
= 0; j
< newwidth
; j
++) {
498 for (k
= 0; k
< components
; k
++) {
499 s
[0] = (*(const GLbyte
*)t
+
500 *(const GLbyte
*)(t
+group_size
) +
501 *(const GLbyte
*)(t
+ysize
) +
502 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
503 s
++; t
+= element_size
;
512 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
513 const GLbyte
*dataIn
, GLbyte
*dataOut
,
514 GLint element_size
,GLint ysize
, GLint group_size
)
516 GLint halfWidth
= width
/ 2;
517 GLint halfHeight
= height
/ 2;
518 const char *src
= (const char *) dataIn
;
519 GLbyte
*dest
= dataOut
;
522 assert(width
== 1 || height
== 1); /* must be 1D */
523 assert(width
!= height
); /* can't be square */
525 if (height
== 1) { /* 1 row */
526 assert(width
!= 1); /* widthxheight can't be 1x1 */
529 for (jj
= 0; jj
< halfWidth
; jj
++) {
531 for (kk
= 0; kk
< components
; kk
++) {
532 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
537 src
+= group_size
; /* skip to next 2 */
540 int padBytes
= ysize
- (width
*group_size
);
541 src
+= padBytes
; /* for assertion only */
544 else if (width
== 1) { /* 1 column */
545 int padBytes
= ysize
- (width
* group_size
);
546 assert(height
!= 1); /* widthxheight can't be 1x1 */
548 /* one vertical column with possible pad bytes per row */
549 /* average two at a time */
551 for (jj
= 0; jj
< halfHeight
; jj
++) {
553 for (kk
= 0; kk
< components
; kk
++) {
554 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
559 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
563 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
566 assert((char *)dest
== &((char *)dataOut
)
567 [components
* element_size
* halfWidth
* halfHeight
]);
568 } /* halve1Dimage_byte() */
570 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
571 const GLushort
*datain
, GLushort
*dataout
,
572 GLint element_size
, GLint ysize
, GLint group_size
,
576 int newwidth
, newheight
;
581 /* handle case where there is only 1 column/row */
582 if (width
== 1 || height
== 1) {
583 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
584 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
585 element_size
,ysize
,group_size
, myswap_bytes
);
589 newwidth
= width
/ 2;
590 newheight
= height
/ 2;
591 padBytes
= ysize
- (width
*group_size
);
593 t
= (const char *)datain
;
597 for (i
= 0; i
< newheight
; i
++) {
598 for (j
= 0; j
< newwidth
; j
++) {
599 for (k
= 0; k
< components
; k
++) {
600 s
[0] = (*(const GLushort
*)t
+
601 *(const GLushort
*)(t
+group_size
) +
602 *(const GLushort
*)(t
+ysize
) +
603 *(const GLushort
*)(t
+ysize
+group_size
) + 2) / 4;
604 s
++; t
+= element_size
;
612 for (i
= 0; i
< newheight
; i
++) {
613 for (j
= 0; j
< newwidth
; j
++) {
614 for (k
= 0; k
< components
; k
++) {
615 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
616 __GLU_SWAP_2_BYTES(t
+group_size
) +
617 __GLU_SWAP_2_BYTES(t
+ysize
) +
618 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
619 s
++; t
+= element_size
;
628 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
629 const GLushort
*dataIn
, GLushort
*dataOut
,
630 GLint element_size
, GLint ysize
,
631 GLint group_size
, GLint myswap_bytes
)
633 GLint halfWidth
= width
/ 2;
634 GLint halfHeight
= height
/ 2;
635 const char *src
= (const char *) dataIn
;
636 GLushort
*dest
= dataOut
;
639 assert(width
== 1 || height
== 1); /* must be 1D */
640 assert(width
!= height
); /* can't be square */
642 if (height
== 1) { /* 1 row */
643 assert(width
!= 1); /* widthxheight can't be 1x1 */
646 for (jj
= 0; jj
< halfWidth
; jj
++) {
648 for (kk
= 0; kk
< components
; kk
++) {
650 GLushort ushort
[BOX2
];
652 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
653 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
656 ushort
[0]= *(const GLushort
*)src
;
657 ushort
[1]= *(const GLushort
*)(src
+group_size
);
660 *dest
= (ushort
[0] + ushort
[1]) / 2;
664 src
+= group_size
; /* skip to next 2 */
667 int padBytes
= ysize
- (width
*group_size
);
668 src
+= padBytes
; /* for assertion only */
671 else if (width
== 1) { /* 1 column */
672 int padBytes
= ysize
- (width
* group_size
);
673 assert(height
!= 1); /* widthxheight can't be 1x1 */
675 /* one vertical column with possible pad bytes per row */
676 /* average two at a time */
678 for (jj
= 0; jj
< halfHeight
; jj
++) {
680 for (kk
= 0; kk
< components
; kk
++) {
682 GLushort ushort
[BOX2
];
684 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
685 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
688 ushort
[0]= *(const GLushort
*)src
;
689 ushort
[1]= *(const GLushort
*)(src
+ysize
);
691 *dest
= (ushort
[0] + ushort
[1]) / 2;
696 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
700 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
703 assert((char *)dest
== &((char *)dataOut
)
704 [components
* element_size
* halfWidth
* halfHeight
]);
706 } /* halve1Dimage_ushort() */
709 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
710 const GLshort
*datain
, GLshort
*dataout
,
711 GLint element_size
, GLint ysize
, GLint group_size
,
715 int newwidth
, newheight
;
720 /* handle case where there is only 1 column/row */
721 if (width
== 1 || height
== 1) {
722 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
723 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
724 element_size
,ysize
,group_size
, myswap_bytes
);
728 newwidth
= width
/ 2;
729 newheight
= height
/ 2;
730 padBytes
= ysize
- (width
*group_size
);
732 t
= (const char *)datain
;
736 for (i
= 0; i
< newheight
; i
++) {
737 for (j
= 0; j
< newwidth
; j
++) {
738 for (k
= 0; k
< components
; k
++) {
739 s
[0] = (*(const GLshort
*)t
+
740 *(const GLshort
*)(t
+group_size
) +
741 *(const GLshort
*)(t
+ysize
) +
742 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
743 s
++; t
+= element_size
;
751 for (i
= 0; i
< newheight
; i
++) {
752 for (j
= 0; j
< newwidth
; j
++) {
753 for (k
= 0; k
< components
; k
++) {
756 b
= __GLU_SWAP_2_BYTES(t
);
757 buf
= *(const GLshort
*)&b
;
758 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
759 buf
+= *(const GLshort
*)&b
;
760 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
761 buf
+= *(const GLshort
*)&b
;
762 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
763 buf
+= *(const GLshort
*)&b
;
764 s
[0] = (GLshort
)((buf
+2)/4);
765 s
++; t
+= element_size
;
774 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
775 const GLshort
*dataIn
, GLshort
*dataOut
,
776 GLint element_size
, GLint ysize
,
777 GLint group_size
, GLint myswap_bytes
)
779 GLint halfWidth
= width
/ 2;
780 GLint halfHeight
= height
/ 2;
781 const char *src
= (const char *) dataIn
;
782 GLshort
*dest
= dataOut
;
785 assert(width
== 1 || height
== 1); /* must be 1D */
786 assert(width
!= height
); /* can't be square */
788 if (height
== 1) { /* 1 row */
789 assert(width
!= 1); /* widthxheight can't be 1x1 */
792 for (jj
= 0; jj
< halfWidth
; jj
++) {
794 for (kk
= 0; kk
< components
; kk
++) {
796 GLshort sshort
[BOX2
];
798 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
799 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
802 sshort
[0]= *(const GLshort
*)src
;
803 sshort
[1]= *(const GLshort
*)(src
+group_size
);
806 *dest
= (sshort
[0] + sshort
[1]) / 2;
810 src
+= group_size
; /* skip to next 2 */
813 int padBytes
= ysize
- (width
*group_size
);
814 src
+= padBytes
; /* for assertion only */
817 else if (width
== 1) { /* 1 column */
818 int padBytes
= ysize
- (width
* group_size
);
819 assert(height
!= 1); /* widthxheight can't be 1x1 */
821 /* one vertical column with possible pad bytes per row */
822 /* average two at a time */
824 for (jj
= 0; jj
< halfHeight
; jj
++) {
826 for (kk
= 0; kk
< components
; kk
++) {
828 GLshort sshort
[BOX2
];
830 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
831 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
834 sshort
[0]= *(const GLshort
*)src
;
835 sshort
[1]= *(const GLshort
*)(src
+ysize
);
837 *dest
= (sshort
[0] + sshort
[1]) / 2;
842 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
846 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
849 assert((char *)dest
== &((char *)dataOut
)
850 [components
* element_size
* halfWidth
* halfHeight
]);
852 } /* halve1Dimage_short() */
855 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
856 const GLuint
*datain
, GLuint
*dataout
,
857 GLint element_size
, GLint ysize
, GLint group_size
,
861 int newwidth
, newheight
;
866 /* handle case where there is only 1 column/row */
867 if (width
== 1 || height
== 1) {
868 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
869 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
870 element_size
,ysize
,group_size
, myswap_bytes
);
874 newwidth
= width
/ 2;
875 newheight
= height
/ 2;
876 padBytes
= ysize
- (width
*group_size
);
878 t
= (const char *)datain
;
882 for (i
= 0; i
< newheight
; i
++) {
883 for (j
= 0; j
< newwidth
; j
++) {
884 for (k
= 0; k
< components
; k
++) {
885 /* need to cast to double to hold large unsigned ints */
886 s
[0] = ((double)*(const GLuint
*)t
+
887 (double)*(const GLuint
*)(t
+group_size
) +
888 (double)*(const GLuint
*)(t
+ysize
) +
889 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
890 s
++; t
+= element_size
;
899 for (i
= 0; i
< newheight
; i
++) {
900 for (j
= 0; j
< newwidth
; j
++) {
901 for (k
= 0; k
< components
; k
++) {
902 /* need to cast to double to hold large unsigned ints */
904 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
905 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
906 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
907 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
908 s
[0] = (GLuint
)(buf
/4 + 0.5);
910 s
++; t
+= element_size
;
920 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
921 const GLuint
*dataIn
, GLuint
*dataOut
,
922 GLint element_size
, GLint ysize
,
923 GLint group_size
, GLint myswap_bytes
)
925 GLint halfWidth
= width
/ 2;
926 GLint halfHeight
= height
/ 2;
927 const char *src
= (const char *) dataIn
;
928 GLuint
*dest
= dataOut
;
931 assert(width
== 1 || height
== 1); /* must be 1D */
932 assert(width
!= height
); /* can't be square */
934 if (height
== 1) { /* 1 row */
935 assert(width
!= 1); /* widthxheight can't be 1x1 */
938 for (jj
= 0; jj
< halfWidth
; jj
++) {
940 for (kk
= 0; kk
< components
; kk
++) {
944 uint
[0]= __GLU_SWAP_4_BYTES(src
);
945 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
948 uint
[0]= *(const GLuint
*)src
;
949 uint
[1]= *(const GLuint
*)(src
+group_size
);
951 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
956 src
+= group_size
; /* skip to next 2 */
959 int padBytes
= ysize
- (width
*group_size
);
960 src
+= padBytes
; /* for assertion only */
963 else if (width
== 1) { /* 1 column */
964 int padBytes
= ysize
- (width
* group_size
);
965 assert(height
!= 1); /* widthxheight can't be 1x1 */
967 /* one vertical column with possible pad bytes per row */
968 /* average two at a time */
970 for (jj
= 0; jj
< halfHeight
; jj
++) {
972 for (kk
= 0; kk
< components
; kk
++) {
976 uint
[0]= __GLU_SWAP_4_BYTES(src
);
977 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
980 uint
[0]= *(const GLuint
*)src
;
981 uint
[1]= *(const GLuint
*)(src
+ysize
);
983 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
988 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
992 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
995 assert((char *)dest
== &((char *)dataOut
)
996 [components
* element_size
* halfWidth
* halfHeight
]);
998 } /* halve1Dimage_uint() */
1000 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
1001 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
1002 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
1005 int newwidth
, newheight
;
1010 /* handle case where there is only 1 column/row */
1011 if (width
== 1 || height
== 1) {
1012 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1013 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1014 element_size
,ysize
,group_size
, myswap_bytes
);
1018 newwidth
= width
/ 2;
1019 newheight
= height
/ 2;
1020 padBytes
= ysize
- (width
*group_size
);
1022 t
= (const char *)datain
;
1024 /* Piece o' cake! */
1026 for (i
= 0; i
< newheight
; i
++) {
1027 for (j
= 0; j
< newwidth
; j
++) {
1028 for (k
= 0; k
< components
; k
++) {
1029 s
[0] = ((float)*(const GLint
*)t
+
1030 (float)*(const GLint
*)(t
+group_size
) +
1031 (float)*(const GLint
*)(t
+ysize
) +
1032 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1033 s
++; t
+= element_size
;
1041 for (i
= 0; i
< newheight
; i
++) {
1042 for (j
= 0; j
< newwidth
; j
++) {
1043 for (k
= 0; k
< components
; k
++) {
1046 b
= __GLU_SWAP_4_BYTES(t
);
1048 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1050 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1052 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1054 s
[0] = (GLint
)(buf
/4 + 0.5);
1056 s
++; t
+= element_size
;
1066 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1067 const GLint
*dataIn
, GLint
*dataOut
,
1068 GLint element_size
, GLint ysize
,
1069 GLint group_size
, GLint myswap_bytes
)
1071 GLint halfWidth
= width
/ 2;
1072 GLint halfHeight
= height
/ 2;
1073 const char *src
= (const char *) dataIn
;
1074 GLint
*dest
= dataOut
;
1077 assert(width
== 1 || height
== 1); /* must be 1D */
1078 assert(width
!= height
); /* can't be square */
1080 if (height
== 1) { /* 1 row */
1081 assert(width
!= 1); /* widthxheight can't be 1x1 */
1084 for (jj
= 0; jj
< halfWidth
; jj
++) {
1086 for (kk
= 0; kk
< components
; kk
++) {
1090 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1091 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1094 uint
[0]= *(const GLuint
*)src
;
1095 uint
[1]= *(const GLuint
*)(src
+group_size
);
1097 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1102 src
+= group_size
; /* skip to next 2 */
1105 int padBytes
= ysize
- (width
*group_size
);
1106 src
+= padBytes
; /* for assertion only */
1109 else if (width
== 1) { /* 1 column */
1110 int padBytes
= ysize
- (width
* group_size
);
1111 assert(height
!= 1); /* widthxheight can't be 1x1 */
1113 /* one vertical column with possible pad bytes per row */
1114 /* average two at a time */
1116 for (jj
= 0; jj
< halfHeight
; jj
++) {
1118 for (kk
= 0; kk
< components
; kk
++) {
1122 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1123 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1126 uint
[0]= *(const GLuint
*)src
;
1127 uint
[1]= *(const GLuint
*)(src
+ysize
);
1129 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1134 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1138 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1141 assert((char *)dest
== &((char *)dataOut
)
1142 [components
* element_size
* halfWidth
* halfHeight
]);
1144 } /* halve1Dimage_int() */
1147 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1148 const GLfloat
*datain
, GLfloat
*dataout
,
1149 GLint element_size
, GLint ysize
, GLint group_size
,
1153 int newwidth
, newheight
;
1158 /* handle case where there is only 1 column/row */
1159 if (width
== 1 || height
== 1) {
1160 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1161 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1162 element_size
,ysize
,group_size
, myswap_bytes
);
1166 newwidth
= width
/ 2;
1167 newheight
= height
/ 2;
1168 padBytes
= ysize
- (width
*group_size
);
1170 t
= (const char *)datain
;
1172 /* Piece o' cake! */
1174 for (i
= 0; i
< newheight
; i
++) {
1175 for (j
= 0; j
< newwidth
; j
++) {
1176 for (k
= 0; k
< components
; k
++) {
1177 s
[0] = (*(const GLfloat
*)t
+
1178 *(const GLfloat
*)(t
+group_size
) +
1179 *(const GLfloat
*)(t
+ysize
) +
1180 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1181 s
++; t
+= element_size
;
1189 for (i
= 0; i
< newheight
; i
++) {
1190 for (j
= 0; j
< newwidth
; j
++) {
1191 for (k
= 0; k
< components
; k
++) {
1192 union { GLuint b
; GLfloat f
; } swapbuf
;
1193 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
);
1195 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1197 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1199 swapbuf
.b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1202 s
++; t
+= element_size
;
1212 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1213 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1214 GLint element_size
, GLint ysize
,
1215 GLint group_size
, GLint myswap_bytes
)
1217 GLint halfWidth
= width
/ 2;
1218 GLint halfHeight
= height
/ 2;
1219 const char *src
= (const char *) dataIn
;
1220 GLfloat
*dest
= dataOut
;
1223 assert(width
== 1 || height
== 1); /* must be 1D */
1224 assert(width
!= height
); /* can't be square */
1226 if (height
== 1) { /* 1 row */
1227 assert(width
!= 1); /* widthxheight can't be 1x1 */
1230 for (jj
= 0; jj
< halfWidth
; jj
++) {
1232 for (kk
= 0; kk
< components
; kk
++) {
1234 GLfloat sfloat
[BOX2
];
1236 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1237 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1240 sfloat
[0]= *(const GLfloat
*)src
;
1241 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1244 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1248 src
+= group_size
; /* skip to next 2 */
1251 int padBytes
= ysize
- (width
*group_size
);
1252 src
+= padBytes
; /* for assertion only */
1255 else if (width
== 1) { /* 1 column */
1256 int padBytes
= ysize
- (width
* group_size
);
1257 assert(height
!= 1); /* widthxheight can't be 1x1 */
1259 /* one vertical column with possible pad bytes per row */
1260 /* average two at a time */
1262 for (jj
= 0; jj
< halfHeight
; jj
++) {
1264 for (kk
= 0; kk
< components
; kk
++) {
1266 GLfloat sfloat
[BOX2
];
1268 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1269 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1272 sfloat
[0]= *(const GLfloat
*)src
;
1273 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1275 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1280 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1281 src
+= ysize
; /* skip to odd row */
1285 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1286 assert((char *)dest
== &((char *)dataOut
)
1287 [components
* element_size
* halfWidth
* halfHeight
]);
1288 } /* halve1Dimage_float() */
1290 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1291 const GLushort
*datain
,
1292 GLint widthout
, GLint heightout
,
1295 float x
, lowx
, highx
, convx
, halfconvx
;
1296 float y
, lowy
, highy
, convy
, halfconvy
;
1297 float xpercent
,ypercent
;
1299 /* Max components in a format is 4, so... */
1302 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1305 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1306 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1309 convy
= (float) heightin
/heightout
;
1310 convx
= (float) widthin
/widthout
;
1311 halfconvx
= convx
/2;
1312 halfconvy
= convy
/2;
1313 for (i
= 0; i
< heightout
; i
++) {
1314 y
= convy
* (i
+0.5);
1315 if (heightin
> heightout
) {
1316 highy
= y
+ halfconvy
;
1317 lowy
= y
- halfconvy
;
1322 for (j
= 0; j
< widthout
; j
++) {
1323 x
= convx
* (j
+0.5);
1324 if (widthin
> widthout
) {
1325 highx
= x
+ halfconvx
;
1326 lowx
= x
- halfconvx
;
1333 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1334 ** to (highx, highy) on input data into this pixel on output
1337 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1343 yindex
= (yint
+ heightin
) % heightin
;
1344 if (highy
< yint
+1) {
1345 ypercent
= highy
- y
;
1347 ypercent
= yint
+1 - y
;
1354 xindex
= (xint
+ widthin
) % widthin
;
1355 if (highx
< xint
+1) {
1356 xpercent
= highx
- x
;
1358 xpercent
= xint
+1 - x
;
1361 percent
= xpercent
* ypercent
;
1363 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1364 for (k
= 0; k
< components
; k
++) {
1365 totals
[k
] += datain
[temp
+ k
] * percent
;
1375 temp
= (j
+ (i
* widthout
)) * components
;
1376 for (k
= 0; k
< components
; k
++) {
1377 /* totals[] should be rounded in the case of enlarging an RGB
1378 * ramp when the type is 332 or 4444
1380 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1386 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1387 GLint heightin
, const GLubyte
*datain
,
1388 GLint widthout
, GLint heightout
,
1389 GLubyte
*dataout
, GLint element_size
,
1390 GLint ysize
, GLint group_size
)
1395 /* Max components in a format is 4, so... */
1400 const char *temp
, *temp0
;
1401 const char *temp_index
;
1404 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1405 float x_percent
, y_percent
;
1406 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1407 float convy_float
, convx_float
;
1408 int convy_int
, convx_int
;
1410 const char *left
, *right
;
1412 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1413 halveImage_ubyte(components
, widthin
, heightin
,
1414 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1415 element_size
, ysize
, group_size
);
1418 convy
= (float) heightin
/heightout
;
1419 convx
= (float) widthin
/widthout
;
1420 convy_int
= floor(convy
);
1421 convy_float
= convy
- convy_int
;
1422 convx_int
= floor(convx
);
1423 convx_float
= convx
- convx_int
;
1425 area
= convx
* convy
;
1429 highy_int
= convy_int
;
1430 highy_float
= convy_float
;
1432 for (i
= 0; i
< heightout
; i
++) {
1433 /* Clamp here to be sure we don't read beyond input buffer. */
1434 if (highy_int
>= heightin
)
1435 highy_int
= heightin
- 1;
1438 highx_int
= convx_int
;
1439 highx_float
= convx_float
;
1441 for (j
= 0; j
< widthout
; j
++) {
1444 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1445 ** to (highx, highy) on input data into this pixel on output
1448 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1450 /* calculate the value for pixels in the 1st row */
1451 xindex
= lowx_int
*group_size
;
1452 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1454 y_percent
= 1-lowy_float
;
1455 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1456 percent
= y_percent
* (1-lowx_float
);
1457 for (k
= 0, temp_index
= temp
; k
< components
;
1458 k
++, temp_index
+= element_size
) {
1459 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1462 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1464 for (k
= 0, temp_index
= temp
; k
< components
;
1465 k
++, temp_index
+= element_size
) {
1466 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1471 percent
= y_percent
* highx_float
;
1472 for (k
= 0, temp_index
= temp
; k
< components
;
1473 k
++, temp_index
+= element_size
) {
1474 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1477 /* calculate the value for pixels in the last row */
1478 y_percent
= highy_float
;
1479 percent
= y_percent
* (1-lowx_float
);
1480 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1481 for (k
= 0, temp_index
= temp
; k
< components
;
1482 k
++, temp_index
+= element_size
) {
1483 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1485 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1487 for (k
= 0, temp_index
= temp
; k
< components
;
1488 k
++, temp_index
+= element_size
) {
1489 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1493 percent
= y_percent
* highx_float
;
1494 for (k
= 0, temp_index
= temp
; k
< components
;
1495 k
++, temp_index
+= element_size
) {
1496 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1500 /* calculate the value for pixels in the 1st and last column */
1501 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1504 for (k
= 0; k
< components
;
1505 k
++, left
+= element_size
, right
+= element_size
) {
1506 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1507 +(GLubyte
)(*(right
))*highx_float
;
1510 } else if (highy_int
> lowy_int
) {
1511 x_percent
= highx_float
- lowx_float
;
1512 percent
= (1-lowy_float
)*x_percent
;
1513 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1514 for (k
= 0, temp_index
= temp
; k
< components
;
1515 k
++, temp_index
+= element_size
) {
1516 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1518 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1520 for (k
= 0, temp_index
= temp
; k
< components
;
1521 k
++, temp_index
+= element_size
) {
1522 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1525 percent
= x_percent
* highy_float
;
1527 for (k
= 0, temp_index
= temp
; k
< components
;
1528 k
++, temp_index
+= element_size
) {
1529 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1531 } else if (highx_int
> lowx_int
) {
1532 y_percent
= highy_float
- lowy_float
;
1533 percent
= (1-lowx_float
)*y_percent
;
1534 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1535 for (k
= 0, temp_index
= temp
; k
< components
;
1536 k
++, temp_index
+= element_size
) {
1537 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1539 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1541 for (k
= 0, temp_index
= temp
; k
< components
;
1542 k
++, temp_index
+= element_size
) {
1543 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1547 percent
= y_percent
* highx_float
;
1548 for (k
= 0, temp_index
= temp
; k
< components
;
1549 k
++, temp_index
+= element_size
) {
1550 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1553 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1554 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1555 for (k
= 0, temp_index
= temp
; k
< components
;
1556 k
++, temp_index
+= element_size
) {
1557 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1563 /* this is for the pixels in the body */
1564 temp0
= (const char *)datain
+ xindex
+ group_size
+
1566 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1568 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1569 for (k
= 0, temp_index
= temp
; k
< components
;
1570 k
++, temp_index
+= element_size
) {
1571 totals
[k
] += (GLubyte
)(*(temp_index
));
1578 outindex
= (j
+ (i
* widthout
)) * components
;
1579 for (k
= 0; k
< components
; k
++) {
1580 dataout
[outindex
+ k
] = totals
[k
]/area
;
1581 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1583 lowx_int
= highx_int
;
1584 lowx_float
= highx_float
;
1585 highx_int
+= convx_int
;
1586 highx_float
+= convx_float
;
1587 if(highx_float
> 1) {
1592 lowy_int
= highy_int
;
1593 lowy_float
= highy_float
;
1594 highy_int
+= convy_int
;
1595 highy_float
+= convy_float
;
1596 if(highy_float
> 1) {
1603 static void scale_internal_byte(GLint components
, GLint widthin
,
1604 GLint heightin
, const GLbyte
*datain
,
1605 GLint widthout
, GLint heightout
,
1606 GLbyte
*dataout
, GLint element_size
,
1607 GLint ysize
, GLint group_size
)
1612 /* Max components in a format is 4, so... */
1617 const char *temp
, *temp0
;
1618 const char *temp_index
;
1621 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1622 float x_percent
, y_percent
;
1623 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1624 float convy_float
, convx_float
;
1625 int convy_int
, convx_int
;
1627 const char *left
, *right
;
1629 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1630 halveImage_byte(components
, widthin
, heightin
,
1631 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1632 element_size
, ysize
, group_size
);
1635 convy
= (float) heightin
/heightout
;
1636 convx
= (float) widthin
/widthout
;
1637 convy_int
= floor(convy
);
1638 convy_float
= convy
- convy_int
;
1639 convx_int
= floor(convx
);
1640 convx_float
= convx
- convx_int
;
1642 area
= convx
* convy
;
1646 highy_int
= convy_int
;
1647 highy_float
= convy_float
;
1649 for (i
= 0; i
< heightout
; i
++) {
1650 /* Clamp here to be sure we don't read beyond input buffer. */
1651 if (highy_int
>= heightin
)
1652 highy_int
= heightin
- 1;
1655 highx_int
= convx_int
;
1656 highx_float
= convx_float
;
1658 for (j
= 0; j
< widthout
; j
++) {
1661 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1662 ** to (highx, highy) on input data into this pixel on output
1665 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1667 /* calculate the value for pixels in the 1st row */
1668 xindex
= lowx_int
*group_size
;
1669 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1671 y_percent
= 1-lowy_float
;
1672 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1673 percent
= y_percent
* (1-lowx_float
);
1674 for (k
= 0, temp_index
= temp
; k
< components
;
1675 k
++, temp_index
+= element_size
) {
1676 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1679 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1681 for (k
= 0, temp_index
= temp
; k
< components
;
1682 k
++, temp_index
+= element_size
) {
1683 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1688 percent
= y_percent
* highx_float
;
1689 for (k
= 0, temp_index
= temp
; k
< components
;
1690 k
++, temp_index
+= element_size
) {
1691 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1694 /* calculate the value for pixels in the last row */
1695 y_percent
= highy_float
;
1696 percent
= y_percent
* (1-lowx_float
);
1697 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1698 for (k
= 0, temp_index
= temp
; k
< components
;
1699 k
++, temp_index
+= element_size
) {
1700 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1702 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1704 for (k
= 0, temp_index
= temp
; k
< components
;
1705 k
++, temp_index
+= element_size
) {
1706 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1710 percent
= y_percent
* highx_float
;
1711 for (k
= 0, temp_index
= temp
; k
< components
;
1712 k
++, temp_index
+= element_size
) {
1713 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1717 /* calculate the value for pixels in the 1st and last column */
1718 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1721 for (k
= 0; k
< components
;
1722 k
++, left
+= element_size
, right
+= element_size
) {
1723 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1724 +(GLbyte
)(*(right
))*highx_float
;
1727 } else if (highy_int
> lowy_int
) {
1728 x_percent
= highx_float
- lowx_float
;
1729 percent
= (1-lowy_float
)*x_percent
;
1730 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1731 for (k
= 0, temp_index
= temp
; k
< components
;
1732 k
++, temp_index
+= element_size
) {
1733 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1735 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1737 for (k
= 0, temp_index
= temp
; k
< components
;
1738 k
++, temp_index
+= element_size
) {
1739 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1742 percent
= x_percent
* highy_float
;
1744 for (k
= 0, temp_index
= temp
; k
< components
;
1745 k
++, temp_index
+= element_size
) {
1746 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1748 } else if (highx_int
> lowx_int
) {
1749 y_percent
= highy_float
- lowy_float
;
1750 percent
= (1-lowx_float
)*y_percent
;
1751 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1752 for (k
= 0, temp_index
= temp
; k
< components
;
1753 k
++, temp_index
+= element_size
) {
1754 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1756 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1758 for (k
= 0, temp_index
= temp
; k
< components
;
1759 k
++, temp_index
+= element_size
) {
1760 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1764 percent
= y_percent
* highx_float
;
1765 for (k
= 0, temp_index
= temp
; k
< components
;
1766 k
++, temp_index
+= element_size
) {
1767 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1770 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1771 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1772 for (k
= 0, temp_index
= temp
; k
< components
;
1773 k
++, temp_index
+= element_size
) {
1774 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1780 /* this is for the pixels in the body */
1781 temp0
= (const char *)datain
+ xindex
+ group_size
+
1783 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1785 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1786 for (k
= 0, temp_index
= temp
; k
< components
;
1787 k
++, temp_index
+= element_size
) {
1788 totals
[k
] += (GLbyte
)(*(temp_index
));
1795 outindex
= (j
+ (i
* widthout
)) * components
;
1796 for (k
= 0; k
< components
; k
++) {
1797 dataout
[outindex
+ k
] = totals
[k
]/area
;
1798 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1800 lowx_int
= highx_int
;
1801 lowx_float
= highx_float
;
1802 highx_int
+= convx_int
;
1803 highx_float
+= convx_float
;
1804 if(highx_float
> 1) {
1809 lowy_int
= highy_int
;
1810 lowy_float
= highy_float
;
1811 highy_int
+= convy_int
;
1812 highy_float
+= convy_float
;
1813 if(highy_float
> 1) {
1820 static void scale_internal_ushort(GLint components
, GLint widthin
,
1821 GLint heightin
, const GLushort
*datain
,
1822 GLint widthout
, GLint heightout
,
1823 GLushort
*dataout
, GLint element_size
,
1824 GLint ysize
, GLint group_size
,
1830 /* Max components in a format is 4, so... */
1835 const char *temp
, *temp0
;
1836 const char *temp_index
;
1839 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1840 float x_percent
, y_percent
;
1841 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1842 float convy_float
, convx_float
;
1843 int convy_int
, convx_int
;
1845 const char *left
, *right
;
1847 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1848 halveImage_ushort(components
, widthin
, heightin
,
1849 (const GLushort
*)datain
, (GLushort
*)dataout
,
1850 element_size
, ysize
, group_size
, myswap_bytes
);
1853 convy
= (float) heightin
/heightout
;
1854 convx
= (float) widthin
/widthout
;
1855 convy_int
= floor(convy
);
1856 convy_float
= convy
- convy_int
;
1857 convx_int
= floor(convx
);
1858 convx_float
= convx
- convx_int
;
1860 area
= convx
* convy
;
1864 highy_int
= convy_int
;
1865 highy_float
= convy_float
;
1867 for (i
= 0; i
< heightout
; i
++) {
1868 /* Clamp here to be sure we don't read beyond input buffer. */
1869 if (highy_int
>= heightin
)
1870 highy_int
= heightin
- 1;
1873 highx_int
= convx_int
;
1874 highx_float
= convx_float
;
1876 for (j
= 0; j
< widthout
; j
++) {
1878 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1879 ** to (highx, highy) on input data into this pixel on output
1882 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1884 /* calculate the value for pixels in the 1st row */
1885 xindex
= lowx_int
*group_size
;
1886 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1888 y_percent
= 1-lowy_float
;
1889 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1890 percent
= y_percent
* (1-lowx_float
);
1891 for (k
= 0, temp_index
= temp
; k
< components
;
1892 k
++, temp_index
+= element_size
) {
1894 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1896 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1900 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1902 for (k
= 0, temp_index
= temp
; k
< components
;
1903 k
++, temp_index
+= element_size
) {
1906 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1908 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1914 percent
= y_percent
* highx_float
;
1915 for (k
= 0, temp_index
= temp
; k
< components
;
1916 k
++, temp_index
+= element_size
) {
1918 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1920 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1924 /* calculate the value for pixels in the last row */
1925 y_percent
= highy_float
;
1926 percent
= y_percent
* (1-lowx_float
);
1927 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1928 for (k
= 0, temp_index
= temp
; k
< components
;
1929 k
++, temp_index
+= element_size
) {
1931 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1933 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1936 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1938 for (k
= 0, temp_index
= temp
; k
< components
;
1939 k
++, temp_index
+= element_size
) {
1942 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1944 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1949 percent
= y_percent
* highx_float
;
1950 for (k
= 0, temp_index
= temp
; k
< components
;
1951 k
++, temp_index
+= element_size
) {
1953 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1955 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1959 /* calculate the value for pixels in the 1st and last column */
1960 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1963 for (k
= 0; k
< components
;
1964 k
++, left
+= element_size
, right
+= element_size
) {
1967 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1968 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1970 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1971 + *(const GLushort
*)right
* highx_float
;
1975 } else if (highy_int
> lowy_int
) {
1976 x_percent
= highx_float
- lowx_float
;
1977 percent
= (1-lowy_float
)*x_percent
;
1978 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1979 for (k
= 0, temp_index
= temp
; k
< components
;
1980 k
++, temp_index
+= element_size
) {
1982 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1984 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1987 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1989 for (k
= 0, temp_index
= temp
; k
< components
;
1990 k
++, temp_index
+= element_size
) {
1993 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
1995 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
1999 percent
= x_percent
* highy_float
;
2001 for (k
= 0, temp_index
= temp
; k
< components
;
2002 k
++, temp_index
+= element_size
) {
2004 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2006 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2009 } else if (highx_int
> lowx_int
) {
2010 y_percent
= highy_float
- lowy_float
;
2011 percent
= (1-lowx_float
)*y_percent
;
2012 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2013 for (k
= 0, temp_index
= temp
; k
< components
;
2014 k
++, temp_index
+= element_size
) {
2016 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2018 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2021 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2023 for (k
= 0, temp_index
= temp
; k
< components
;
2024 k
++, temp_index
+= element_size
) {
2027 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2029 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2034 percent
= y_percent
* highx_float
;
2035 for (k
= 0, temp_index
= temp
; k
< components
;
2036 k
++, temp_index
+= element_size
) {
2038 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2040 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2044 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2045 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2046 for (k
= 0, temp_index
= temp
; k
< components
;
2047 k
++, temp_index
+= element_size
) {
2049 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2051 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2056 /* this is for the pixels in the body */
2057 temp0
= (const char *)datain
+ xindex
+ group_size
+
2059 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2061 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2062 for (k
= 0, temp_index
= temp
; k
< components
;
2063 k
++, temp_index
+= element_size
) {
2065 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2067 totals
[k
] += *(const GLushort
*)temp_index
;
2075 outindex
= (j
+ (i
* widthout
)) * components
;
2076 for (k
= 0; k
< components
; k
++) {
2077 dataout
[outindex
+ k
] = totals
[k
]/area
;
2078 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2080 lowx_int
= highx_int
;
2081 lowx_float
= highx_float
;
2082 highx_int
+= convx_int
;
2083 highx_float
+= convx_float
;
2084 if(highx_float
> 1) {
2089 lowy_int
= highy_int
;
2090 lowy_float
= highy_float
;
2091 highy_int
+= convy_int
;
2092 highy_float
+= convy_float
;
2093 if(highy_float
> 1) {
2100 static void scale_internal_short(GLint components
, GLint widthin
,
2101 GLint heightin
, const GLshort
*datain
,
2102 GLint widthout
, GLint heightout
,
2103 GLshort
*dataout
, GLint element_size
,
2104 GLint ysize
, GLint group_size
,
2110 /* Max components in a format is 4, so... */
2115 const char *temp
, *temp0
;
2116 const char *temp_index
;
2119 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2120 float x_percent
, y_percent
;
2121 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2122 float convy_float
, convx_float
;
2123 int convy_int
, convx_int
;
2125 const char *left
, *right
;
2127 GLushort swapbuf
; /* unsigned buffer */
2129 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2130 halveImage_short(components
, widthin
, heightin
,
2131 (const GLshort
*)datain
, (GLshort
*)dataout
,
2132 element_size
, ysize
, group_size
, myswap_bytes
);
2135 convy
= (float) heightin
/heightout
;
2136 convx
= (float) widthin
/widthout
;
2137 convy_int
= floor(convy
);
2138 convy_float
= convy
- convy_int
;
2139 convx_int
= floor(convx
);
2140 convx_float
= convx
- convx_int
;
2142 area
= convx
* convy
;
2146 highy_int
= convy_int
;
2147 highy_float
= convy_float
;
2149 for (i
= 0; i
< heightout
; i
++) {
2150 /* Clamp here to be sure we don't read beyond input buffer. */
2151 if (highy_int
>= heightin
)
2152 highy_int
= heightin
- 1;
2155 highx_int
= convx_int
;
2156 highx_float
= convx_float
;
2158 for (j
= 0; j
< widthout
; j
++) {
2160 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2161 ** to (highx, highy) on input data into this pixel on output
2164 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2166 /* calculate the value for pixels in the 1st row */
2167 xindex
= lowx_int
*group_size
;
2168 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2170 y_percent
= 1-lowy_float
;
2171 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2172 percent
= y_percent
* (1-lowx_float
);
2173 for (k
= 0, temp_index
= temp
; k
< components
;
2174 k
++, temp_index
+= element_size
) {
2176 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2177 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2179 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2183 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2185 for (k
= 0, temp_index
= temp
; k
< components
;
2186 k
++, temp_index
+= element_size
) {
2188 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2189 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2191 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2197 percent
= y_percent
* highx_float
;
2198 for (k
= 0, temp_index
= temp
; k
< components
;
2199 k
++, temp_index
+= element_size
) {
2201 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2202 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2204 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2208 /* calculate the value for pixels in the last row */
2209 y_percent
= highy_float
;
2210 percent
= y_percent
* (1-lowx_float
);
2211 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2212 for (k
= 0, temp_index
= temp
; k
< components
;
2213 k
++, temp_index
+= element_size
) {
2215 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2216 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2218 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2221 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2223 for (k
= 0, temp_index
= temp
; k
< components
;
2224 k
++, temp_index
+= element_size
) {
2226 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2227 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2229 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2234 percent
= y_percent
* highx_float
;
2235 for (k
= 0, temp_index
= temp
; k
< components
;
2236 k
++, temp_index
+= element_size
) {
2238 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2239 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2241 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2245 /* calculate the value for pixels in the 1st and last column */
2246 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2249 for (k
= 0; k
< components
;
2250 k
++, left
+= element_size
, right
+= element_size
) {
2252 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2253 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2254 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2255 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2257 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2258 + *(const GLshort
*)right
* highx_float
;
2262 } else if (highy_int
> lowy_int
) {
2263 x_percent
= highx_float
- lowx_float
;
2264 percent
= (1-lowy_float
)*x_percent
;
2265 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2266 for (k
= 0, temp_index
= temp
; k
< components
;
2267 k
++, temp_index
+= element_size
) {
2269 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2270 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2272 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2275 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2277 for (k
= 0, temp_index
= temp
; k
< components
;
2278 k
++, temp_index
+= element_size
) {
2280 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2281 totals
[k
] += *(const GLshort
*)&swapbuf
* x_percent
;
2283 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2287 percent
= x_percent
* highy_float
;
2289 for (k
= 0, temp_index
= temp
; k
< components
;
2290 k
++, temp_index
+= element_size
) {
2292 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2293 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2295 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2298 } else if (highx_int
> lowx_int
) {
2299 y_percent
= highy_float
- lowy_float
;
2300 percent
= (1-lowx_float
)*y_percent
;
2302 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2303 for (k
= 0, temp_index
= temp
; k
< components
;
2304 k
++, temp_index
+= element_size
) {
2306 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2307 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2309 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2312 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2314 for (k
= 0, temp_index
= temp
; k
< components
;
2315 k
++, temp_index
+= element_size
) {
2317 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2318 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2320 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2325 percent
= y_percent
* highx_float
;
2326 for (k
= 0, temp_index
= temp
; k
< components
;
2327 k
++, temp_index
+= element_size
) {
2329 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2330 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2332 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2336 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2337 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2338 for (k
= 0, temp_index
= temp
; k
< components
;
2339 k
++, temp_index
+= element_size
) {
2341 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2342 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2344 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2349 /* this is for the pixels in the body */
2350 temp0
= (const char *)datain
+ xindex
+ group_size
+
2352 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2354 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2355 for (k
= 0, temp_index
= temp
; k
< components
;
2356 k
++, temp_index
+= element_size
) {
2358 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2359 totals
[k
] += *(const GLshort
*)&swapbuf
;
2361 totals
[k
] += *(const GLshort
*)temp_index
;
2369 outindex
= (j
+ (i
* widthout
)) * components
;
2370 for (k
= 0; k
< components
; k
++) {
2371 dataout
[outindex
+ k
] = totals
[k
]/area
;
2372 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2374 lowx_int
= highx_int
;
2375 lowx_float
= highx_float
;
2376 highx_int
+= convx_int
;
2377 highx_float
+= convx_float
;
2378 if(highx_float
> 1) {
2383 lowy_int
= highy_int
;
2384 lowy_float
= highy_float
;
2385 highy_int
+= convy_int
;
2386 highy_float
+= convy_float
;
2387 if(highy_float
> 1) {
2394 static void scale_internal_uint(GLint components
, GLint widthin
,
2395 GLint heightin
, const GLuint
*datain
,
2396 GLint widthout
, GLint heightout
,
2397 GLuint
*dataout
, GLint element_size
,
2398 GLint ysize
, GLint group_size
,
2404 /* Max components in a format is 4, so... */
2409 const char *temp
, *temp0
;
2410 const char *temp_index
;
2413 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2414 float x_percent
, y_percent
;
2415 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2416 float convy_float
, convx_float
;
2417 int convy_int
, convx_int
;
2419 const char *left
, *right
;
2421 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2422 halveImage_uint(components
, widthin
, heightin
,
2423 (const GLuint
*)datain
, (GLuint
*)dataout
,
2424 element_size
, ysize
, group_size
, myswap_bytes
);
2427 convy
= (float) heightin
/heightout
;
2428 convx
= (float) widthin
/widthout
;
2429 convy_int
= floor(convy
);
2430 convy_float
= convy
- convy_int
;
2431 convx_int
= floor(convx
);
2432 convx_float
= convx
- convx_int
;
2434 area
= convx
* convy
;
2438 highy_int
= convy_int
;
2439 highy_float
= convy_float
;
2441 for (i
= 0; i
< heightout
; i
++) {
2442 /* Clamp here to be sure we don't read beyond input buffer. */
2443 if (highy_int
>= heightin
)
2444 highy_int
= heightin
- 1;
2447 highx_int
= convx_int
;
2448 highx_float
= convx_float
;
2450 for (j
= 0; j
< widthout
; j
++) {
2452 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2453 ** to (highx, highy) on input data into this pixel on output
2456 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2458 /* calculate the value for pixels in the 1st row */
2459 xindex
= lowx_int
*group_size
;
2460 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2462 y_percent
= 1-lowy_float
;
2463 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2464 percent
= y_percent
* (1-lowx_float
);
2465 for (k
= 0, temp_index
= temp
; k
< components
;
2466 k
++, temp_index
+= element_size
) {
2468 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2470 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2474 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2476 for (k
= 0, temp_index
= temp
; k
< components
;
2477 k
++, temp_index
+= element_size
) {
2480 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2482 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2488 percent
= y_percent
* highx_float
;
2489 for (k
= 0, temp_index
= temp
; k
< components
;
2490 k
++, temp_index
+= element_size
) {
2492 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2494 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2498 /* calculate the value for pixels in the last row */
2499 y_percent
= highy_float
;
2500 percent
= y_percent
* (1-lowx_float
);
2501 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2502 for (k
= 0, temp_index
= temp
; k
< components
;
2503 k
++, temp_index
+= element_size
) {
2505 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2507 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2510 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2512 for (k
= 0, temp_index
= temp
; k
< components
;
2513 k
++, temp_index
+= element_size
) {
2516 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2518 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2523 percent
= y_percent
* highx_float
;
2524 for (k
= 0, temp_index
= temp
; k
< components
;
2525 k
++, temp_index
+= element_size
) {
2527 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2529 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2533 /* calculate the value for pixels in the 1st and last column */
2534 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2537 for (k
= 0; k
< components
;
2538 k
++, left
+= element_size
, right
+= element_size
) {
2541 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2542 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2544 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2545 + *(const GLuint
*)right
* highx_float
;
2549 } else if (highy_int
> lowy_int
) {
2550 x_percent
= highx_float
- lowx_float
;
2551 percent
= (1-lowy_float
)*x_percent
;
2552 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2553 for (k
= 0, temp_index
= temp
; k
< components
;
2554 k
++, temp_index
+= element_size
) {
2556 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2558 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2561 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2563 for (k
= 0, temp_index
= temp
; k
< components
;
2564 k
++, temp_index
+= element_size
) {
2567 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2569 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2573 percent
= x_percent
* highy_float
;
2575 for (k
= 0, temp_index
= temp
; k
< components
;
2576 k
++, temp_index
+= element_size
) {
2578 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2580 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2583 } else if (highx_int
> lowx_int
) {
2584 y_percent
= highy_float
- lowy_float
;
2585 percent
= (1-lowx_float
)*y_percent
;
2587 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2588 for (k
= 0, temp_index
= temp
; k
< components
;
2589 k
++, temp_index
+= element_size
) {
2591 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2593 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2596 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2598 for (k
= 0, temp_index
= temp
; k
< components
;
2599 k
++, temp_index
+= element_size
) {
2602 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2604 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2609 percent
= y_percent
* highx_float
;
2610 for (k
= 0, temp_index
= temp
; k
< components
;
2611 k
++, temp_index
+= element_size
) {
2613 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2615 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2619 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2620 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2621 for (k
= 0, temp_index
= temp
; k
< components
;
2622 k
++, temp_index
+= element_size
) {
2624 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2626 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2631 /* this is for the pixels in the body */
2632 temp0
= (const char *)datain
+ xindex
+ group_size
+
2634 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2636 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2637 for (k
= 0, temp_index
= temp
; k
< components
;
2638 k
++, temp_index
+= element_size
) {
2640 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2642 totals
[k
] += *(const GLuint
*)temp_index
;
2650 outindex
= (j
+ (i
* widthout
)) * components
;
2651 for (k
= 0; k
< components
; k
++) {
2652 /* clamp at UINT_MAX */
2653 float value
= totals
[k
]/area
;
2654 if (value
>= (float) UINT_MAX
) { /* need '=' */
2655 dataout
[outindex
+ k
] = UINT_MAX
;
2657 else dataout
[outindex
+ k
] = value
;
2659 lowx_int
= highx_int
;
2660 lowx_float
= highx_float
;
2661 highx_int
+= convx_int
;
2662 highx_float
+= convx_float
;
2663 if(highx_float
> 1) {
2668 lowy_int
= highy_int
;
2669 lowy_float
= highy_float
;
2670 highy_int
+= convy_int
;
2671 highy_float
+= convy_float
;
2672 if(highy_float
> 1) {
2681 static void scale_internal_int(GLint components
, GLint widthin
,
2682 GLint heightin
, const GLint
*datain
,
2683 GLint widthout
, GLint heightout
,
2684 GLint
*dataout
, GLint element_size
,
2685 GLint ysize
, GLint group_size
,
2691 /* Max components in a format is 4, so... */
2696 const char *temp
, *temp0
;
2697 const char *temp_index
;
2700 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2701 float x_percent
, y_percent
;
2702 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2703 float convy_float
, convx_float
;
2704 int convy_int
, convx_int
;
2706 const char *left
, *right
;
2708 GLuint swapbuf
; /* unsigned buffer */
2710 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2711 halveImage_int(components
, widthin
, heightin
,
2712 (const GLint
*)datain
, (GLint
*)dataout
,
2713 element_size
, ysize
, group_size
, myswap_bytes
);
2716 convy
= (float) heightin
/heightout
;
2717 convx
= (float) widthin
/widthout
;
2718 convy_int
= floor(convy
);
2719 convy_float
= convy
- convy_int
;
2720 convx_int
= floor(convx
);
2721 convx_float
= convx
- convx_int
;
2723 area
= convx
* convy
;
2727 highy_int
= convy_int
;
2728 highy_float
= convy_float
;
2730 for (i
= 0; i
< heightout
; i
++) {
2731 /* Clamp here to be sure we don't read beyond input buffer. */
2732 if (highy_int
>= heightin
)
2733 highy_int
= heightin
- 1;
2736 highx_int
= convx_int
;
2737 highx_float
= convx_float
;
2739 for (j
= 0; j
< widthout
; j
++) {
2741 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2742 ** to (highx, highy) on input data into this pixel on output
2745 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2747 /* calculate the value for pixels in the 1st row */
2748 xindex
= lowx_int
*group_size
;
2749 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2751 y_percent
= 1-lowy_float
;
2752 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2753 percent
= y_percent
* (1-lowx_float
);
2754 for (k
= 0, temp_index
= temp
; k
< components
;
2755 k
++, temp_index
+= element_size
) {
2757 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2758 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2760 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2764 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2766 for (k
= 0, temp_index
= temp
; k
< components
;
2767 k
++, temp_index
+= element_size
) {
2769 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2770 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2772 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2778 percent
= y_percent
* highx_float
;
2779 for (k
= 0, temp_index
= temp
; k
< components
;
2780 k
++, temp_index
+= element_size
) {
2782 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2783 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2785 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2789 /* calculate the value for pixels in the last row */
2790 y_percent
= highy_float
;
2791 percent
= y_percent
* (1-lowx_float
);
2792 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2793 for (k
= 0, temp_index
= temp
; k
< components
;
2794 k
++, temp_index
+= element_size
) {
2796 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2797 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2799 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2802 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2804 for (k
= 0, temp_index
= temp
; k
< components
;
2805 k
++, temp_index
+= element_size
) {
2807 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2808 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2810 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2815 percent
= y_percent
* highx_float
;
2816 for (k
= 0, temp_index
= temp
; k
< components
;
2817 k
++, temp_index
+= element_size
) {
2819 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2820 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2822 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2826 /* calculate the value for pixels in the 1st and last column */
2827 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2830 for (k
= 0; k
< components
;
2831 k
++, left
+= element_size
, right
+= element_size
) {
2833 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2834 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2835 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2836 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2838 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2839 + *(const GLint
*)right
* highx_float
;
2843 } else if (highy_int
> lowy_int
) {
2844 x_percent
= highx_float
- lowx_float
;
2845 percent
= (1-lowy_float
)*x_percent
;
2846 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2847 for (k
= 0, temp_index
= temp
; k
< components
;
2848 k
++, temp_index
+= element_size
) {
2850 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2851 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2853 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2856 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2858 for (k
= 0, temp_index
= temp
; k
< components
;
2859 k
++, temp_index
+= element_size
) {
2861 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2862 totals
[k
] += *(const GLint
*)&swapbuf
* x_percent
;
2864 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2868 percent
= x_percent
* highy_float
;
2870 for (k
= 0, temp_index
= temp
; k
< components
;
2871 k
++, temp_index
+= element_size
) {
2873 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2874 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2876 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2879 } else if (highx_int
> lowx_int
) {
2880 y_percent
= highy_float
- lowy_float
;
2881 percent
= (1-lowx_float
)*y_percent
;
2883 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2884 for (k
= 0, temp_index
= temp
; k
< components
;
2885 k
++, temp_index
+= element_size
) {
2887 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2888 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2890 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2893 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2895 for (k
= 0, temp_index
= temp
; k
< components
;
2896 k
++, temp_index
+= element_size
) {
2898 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2899 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2901 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2906 percent
= y_percent
* highx_float
;
2907 for (k
= 0, temp_index
= temp
; k
< components
;
2908 k
++, temp_index
+= element_size
) {
2910 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2911 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2913 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2917 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2918 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2919 for (k
= 0, temp_index
= temp
; k
< components
;
2920 k
++, temp_index
+= element_size
) {
2922 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2923 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2925 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2930 /* this is for the pixels in the body */
2931 temp0
= (const char *)datain
+ xindex
+ group_size
+
2933 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2935 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2936 for (k
= 0, temp_index
= temp
; k
< components
;
2937 k
++, temp_index
+= element_size
) {
2939 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2940 totals
[k
] += *(const GLint
*)&swapbuf
;
2942 totals
[k
] += *(const GLint
*)temp_index
;
2950 outindex
= (j
+ (i
* widthout
)) * components
;
2951 for (k
= 0; k
< components
; k
++) {
2952 dataout
[outindex
+ k
] = totals
[k
]/area
;
2953 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2955 lowx_int
= highx_int
;
2956 lowx_float
= highx_float
;
2957 highx_int
+= convx_int
;
2958 highx_float
+= convx_float
;
2959 if(highx_float
> 1) {
2964 lowy_int
= highy_int
;
2965 lowy_float
= highy_float
;
2966 highy_int
+= convy_int
;
2967 highy_float
+= convy_float
;
2968 if(highy_float
> 1) {
2977 static void scale_internal_float(GLint components
, GLint widthin
,
2978 GLint heightin
, const GLfloat
*datain
,
2979 GLint widthout
, GLint heightout
,
2980 GLfloat
*dataout
, GLint element_size
,
2981 GLint ysize
, GLint group_size
,
2987 /* Max components in a format is 4, so... */
2992 const char *temp
, *temp0
;
2993 const char *temp_index
;
2996 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2997 float x_percent
, y_percent
;
2998 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2999 float convy_float
, convx_float
;
3000 int convy_int
, convx_int
;
3002 const char *left
, *right
;
3004 union { GLuint b
; GLfloat f
; } swapbuf
;
3006 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
3007 halveImage_float(components
, widthin
, heightin
,
3008 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
3009 element_size
, ysize
, group_size
, myswap_bytes
);
3012 convy
= (float) heightin
/heightout
;
3013 convx
= (float) widthin
/widthout
;
3014 convy_int
= floor(convy
);
3015 convy_float
= convy
- convy_int
;
3016 convx_int
= floor(convx
);
3017 convx_float
= convx
- convx_int
;
3019 area
= convx
* convy
;
3023 highy_int
= convy_int
;
3024 highy_float
= convy_float
;
3026 for (i
= 0; i
< heightout
; i
++) {
3027 /* Clamp here to be sure we don't read beyond input buffer. */
3028 if (highy_int
>= heightin
)
3029 highy_int
= heightin
- 1;
3032 highx_int
= convx_int
;
3033 highx_float
= convx_float
;
3035 for (j
= 0; j
< widthout
; j
++) {
3037 ** Ok, now apply box filter to box that goes from (lowx, lowy)
3038 ** to (highx, highy) on input data into this pixel on output
3041 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3043 /* calculate the value for pixels in the 1st row */
3044 xindex
= lowx_int
*group_size
;
3045 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3047 y_percent
= 1-lowy_float
;
3048 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3049 percent
= y_percent
* (1-lowx_float
);
3050 for (k
= 0, temp_index
= temp
; k
< components
;
3051 k
++, temp_index
+= element_size
) {
3053 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3054 totals
[k
] += swapbuf
.f
* percent
;
3056 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3060 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3062 for (k
= 0, temp_index
= temp
; k
< components
;
3063 k
++, temp_index
+= element_size
) {
3065 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3066 totals
[k
] += swapbuf
.f
* y_percent
;
3068 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3074 percent
= y_percent
* highx_float
;
3075 for (k
= 0, temp_index
= temp
; k
< components
;
3076 k
++, temp_index
+= element_size
) {
3078 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3079 totals
[k
] += swapbuf
.f
* percent
;
3081 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3085 /* calculate the value for pixels in the last row */
3086 y_percent
= highy_float
;
3087 percent
= y_percent
* (1-lowx_float
);
3088 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3089 for (k
= 0, temp_index
= temp
; k
< components
;
3090 k
++, temp_index
+= element_size
) {
3092 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3093 totals
[k
] += swapbuf
.f
* percent
;
3095 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3098 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3100 for (k
= 0, temp_index
= temp
; k
< components
;
3101 k
++, temp_index
+= element_size
) {
3103 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3104 totals
[k
] += swapbuf
.f
* y_percent
;
3106 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3111 percent
= y_percent
* highx_float
;
3112 for (k
= 0, temp_index
= temp
; k
< components
;
3113 k
++, temp_index
+= element_size
) {
3115 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3116 totals
[k
] += swapbuf
.f
* percent
;
3118 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3122 /* calculate the value for pixels in the 1st and last column */
3123 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3126 for (k
= 0; k
< components
;
3127 k
++, left
+= element_size
, right
+= element_size
) {
3129 swapbuf
.b
= __GLU_SWAP_4_BYTES(left
);
3130 totals
[k
] += swapbuf
.f
* (1-lowx_float
);
3131 swapbuf
.b
= __GLU_SWAP_4_BYTES(right
);
3132 totals
[k
] += swapbuf
.f
* highx_float
;
3134 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3135 + *(const GLfloat
*)right
* highx_float
;
3139 } else if (highy_int
> lowy_int
) {
3140 x_percent
= highx_float
- lowx_float
;
3141 percent
= (1-lowy_float
)*x_percent
;
3142 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3143 for (k
= 0, temp_index
= temp
; k
< components
;
3144 k
++, temp_index
+= element_size
) {
3146 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3147 totals
[k
] += swapbuf
.f
* percent
;
3149 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3152 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3154 for (k
= 0, temp_index
= temp
; k
< components
;
3155 k
++, temp_index
+= element_size
) {
3157 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3158 totals
[k
] += swapbuf
.f
* x_percent
;
3160 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3164 percent
= x_percent
* highy_float
;
3166 for (k
= 0, temp_index
= temp
; k
< components
;
3167 k
++, temp_index
+= element_size
) {
3169 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3170 totals
[k
] += swapbuf
.f
* percent
;
3172 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3175 } else if (highx_int
> lowx_int
) {
3176 y_percent
= highy_float
- lowy_float
;
3177 percent
= (1-lowx_float
)*y_percent
;
3179 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3180 for (k
= 0, temp_index
= temp
; k
< components
;
3181 k
++, temp_index
+= element_size
) {
3183 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3184 totals
[k
] += swapbuf
.f
* percent
;
3186 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3189 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3191 for (k
= 0, temp_index
= temp
; k
< components
;
3192 k
++, temp_index
+= element_size
) {
3194 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3195 totals
[k
] += swapbuf
.f
* y_percent
;
3197 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3202 percent
= y_percent
* highx_float
;
3203 for (k
= 0, temp_index
= temp
; k
< components
;
3204 k
++, temp_index
+= element_size
) {
3206 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3207 totals
[k
] += swapbuf
.f
* percent
;
3209 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3213 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3214 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3215 for (k
= 0, temp_index
= temp
; k
< components
;
3216 k
++, temp_index
+= element_size
) {
3218 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3219 totals
[k
] += swapbuf
.f
* percent
;
3221 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3226 /* this is for the pixels in the body */
3227 temp0
= (const char *)datain
+ xindex
+ group_size
+
3229 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3231 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3232 for (k
= 0, temp_index
= temp
; k
< components
;
3233 k
++, temp_index
+= element_size
) {
3235 swapbuf
.b
= __GLU_SWAP_4_BYTES(temp_index
);
3236 totals
[k
] += swapbuf
.f
;
3238 totals
[k
] += *(const GLfloat
*)temp_index
;
3246 outindex
= (j
+ (i
* widthout
)) * components
;
3247 for (k
= 0; k
< components
; k
++) {
3248 dataout
[outindex
+ k
] = totals
[k
]/area
;
3249 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3251 lowx_int
= highx_int
;
3252 lowx_float
= highx_float
;
3253 highx_int
+= convx_int
;
3254 highx_float
+= convx_float
;
3255 if(highx_float
> 1) {
3260 lowy_int
= highy_int
;
3261 lowy_float
= highy_float
;
3262 highy_int
+= convy_int
;
3263 highy_float
+= convy_float
;
3264 if(highy_float
> 1) {
3271 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3273 if (!legalFormat(format
) || !legalType(type
)) {
3274 return GLU_INVALID_ENUM
;
3276 if (format
== GL_STENCIL_INDEX
) {
3277 return GLU_INVALID_ENUM
;
3280 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3281 return GLU_INVALID_OPERATION
;
3285 } /* checkMipmapArgs() */
3287 static GLboolean
legalFormat(GLenum format
)
3290 case GL_COLOR_INDEX
:
3291 case GL_STENCIL_INDEX
:
3292 case GL_DEPTH_COMPONENT
:
3300 case GL_LUMINANCE_ALPHA
:
3310 static GLboolean
legalType(GLenum type
)
3315 case GL_UNSIGNED_BYTE
:
3317 case GL_UNSIGNED_SHORT
:
3319 case GL_UNSIGNED_INT
:
3321 case GL_UNSIGNED_BYTE_3_3_2
:
3322 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3323 case GL_UNSIGNED_SHORT_5_6_5
:
3324 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3325 case GL_UNSIGNED_SHORT_4_4_4_4
:
3326 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3327 case GL_UNSIGNED_SHORT_5_5_5_1
:
3328 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3329 case GL_UNSIGNED_INT_8_8_8_8
:
3330 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3331 case GL_UNSIGNED_INT_10_10_10_2
:
3332 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3340 static GLboolean
isTypePackedPixel(GLenum type
)
3342 assert(legalType(type
));
3344 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3345 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3346 type
== GL_UNSIGNED_SHORT_5_6_5
||
3347 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3348 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3349 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3350 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3351 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3352 type
== GL_UNSIGNED_INT_8_8_8_8
||
3353 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3354 type
== GL_UNSIGNED_INT_10_10_10_2
||
3355 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3359 } /* isTypePackedPixel() */
3361 /* Determines if the packed pixel type is compatible with the format */
3362 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3364 /* if not a packed pixel type then return true */
3365 if (!isTypePackedPixel(type
)) {
3369 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3370 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3371 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3372 && format
!= GL_RGB
)
3375 /* 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 &
3376 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3378 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3379 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3380 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3381 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3382 type
== GL_UNSIGNED_INT_8_8_8_8
||
3383 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3384 type
== GL_UNSIGNED_INT_10_10_10_2
||
3385 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3386 (format
!= GL_RGBA
&&
3387 format
!= GL_BGRA
)) {
3392 } /* isLegalFormatForPackedPixelType() */
3394 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3397 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3398 totalLevels
< maxLevel
)
3400 else return GL_TRUE
;
3401 } /* isLegalLevels() */
3403 /* Given user requested texture size, determine if it fits. If it
3404 * doesn't then halve both sides and make the determination again
3405 * until it does fit (for IR only).
3406 * Note that proxy textures are not implemented in RE* even though
3407 * they advertise the texture extension.
3408 * Note that proxy textures are implemented but not according to spec in
3411 static void closestFit(GLenum target
, GLint width
, GLint height
,
3412 GLint internalFormat
, GLenum format
, GLenum type
,
3413 GLint
*newWidth
, GLint
*newHeight
)
3415 /* Use proxy textures if OpenGL version is >= 1.1 */
3416 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3418 GLint widthPowerOf2
= nearestPower(width
);
3419 GLint heightPowerOf2
= nearestPower(height
);
3423 /* compute level 1 width & height, clamping each at 1 */
3424 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3425 widthPowerOf2
>> 1 :
3427 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3428 heightPowerOf2
>> 1 :
3431 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3433 /* does width x height at level 1 & all their mipmaps fit? */
3434 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3435 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3436 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3438 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3440 #if defined(GL_ARB_texture_cube_map)
3441 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3442 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3443 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3444 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3445 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3446 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3447 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3448 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3450 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3452 #endif /* GL_ARB_texture_cube_map */
3454 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3455 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3456 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3457 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3459 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3460 /* does it fit??? */
3461 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3462 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3463 /* An 1x1 texture couldn't fit for some reason, so
3464 * break out. This should never happen. But things
3465 * happen. The disadvantage with this if-statement is
3466 * that we will never be aware of when this happens
3467 * since it will silently branch out.
3469 goto noProxyTextures
;
3471 widthPowerOf2
= widthAtLevelOne
;
3472 heightPowerOf2
= heightAtLevelOne
;
3474 /* else it does fit */
3475 } while (proxyWidth
== 0);
3476 /* loop must terminate! */
3478 /* return the width & height at level 0 that fits */
3479 *newWidth
= widthPowerOf2
;
3480 *newHeight
= heightPowerOf2
;
3481 /*printf("Proxy Textures\n");*/
3482 } /* if gluCheckExtension() */
3483 else { /* no texture extension, so do this instead */
3488 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3489 /* clamp user's texture sizes to maximum sizes, if necessary */
3490 *newWidth
= nearestPower(width
);
3491 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3492 *newHeight
= nearestPower(height
);
3493 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3494 /*printf("NO proxy textures\n");*/
3496 } /* closestFit() */
3499 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3500 GLenum typein
, const void *datain
,
3501 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3505 GLushort
*beforeImage
;
3506 GLushort
*afterImage
;
3507 PixelStorageModes psm
;
3509 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3512 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3513 return GLU_INVALID_VALUE
;
3515 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3516 return GLU_INVALID_ENUM
;
3518 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3519 return GLU_INVALID_OPERATION
;
3521 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3522 return GLU_INVALID_OPERATION
;
3525 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3527 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3528 if (beforeImage
== NULL
|| afterImage
== NULL
) {
3531 return GLU_OUT_OF_MEMORY
;
3534 retrieveStoreModes(&psm
);
3535 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3536 datain
, beforeImage
);
3537 components
= elements_per_group(format
, 0);
3538 scale_internal(components
, widthin
, heightin
, beforeImage
,
3539 widthout
, heightout
, afterImage
);
3540 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3541 is_index(format
), afterImage
, dataout
);
3542 free((GLbyte
*) beforeImage
);
3543 free((GLbyte
*) afterImage
);
3548 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3550 GLsizei widthPowerOf2
,
3551 GLenum format
, GLenum type
,
3552 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3556 GLint level
, levels
;
3558 GLint newImage_width
;
3559 GLushort
*otherImage
;
3560 GLushort
*imageTemp
;
3563 PixelStorageModes psm
;
3565 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3570 newwidth
= widthPowerOf2
;
3571 levels
= computeLog(newwidth
);
3575 retrieveStoreModes(&psm
);
3576 newImage
= (GLushort
*)
3577 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3578 newImage_width
= width
;
3579 if (newImage
== NULL
) {
3580 return GLU_OUT_OF_MEMORY
;
3582 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3584 cmpts
= elements_per_group(format
,type
);
3585 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3586 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3587 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3588 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3590 ** If swap_bytes was set, swapping occurred in fill_image.
3592 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3594 for (level
= userLevel
; level
<= levels
; level
++) {
3595 if (newImage_width
== newwidth
) {
3596 /* Use newImage for this level */
3597 if (baseLevel
<= level
&& level
<= maxLevel
) {
3598 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3599 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3602 if (otherImage
== NULL
) {
3603 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3604 otherImage
= (GLushort
*) malloc(memreq
);
3605 if (otherImage
== NULL
) {
3606 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3607 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3608 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3609 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3610 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3612 return GLU_OUT_OF_MEMORY
;
3615 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3616 newwidth
, 1, otherImage
);
3617 /* Swap newImage and otherImage */
3618 imageTemp
= otherImage
;
3619 otherImage
= newImage
;
3620 newImage
= imageTemp
;
3622 newImage_width
= newwidth
;
3623 if (baseLevel
<= level
&& level
<= maxLevel
) {
3624 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3625 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3628 if (newwidth
> 1) newwidth
/= 2;
3630 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3631 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3632 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3633 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3634 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3636 free((GLbyte
*) newImage
);
3638 free((GLbyte
*) otherImage
);
3644 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3646 GLenum format
, GLenum type
,
3647 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3652 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3653 if (rc
!= 0) return rc
;
3656 return GLU_INVALID_VALUE
;
3659 levels
= computeLog(width
);
3662 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3663 return GLU_INVALID_VALUE
;
3665 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3668 userLevel
, baseLevel
, maxLevel
,
3670 } /* gluBuild1DMipmapLevels() */
3673 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3674 GLenum format
, GLenum type
,
3677 GLint widthPowerOf2
;
3681 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3682 if (rc
!= 0) return rc
;
3685 return GLU_INVALID_VALUE
;
3688 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3689 levels
= computeLog(widthPowerOf2
);
3691 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3694 format
,type
,0,0,levels
,data
);
3697 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3698 GLint width
, GLint height
, GLenum format
,
3699 GLenum type
, const void *data
)
3701 GLint newwidth
, newheight
;
3702 GLint level
, levels
;
3704 GLint newImage_width
;
3705 GLint newImage_height
;
3706 GLushort
*otherImage
;
3707 GLushort
*imageTemp
;
3710 PixelStorageModes psm
;
3712 retrieveStoreModes(&psm
);
3715 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3716 newwidth
= nearestPower(width
);
3717 if (newwidth
> maxsize
) newwidth
= maxsize
;
3718 newheight
= nearestPower(height
);
3719 if (newheight
> maxsize
) newheight
= maxsize
;
3721 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3722 &newwidth
,&newheight
);
3724 levels
= computeLog(newwidth
);
3725 level
= computeLog(newheight
);
3726 if (level
> levels
) levels
=level
;
3729 newImage
= (GLushort
*)
3730 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3731 newImage_width
= width
;
3732 newImage_height
= height
;
3733 if (newImage
== NULL
) {
3734 return GLU_OUT_OF_MEMORY
;
3737 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3740 cmpts
= elements_per_group(format
,type
);
3741 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3742 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3743 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3744 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3746 ** If swap_bytes was set, swapping occurred in fill_image.
3748 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3750 for (level
= 0; level
<= levels
; level
++) {
3751 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3752 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3753 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3756 if (otherImage
== NULL
) {
3758 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3759 otherImage
= (GLushort
*) malloc(memreq
);
3760 if (otherImage
== NULL
) {
3761 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3762 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3763 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3764 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3765 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3767 return GLU_OUT_OF_MEMORY
;
3770 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3771 newwidth
, newheight
, otherImage
);
3772 /* Swap newImage and otherImage */
3773 imageTemp
= otherImage
;
3774 otherImage
= newImage
;
3775 newImage
= imageTemp
;
3777 newImage_width
= newwidth
;
3778 newImage_height
= newheight
;
3779 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3780 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3783 if (newwidth
> 1) newwidth
/= 2;
3784 if (newheight
> 1) newheight
/= 2;
3786 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3787 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3788 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3789 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3790 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3792 free((GLbyte
*) newImage
);
3794 free((GLbyte
*) otherImage
);
3799 /* To make swapping images less error prone */
3800 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3801 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3803 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3804 GLsizei width
, GLsizei height
,
3805 GLsizei widthPowerOf2
,
3806 GLsizei heightPowerOf2
,
3807 GLenum format
, GLenum type
,
3809 GLint baseLevel
,GLint maxLevel
,
3812 GLint newwidth
, newheight
;
3813 GLint level
, levels
;
3814 const void *usersImage
; /* passed from user. Don't touch! */
3815 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3816 __GLU_INIT_SWAP_IMAGE
;
3820 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3821 GLint rowsize
, padding
;
3822 PixelStorageModes psm
;
3824 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3825 assert(width
>= 1 && height
>= 1);
3827 if(type
== GL_BITMAP
) {
3828 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3829 format
, type
, data
);
3832 srcImage
= dstImage
= NULL
;
3834 newwidth
= widthPowerOf2
;
3835 newheight
= heightPowerOf2
;
3836 levels
= computeLog(newwidth
);
3837 level
= computeLog(newheight
);
3838 if (level
> levels
) levels
=level
;
3842 retrieveStoreModes(&psm
);
3843 myswap_bytes
= psm
.unpack_swap_bytes
;
3844 cmpts
= elements_per_group(format
,type
);
3845 if (psm
.unpack_row_length
> 0) {
3846 groups_per_line
= psm
.unpack_row_length
;
3848 groups_per_line
= width
;
3851 element_size
= bytes_per_element(type
);
3852 group_size
= element_size
* cmpts
;
3853 if (element_size
== 1) myswap_bytes
= 0;
3855 rowsize
= groups_per_line
* group_size
;
3856 padding
= (rowsize
% psm
.unpack_alignment
);
3858 rowsize
+= psm
.unpack_alignment
- padding
;
3860 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3861 psm
.unpack_skip_pixels
* group_size
;
3863 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3864 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3865 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3869 /* already power-of-two square */
3870 if (width
== newwidth
&& height
== newheight
) {
3871 /* Use usersImage for level userLevel */
3872 if (baseLevel
<= level
&& level
<= maxLevel
) {
3873 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3874 glTexImage2D(target
, level
, internalFormat
, width
,
3875 height
, 0, format
, type
,
3878 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3879 if(levels
== 0) { /* we're done. clean up and return */
3880 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3881 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3882 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3883 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3884 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3888 int nextWidth
= newwidth
/2;
3889 int nextHeight
= newheight
/2;
3892 if (nextWidth
< 1) nextWidth
= 1;
3893 if (nextHeight
< 1) nextHeight
= 1;
3894 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3898 case GL_UNSIGNED_BYTE
:
3899 dstImage
= (GLubyte
*)malloc(memreq
);
3902 dstImage
= (GLbyte
*)malloc(memreq
);
3904 case GL_UNSIGNED_SHORT
:
3905 dstImage
= (GLushort
*)malloc(memreq
);
3908 dstImage
= (GLshort
*)malloc(memreq
);
3910 case GL_UNSIGNED_INT
:
3911 dstImage
= (GLuint
*)malloc(memreq
);
3914 dstImage
= (GLint
*)malloc(memreq
);
3917 dstImage
= (GLfloat
*)malloc(memreq
);
3919 case GL_UNSIGNED_BYTE_3_3_2
:
3920 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3921 dstImage
= (GLubyte
*)malloc(memreq
);
3923 case GL_UNSIGNED_SHORT_5_6_5
:
3924 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3925 case GL_UNSIGNED_SHORT_4_4_4_4
:
3926 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3927 case GL_UNSIGNED_SHORT_5_5_5_1
:
3928 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3929 dstImage
= (GLushort
*)malloc(memreq
);
3931 case GL_UNSIGNED_INT_8_8_8_8
:
3932 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3933 case GL_UNSIGNED_INT_10_10_10_2
:
3934 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3935 dstImage
= (GLuint
*)malloc(memreq
);
3938 return GLU_INVALID_ENUM
;
3940 if (dstImage
== NULL
) {
3941 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3942 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3943 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3944 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3945 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3946 return GLU_OUT_OF_MEMORY
;
3950 case GL_UNSIGNED_BYTE
:
3951 halveImage_ubyte(cmpts
, width
, height
,
3952 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3953 element_size
, rowsize
, group_size
);
3956 halveImage_byte(cmpts
, width
, height
,
3957 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3958 element_size
, rowsize
, group_size
);
3960 case GL_UNSIGNED_SHORT
:
3961 halveImage_ushort(cmpts
, width
, height
,
3962 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3963 element_size
, rowsize
, group_size
, myswap_bytes
);
3966 halveImage_short(cmpts
, width
, height
,
3967 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3968 element_size
, rowsize
, group_size
, myswap_bytes
);
3970 case GL_UNSIGNED_INT
:
3971 halveImage_uint(cmpts
, width
, height
,
3972 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3973 element_size
, rowsize
, group_size
, myswap_bytes
);
3976 halveImage_int(cmpts
, width
, height
,
3977 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3978 element_size
, rowsize
, group_size
, myswap_bytes
);
3981 halveImage_float(cmpts
, width
, height
,
3982 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3983 element_size
, rowsize
, group_size
, myswap_bytes
);
3985 case GL_UNSIGNED_BYTE_3_3_2
:
3986 assert(format
== GL_RGB
);
3987 halveImagePackedPixel(3,extract332
,shove332
,
3988 width
,height
,usersImage
,dstImage
,
3989 element_size
,rowsize
,myswap_bytes
);
3991 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3992 assert(format
== GL_RGB
);
3993 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3994 width
,height
,usersImage
,dstImage
,
3995 element_size
,rowsize
,myswap_bytes
);
3997 case GL_UNSIGNED_SHORT_5_6_5
:
3998 halveImagePackedPixel(3,extract565
,shove565
,
3999 width
,height
,usersImage
,dstImage
,
4000 element_size
,rowsize
,myswap_bytes
);
4002 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4003 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4004 width
,height
,usersImage
,dstImage
,
4005 element_size
,rowsize
,myswap_bytes
);
4007 case GL_UNSIGNED_SHORT_4_4_4_4
:
4008 halveImagePackedPixel(4,extract4444
,shove4444
,
4009 width
,height
,usersImage
,dstImage
,
4010 element_size
,rowsize
,myswap_bytes
);
4012 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4013 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4014 width
,height
,usersImage
,dstImage
,
4015 element_size
,rowsize
,myswap_bytes
);
4017 case GL_UNSIGNED_SHORT_5_5_5_1
:
4018 halveImagePackedPixel(4,extract5551
,shove5551
,
4019 width
,height
,usersImage
,dstImage
,
4020 element_size
,rowsize
,myswap_bytes
);
4022 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4023 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4024 width
,height
,usersImage
,dstImage
,
4025 element_size
,rowsize
,myswap_bytes
);
4027 case GL_UNSIGNED_INT_8_8_8_8
:
4028 halveImagePackedPixel(4,extract8888
,shove8888
,
4029 width
,height
,usersImage
,dstImage
,
4030 element_size
,rowsize
,myswap_bytes
);
4032 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4033 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4034 width
,height
,usersImage
,dstImage
,
4035 element_size
,rowsize
,myswap_bytes
);
4037 case GL_UNSIGNED_INT_10_10_10_2
:
4038 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4039 width
,height
,usersImage
,dstImage
,
4040 element_size
,rowsize
,myswap_bytes
);
4042 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4043 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4044 width
,height
,usersImage
,dstImage
,
4045 element_size
,rowsize
,myswap_bytes
);
4052 newheight
= height
/2;
4054 if (newwidth
< 1) newwidth
= 1;
4055 if (newheight
< 1) newheight
= 1;
4058 rowsize
= newwidth
* group_size
;
4059 memreq
= image_size(newwidth
, newheight
, format
, type
);
4060 /* Swap srcImage and dstImage */
4061 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4063 case GL_UNSIGNED_BYTE
:
4064 dstImage
= (GLubyte
*)malloc(memreq
);
4067 dstImage
= (GLbyte
*)malloc(memreq
);
4069 case GL_UNSIGNED_SHORT
:
4070 dstImage
= (GLushort
*)malloc(memreq
);
4073 dstImage
= (GLshort
*)malloc(memreq
);
4075 case GL_UNSIGNED_INT
:
4076 dstImage
= (GLuint
*)malloc(memreq
);
4079 dstImage
= (GLint
*)malloc(memreq
);
4082 dstImage
= (GLfloat
*)malloc(memreq
);
4084 case GL_UNSIGNED_BYTE_3_3_2
:
4085 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4086 dstImage
= (GLubyte
*)malloc(memreq
);
4088 case GL_UNSIGNED_SHORT_5_6_5
:
4089 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4090 case GL_UNSIGNED_SHORT_4_4_4_4
:
4091 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4092 case GL_UNSIGNED_SHORT_5_5_5_1
:
4093 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4094 dstImage
= (GLushort
*)malloc(memreq
);
4096 case GL_UNSIGNED_INT_8_8_8_8
:
4097 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4098 case GL_UNSIGNED_INT_10_10_10_2
:
4099 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4100 dstImage
= (GLuint
*)malloc(memreq
);
4103 return GLU_INVALID_ENUM
;
4105 if (dstImage
== NULL
) {
4106 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4107 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4108 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4109 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4110 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4112 return GLU_OUT_OF_MEMORY
;
4114 /* level userLevel+1 is in srcImage; level userLevel already saved */
4115 level
= userLevel
+1;
4116 } else { /* user's image is *not* nice power-of-2 sized square */
4117 memreq
= image_size(newwidth
, newheight
, format
, type
);
4119 case GL_UNSIGNED_BYTE
:
4120 dstImage
= (GLubyte
*)malloc(memreq
);
4123 dstImage
= (GLbyte
*)malloc(memreq
);
4125 case GL_UNSIGNED_SHORT
:
4126 dstImage
= (GLushort
*)malloc(memreq
);
4129 dstImage
= (GLshort
*)malloc(memreq
);
4131 case GL_UNSIGNED_INT
:
4132 dstImage
= (GLuint
*)malloc(memreq
);
4135 dstImage
= (GLint
*)malloc(memreq
);
4138 dstImage
= (GLfloat
*)malloc(memreq
);
4140 case GL_UNSIGNED_BYTE_3_3_2
:
4141 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4142 dstImage
= (GLubyte
*)malloc(memreq
);
4144 case GL_UNSIGNED_SHORT_5_6_5
:
4145 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4146 case GL_UNSIGNED_SHORT_4_4_4_4
:
4147 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4148 case GL_UNSIGNED_SHORT_5_5_5_1
:
4149 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4150 dstImage
= (GLushort
*)malloc(memreq
);
4152 case GL_UNSIGNED_INT_8_8_8_8
:
4153 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4154 case GL_UNSIGNED_INT_10_10_10_2
:
4155 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4156 dstImage
= (GLuint
*)malloc(memreq
);
4159 return GLU_INVALID_ENUM
;
4162 if (dstImage
== NULL
) {
4163 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4164 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4165 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4166 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4167 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4168 return GLU_OUT_OF_MEMORY
;
4172 case GL_UNSIGNED_BYTE
:
4173 scale_internal_ubyte(cmpts
, width
, height
,
4174 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4175 (GLubyte
*)dstImage
, element_size
,
4176 rowsize
, group_size
);
4179 scale_internal_byte(cmpts
, width
, height
,
4180 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4181 (GLbyte
*)dstImage
, element_size
,
4182 rowsize
, group_size
);
4184 case GL_UNSIGNED_SHORT
:
4185 scale_internal_ushort(cmpts
, width
, height
,
4186 (const GLushort
*)usersImage
, newwidth
, newheight
,
4187 (GLushort
*)dstImage
, element_size
,
4188 rowsize
, group_size
, myswap_bytes
);
4191 scale_internal_short(cmpts
, width
, height
,
4192 (const GLshort
*)usersImage
, newwidth
, newheight
,
4193 (GLshort
*)dstImage
, element_size
,
4194 rowsize
, group_size
, myswap_bytes
);
4196 case GL_UNSIGNED_INT
:
4197 scale_internal_uint(cmpts
, width
, height
,
4198 (const GLuint
*)usersImage
, newwidth
, newheight
,
4199 (GLuint
*)dstImage
, element_size
,
4200 rowsize
, group_size
, myswap_bytes
);
4203 scale_internal_int(cmpts
, width
, height
,
4204 (const GLint
*)usersImage
, newwidth
, newheight
,
4205 (GLint
*)dstImage
, element_size
,
4206 rowsize
, group_size
, myswap_bytes
);
4209 scale_internal_float(cmpts
, width
, height
,
4210 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4211 (GLfloat
*)dstImage
, element_size
,
4212 rowsize
, group_size
, myswap_bytes
);
4214 case GL_UNSIGNED_BYTE_3_3_2
:
4215 scaleInternalPackedPixel(3,extract332
,shove332
,
4216 width
, height
,usersImage
,
4217 newwidth
,newheight
,(void *)dstImage
,
4218 element_size
,rowsize
,myswap_bytes
);
4220 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4221 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4222 width
, height
,usersImage
,
4223 newwidth
,newheight
,(void *)dstImage
,
4224 element_size
,rowsize
,myswap_bytes
);
4226 case GL_UNSIGNED_SHORT_5_6_5
:
4227 scaleInternalPackedPixel(3,extract565
,shove565
,
4228 width
, height
,usersImage
,
4229 newwidth
,newheight
,(void *)dstImage
,
4230 element_size
,rowsize
,myswap_bytes
);
4232 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4233 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4234 width
, height
,usersImage
,
4235 newwidth
,newheight
,(void *)dstImage
,
4236 element_size
,rowsize
,myswap_bytes
);
4238 case GL_UNSIGNED_SHORT_4_4_4_4
:
4239 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4240 width
, height
,usersImage
,
4241 newwidth
,newheight
,(void *)dstImage
,
4242 element_size
,rowsize
,myswap_bytes
);
4244 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4245 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4246 width
, height
,usersImage
,
4247 newwidth
,newheight
,(void *)dstImage
,
4248 element_size
,rowsize
,myswap_bytes
);
4250 case GL_UNSIGNED_SHORT_5_5_5_1
:
4251 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4252 width
, height
,usersImage
,
4253 newwidth
,newheight
,(void *)dstImage
,
4254 element_size
,rowsize
,myswap_bytes
);
4256 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4257 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4258 width
, height
,usersImage
,
4259 newwidth
,newheight
,(void *)dstImage
,
4260 element_size
,rowsize
,myswap_bytes
);
4262 case GL_UNSIGNED_INT_8_8_8_8
:
4263 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4264 width
, height
,usersImage
,
4265 newwidth
,newheight
,(void *)dstImage
,
4266 element_size
,rowsize
,myswap_bytes
);
4268 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4269 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4270 width
, height
,usersImage
,
4271 newwidth
,newheight
,(void *)dstImage
,
4272 element_size
,rowsize
,myswap_bytes
);
4274 case GL_UNSIGNED_INT_10_10_10_2
:
4275 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4276 width
, height
,usersImage
,
4277 newwidth
,newheight
,(void *)dstImage
,
4278 element_size
,rowsize
,myswap_bytes
);
4280 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4281 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4282 width
, height
,usersImage
,
4283 newwidth
,newheight
,(void *)dstImage
,
4284 element_size
,rowsize
,myswap_bytes
);
4291 rowsize
= newwidth
* group_size
;
4292 /* Swap dstImage and srcImage */
4293 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4295 if(levels
!= 0) { /* use as little memory as possible */
4297 int nextWidth
= newwidth
/2;
4298 int nextHeight
= newheight
/2;
4299 if (nextWidth
< 1) nextWidth
= 1;
4300 if (nextHeight
< 1) nextHeight
= 1;
4302 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4306 case GL_UNSIGNED_BYTE
:
4307 dstImage
= (GLubyte
*)malloc(memreq
);
4310 dstImage
= (GLbyte
*)malloc(memreq
);
4312 case GL_UNSIGNED_SHORT
:
4313 dstImage
= (GLushort
*)malloc(memreq
);
4316 dstImage
= (GLshort
*)malloc(memreq
);
4318 case GL_UNSIGNED_INT
:
4319 dstImage
= (GLuint
*)malloc(memreq
);
4322 dstImage
= (GLint
*)malloc(memreq
);
4325 dstImage
= (GLfloat
*)malloc(memreq
);
4327 case GL_UNSIGNED_BYTE_3_3_2
:
4328 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4329 dstImage
= (GLubyte
*)malloc(memreq
);
4331 case GL_UNSIGNED_SHORT_5_6_5
:
4332 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4333 case GL_UNSIGNED_SHORT_4_4_4_4
:
4334 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4335 case GL_UNSIGNED_SHORT_5_5_5_1
:
4336 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4337 dstImage
= (GLushort
*)malloc(memreq
);
4339 case GL_UNSIGNED_INT_8_8_8_8
:
4340 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4341 case GL_UNSIGNED_INT_10_10_10_2
:
4342 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4343 dstImage
= (GLuint
*)malloc(memreq
);
4346 return GLU_INVALID_ENUM
;
4348 if (dstImage
== NULL
) {
4349 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4350 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4351 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4352 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4353 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4355 return GLU_OUT_OF_MEMORY
;
4358 /* level userLevel is in srcImage; nothing saved yet */
4362 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4363 if (baseLevel
<= level
&& level
<= maxLevel
) {
4364 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4365 format
, type
, (void *)srcImage
);
4368 level
++; /* update current level for the loop */
4369 for (; level
<= levels
; level
++) {
4371 case GL_UNSIGNED_BYTE
:
4372 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4373 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4374 rowsize
, group_size
);
4377 halveImage_byte(cmpts
, newwidth
, newheight
,
4378 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4379 rowsize
, group_size
);
4381 case GL_UNSIGNED_SHORT
:
4382 halveImage_ushort(cmpts
, newwidth
, newheight
,
4383 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4384 rowsize
, group_size
, myswap_bytes
);
4387 halveImage_short(cmpts
, newwidth
, newheight
,
4388 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4389 rowsize
, group_size
, myswap_bytes
);
4391 case GL_UNSIGNED_INT
:
4392 halveImage_uint(cmpts
, newwidth
, newheight
,
4393 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4394 rowsize
, group_size
, myswap_bytes
);
4397 halveImage_int(cmpts
, newwidth
, newheight
,
4398 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4399 rowsize
, group_size
, myswap_bytes
);
4402 halveImage_float(cmpts
, newwidth
, newheight
,
4403 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4404 rowsize
, group_size
, myswap_bytes
);
4406 case GL_UNSIGNED_BYTE_3_3_2
:
4407 halveImagePackedPixel(3,extract332
,shove332
,
4409 srcImage
,dstImage
,element_size
,rowsize
,
4412 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4413 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4415 srcImage
,dstImage
,element_size
,rowsize
,
4418 case GL_UNSIGNED_SHORT_5_6_5
:
4419 halveImagePackedPixel(3,extract565
,shove565
,
4421 srcImage
,dstImage
,element_size
,rowsize
,
4424 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4425 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4427 srcImage
,dstImage
,element_size
,rowsize
,
4430 case GL_UNSIGNED_SHORT_4_4_4_4
:
4431 halveImagePackedPixel(4,extract4444
,shove4444
,
4433 srcImage
,dstImage
,element_size
,rowsize
,
4436 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4437 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4439 srcImage
,dstImage
,element_size
,rowsize
,
4442 case GL_UNSIGNED_SHORT_5_5_5_1
:
4443 halveImagePackedPixel(4,extract5551
,shove5551
,
4445 srcImage
,dstImage
,element_size
,rowsize
,
4448 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4449 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4451 srcImage
,dstImage
,element_size
,rowsize
,
4454 case GL_UNSIGNED_INT_8_8_8_8
:
4455 halveImagePackedPixel(4,extract8888
,shove8888
,
4457 srcImage
,dstImage
,element_size
,rowsize
,
4460 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4461 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4463 srcImage
,dstImage
,element_size
,rowsize
,
4466 case GL_UNSIGNED_INT_10_10_10_2
:
4467 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4469 srcImage
,dstImage
,element_size
,rowsize
,
4472 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4473 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4475 srcImage
,dstImage
,element_size
,rowsize
,
4483 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4485 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4486 if (newheight
> 1) newheight
/= 2;
4488 /* compute amount to pad per row, if any */
4489 int rowPad
= rowsize
% psm
.unpack_alignment
;
4491 /* should row be padded? */
4492 if (rowPad
== 0) { /* nope, row should not be padded */
4493 /* call tex image with srcImage untouched since it's not padded */
4494 if (baseLevel
<= level
&& level
<= maxLevel
) {
4495 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4496 format
, type
, (void *) srcImage
);
4499 else { /* yes, row should be padded */
4500 /* compute length of new row in bytes, including padding */
4501 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4502 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4504 /* allocate new image for mipmap of size newRowLength x newheight */
4505 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4506 if (newMipmapImage
== NULL
) {
4507 /* out of memory so return */
4508 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4509 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4510 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4511 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4512 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4513 return GLU_OUT_OF_MEMORY
;
4516 /* copy image from srcImage into newMipmapImage by rows */
4518 dstTrav
= (unsigned char *) newMipmapImage
,
4519 srcTrav
= (unsigned char *) srcImage
;
4522 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4523 srcTrav
+= rowsize
) { /* ...is skipped */
4524 memcpy(dstTrav
,srcTrav
,rowsize
);
4525 /* note that the pad bytes are not visited and will contain
4526 * garbage, which is ok.
4530 /* ...and use this new image for mipmapping instead */
4531 if (baseLevel
<= level
&& level
<= maxLevel
) {
4532 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4533 format
, type
, newMipmapImage
);
4535 free(newMipmapImage
); /* don't forget to free it! */
4539 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4540 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4541 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4542 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4543 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4545 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4546 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4550 } /* gluBuild2DMipmapLevelsCore() */
4553 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4554 GLsizei width
, GLsizei height
,
4555 GLenum format
, GLenum type
,
4556 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4561 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4562 if (rc
!= 0) return rc
;
4564 if (width
< 1 || height
< 1) {
4565 return GLU_INVALID_VALUE
;
4568 levels
= computeLog(width
);
4569 level
= computeLog(height
);
4570 if (level
> levels
) levels
=level
;
4573 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4574 return GLU_INVALID_VALUE
;
4576 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4580 userLevel
, baseLevel
, maxLevel
,
4582 } /* gluBuild2DMipmapLevels() */
4585 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4586 GLsizei width
, GLsizei height
,
4587 GLenum format
, GLenum type
,
4590 GLint widthPowerOf2
, heightPowerOf2
;
4593 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4594 if (rc
!= 0) return rc
;
4596 if (width
< 1 || height
< 1) {
4597 return GLU_INVALID_VALUE
;
4600 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4601 &widthPowerOf2
,&heightPowerOf2
);
4603 levels
= computeLog(widthPowerOf2
);
4604 level
= computeLog(heightPowerOf2
);
4605 if (level
> levels
) levels
=level
;
4607 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4609 widthPowerOf2
,heightPowerOf2
,
4612 } /* gluBuild2DMipmaps() */
4616 ** This routine is for the limited case in which
4617 ** type == GL_UNSIGNED_BYTE && format != index &&
4618 ** unpack_alignment = 1 && unpack_swap_bytes == false
4620 ** so all of the work data can be kept as ubytes instead of shorts.
4622 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4623 GLenum target
, GLint components
, GLint width
,
4624 GLint height
, GLenum format
,
4625 GLenum type
, void *data
)
4627 GLint newwidth
, newheight
;
4628 GLint level
, levels
;
4630 GLint newImage_width
;
4631 GLint newImage_height
;
4632 GLubyte
*otherImage
;
4639 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4640 newwidth
= nearestPower(width
);
4641 if (newwidth
> maxsize
) newwidth
= maxsize
;
4642 newheight
= nearestPower(height
);
4643 if (newheight
> maxsize
) newheight
= maxsize
;
4645 closestFit(target
,width
,height
,components
,format
,type
,
4646 &newwidth
,&newheight
);
4648 levels
= computeLog(newwidth
);
4649 level
= computeLog(newheight
);
4650 if (level
> levels
) levels
=level
;
4652 cmpts
= elements_per_group(format
,type
);
4656 ** No need to copy the user data if its in the packed correctly.
4657 ** Make sure that later routines don't change that data.
4659 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4660 newImage
= (GLubyte
*)data
;
4661 newImage_width
= width
;
4662 newImage_height
= height
;
4665 GLint groups_per_line
;
4666 GLint elements_per_line
;
4667 const GLubyte
*start
;
4668 const GLubyte
*iter
;
4672 newImage
= (GLubyte
*)
4673 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4674 newImage_width
= width
;
4675 newImage_height
= height
;
4676 if (newImage
== NULL
) {
4677 return GLU_OUT_OF_MEMORY
;
4681 ** Abbreviated version of fill_image for this restricted case.
4683 if (psm
->unpack_row_length
> 0) {
4684 groups_per_line
= psm
->unpack_row_length
;
4686 groups_per_line
= width
;
4688 rowsize
= groups_per_line
* cmpts
;
4689 elements_per_line
= width
* cmpts
;
4690 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4691 psm
->unpack_skip_pixels
* cmpts
;
4694 for (i
= 0; i
< height
; i
++) {
4696 for (j
= 0; j
< elements_per_line
; j
++) {
4706 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4707 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4708 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4709 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4710 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4712 for (level
= 0; level
<= levels
; level
++) {
4713 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4714 /* Use newImage for this level */
4715 glTexImage2D(target
, level
, components
, newImage_width
,
4716 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4719 if (otherImage
== NULL
) {
4721 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4722 otherImage
= (GLubyte
*) malloc(memreq
);
4723 if (otherImage
== NULL
) {
4724 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4725 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4726 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4727 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4728 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4729 return GLU_OUT_OF_MEMORY
;
4733 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4734 newImage, newwidth, newheight, otherImage);
4736 /* Swap newImage and otherImage */
4737 imageTemp
= otherImage
;
4738 otherImage
= newImage
;
4739 newImage
= imageTemp
;
4741 newImage_width
= newwidth
;
4742 newImage_height
= newheight
;
4743 glTexImage2D(target
, level
, components
, newImage_width
,
4744 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4747 if (newwidth
> 1) newwidth
/= 2;
4748 if (newheight
> 1) newheight
/= 2;
4750 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4751 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4752 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4753 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4754 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4756 if (newImage
!= (const GLubyte
*)data
) {
4757 free((GLbyte
*) newImage
);
4759 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4760 free((GLbyte
*) otherImage
);
4769 static GLint
elements_per_group(GLenum format
, GLenum type
)
4772 * Return the number of elements per group of a specified format
4775 /* If the type is packedpixels then answer is 1 (ignore format) */
4776 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4777 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4778 type
== GL_UNSIGNED_SHORT_5_6_5
||
4779 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4780 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4781 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4782 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4783 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4784 type
== GL_UNSIGNED_INT_8_8_8_8
||
4785 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4786 type
== GL_UNSIGNED_INT_10_10_10_2
||
4787 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4791 /* Types are not packed pixels, so get elements per group */
4796 case GL_LUMINANCE_ALPHA
:
4806 static GLfloat
bytes_per_element(GLenum type
)
4809 * Return the number of bytes per element, based on the element type
4814 case GL_UNSIGNED_SHORT
:
4815 return(sizeof(GLushort
));
4817 return(sizeof(GLshort
));
4818 case GL_UNSIGNED_BYTE
:
4819 return(sizeof(GLubyte
));
4821 return(sizeof(GLbyte
));
4823 return(sizeof(GLint
));
4824 case GL_UNSIGNED_INT
:
4825 return(sizeof(GLuint
));
4827 return(sizeof(GLfloat
));
4828 case GL_UNSIGNED_BYTE_3_3_2
:
4829 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4830 return(sizeof(GLubyte
));
4831 case GL_UNSIGNED_SHORT_5_6_5
:
4832 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4833 case GL_UNSIGNED_SHORT_4_4_4_4
:
4834 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4835 case GL_UNSIGNED_SHORT_5_5_5_1
:
4836 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4837 return(sizeof(GLushort
));
4838 case GL_UNSIGNED_INT_8_8_8_8
:
4839 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4840 case GL_UNSIGNED_INT_10_10_10_2
:
4841 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4842 return(sizeof(GLuint
));
4848 static GLint
is_index(GLenum format
)
4850 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4854 ** Compute memory required for internal packed array of data of given type
4857 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4864 components
= elements_per_group(format
,type
);
4865 if (type
== GL_BITMAP
) {
4866 bytes_per_row
= (width
+ 7) / 8;
4868 bytes_per_row
= bytes_per_element(type
) * width
;
4870 return bytes_per_row
* height
* components
;
4874 ** Extract array from user's data applying all pixel store modes.
4875 ** The internal format used is an array of unsigned shorts.
4877 static void fill_image(const PixelStorageModes
*psm
,
4878 GLint width
, GLint height
, GLenum format
,
4879 GLenum type
, GLboolean index_format
,
4880 const void *userdata
, GLushort
*newimage
)
4886 GLint groups_per_line
;
4888 GLint elements_per_line
;
4889 const GLubyte
*start
;
4890 const GLubyte
*iter
;
4895 myswap_bytes
= psm
->unpack_swap_bytes
;
4896 components
= elements_per_group(format
,type
);
4897 if (psm
->unpack_row_length
> 0) {
4898 groups_per_line
= psm
->unpack_row_length
;
4900 groups_per_line
= width
;
4903 /* All formats except GL_BITMAP fall out trivially */
4904 if (type
== GL_BITMAP
) {
4908 rowsize
= (groups_per_line
* components
+ 7) / 8;
4909 padding
= (rowsize
% psm
->unpack_alignment
);
4911 rowsize
+= psm
->unpack_alignment
- padding
;
4913 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4914 (psm
->unpack_skip_pixels
* components
/ 8);
4915 elements_per_line
= width
* components
;
4917 for (i
= 0; i
< height
; i
++) {
4919 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4920 for (j
= 0; j
< elements_per_line
; j
++) {
4922 if (psm
->unpack_lsb_first
) {
4923 current_bit
= iter
[0] & (1 << bit_offset
);
4925 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4937 if (bit_offset
== 8) {
4946 element_size
= bytes_per_element(type
);
4947 group_size
= element_size
* components
;
4948 if (element_size
== 1) myswap_bytes
= 0;
4950 rowsize
= groups_per_line
* group_size
;
4951 padding
= (rowsize
% psm
->unpack_alignment
);
4953 rowsize
+= psm
->unpack_alignment
- padding
;
4955 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4956 psm
->unpack_skip_pixels
* group_size
;
4957 elements_per_line
= width
* components
;
4960 for (i
= 0; i
< height
; i
++) {
4962 for (j
= 0; j
< elements_per_line
; j
++) {
4964 float extractComponents
[4];
4967 case GL_UNSIGNED_BYTE_3_3_2
:
4968 extract332(0,iter
,extractComponents
);
4969 for (k
= 0; k
< 3; k
++) {
4970 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4973 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4974 extract233rev(0,iter
,extractComponents
);
4975 for (k
= 0; k
< 3; k
++) {
4976 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4979 case GL_UNSIGNED_BYTE
:
4983 *iter2
++ = (*iter
) * 257;
4988 *iter2
++ = *((const GLbyte
*) iter
);
4991 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4994 case GL_UNSIGNED_SHORT_5_6_5
:
4995 extract565(myswap_bytes
,iter
,extractComponents
);
4996 for (k
= 0; k
< 3; k
++) {
4997 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5000 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5001 extract565rev(myswap_bytes
,iter
,extractComponents
);
5002 for (k
= 0; k
< 3; k
++) {
5003 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5006 case GL_UNSIGNED_SHORT_4_4_4_4
:
5007 extract4444(myswap_bytes
,iter
,extractComponents
);
5008 for (k
= 0; k
< 4; k
++) {
5009 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5012 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5013 extract4444rev(myswap_bytes
,iter
,extractComponents
);
5014 for (k
= 0; k
< 4; k
++) {
5015 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5018 case GL_UNSIGNED_SHORT_5_5_5_1
:
5019 extract5551(myswap_bytes
,iter
,extractComponents
);
5020 for (k
= 0; k
< 4; k
++) {
5021 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5024 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5025 extract1555rev(myswap_bytes
,iter
,extractComponents
);
5026 for (k
= 0; k
< 4; k
++) {
5027 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5030 case GL_UNSIGNED_SHORT
:
5033 widget
.ub
[0] = iter
[1];
5034 widget
.ub
[1] = iter
[0];
5036 widget
.ub
[0] = iter
[0];
5037 widget
.ub
[1] = iter
[1];
5039 if (type
== GL_SHORT
) {
5041 *iter2
++ = widget
.s
[0];
5044 *iter2
++ = widget
.s
[0]*2;
5047 *iter2
++ = widget
.us
[0];
5050 case GL_UNSIGNED_INT_8_8_8_8
:
5051 extract8888(myswap_bytes
,iter
,extractComponents
);
5052 for (k
= 0; k
< 4; k
++) {
5053 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5056 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5057 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5058 for (k
= 0; k
< 4; k
++) {
5059 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5062 case GL_UNSIGNED_INT_10_10_10_2
:
5063 extract1010102(myswap_bytes
,iter
,extractComponents
);
5064 for (k
= 0; k
< 4; k
++) {
5065 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5068 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5069 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5070 for (k
= 0; k
< 4; k
++) {
5071 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5075 case GL_UNSIGNED_INT
:
5078 widget
.ub
[0] = iter
[3];
5079 widget
.ub
[1] = iter
[2];
5080 widget
.ub
[2] = iter
[1];
5081 widget
.ub
[3] = iter
[0];
5083 widget
.ub
[0] = iter
[0];
5084 widget
.ub
[1] = iter
[1];
5085 widget
.ub
[2] = iter
[2];
5086 widget
.ub
[3] = iter
[3];
5088 if (type
== GL_FLOAT
) {
5090 *iter2
++ = widget
.f
;
5092 *iter2
++ = 65535 * widget
.f
;
5094 } else if (type
== GL_UNSIGNED_INT
) {
5096 *iter2
++ = widget
.ui
;
5098 *iter2
++ = widget
.ui
>> 16;
5102 *iter2
++ = widget
.i
;
5104 *iter2
++ = widget
.i
>> 15;
5109 iter
+= element_size
;
5113 /* want 'iter' pointing at start, not within, row for assertion
5120 /* iterators should be one byte past end */
5121 if (!isTypePackedPixel(type
)) {
5122 assert(iter2
== &newimage
[width
*height
*components
]);
5125 assert(iter2
== &newimage
[width
*height
*
5126 elements_per_group(format
,0)]);
5128 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5129 psm
->unpack_skip_rows
* rowsize
+
5130 psm
->unpack_skip_pixels
* group_size
] );
5133 } /* fill_image() */
5136 ** Insert array into user's data applying all pixel store modes.
5137 ** The internal format is an array of unsigned shorts.
5138 ** empty_image() because it is the opposite of fill_image().
5140 static void empty_image(const PixelStorageModes
*psm
,
5141 GLint width
, GLint height
, GLenum format
,
5142 GLenum type
, GLboolean index_format
,
5143 const GLushort
*oldimage
, void *userdata
)
5149 GLint groups_per_line
;
5151 GLint elements_per_line
;
5154 const GLushort
*iter2
;
5158 myswap_bytes
= psm
->pack_swap_bytes
;
5159 components
= elements_per_group(format
,type
);
5160 if (psm
->pack_row_length
> 0) {
5161 groups_per_line
= psm
->pack_row_length
;
5163 groups_per_line
= width
;
5166 /* All formats except GL_BITMAP fall out trivially */
5167 if (type
== GL_BITMAP
) {
5171 rowsize
= (groups_per_line
* components
+ 7) / 8;
5172 padding
= (rowsize
% psm
->pack_alignment
);
5174 rowsize
+= psm
->pack_alignment
- padding
;
5176 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5177 (psm
->pack_skip_pixels
* components
/ 8);
5178 elements_per_line
= width
* components
;
5180 for (i
= 0; i
< height
; i
++) {
5182 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5183 for (j
= 0; j
< elements_per_line
; j
++) {
5185 current_bit
= iter2
[0] & 1;
5187 if (iter2
[0] > 32767) {
5195 if (psm
->pack_lsb_first
) {
5196 *iter
|= (1 << bit_offset
);
5198 *iter
|= (1 << (7 - bit_offset
));
5201 if (psm
->pack_lsb_first
) {
5202 *iter
&= ~(1 << bit_offset
);
5204 *iter
&= ~(1 << (7 - bit_offset
));
5209 if (bit_offset
== 8) {
5218 float shoveComponents
[4];
5220 element_size
= bytes_per_element(type
);
5221 group_size
= element_size
* components
;
5222 if (element_size
== 1) myswap_bytes
= 0;
5224 rowsize
= groups_per_line
* group_size
;
5225 padding
= (rowsize
% psm
->pack_alignment
);
5227 rowsize
+= psm
->pack_alignment
- padding
;
5229 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5230 psm
->pack_skip_pixels
* group_size
;
5231 elements_per_line
= width
* components
;
5234 for (i
= 0; i
< height
; i
++) {
5236 for (j
= 0; j
< elements_per_line
; j
++) {
5240 case GL_UNSIGNED_BYTE_3_3_2
:
5241 for (k
= 0; k
< 3; k
++) {
5242 shoveComponents
[k
]= *iter2
++ / 65535.0;
5244 shove332(shoveComponents
,0,(void *)iter
);
5246 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5247 for (k
= 0; k
< 3; k
++) {
5248 shoveComponents
[k
]= *iter2
++ / 65535.0;
5250 shove233rev(shoveComponents
,0,(void *)iter
);
5252 case GL_UNSIGNED_BYTE
:
5256 *iter
= *iter2
++ >> 8;
5261 *((GLbyte
*) iter
) = *iter2
++;
5263 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5266 case GL_UNSIGNED_SHORT_5_6_5
:
5267 for (k
= 0; k
< 3; k
++) {
5268 shoveComponents
[k
]= *iter2
++ / 65535.0;
5270 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5272 iter
[0] = widget
.ub
[1];
5273 iter
[1] = widget
.ub
[0];
5276 *(GLushort
*)iter
= widget
.us
[0];
5279 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5280 for (k
= 0; k
< 3; k
++) {
5281 shoveComponents
[k
]= *iter2
++ / 65535.0;
5283 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5285 iter
[0] = widget
.ub
[1];
5286 iter
[1] = widget
.ub
[0];
5289 *(GLushort
*)iter
= widget
.us
[0];
5292 case GL_UNSIGNED_SHORT_4_4_4_4
:
5293 for (k
= 0; k
< 4; k
++) {
5294 shoveComponents
[k
]= *iter2
++ / 65535.0;
5296 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5298 iter
[0] = widget
.ub
[1];
5299 iter
[1] = widget
.ub
[0];
5301 *(GLushort
*)iter
= widget
.us
[0];
5304 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5305 for (k
= 0; k
< 4; k
++) {
5306 shoveComponents
[k
]= *iter2
++ / 65535.0;
5308 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5310 iter
[0] = widget
.ub
[1];
5311 iter
[1] = widget
.ub
[0];
5313 *(GLushort
*)iter
= widget
.us
[0];
5316 case GL_UNSIGNED_SHORT_5_5_5_1
:
5317 for (k
= 0; k
< 4; k
++) {
5318 shoveComponents
[k
]= *iter2
++ / 65535.0;
5320 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5322 iter
[0] = widget
.ub
[1];
5323 iter
[1] = widget
.ub
[0];
5325 *(GLushort
*)iter
= widget
.us
[0];
5328 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5329 for (k
= 0; k
< 4; k
++) {
5330 shoveComponents
[k
]= *iter2
++ / 65535.0;
5332 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5334 iter
[0] = widget
.ub
[1];
5335 iter
[1] = widget
.ub
[0];
5337 *(GLushort
*)iter
= widget
.us
[0];
5340 case GL_UNSIGNED_SHORT
:
5342 if (type
== GL_SHORT
) {
5344 widget
.s
[0] = *iter2
++;
5346 widget
.s
[0] = *iter2
++ >> 1;
5349 widget
.us
[0] = *iter2
++;
5352 iter
[0] = widget
.ub
[1];
5353 iter
[1] = widget
.ub
[0];
5355 iter
[0] = widget
.ub
[0];
5356 iter
[1] = widget
.ub
[1];
5359 case GL_UNSIGNED_INT_8_8_8_8
:
5360 for (k
= 0; k
< 4; k
++) {
5361 shoveComponents
[k
]= *iter2
++ / 65535.0;
5363 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5365 iter
[3] = widget
.ub
[0];
5366 iter
[2] = widget
.ub
[1];
5367 iter
[1] = widget
.ub
[2];
5368 iter
[0] = widget
.ub
[3];
5370 *(GLuint
*)iter
= widget
.ui
;
5374 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5375 for (k
= 0; k
< 4; k
++) {
5376 shoveComponents
[k
]= *iter2
++ / 65535.0;
5378 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5380 iter
[3] = widget
.ub
[0];
5381 iter
[2] = widget
.ub
[1];
5382 iter
[1] = widget
.ub
[2];
5383 iter
[0] = widget
.ub
[3];
5385 *(GLuint
*)iter
= widget
.ui
;
5388 case GL_UNSIGNED_INT_10_10_10_2
:
5389 for (k
= 0; k
< 4; k
++) {
5390 shoveComponents
[k
]= *iter2
++ / 65535.0;
5392 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5394 iter
[3] = widget
.ub
[0];
5395 iter
[2] = widget
.ub
[1];
5396 iter
[1] = widget
.ub
[2];
5397 iter
[0] = widget
.ub
[3];
5399 *(GLuint
*)iter
= widget
.ui
;
5402 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5403 for (k
= 0; k
< 4; k
++) {
5404 shoveComponents
[k
]= *iter2
++ / 65535.0;
5406 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
5408 iter
[3] = widget
.ub
[0];
5409 iter
[2] = widget
.ub
[1];
5410 iter
[1] = widget
.ub
[2];
5411 iter
[0] = widget
.ub
[3];
5413 *(GLuint
*)iter
= widget
.ui
;
5417 case GL_UNSIGNED_INT
:
5419 if (type
== GL_FLOAT
) {
5421 widget
.f
= *iter2
++;
5423 widget
.f
= *iter2
++ / (float) 65535.0;
5425 } else if (type
== GL_UNSIGNED_INT
) {
5427 widget
.ui
= *iter2
++;
5429 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5433 widget
.i
= *iter2
++;
5435 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5439 iter
[3] = widget
.ub
[0];
5440 iter
[2] = widget
.ub
[1];
5441 iter
[1] = widget
.ub
[2];
5442 iter
[0] = widget
.ub
[3];
5444 iter
[0] = widget
.ub
[0];
5445 iter
[1] = widget
.ub
[1];
5446 iter
[2] = widget
.ub
[2];
5447 iter
[3] = widget
.ub
[3];
5451 iter
+= element_size
;
5455 /* want 'iter' pointing at start, not within, row for assertion
5462 /* iterators should be one byte past end */
5463 if (!isTypePackedPixel(type
)) {
5464 assert(iter2
== &oldimage
[width
*height
*components
]);
5467 assert(iter2
== &oldimage
[width
*height
*
5468 elements_per_group(format
,0)]);
5470 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5471 psm
->pack_skip_rows
* rowsize
+
5472 psm
->pack_skip_pixels
* group_size
] );
5475 } /* empty_image() */
5477 /*--------------------------------------------------------------------------
5478 * Decimation of packed pixel types
5479 *--------------------------------------------------------------------------
5481 static void extract332(int isSwap
,
5482 const void *packedPixel
, GLfloat extractComponents
[])
5484 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5486 isSwap
= isSwap
; /* turn off warnings */
5488 /* 11100000 == 0xe0 */
5489 /* 00011100 == 0x1c */
5490 /* 00000011 == 0x03 */
5492 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5493 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5494 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5495 } /* extract332() */
5497 static void shove332(const GLfloat shoveComponents
[],
5498 int index
, void *packedPixel
)
5500 /* 11100000 == 0xe0 */
5501 /* 00011100 == 0x1c */
5502 /* 00000011 == 0x03 */
5504 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5505 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5506 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5508 /* due to limited precision, need to round before shoving */
5509 ((GLubyte
*)packedPixel
)[index
] =
5510 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5511 ((GLubyte
*)packedPixel
)[index
] |=
5512 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5513 ((GLubyte
*)packedPixel
)[index
] |=
5514 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5517 static void extract233rev(int isSwap
,
5518 const void *packedPixel
, GLfloat extractComponents
[])
5520 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5522 isSwap
= isSwap
; /* turn off warnings */
5524 /* 0000,0111 == 0x07 */
5525 /* 0011,1000 == 0x38 */
5526 /* 1100,0000 == 0xC0 */
5528 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5529 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5530 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5531 } /* extract233rev() */
5533 static void shove233rev(const GLfloat shoveComponents
[],
5534 int index
, void *packedPixel
)
5536 /* 0000,0111 == 0x07 */
5537 /* 0011,1000 == 0x38 */
5538 /* 1100,0000 == 0xC0 */
5540 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5541 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5542 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5544 /* due to limited precision, need to round before shoving */
5545 ((GLubyte
*)packedPixel
)[index
] =
5546 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5547 ((GLubyte
*)packedPixel
)[index
]|=
5548 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5549 ((GLubyte
*)packedPixel
)[index
]|=
5550 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5551 } /* shove233rev() */
5553 static void extract565(int isSwap
,
5554 const void *packedPixel
, GLfloat extractComponents
[])
5556 GLushort ushort
= *(const GLushort
*)packedPixel
;
5559 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5562 ushort
= *(const GLushort
*)packedPixel
;
5565 /* 11111000,00000000 == 0xf800 */
5566 /* 00000111,11100000 == 0x07e0 */
5567 /* 00000000,00011111 == 0x001f */
5569 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5570 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5571 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5572 } /* extract565() */
5574 static void shove565(const GLfloat shoveComponents
[],
5575 int index
,void *packedPixel
)
5577 /* 11111000,00000000 == 0xf800 */
5578 /* 00000111,11100000 == 0x07e0 */
5579 /* 00000000,00011111 == 0x001f */
5581 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5582 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5583 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5585 /* due to limited precision, need to round before shoving */
5586 ((GLushort
*)packedPixel
)[index
] =
5587 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5588 ((GLushort
*)packedPixel
)[index
]|=
5589 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5590 ((GLushort
*)packedPixel
)[index
]|=
5591 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5594 static void extract565rev(int isSwap
,
5595 const void *packedPixel
, GLfloat extractComponents
[])
5597 GLushort ushort
= *(const GLushort
*)packedPixel
;
5600 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5603 ushort
= *(const GLushort
*)packedPixel
;
5606 /* 00000000,00011111 == 0x001f */
5607 /* 00000111,11100000 == 0x07e0 */
5608 /* 11111000,00000000 == 0xf800 */
5610 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5611 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5612 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5613 } /* extract565rev() */
5615 static void shove565rev(const GLfloat shoveComponents
[],
5616 int index
,void *packedPixel
)
5618 /* 00000000,00011111 == 0x001f */
5619 /* 00000111,11100000 == 0x07e0 */
5620 /* 11111000,00000000 == 0xf800 */
5622 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5623 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5624 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5626 /* due to limited precision, need to round before shoving */
5627 ((GLushort
*)packedPixel
)[index
] =
5628 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5629 ((GLushort
*)packedPixel
)[index
]|=
5630 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5631 ((GLushort
*)packedPixel
)[index
]|=
5632 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5633 } /* shove565rev() */
5635 static void extract4444(int isSwap
,const void *packedPixel
,
5636 GLfloat extractComponents
[])
5641 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5644 ushort
= *(const GLushort
*)packedPixel
;
5647 /* 11110000,00000000 == 0xf000 */
5648 /* 00001111,00000000 == 0x0f00 */
5649 /* 00000000,11110000 == 0x00f0 */
5650 /* 00000000,00001111 == 0x000f */
5652 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5653 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5654 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5655 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5656 } /* extract4444() */
5658 static void shove4444(const GLfloat shoveComponents
[],
5659 int index
,void *packedPixel
)
5661 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5662 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5663 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5664 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5666 /* due to limited precision, need to round before shoving */
5667 ((GLushort
*)packedPixel
)[index
] =
5668 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5669 ((GLushort
*)packedPixel
)[index
]|=
5670 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5671 ((GLushort
*)packedPixel
)[index
]|=
5672 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5673 ((GLushort
*)packedPixel
)[index
]|=
5674 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5677 static void extract4444rev(int isSwap
,const void *packedPixel
,
5678 GLfloat extractComponents
[])
5683 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5686 ushort
= *(const GLushort
*)packedPixel
;
5689 /* 00000000,00001111 == 0x000f */
5690 /* 00000000,11110000 == 0x00f0 */
5691 /* 00001111,00000000 == 0x0f00 */
5692 /* 11110000,00000000 == 0xf000 */
5695 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5696 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5697 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5698 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5699 } /* extract4444rev() */
5701 static void shove4444rev(const GLfloat shoveComponents
[],
5702 int index
,void *packedPixel
)
5704 /* 00000000,00001111 == 0x000f */
5705 /* 00000000,11110000 == 0x00f0 */
5706 /* 00001111,00000000 == 0x0f00 */
5707 /* 11110000,00000000 == 0xf000 */
5709 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5710 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5711 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5712 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5714 /* due to limited precision, need to round before shoving */
5715 ((GLushort
*)packedPixel
)[index
] =
5716 ((GLushort
)((shoveComponents
[0] * 15)+0.5) ) & 0x000F;
5717 ((GLushort
*)packedPixel
)[index
]|=
5718 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5719 ((GLushort
*)packedPixel
)[index
]|=
5720 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5721 ((GLushort
*)packedPixel
)[index
]|=
5722 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5723 } /* shove4444rev() */
5725 static void extract5551(int isSwap
,const void *packedPixel
,
5726 GLfloat extractComponents
[])
5731 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5734 ushort
= *(const GLushort
*)packedPixel
;
5737 /* 11111000,00000000 == 0xf800 */
5738 /* 00000111,11000000 == 0x07c0 */
5739 /* 00000000,00111110 == 0x003e */
5740 /* 00000000,00000001 == 0x0001 */
5742 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5743 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5744 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5745 extractComponents
[3]=(float)((ushort
& 0x0001) );
5746 } /* extract5551() */
5748 static void shove5551(const GLfloat shoveComponents
[],
5749 int index
,void *packedPixel
)
5751 /* 11111000,00000000 == 0xf800 */
5752 /* 00000111,11000000 == 0x07c0 */
5753 /* 00000000,00111110 == 0x003e */
5754 /* 00000000,00000001 == 0x0001 */
5756 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5757 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5758 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5759 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5761 /* due to limited precision, need to round before shoving */
5762 ((GLushort
*)packedPixel
)[index
] =
5763 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5764 ((GLushort
*)packedPixel
)[index
]|=
5765 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5766 ((GLushort
*)packedPixel
)[index
]|=
5767 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5768 ((GLushort
*)packedPixel
)[index
]|=
5769 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5772 static void extract1555rev(int isSwap
,const void *packedPixel
,
5773 GLfloat extractComponents
[])
5778 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5781 ushort
= *(const GLushort
*)packedPixel
;
5784 /* 00000000,00011111 == 0x001F */
5785 /* 00000011,11100000 == 0x03E0 */
5786 /* 01111100,00000000 == 0x7C00 */
5787 /* 10000000,00000000 == 0x8000 */
5790 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5791 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5792 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5793 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5794 } /* extract1555rev() */
5796 static void shove1555rev(const GLfloat shoveComponents
[],
5797 int index
,void *packedPixel
)
5799 /* 00000000,00011111 == 0x001F */
5800 /* 00000011,11100000 == 0x03E0 */
5801 /* 01111100,00000000 == 0x7C00 */
5802 /* 10000000,00000000 == 0x8000 */
5804 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5805 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5806 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5807 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5809 /* due to limited precision, need to round before shoving */
5810 ((GLushort
*)packedPixel
)[index
] =
5811 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5812 ((GLushort
*)packedPixel
)[index
]|=
5813 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5814 ((GLushort
*)packedPixel
)[index
]|=
5815 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5816 ((GLushort
*)packedPixel
)[index
]|=
5817 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5818 } /* shove1555rev() */
5820 static void extract8888(int isSwap
,
5821 const void *packedPixel
, GLfloat extractComponents
[])
5826 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5829 uint
= *(const GLuint
*)packedPixel
;
5832 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5833 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5834 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5835 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5838 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5839 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5840 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5841 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5842 } /* extract8888() */
5844 static void shove8888(const GLfloat shoveComponents
[],
5845 int index
,void *packedPixel
)
5847 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5848 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5849 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5850 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5852 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5853 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5854 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5855 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5857 /* due to limited precision, need to round before shoving */
5858 ((GLuint
*)packedPixel
)[index
] =
5859 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5860 ((GLuint
*)packedPixel
)[index
]|=
5861 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5862 ((GLuint
*)packedPixel
)[index
]|=
5863 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5864 ((GLuint
*)packedPixel
)[index
]|=
5865 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5868 static void extract8888rev(int isSwap
,
5869 const void *packedPixel
,GLfloat extractComponents
[])
5874 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5877 uint
= *(const GLuint
*)packedPixel
;
5880 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5881 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5882 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5883 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5886 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5887 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5888 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5889 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5890 } /* extract8888rev() */
5892 static void shove8888rev(const GLfloat shoveComponents
[],
5893 int index
,void *packedPixel
)
5895 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5896 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5897 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5898 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5900 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5901 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5902 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5903 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5905 /* due to limited precision, need to round before shoving */
5906 ((GLuint
*)packedPixel
)[index
] =
5907 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5908 ((GLuint
*)packedPixel
)[index
]|=
5909 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5910 ((GLuint
*)packedPixel
)[index
]|=
5911 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5912 ((GLuint
*)packedPixel
)[index
]|=
5913 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5914 } /* shove8888rev() */
5916 static void extract1010102(int isSwap
,
5917 const void *packedPixel
,GLfloat extractComponents
[])
5922 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5925 uint
= *(const GLuint
*)packedPixel
;
5928 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5929 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5930 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5931 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5934 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5935 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5936 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5937 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5938 } /* extract1010102() */
5940 static void shove1010102(const GLfloat shoveComponents
[],
5941 int index
,void *packedPixel
)
5943 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5944 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5945 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5946 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5948 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5949 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5950 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5951 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5953 /* due to limited precision, need to round before shoving */
5954 ((GLuint
*)packedPixel
)[index
] =
5955 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5956 ((GLuint
*)packedPixel
)[index
]|=
5957 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5958 ((GLuint
*)packedPixel
)[index
]|=
5959 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5960 ((GLuint
*)packedPixel
)[index
]|=
5961 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5962 } /* shove1010102() */
5964 static void extract2101010rev(int isSwap
,
5965 const void *packedPixel
,
5966 GLfloat extractComponents
[])
5971 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5974 uint
= *(const GLuint
*)packedPixel
;
5977 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5978 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5979 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5980 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5983 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5984 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5985 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5986 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5988 } /* extract2101010rev() */
5990 static void shove2101010rev(const GLfloat shoveComponents
[],
5991 int index
,void *packedPixel
)
5993 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5994 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5995 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5996 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5998 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5999 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
6000 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
6001 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
6003 /* due to limited precision, need to round before shoving */
6004 ((GLuint
*)packedPixel
)[index
] =
6005 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
6006 ((GLuint
*)packedPixel
)[index
]|=
6007 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
6008 ((GLuint
*)packedPixel
)[index
]|=
6009 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
6010 ((GLuint
*)packedPixel
)[index
]|=
6011 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
6012 } /* shove2101010rev() */
6014 static void scaleInternalPackedPixel(int components
,
6015 void (*extractPackedPixel
)
6016 (int, const void *,GLfloat
[]),
6017 void (*shovePackedPixel
)
6018 (const GLfloat
[], int, void *),
6019 GLint widthIn
,GLint heightIn
,
6021 GLint widthOut
,GLint heightOut
,
6023 GLint pixelSizeInBytes
,
6024 GLint rowSizeInBytes
,GLint isSwap
)
6030 /* Max components in a format is 4, so... */
6032 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
6037 const char *temp
, *temp0
;
6040 int lowx_int
, highx_int
, lowy_int
, highy_int
;
6041 float x_percent
, y_percent
;
6042 float lowx_float
, highx_float
, lowy_float
, highy_float
;
6043 float convy_float
, convx_float
;
6044 int convy_int
, convx_int
;
6046 const char *left
, *right
;
6048 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
6049 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6050 widthIn
, heightIn
, dataIn
, dataOut
,
6051 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6054 convy
= (float) heightIn
/heightOut
;
6055 convx
= (float) widthIn
/widthOut
;
6056 convy_int
= floor(convy
);
6057 convy_float
= convy
- convy_int
;
6058 convx_int
= floor(convx
);
6059 convx_float
= convx
- convx_int
;
6061 area
= convx
* convy
;
6065 highy_int
= convy_int
;
6066 highy_float
= convy_float
;
6068 for (i
= 0; i
< heightOut
; i
++) {
6071 highx_int
= convx_int
;
6072 highx_float
= convx_float
;
6074 for (j
= 0; j
< widthOut
; j
++) {
6076 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6077 ** to (highx, highy) on input data into this pixel on output
6080 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6082 /* calculate the value for pixels in the 1st row */
6083 xindex
= lowx_int
*pixelSizeInBytes
;
6084 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6086 y_percent
= 1-lowy_float
;
6087 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6088 percent
= y_percent
* (1-lowx_float
);
6090 for (k
= 0, temp_index
= temp
; k
< components
;
6091 k
++, temp_index
+= element_size
) {
6093 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6095 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6099 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6100 for (k
= 0; k
< components
; k
++) {
6101 totals
[k
]+= extractTotals
[k
] * percent
;
6105 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6106 temp
+= pixelSizeInBytes
;
6108 for (k
= 0, temp_index
= temp
; k
< components
;
6109 k
++, temp_index
+= element_size
) {
6112 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6114 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6118 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6119 for (k
= 0; k
< components
; k
++) {
6120 totals
[k
]+= extractTotals
[k
] * y_percent
;
6124 temp
+= pixelSizeInBytes
;
6126 percent
= y_percent
* highx_float
;
6128 for (k
= 0, temp_index
= temp
; k
< components
;
6129 k
++, temp_index
+= element_size
) {
6131 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6133 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6137 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6138 for (k
= 0; k
< components
; k
++) {
6139 totals
[k
]+= extractTotals
[k
] * percent
;
6143 /* calculate the value for pixels in the last row */
6145 y_percent
= highy_float
;
6146 percent
= y_percent
* (1-lowx_float
);
6147 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6149 for (k
= 0, temp_index
= temp
; k
< components
;
6150 k
++, temp_index
+= element_size
) {
6152 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6154 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6158 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6159 for (k
= 0; k
< components
; k
++) {
6160 totals
[k
]+= extractTotals
[k
] * percent
;
6163 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6164 temp
+= pixelSizeInBytes
;
6166 for (k
= 0, temp_index
= temp
; k
< components
;
6167 k
++, temp_index
+= element_size
) {
6170 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6172 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6176 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6177 for (k
= 0; k
< components
; k
++) {
6178 totals
[k
]+= extractTotals
[k
] * y_percent
;
6183 temp
+= pixelSizeInBytes
;
6184 percent
= y_percent
* highx_float
;
6186 for (k
= 0, temp_index
= temp
; k
< components
;
6187 k
++, temp_index
+= element_size
) {
6189 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6191 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6195 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6196 for (k
= 0; k
< components
; k
++) {
6197 totals
[k
]+= extractTotals
[k
] * percent
;
6201 /* calculate the value for pixels in the 1st and last column */
6202 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6203 left
+= rowSizeInBytes
;
6204 right
+= rowSizeInBytes
;
6206 for (k
= 0; k
< components
;
6207 k
++, left
+= element_size
, right
+= element_size
) {
6210 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6211 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6213 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6214 + *(const GLushort
*)right
* highx_float
;
6218 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6219 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6220 for (k
= 0; k
< components
; k
++) {
6221 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6222 extractMoreTotals
[k
]*highx_float
);
6226 } else if (highy_int
> lowy_int
) {
6227 x_percent
= highx_float
- lowx_float
;
6228 percent
= (1-lowy_float
)*x_percent
;
6229 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6231 for (k
= 0, temp_index
= temp
; k
< components
;
6232 k
++, temp_index
+= element_size
) {
6234 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6236 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6240 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6241 for (k
= 0; k
< components
; k
++) {
6242 totals
[k
]+= extractTotals
[k
] * percent
;
6245 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6246 temp
+= rowSizeInBytes
;
6248 for (k
= 0, temp_index
= temp
; k
< components
;
6249 k
++, temp_index
+= element_size
) {
6252 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6254 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6258 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6259 for (k
= 0; k
< components
; k
++) {
6260 totals
[k
]+= extractTotals
[k
] * x_percent
;
6264 percent
= x_percent
* highy_float
;
6265 temp
+= rowSizeInBytes
;
6267 for (k
= 0, temp_index
= temp
; k
< components
;
6268 k
++, temp_index
+= element_size
) {
6270 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6272 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6276 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6277 for (k
= 0; k
< components
; k
++) {
6278 totals
[k
]+= extractTotals
[k
] * percent
;
6281 } else if (highx_int
> lowx_int
) {
6282 y_percent
= highy_float
- lowy_float
;
6283 percent
= (1-lowx_float
)*y_percent
;
6284 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6286 for (k
= 0, temp_index
= temp
; k
< components
;
6287 k
++, temp_index
+= element_size
) {
6289 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6291 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6295 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6296 for (k
= 0; k
< components
; k
++) {
6297 totals
[k
]+= extractTotals
[k
] * percent
;
6300 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6301 temp
+= pixelSizeInBytes
;
6303 for (k
= 0, temp_index
= temp
; k
< components
;
6304 k
++, temp_index
+= element_size
) {
6307 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6309 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6313 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6314 for (k
= 0; k
< components
; k
++) {
6315 totals
[k
]+= extractTotals
[k
] * y_percent
;
6319 temp
+= pixelSizeInBytes
;
6320 percent
= y_percent
* highx_float
;
6322 for (k
= 0, temp_index
= temp
; k
< components
;
6323 k
++, temp_index
+= element_size
) {
6325 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6327 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6331 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6332 for (k
= 0; k
< components
; k
++) {
6333 totals
[k
]+= extractTotals
[k
] * percent
;
6337 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6338 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6340 for (k
= 0, temp_index
= temp
; k
< components
;
6341 k
++, temp_index
+= element_size
) {
6343 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6345 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6349 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6350 for (k
= 0; k
< components
; k
++) {
6351 totals
[k
]+= extractTotals
[k
] * percent
;
6356 /* this is for the pixels in the body */
6357 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6358 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6360 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6362 for (k
= 0, temp_index
= temp
; k
< components
;
6363 k
++, temp_index
+= element_size
) {
6365 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6367 totals
[k
] += *(const GLushort
*)temp_index
;
6371 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6372 for (k
= 0; k
< components
; k
++) {
6373 totals
[k
]+= extractTotals
[k
];
6376 temp
+= pixelSizeInBytes
;
6378 temp0
+= rowSizeInBytes
;
6381 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6383 for (k
= 0; k
< components
; k
++) {
6384 dataout
[outindex
+ k
] = totals
[k
]/area
;
6385 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6388 for (k
= 0; k
< components
; k
++) {
6389 shoveTotals
[k
]= totals
[k
]/area
;
6391 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6393 lowx_int
= highx_int
;
6394 lowx_float
= highx_float
;
6395 highx_int
+= convx_int
;
6396 highx_float
+= convx_float
;
6397 if(highx_float
> 1) {
6402 lowy_int
= highy_int
;
6403 lowy_float
= highy_float
;
6404 highy_int
+= convy_int
;
6405 highy_float
+= convy_float
;
6406 if(highy_float
> 1) {
6412 assert(outindex
== (widthOut
*heightOut
- 1));
6413 } /* scaleInternalPackedPixel() */
6415 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6416 * inputs; not always equal. Output NEVER has row padding.
6418 static void halveImagePackedPixel(int components
,
6419 void (*extractPackedPixel
)
6420 (int, const void *,GLfloat
[]),
6421 void (*shovePackedPixel
)
6422 (const GLfloat
[],int, void *),
6423 GLint width
, GLint height
,
6424 const void *dataIn
, void *dataOut
,
6425 GLint pixelSizeInBytes
,
6426 GLint rowSizeInBytes
, GLint isSwap
)
6428 /* handle case where there is only 1 column/row */
6429 if (width
== 1 || height
== 1) {
6430 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6431 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6432 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6433 rowSizeInBytes
,isSwap
);
6440 int halfWidth
= width
/ 2;
6441 int halfHeight
= height
/ 2;
6442 const char *src
= (const char *) dataIn
;
6443 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6446 for (ii
= 0; ii
< halfHeight
; ii
++) {
6447 for (jj
= 0; jj
< halfWidth
; jj
++) {
6449 float totals
[4]; /* 4 is maximum components */
6450 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6453 (*extractPackedPixel
)(isSwap
,src
,
6454 &extractTotals
[0][0]);
6455 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6456 &extractTotals
[1][0]);
6457 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6458 &extractTotals
[2][0]);
6459 (*extractPackedPixel
)(isSwap
,
6460 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6461 &extractTotals
[3][0]);
6462 for (cc
= 0; cc
< components
; cc
++) {
6465 /* grab 4 pixels to average */
6467 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6468 * extractTotals[2][RED]+extractTotals[3][RED];
6469 * totals[RED]/= 4.0;
6471 for (kk
= 0; kk
< BOX4
; kk
++) {
6472 totals
[cc
]+= extractTotals
[kk
][cc
];
6474 totals
[cc
]/= (float)BOX4
;
6476 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6479 /* skip over to next square of 4 */
6480 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6482 /* skip past pad bytes, if any, to get to next row */
6485 /* src is at beginning of a row here, but it's the second row of
6486 * the square block of 4 pixels that we just worked on so we
6487 * need to go one more row.
6495 src
+= rowSizeInBytes
;
6498 /* both pointers must reach one byte after the end */
6499 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6500 assert(outIndex
== halfWidth
* halfHeight
);
6502 } /* halveImagePackedPixel() */
6504 static void halve1DimagePackedPixel(int components
,
6505 void (*extractPackedPixel
)
6506 (int, const void *,GLfloat
[]),
6507 void (*shovePackedPixel
)
6508 (const GLfloat
[],int, void *),
6509 GLint width
, GLint height
,
6510 const void *dataIn
, void *dataOut
,
6511 GLint pixelSizeInBytes
,
6512 GLint rowSizeInBytes
, GLint isSwap
)
6514 int halfWidth
= width
/ 2;
6515 int halfHeight
= height
/ 2;
6516 const char *src
= (const char *) dataIn
;
6519 assert(width
== 1 || height
== 1); /* must be 1D */
6520 assert(width
!= height
); /* can't be square */
6522 if (height
== 1) { /* 1 row */
6525 assert(width
!= 1); /* widthxheight can't be 1x1 */
6528 /* one horizontal row with possible pad bytes */
6530 for (jj
= 0; jj
< halfWidth
; jj
++) {
6532 float totals
[4]; /* 4 is maximum components */
6533 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6536 /* average two at a time, instead of four */
6537 (*extractPackedPixel
)(isSwap
,src
,
6538 &extractTotals
[0][0]);
6539 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6540 &extractTotals
[1][0]);
6541 for (cc
= 0; cc
< components
; cc
++) {
6544 /* grab 2 pixels to average */
6546 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6547 * totals[RED]/= 2.0;
6549 for (kk
= 0; kk
< BOX2
; kk
++) {
6550 totals
[cc
]+= extractTotals
[kk
][cc
];
6552 totals
[cc
]/= (float)BOX2
;
6554 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6557 /* skip over to next group of 2 */
6558 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6562 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6563 src
+= padBytes
; /* for assertion only */
6565 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6566 assert(outIndex
== halfWidth
* halfHeight
);
6568 else if (width
== 1) { /* 1 column */
6571 assert(height
!= 1); /* widthxheight can't be 1x1 */
6573 /* one vertical column with possible pad bytes per row */
6574 /* average two at a time */
6576 for (jj
= 0; jj
< halfHeight
; jj
++) {
6578 float totals
[4]; /* 4 is maximum components */
6579 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6582 /* average two at a time, instead of four */
6583 (*extractPackedPixel
)(isSwap
,src
,
6584 &extractTotals
[0][0]);
6585 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6586 &extractTotals
[1][0]);
6587 for (cc
= 0; cc
< components
; cc
++) {
6590 /* grab 2 pixels to average */
6592 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6593 * totals[RED]/= 2.0;
6595 for (kk
= 0; kk
< BOX2
; kk
++) {
6596 totals
[cc
]+= extractTotals
[kk
][cc
];
6598 totals
[cc
]/= (float)BOX2
;
6600 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6603 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6606 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6607 assert(outIndex
== halfWidth
* halfHeight
);
6609 } /* halve1DimagePackedPixel() */
6611 /*===========================================================================*/
6613 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6615 * This section ensures that GLU 1.3 will load and run on
6616 * a GL 1.1 implementation. It dynamically resolves the
6617 * call to glTexImage3D() which might not be available.
6618 * Or is it might be supported as an extension.
6619 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6622 typedef void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6623 GLenum internalFormat
,
6624 GLsizei width
, GLsizei height
,
6625 GLsizei depth
, GLint border
,
6626 GLenum format
, GLenum type
,
6627 const GLvoid
*pixels
);
6629 static TexImage3Dproc pTexImage3D
= 0;
6631 #if !defined(_WIN32) && !defined(__WIN32__)
6633 # include <sys/types.h>
6635 WINGDIAPI PROC WINAPI
wglGetProcAddress(LPCSTR
);
6638 static void gluTexImage3D( GLenum target
, GLint level
,
6639 GLenum internalFormat
,
6640 GLsizei width
, GLsizei height
,
6641 GLsizei depth
, GLint border
,
6642 GLenum format
, GLenum type
,
6643 const GLvoid
*pixels
)
6646 #if defined(_WIN32) || defined(__WIN32__)
6647 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6649 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6651 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6652 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6654 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6659 /* Now call glTexImage3D */
6661 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6662 depth
, border
, format
, type
, pixels
);
6667 /* Only bind to a GL 1.2 implementation: */
6668 #define gluTexImage3D glTexImage3D
6672 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6673 GLenum format
, GLenum type
)
6675 int components
= elements_per_group(format
,type
);
6676 int bytes_per_row
= bytes_per_element(type
) * width
;
6678 assert(width
> 0 && height
> 0 && depth
> 0);
6679 assert(type
!= GL_BITMAP
);
6681 return bytes_per_row
* height
* depth
* components
;
6682 } /* imageSize3D() */
6684 static void fillImage3D(const PixelStorageModes
*psm
,
6685 GLint width
, GLint height
, GLint depth
, GLenum format
,
6686 GLenum type
, GLboolean indexFormat
,
6687 const void *userImage
, GLushort
*newImage
)
6696 int elementsPerLine
;
6699 const GLubyte
*start
, *rowStart
, *iter
;
6703 myswapBytes
= psm
->unpack_swap_bytes
;
6704 components
= elements_per_group(format
,type
);
6705 if (psm
->unpack_row_length
> 0) {
6706 groupsPerLine
= psm
->unpack_row_length
;
6709 groupsPerLine
= width
;
6711 elementSize
= bytes_per_element(type
);
6712 groupSize
= elementSize
* components
;
6713 if (elementSize
== 1) myswapBytes
= 0;
6716 if (psm
->unpack_image_height
> 0) {
6717 rowsPerImage
= psm
->unpack_image_height
;
6720 rowsPerImage
= height
;
6724 rowSize
= groupsPerLine
* groupSize
;
6725 padding
= rowSize
% psm
->unpack_alignment
;
6727 rowSize
+= psm
->unpack_alignment
- padding
;
6730 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6732 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6733 psm
->unpack_skip_pixels
* groupSize
+
6735 psm
->unpack_skip_images
* imageSize
;
6736 elementsPerLine
= width
* components
;
6739 for (dd
= 0; dd
< depth
; dd
++) {
6742 for (hh
= 0; hh
< height
; hh
++) {
6745 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6747 float extractComponents
[4];
6750 case GL_UNSIGNED_BYTE
:
6754 *iter2
++ = (*iter
) * 257;
6759 *iter2
++ = *((const GLbyte
*) iter
);
6762 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6765 case GL_UNSIGNED_BYTE_3_3_2
:
6766 extract332(0,iter
,extractComponents
);
6767 for (k
= 0; k
< 3; k
++) {
6768 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6771 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6772 extract233rev(0,iter
,extractComponents
);
6773 for (k
= 0; k
< 3; k
++) {
6774 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6777 case GL_UNSIGNED_SHORT_5_6_5
:
6778 extract565(myswapBytes
,iter
,extractComponents
);
6779 for (k
= 0; k
< 3; k
++) {
6780 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6783 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6784 extract565rev(myswapBytes
,iter
,extractComponents
);
6785 for (k
= 0; k
< 3; k
++) {
6786 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6789 case GL_UNSIGNED_SHORT_4_4_4_4
:
6790 extract4444(myswapBytes
,iter
,extractComponents
);
6791 for (k
= 0; k
< 4; k
++) {
6792 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6795 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6796 extract4444rev(myswapBytes
,iter
,extractComponents
);
6797 for (k
= 0; k
< 4; k
++) {
6798 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6801 case GL_UNSIGNED_SHORT_5_5_5_1
:
6802 extract5551(myswapBytes
,iter
,extractComponents
);
6803 for (k
= 0; k
< 4; k
++) {
6804 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6807 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6808 extract1555rev(myswapBytes
,iter
,extractComponents
);
6809 for (k
= 0; k
< 4; k
++) {
6810 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6813 case GL_UNSIGNED_SHORT
:
6816 widget
.ub
[0] = iter
[1];
6817 widget
.ub
[1] = iter
[0];
6819 widget
.ub
[0] = iter
[0];
6820 widget
.ub
[1] = iter
[1];
6822 if (type
== GL_SHORT
) {
6824 *iter2
++ = widget
.s
[0];
6827 *iter2
++ = widget
.s
[0]*2;
6830 *iter2
++ = widget
.us
[0];
6833 case GL_UNSIGNED_INT_8_8_8_8
:
6834 extract8888(myswapBytes
,iter
,extractComponents
);
6835 for (k
= 0; k
< 4; k
++) {
6836 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6839 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6840 extract8888rev(myswapBytes
,iter
,extractComponents
);
6841 for (k
= 0; k
< 4; k
++) {
6842 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6845 case GL_UNSIGNED_INT_10_10_10_2
:
6846 extract1010102(myswapBytes
,iter
,extractComponents
);
6847 for (k
= 0; k
< 4; k
++) {
6848 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6851 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6852 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6853 for (k
= 0; k
< 4; k
++) {
6854 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6858 case GL_UNSIGNED_INT
:
6861 widget
.ub
[0] = iter
[3];
6862 widget
.ub
[1] = iter
[2];
6863 widget
.ub
[2] = iter
[1];
6864 widget
.ub
[3] = iter
[0];
6866 widget
.ub
[0] = iter
[0];
6867 widget
.ub
[1] = iter
[1];
6868 widget
.ub
[2] = iter
[2];
6869 widget
.ub
[3] = iter
[3];
6871 if (type
== GL_FLOAT
) {
6873 *iter2
++ = widget
.f
;
6875 *iter2
++ = 65535 * widget
.f
;
6877 } else if (type
== GL_UNSIGNED_INT
) {
6879 *iter2
++ = widget
.ui
;
6881 *iter2
++ = widget
.ui
>> 16;
6885 *iter2
++ = widget
.i
;
6887 *iter2
++ = widget
.i
>> 15;
6899 iter
= rowStart
; /* for assertion purposes */
6905 /* iterators should be one byte past end */
6906 if (!isTypePackedPixel(type
)) {
6907 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6910 assert(iter2
== &newImage
[width
*height
*depth
*
6911 elements_per_group(format
,0)]);
6913 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6914 psm
->unpack_skip_rows
* rowSize
+
6915 psm
->unpack_skip_pixels
* groupSize
+
6917 psm
->unpack_skip_images
* imageSize
] );
6918 } /* fillImage3D () */
6920 static void scaleInternal3D(GLint components
,
6921 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6922 const GLushort
*dataIn
,
6923 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6926 float x
, lowx
, highx
, convx
, halfconvx
;
6927 float y
, lowy
, highy
, convy
, halfconvy
;
6928 float z
, lowz
, highz
, convz
, halfconvz
;
6929 float xpercent
,ypercent
,zpercent
;
6931 /* Max components in a format is 4, so... */
6934 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6937 convz
= (float) depthIn
/depthOut
;
6938 convy
= (float) heightIn
/heightOut
;
6939 convx
= (float) widthIn
/widthOut
;
6940 halfconvx
= convx
/2;
6941 halfconvy
= convy
/2;
6942 halfconvz
= convz
/2;
6943 for (d
= 0; d
< depthOut
; d
++) {
6944 z
= convz
* (d
+0.5);
6945 if (depthIn
> depthOut
) {
6946 highz
= z
+ halfconvz
;
6947 lowz
= z
- halfconvz
;
6952 for (i
= 0; i
< heightOut
; i
++) {
6953 y
= convy
* (i
+0.5);
6954 if (heightIn
> heightOut
) {
6955 highy
= y
+ halfconvy
;
6956 lowy
= y
- halfconvy
;
6961 for (j
= 0; j
< widthOut
; j
++) {
6962 x
= convx
* (j
+0.5);
6963 if (widthIn
> widthOut
) {
6964 highx
= x
+ halfconvx
;
6965 lowx
= x
- halfconvx
;
6972 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6973 ** lowz) to (highx, highy, highz) on input data into this pixel
6976 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6982 zindex
= (zint
+ depthIn
) % depthIn
;
6983 if (highz
< zint
+1) {
6984 zpercent
= highz
- z
;
6986 zpercent
= zint
+1 - z
;
6992 yindex
= (yint
+ heightIn
) % heightIn
;
6993 if (highy
< yint
+1) {
6994 ypercent
= highy
- y
;
6996 ypercent
= yint
+1 - y
;
7003 xindex
= (xint
+ widthIn
) % widthIn
;
7004 if (highx
< xint
+1) {
7005 xpercent
= highx
- x
;
7007 xpercent
= xint
+1 - x
;
7010 percent
= xpercent
* ypercent
* zpercent
;
7013 temp
= (xindex
+ (yindex
*widthIn
) +
7014 (zindex
*widthIn
*heightIn
)) * components
;
7015 for (k
= 0; k
< components
; k
++) {
7016 assert(0 <= (temp
+k
) &&
7018 (widthIn
*heightIn
*depthIn
*components
));
7019 totals
[k
] += dataIn
[temp
+ k
] * percent
;
7034 temp
= (j
+ (i
* widthOut
) +
7035 (d
*widthOut
*heightOut
)) * components
;
7036 for (k
= 0; k
< components
; k
++) {
7037 /* totals[] should be rounded in the case of enlarging an
7038 * RGB ramp when the type is 332 or 4444
7040 assert(0 <= (temp
+k
) &&
7041 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
7042 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
7047 } /* scaleInternal3D() */
7049 static void emptyImage3D(const PixelStorageModes
*psm
,
7050 GLint width
, GLint height
, GLint depth
,
7051 GLenum format
, GLenum type
, GLboolean indexFormat
,
7052 const GLushort
*oldImage
, void *userImage
)
7061 GLubyte
*start
, *rowStart
, *iter
;
7062 int elementsPerLine
;
7063 const GLushort
*iter2
;
7068 myswapBytes
= psm
->pack_swap_bytes
;
7069 components
= elements_per_group(format
,type
);
7070 if (psm
->pack_row_length
> 0) {
7071 groupsPerLine
= psm
->pack_row_length
;
7074 groupsPerLine
= width
;
7077 elementSize
= bytes_per_element(type
);
7078 groupSize
= elementSize
* components
;
7079 if (elementSize
== 1) myswapBytes
= 0;
7082 if (psm
->pack_image_height
> 0) {
7083 rowsPerImage
= psm
->pack_image_height
;
7086 rowsPerImage
= height
;
7091 rowSize
= groupsPerLine
* groupSize
;
7092 padding
= rowSize
% psm
->pack_alignment
;
7094 rowSize
+= psm
->pack_alignment
- padding
;
7097 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7099 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7100 psm
->pack_skip_pixels
* groupSize
+
7102 psm
->pack_skip_images
* imageSize
;
7103 elementsPerLine
= width
* components
;
7106 for (dd
= 0; dd
< depth
; dd
++) {
7109 for (ii
= 0; ii
< height
; ii
++) {
7112 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7114 float shoveComponents
[4];
7117 case GL_UNSIGNED_BYTE
:
7121 *iter
= *iter2
++ >> 8;
7126 *((GLbyte
*) iter
) = *iter2
++;
7128 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7131 case GL_UNSIGNED_BYTE_3_3_2
:
7132 for (k
= 0; k
< 3; k
++) {
7133 shoveComponents
[k
]= *iter2
++ / 65535.0;
7135 shove332(shoveComponents
,0,(void *)iter
);
7137 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7138 for (k
= 0; k
< 3; k
++) {
7139 shoveComponents
[k
]= *iter2
++ / 65535.0;
7141 shove233rev(shoveComponents
,0,(void *)iter
);
7143 case GL_UNSIGNED_SHORT_5_6_5
:
7144 for (k
= 0; k
< 3; k
++) {
7145 shoveComponents
[k
]= *iter2
++ / 65535.0;
7147 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7149 iter
[0] = widget
.ub
[1];
7150 iter
[1] = widget
.ub
[0];
7153 *(GLushort
*)iter
= widget
.us
[0];
7156 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7157 for (k
= 0; k
< 3; k
++) {
7158 shoveComponents
[k
]= *iter2
++ / 65535.0;
7160 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7162 iter
[0] = widget
.ub
[1];
7163 iter
[1] = widget
.ub
[0];
7166 *(GLushort
*)iter
= widget
.us
[0];
7169 case GL_UNSIGNED_SHORT_4_4_4_4
:
7170 for (k
= 0; k
< 4; k
++) {
7171 shoveComponents
[k
]= *iter2
++ / 65535.0;
7173 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7175 iter
[0] = widget
.ub
[1];
7176 iter
[1] = widget
.ub
[0];
7178 *(GLushort
*)iter
= widget
.us
[0];
7181 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7182 for (k
= 0; k
< 4; k
++) {
7183 shoveComponents
[k
]= *iter2
++ / 65535.0;
7185 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7187 iter
[0] = widget
.ub
[1];
7188 iter
[1] = widget
.ub
[0];
7190 *(GLushort
*)iter
= widget
.us
[0];
7193 case GL_UNSIGNED_SHORT_5_5_5_1
:
7194 for (k
= 0; k
< 4; k
++) {
7195 shoveComponents
[k
]= *iter2
++ / 65535.0;
7197 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7199 iter
[0] = widget
.ub
[1];
7200 iter
[1] = widget
.ub
[0];
7202 *(GLushort
*)iter
= widget
.us
[0];
7205 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7206 for (k
= 0; k
< 4; k
++) {
7207 shoveComponents
[k
]= *iter2
++ / 65535.0;
7209 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7211 iter
[0] = widget
.ub
[1];
7212 iter
[1] = widget
.ub
[0];
7214 *(GLushort
*)iter
= widget
.us
[0];
7217 case GL_UNSIGNED_SHORT
:
7219 if (type
== GL_SHORT
) {
7221 widget
.s
[0] = *iter2
++;
7223 widget
.s
[0] = *iter2
++ >> 1;
7226 widget
.us
[0] = *iter2
++;
7229 iter
[0] = widget
.ub
[1];
7230 iter
[1] = widget
.ub
[0];
7232 iter
[0] = widget
.ub
[0];
7233 iter
[1] = widget
.ub
[1];
7236 case GL_UNSIGNED_INT_8_8_8_8
:
7237 for (k
= 0; k
< 4; k
++) {
7238 shoveComponents
[k
]= *iter2
++ / 65535.0;
7240 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7242 iter
[3] = widget
.ub
[0];
7243 iter
[2] = widget
.ub
[1];
7244 iter
[1] = widget
.ub
[2];
7245 iter
[0] = widget
.ub
[3];
7247 *(GLuint
*)iter
= widget
.ui
;
7250 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7251 for (k
= 0; k
< 4; k
++) {
7252 shoveComponents
[k
]= *iter2
++ / 65535.0;
7254 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7256 iter
[3] = widget
.ub
[0];
7257 iter
[2] = widget
.ub
[1];
7258 iter
[1] = widget
.ub
[2];
7259 iter
[0] = widget
.ub
[3];
7261 *(GLuint
*)iter
= widget
.ui
;
7264 case GL_UNSIGNED_INT_10_10_10_2
:
7265 for (k
= 0; k
< 4; k
++) {
7266 shoveComponents
[k
]= *iter2
++ / 65535.0;
7268 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7270 iter
[3] = widget
.ub
[0];
7271 iter
[2] = widget
.ub
[1];
7272 iter
[1] = widget
.ub
[2];
7273 iter
[0] = widget
.ub
[3];
7275 *(GLuint
*)iter
= widget
.ui
;
7278 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7279 for (k
= 0; k
< 4; k
++) {
7280 shoveComponents
[k
]= *iter2
++ / 65535.0;
7282 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7284 iter
[3] = widget
.ub
[0];
7285 iter
[2] = widget
.ub
[1];
7286 iter
[1] = widget
.ub
[2];
7287 iter
[0] = widget
.ub
[3];
7289 *(GLuint
*)iter
= widget
.ui
;
7293 case GL_UNSIGNED_INT
:
7295 if (type
== GL_FLOAT
) {
7297 widget
.f
= *iter2
++;
7299 widget
.f
= *iter2
++ / (float) 65535.0;
7301 } else if (type
== GL_UNSIGNED_INT
) {
7303 widget
.ui
= *iter2
++;
7305 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7309 widget
.i
= *iter2
++;
7311 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
7315 iter
[3] = widget
.ub
[0];
7316 iter
[2] = widget
.ub
[1];
7317 iter
[1] = widget
.ub
[2];
7318 iter
[0] = widget
.ub
[3];
7320 iter
[0] = widget
.ub
[0];
7321 iter
[1] = widget
.ub
[1];
7322 iter
[2] = widget
.ub
[2];
7323 iter
[3] = widget
.ub
[3];
7339 /* iterators should be one byte past end */
7340 if (!isTypePackedPixel(type
)) {
7341 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7344 assert(iter2
== &oldImage
[width
*height
*depth
*
7345 elements_per_group(format
,0)]);
7347 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7348 psm
->unpack_skip_rows
* rowSize
+
7349 psm
->unpack_skip_pixels
* groupSize
+
7351 psm
->unpack_skip_images
* imageSize
] );
7352 } /* emptyImage3D() */
7355 int gluScaleImage3D(GLenum format
,
7356 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7357 GLenum typeIn
, const void *dataIn
,
7358 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7359 GLenum typeOut
, void *dataOut
)
7362 GLushort
*beforeImage
, *afterImage
;
7363 PixelStorageModes psm
;
7365 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7366 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7370 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7371 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7372 return GLU_INVALID_VALUE
;
7375 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7376 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7377 return GLU_INVALID_ENUM
;
7379 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7380 return GLU_INVALID_OPERATION
;
7382 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7383 return GLU_INVALID_OPERATION
;
7386 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7387 GL_UNSIGNED_SHORT
));
7388 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7389 GL_UNSIGNED_SHORT
));
7390 if (beforeImage
== NULL
|| afterImage
== NULL
) {
7393 return GLU_OUT_OF_MEMORY
;
7395 retrieveStoreModes3D(&psm
);
7397 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7398 dataIn
, beforeImage
);
7399 components
= elements_per_group(format
,0);
7400 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7401 widthOut
,heightOut
,depthOut
,afterImage
);
7402 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7403 is_index(format
),afterImage
, dataOut
);
7404 free((void *) beforeImage
);
7405 free((void *) afterImage
);
7408 } /* gluScaleImage3D() */
7411 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7412 GLint internalFormat
, GLenum format
, GLenum type
,
7413 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7415 GLint widthPowerOf2
= nearestPower(width
);
7416 GLint heightPowerOf2
= nearestPower(height
);
7417 GLint depthPowerOf2
= nearestPower(depth
);
7421 /* compute level 1 width & height & depth, clamping each at 1 */
7422 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7423 widthPowerOf2
>> 1 :
7425 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7426 heightPowerOf2
>> 1 :
7428 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7429 depthPowerOf2
>> 1 :
7431 GLenum proxyTarget
= GL_PROXY_TEXTURE_3D
;
7432 assert(widthAtLevelOne
> 0);
7433 assert(heightAtLevelOne
> 0);
7434 assert(depthAtLevelOne
> 0);
7436 /* does width x height x depth at level 1 & all their mipmaps fit? */
7437 assert(target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
);
7438 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7440 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7441 0,format
,type
,NULL
);
7442 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7443 /* does it fit??? */
7444 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7445 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7446 depthPowerOf2
== 1) {
7447 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7450 widthPowerOf2
= widthAtLevelOne
;
7451 heightPowerOf2
= heightAtLevelOne
;
7452 depthPowerOf2
= depthAtLevelOne
;
7454 /* else it does fit */
7455 } while (proxyWidth
== 0);
7456 /* loop must terminate! */
7458 /* return the width & height at level 0 that fits */
7459 *newWidth
= widthPowerOf2
;
7460 *newHeight
= heightPowerOf2
;
7461 *newDepth
= depthPowerOf2
;
7462 /*printf("Proxy Textures\n");*/
7463 } /* closestFit3D() */
7465 static void halveImagePackedPixelSlice(int components
,
7466 void (*extractPackedPixel
)
7467 (int, const void *,GLfloat
[]),
7468 void (*shovePackedPixel
)
7469 (const GLfloat
[],int, void *),
7470 GLint width
, GLint height
, GLint depth
,
7471 const void *dataIn
, void *dataOut
,
7472 GLint pixelSizeInBytes
,
7473 GLint rowSizeInBytes
,
7474 GLint imageSizeInBytes
,
7478 int halfWidth
= width
/ 2;
7479 int halfHeight
= height
/ 2;
7480 int halfDepth
= depth
/ 2;
7481 const char *src
= (const char *)dataIn
;
7484 assert((width
== 1 || height
== 1) && depth
>= 2);
7486 if (width
== height
) { /* a 1-pixel column viewed from top */
7487 assert(width
== 1 && height
== 1);
7490 for (ii
= 0; ii
< halfDepth
; ii
++) {
7492 float extractTotals
[BOX2
][4];
7495 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7496 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7497 &extractTotals
[1][0]);
7498 for (cc
= 0; cc
< components
; cc
++) {
7501 /* average 2 pixels since only a column */
7503 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7504 * totals[RED]/= 2.0;
7506 for (kk
= 0; kk
< BOX2
; kk
++) {
7507 totals
[cc
]+= extractTotals
[kk
][cc
];
7509 totals
[cc
]/= (float)BOX2
;
7512 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7514 /* skip over to next group of 2 */
7515 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7518 else if (height
== 1) { /* horizontal slice viewed from top */
7521 for (ii
= 0; ii
< halfDepth
; ii
++) {
7522 for (jj
= 0; jj
< halfWidth
; jj
++) {
7524 float extractTotals
[BOX4
][4];
7527 (*extractPackedPixel
)(isSwap
,src
,
7528 &extractTotals
[0][0]);
7529 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7530 &extractTotals
[1][0]);
7531 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7532 &extractTotals
[2][0]);
7533 (*extractPackedPixel
)(isSwap
,
7534 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7535 &extractTotals
[3][0]);
7536 for (cc
= 0; cc
< components
; cc
++) {
7539 /* grab 4 pixels to average */
7541 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7542 * extractTotals[2][RED]+extractTotals[3][RED];
7543 * totals[RED]/= 4.0;
7545 for (kk
= 0; kk
< BOX4
; kk
++) {
7546 totals
[cc
]+= extractTotals
[kk
][cc
];
7548 totals
[cc
]/= (float)BOX4
;
7550 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7553 /* skip over to next horizontal square of 4 */
7554 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7560 else if (width
== 1) { /* vertical slice viewed from top */
7561 assert(height
!= 1);
7563 for (ii
= 0; ii
< halfDepth
; ii
++) {
7564 for (jj
= 0; jj
< halfHeight
; jj
++) {
7566 float extractTotals
[BOX4
][4];
7569 (*extractPackedPixel
)(isSwap
,src
,
7570 &extractTotals
[0][0]);
7571 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7572 &extractTotals
[1][0]);
7573 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7574 &extractTotals
[2][0]);
7575 (*extractPackedPixel
)(isSwap
,
7576 (src
+imageSizeInBytes
+rowSizeInBytes
),
7577 &extractTotals
[3][0]);
7578 for (cc
= 0; cc
< components
; cc
++) {
7581 /* grab 4 pixels to average */
7583 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7584 * extractTotals[2][RED]+extractTotals[3][RED];
7585 * totals[RED]/= 4.0;
7587 for (kk
= 0; kk
< BOX4
; kk
++) {
7588 totals
[cc
]+= extractTotals
[kk
][cc
];
7590 totals
[cc
]/= (float)BOX4
;
7592 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7596 /* skip over to next vertical square of 4 */
7597 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7603 } /* halveImagePackedPixelSlice() */
7605 static void halveImagePackedPixel3D(int components
,
7606 void (*extractPackedPixel
)
7607 (int, const void *,GLfloat
[]),
7608 void (*shovePackedPixel
)
7609 (const GLfloat
[],int, void *),
7610 GLint width
, GLint height
, GLint depth
,
7611 const void *dataIn
, void *dataOut
,
7612 GLint pixelSizeInBytes
,
7613 GLint rowSizeInBytes
,
7614 GLint imageSizeInBytes
,
7618 assert(1 <= width
&& 1 <= height
);
7620 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7621 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7622 rowSizeInBytes
,isSwap
);
7625 /* a horizontal or vertical slice viewed from top */
7626 else if (width
== 1 || height
== 1) {
7629 halveImagePackedPixelSlice(components
,
7630 extractPackedPixel
,shovePackedPixel
,
7631 width
, height
, depth
, dataIn
, dataOut
,
7632 pixelSizeInBytes
, rowSizeInBytes
,
7633 imageSizeInBytes
, isSwap
);
7639 int halfWidth
= width
/ 2;
7640 int halfHeight
= height
/ 2;
7641 int halfDepth
= depth
/ 2;
7642 const char *src
= (const char *) dataIn
;
7643 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7646 for (dd
= 0; dd
< halfDepth
; dd
++) {
7647 for (ii
= 0; ii
< halfHeight
; ii
++) {
7648 for (jj
= 0; jj
< halfWidth
; jj
++) {
7650 float totals
[4]; /* 4 is maximum components */
7651 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7654 (*extractPackedPixel
)(isSwap
,src
,
7655 &extractTotals
[0][0]);
7656 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7657 &extractTotals
[1][0]);
7658 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7659 &extractTotals
[2][0]);
7660 (*extractPackedPixel
)(isSwap
,
7661 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7662 &extractTotals
[3][0]);
7664 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7665 &extractTotals
[4][0]);
7666 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7667 &extractTotals
[5][0]);
7668 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7669 &extractTotals
[6][0]);
7670 (*extractPackedPixel
)(isSwap
,
7671 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7672 &extractTotals
[7][0]);
7673 for (cc
= 0; cc
< components
; cc
++) {
7676 /* grab 8 pixels to average */
7678 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7679 * extractTotals[2][RED]+extractTotals[3][RED]+
7680 * extractTotals[4][RED]+extractTotals[5][RED]+
7681 * extractTotals[6][RED]+extractTotals[7][RED];
7682 * totals[RED]/= 8.0;
7684 for (kk
= 0; kk
< BOX8
; kk
++) {
7685 totals
[cc
]+= extractTotals
[kk
][cc
];
7687 totals
[cc
]/= (float)BOX8
;
7689 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7692 /* skip over to next square of 4 */
7693 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7695 /* skip past pad bytes, if any, to get to next row */
7698 /* src is at beginning of a row here, but it's the second row of
7699 * the square block of 4 pixels that we just worked on so we
7700 * need to go one more row.
7708 src
+= rowSizeInBytes
;
7711 src
+= imageSizeInBytes
;
7714 /* both pointers must reach one byte after the end */
7715 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7716 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7719 } /* halveImagePackedPixel3D() */
7721 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7725 GLsizei widthPowerOf2
,
7726 GLsizei heightPowerOf2
,
7727 GLsizei depthPowerOf2
,
7728 GLenum format
, GLenum type
,
7730 GLint baseLevel
,GLint maxLevel
,
7733 GLint newWidth
, newHeight
, newDepth
;
7734 GLint level
, levels
;
7735 const void *usersImage
;
7736 void *srcImage
, *dstImage
;
7737 __GLU_INIT_SWAP_IMAGE
;
7741 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7742 GLint rowsPerImage
, imageSize
;
7743 GLint rowSize
, padding
;
7744 PixelStorageModes psm
;
7746 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7747 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7748 assert(type
!= GL_BITMAP
);
7750 srcImage
= dstImage
= NULL
;
7752 newWidth
= widthPowerOf2
;
7753 newHeight
= heightPowerOf2
;
7754 newDepth
= depthPowerOf2
;
7755 levels
= computeLog(newWidth
);
7756 level
= computeLog(newHeight
);
7757 if (level
> levels
) levels
=level
;
7758 level
= computeLog(newDepth
);
7759 if (level
> levels
) levels
=level
;
7763 retrieveStoreModes3D(&psm
);
7764 myswapBytes
= psm
.unpack_swap_bytes
;
7765 cmpts
= elements_per_group(format
,type
);
7766 if (psm
.unpack_row_length
> 0) {
7767 groupsPerLine
= psm
.unpack_row_length
;
7769 groupsPerLine
= width
;
7772 elementSize
= bytes_per_element(type
);
7773 groupSize
= elementSize
* cmpts
;
7774 if (elementSize
== 1) myswapBytes
= 0;
7777 if (psm
.unpack_image_height
> 0) {
7778 rowsPerImage
= psm
.unpack_image_height
;
7781 rowsPerImage
= height
;
7785 rowSize
= groupsPerLine
* groupSize
;
7786 padding
= (rowSize
% psm
.unpack_alignment
);
7788 rowSize
+= psm
.unpack_alignment
- padding
;
7791 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7793 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7794 psm
.unpack_skip_pixels
* groupSize
+
7796 psm
.unpack_skip_images
* imageSize
;
7798 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7799 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7800 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7801 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7802 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7806 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7807 /* Use usersImage for level userLevel */
7808 if (baseLevel
<= level
&& level
<= maxLevel
) {
7809 gluTexImage3D(target
, level
, internalFormat
, width
,
7810 height
, depth
, 0, format
, type
,
7813 if(levels
== 0) { /* we're done. clean up and return */
7814 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7815 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7816 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7817 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7818 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7819 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7820 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7824 int nextWidth
= newWidth
/2;
7825 int nextHeight
= newHeight
/2;
7826 int nextDepth
= newDepth
/2;
7829 if (nextWidth
< 1) nextWidth
= 1;
7830 if (nextHeight
< 1) nextHeight
= 1;
7831 if (nextDepth
< 1) nextDepth
= 1;
7832 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7835 case GL_UNSIGNED_BYTE
:
7836 dstImage
= (GLubyte
*)malloc(memReq
);
7839 dstImage
= (GLbyte
*)malloc(memReq
);
7841 case GL_UNSIGNED_SHORT
:
7842 dstImage
= (GLushort
*)malloc(memReq
);
7845 dstImage
= (GLshort
*)malloc(memReq
);
7847 case GL_UNSIGNED_INT
:
7848 dstImage
= (GLuint
*)malloc(memReq
);
7851 dstImage
= (GLint
*)malloc(memReq
);
7854 dstImage
= (GLfloat
*)malloc(memReq
);
7856 case GL_UNSIGNED_BYTE_3_3_2
:
7857 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7858 dstImage
= (GLubyte
*)malloc(memReq
);
7860 case GL_UNSIGNED_SHORT_5_6_5
:
7861 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7862 case GL_UNSIGNED_SHORT_4_4_4_4
:
7863 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7864 case GL_UNSIGNED_SHORT_5_5_5_1
:
7865 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7866 dstImage
= (GLushort
*)malloc(memReq
);
7868 case GL_UNSIGNED_INT_8_8_8_8
:
7869 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7870 case GL_UNSIGNED_INT_10_10_10_2
:
7871 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7872 dstImage
= (GLuint
*)malloc(memReq
);
7875 return GLU_INVALID_ENUM
; /* assertion */
7877 if (dstImage
== NULL
) {
7878 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7879 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7880 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7881 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7882 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7883 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7884 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7885 return GLU_OUT_OF_MEMORY
;
7889 case GL_UNSIGNED_BYTE
:
7891 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7893 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7894 imageSize
,myswapBytes
);
7897 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7898 elementSize
,rowSize
,groupSize
);
7903 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7905 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7906 imageSize
,myswapBytes
);
7909 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7910 elementSize
,rowSize
,groupSize
);
7913 case GL_UNSIGNED_SHORT
:
7915 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7917 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7918 imageSize
,myswapBytes
);
7921 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7922 elementSize
,rowSize
,groupSize
,myswapBytes
);
7927 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7929 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7930 imageSize
,myswapBytes
);
7933 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7934 elementSize
,rowSize
,groupSize
,myswapBytes
);
7937 case GL_UNSIGNED_INT
:
7939 halveImage3D(cmpts
,extractUint
,shoveUint
,
7941 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7942 imageSize
,myswapBytes
);
7945 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7946 elementSize
,rowSize
,groupSize
,myswapBytes
);
7951 halveImage3D(cmpts
,extractSint
,shoveSint
,
7953 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7954 imageSize
,myswapBytes
);
7957 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7958 elementSize
,rowSize
,groupSize
,myswapBytes
);
7963 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7965 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7966 imageSize
,myswapBytes
);
7969 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7970 elementSize
,rowSize
,groupSize
,myswapBytes
);
7973 case GL_UNSIGNED_BYTE_3_3_2
:
7974 assert(format
== GL_RGB
);
7975 halveImagePackedPixel3D(3,extract332
,shove332
,
7976 width
,height
,depth
,usersImage
,dstImage
,
7977 elementSize
,rowSize
,imageSize
,myswapBytes
);
7979 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7980 assert(format
== GL_RGB
);
7981 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7982 width
,height
,depth
,usersImage
,dstImage
,
7983 elementSize
,rowSize
,imageSize
,myswapBytes
);
7985 case GL_UNSIGNED_SHORT_5_6_5
:
7986 halveImagePackedPixel3D(3,extract565
,shove565
,
7987 width
,height
,depth
,usersImage
,dstImage
,
7988 elementSize
,rowSize
,imageSize
,myswapBytes
);
7990 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7991 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7992 width
,height
,depth
,usersImage
,dstImage
,
7993 elementSize
,rowSize
,imageSize
,myswapBytes
);
7995 case GL_UNSIGNED_SHORT_4_4_4_4
:
7996 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7997 width
,height
,depth
,usersImage
,dstImage
,
7998 elementSize
,rowSize
,imageSize
,myswapBytes
);
8000 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8001 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8002 width
,height
,depth
,usersImage
,dstImage
,
8003 elementSize
,rowSize
,imageSize
,myswapBytes
);
8005 case GL_UNSIGNED_SHORT_5_5_5_1
:
8006 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8007 width
,height
,depth
,usersImage
,dstImage
,
8008 elementSize
,rowSize
,imageSize
,myswapBytes
);
8010 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8011 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8012 width
,height
,depth
,usersImage
,dstImage
,
8013 elementSize
,rowSize
,imageSize
,myswapBytes
);
8015 case GL_UNSIGNED_INT_8_8_8_8
:
8016 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8017 width
,height
,depth
,usersImage
,dstImage
,
8018 elementSize
,rowSize
,imageSize
,myswapBytes
);
8020 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8021 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8022 width
,height
,depth
,usersImage
,dstImage
,
8023 elementSize
,rowSize
,imageSize
,myswapBytes
);
8025 case GL_UNSIGNED_INT_10_10_10_2
:
8026 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8027 width
,height
,depth
,usersImage
,dstImage
,
8028 elementSize
,rowSize
,imageSize
,myswapBytes
);
8030 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8031 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8032 width
,height
,depth
,usersImage
,dstImage
,
8033 elementSize
,rowSize
,imageSize
,myswapBytes
);
8040 newHeight
= height
/2;
8043 if (newWidth
< 1) newWidth
= 1;
8044 if (newHeight
< 1) newHeight
= 1;
8045 if (newDepth
< 1) newDepth
= 1;
8048 rowSize
= newWidth
* groupSize
;
8049 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8050 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8051 /* Swap srcImage and dstImage */
8052 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8054 case GL_UNSIGNED_BYTE
:
8055 dstImage
= (GLubyte
*)malloc(memReq
);
8058 dstImage
= (GLbyte
*)malloc(memReq
);
8060 case GL_UNSIGNED_SHORT
:
8061 dstImage
= (GLushort
*)malloc(memReq
);
8064 dstImage
= (GLshort
*)malloc(memReq
);
8066 case GL_UNSIGNED_INT
:
8067 dstImage
= (GLuint
*)malloc(memReq
);
8070 dstImage
= (GLint
*)malloc(memReq
);
8073 dstImage
= (GLfloat
*)malloc(memReq
);
8075 case GL_UNSIGNED_BYTE_3_3_2
:
8076 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8077 dstImage
= (GLubyte
*)malloc(memReq
);
8079 case GL_UNSIGNED_SHORT_5_6_5
:
8080 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8081 case GL_UNSIGNED_SHORT_4_4_4_4
:
8082 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8083 case GL_UNSIGNED_SHORT_5_5_5_1
:
8084 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8085 dstImage
= (GLushort
*)malloc(memReq
);
8087 case GL_UNSIGNED_INT_8_8_8_8
:
8088 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8089 case GL_UNSIGNED_INT_10_10_10_2
:
8090 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8091 dstImage
= (GLuint
*)malloc(memReq
);
8094 return GLU_INVALID_ENUM
; /* assertion */
8096 if (dstImage
== NULL
) {
8097 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8098 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8099 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8100 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8101 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8102 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8103 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8105 return GLU_OUT_OF_MEMORY
;
8107 /* level userLevel+1 is in srcImage; level userLevel already saved */
8108 level
= userLevel
+1;
8109 } else {/* user's image is *not* nice power-of-2 sized square */
8110 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8112 case GL_UNSIGNED_BYTE
:
8113 dstImage
= (GLubyte
*)malloc(memReq
);
8116 dstImage
= (GLbyte
*)malloc(memReq
);
8118 case GL_UNSIGNED_SHORT
:
8119 dstImage
= (GLushort
*)malloc(memReq
);
8122 dstImage
= (GLshort
*)malloc(memReq
);
8124 case GL_UNSIGNED_INT
:
8125 dstImage
= (GLuint
*)malloc(memReq
);
8128 dstImage
= (GLint
*)malloc(memReq
);
8131 dstImage
= (GLfloat
*)malloc(memReq
);
8133 case GL_UNSIGNED_BYTE_3_3_2
:
8134 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8135 dstImage
= (GLubyte
*)malloc(memReq
);
8137 case GL_UNSIGNED_SHORT_5_6_5
:
8138 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8139 case GL_UNSIGNED_SHORT_4_4_4_4
:
8140 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8141 case GL_UNSIGNED_SHORT_5_5_5_1
:
8142 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8143 dstImage
= (GLushort
*)malloc(memReq
);
8145 case GL_UNSIGNED_INT_8_8_8_8
:
8146 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8147 case GL_UNSIGNED_INT_10_10_10_2
:
8148 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8149 dstImage
= (GLuint
*)malloc(memReq
);
8152 return GLU_INVALID_ENUM
; /* assertion */
8155 if (dstImage
== NULL
) {
8156 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8157 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8158 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8159 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8160 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8161 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8162 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8163 return GLU_OUT_OF_MEMORY
;
8165 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8166 width,height,depth,newWidth,newHeight,newDepth);*/
8168 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8169 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8172 rowSize
= newWidth
* groupSize
;
8173 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8174 /* Swap dstImage and srcImage */
8175 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8177 if(levels
!= 0) { /* use as little memory as possible */
8179 int nextWidth
= newWidth
/2;
8180 int nextHeight
= newHeight
/2;
8181 int nextDepth
= newDepth
/2;
8182 if (nextWidth
< 1) nextWidth
= 1;
8183 if (nextHeight
< 1) nextHeight
= 1;
8184 if (nextDepth
< 1) nextDepth
= 1;
8186 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8189 case GL_UNSIGNED_BYTE
:
8190 dstImage
= (GLubyte
*)malloc(memReq
);
8193 dstImage
= (GLbyte
*)malloc(memReq
);
8195 case GL_UNSIGNED_SHORT
:
8196 dstImage
= (GLushort
*)malloc(memReq
);
8199 dstImage
= (GLshort
*)malloc(memReq
);
8201 case GL_UNSIGNED_INT
:
8202 dstImage
= (GLuint
*)malloc(memReq
);
8205 dstImage
= (GLint
*)malloc(memReq
);
8208 dstImage
= (GLfloat
*)malloc(memReq
);
8210 case GL_UNSIGNED_BYTE_3_3_2
:
8211 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8212 dstImage
= (GLubyte
*)malloc(memReq
);
8214 case GL_UNSIGNED_SHORT_5_6_5
:
8215 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8216 case GL_UNSIGNED_SHORT_4_4_4_4
:
8217 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8218 case GL_UNSIGNED_SHORT_5_5_5_1
:
8219 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8220 dstImage
= (GLushort
*)malloc(memReq
);
8222 case GL_UNSIGNED_INT_8_8_8_8
:
8223 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8224 case GL_UNSIGNED_INT_10_10_10_2
:
8225 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8226 dstImage
= (GLuint
*)malloc(memReq
);
8229 return GLU_INVALID_ENUM
; /* assertion */
8231 if (dstImage
== NULL
) {
8232 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8233 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8234 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8235 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8236 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8237 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8238 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8240 return GLU_OUT_OF_MEMORY
;
8243 /* level userLevel is in srcImage; nothing saved yet */
8247 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8248 if (baseLevel
<= level
&& level
<= maxLevel
) {
8249 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8250 0,format
, type
, (void *)srcImage
);
8252 level
++; /* update current level for the loop */
8253 for (; level
<= levels
; level
++) {
8255 case GL_UNSIGNED_BYTE
:
8257 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8258 newWidth
,newHeight
,newDepth
,
8259 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8260 imageSize
,myswapBytes
);
8263 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8264 elementSize
,rowSize
,groupSize
);
8269 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8270 newWidth
,newHeight
,newDepth
,
8271 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8272 imageSize
,myswapBytes
);
8275 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8276 elementSize
,rowSize
,groupSize
);
8279 case GL_UNSIGNED_SHORT
:
8281 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8282 newWidth
,newHeight
,newDepth
,
8283 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8284 imageSize
,myswapBytes
);
8287 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8288 elementSize
,rowSize
,groupSize
,myswapBytes
);
8293 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8294 newWidth
,newHeight
,newDepth
,
8295 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8296 imageSize
,myswapBytes
);
8299 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8300 elementSize
,rowSize
,groupSize
,myswapBytes
);
8303 case GL_UNSIGNED_INT
:
8305 halveImage3D(cmpts
,extractUint
,shoveUint
,
8306 newWidth
,newHeight
,newDepth
,
8307 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8308 imageSize
,myswapBytes
);
8311 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8312 elementSize
,rowSize
,groupSize
,myswapBytes
);
8317 halveImage3D(cmpts
,extractSint
,shoveSint
,
8318 newWidth
,newHeight
,newDepth
,
8319 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8320 imageSize
,myswapBytes
);
8323 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8324 elementSize
,rowSize
,groupSize
,myswapBytes
);
8329 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8330 newWidth
,newHeight
,newDepth
,
8331 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8332 imageSize
,myswapBytes
);
8335 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8336 elementSize
,rowSize
,groupSize
,myswapBytes
);
8339 case GL_UNSIGNED_BYTE_3_3_2
:
8340 halveImagePackedPixel3D(3,extract332
,shove332
,
8341 newWidth
,newHeight
,newDepth
,
8342 srcImage
,dstImage
,elementSize
,rowSize
,
8343 imageSize
,myswapBytes
);
8345 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8346 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8347 newWidth
,newHeight
,newDepth
,
8348 srcImage
,dstImage
,elementSize
,rowSize
,
8349 imageSize
,myswapBytes
);
8351 case GL_UNSIGNED_SHORT_5_6_5
:
8352 halveImagePackedPixel3D(3,extract565
,shove565
,
8353 newWidth
,newHeight
,newDepth
,
8354 srcImage
,dstImage
,elementSize
,rowSize
,
8355 imageSize
,myswapBytes
);
8357 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8358 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8359 newWidth
,newHeight
,newDepth
,
8360 srcImage
,dstImage
,elementSize
,rowSize
,
8361 imageSize
,myswapBytes
);
8363 case GL_UNSIGNED_SHORT_4_4_4_4
:
8364 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8365 newWidth
,newHeight
,newDepth
,
8366 srcImage
,dstImage
,elementSize
,rowSize
,
8367 imageSize
,myswapBytes
);
8369 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8370 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8371 newWidth
,newHeight
,newDepth
,
8372 srcImage
,dstImage
,elementSize
,rowSize
,
8373 imageSize
,myswapBytes
);
8375 case GL_UNSIGNED_SHORT_5_5_5_1
:
8376 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8377 newWidth
,newHeight
,newDepth
,
8378 srcImage
,dstImage
,elementSize
,rowSize
,
8379 imageSize
,myswapBytes
);
8381 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8382 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8383 newWidth
,newHeight
,newDepth
,
8384 srcImage
,dstImage
,elementSize
,rowSize
,
8385 imageSize
,myswapBytes
);
8387 case GL_UNSIGNED_INT_8_8_8_8
:
8388 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8389 newWidth
,newHeight
,newDepth
,
8390 srcImage
,dstImage
,elementSize
,rowSize
,
8391 imageSize
,myswapBytes
);
8393 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8394 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8395 newWidth
,newHeight
,newDepth
,
8396 srcImage
,dstImage
,elementSize
,rowSize
,
8397 imageSize
,myswapBytes
);
8399 case GL_UNSIGNED_INT_10_10_10_2
:
8400 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8401 newWidth
,newHeight
,newDepth
,
8402 srcImage
,dstImage
,elementSize
,rowSize
,
8403 imageSize
,myswapBytes
);
8405 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8406 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8407 newWidth
,newHeight
,newDepth
,
8408 srcImage
,dstImage
,elementSize
,rowSize
,
8409 imageSize
,myswapBytes
);
8416 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8418 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8419 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8420 if (newDepth
> 1) newDepth
/= 2;
8422 /* call tex image with srcImage untouched since it's not padded */
8423 if (baseLevel
<= level
&& level
<= maxLevel
) {
8424 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8425 newDepth
,0, format
, type
, (void *) srcImage
);
8429 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8430 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8431 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8432 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8433 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8434 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8435 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8437 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8438 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8442 } /* gluBuild3DMipmapLevelsCore() */
8445 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8446 GLsizei width
, GLsizei height
, GLsizei depth
,
8447 GLenum format
, GLenum type
,
8448 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8453 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8454 if (rc
!= 0) return rc
;
8456 if (width
< 1 || height
< 1 || depth
< 1) {
8457 return GLU_INVALID_VALUE
;
8460 if(type
== GL_BITMAP
) {
8461 return GLU_INVALID_ENUM
;
8464 levels
= computeLog(width
);
8465 level
= computeLog(height
);
8466 if (level
> levels
) levels
=level
;
8467 level
= computeLog(depth
);
8468 if (level
> levels
) levels
=level
;
8471 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8472 return GLU_INVALID_VALUE
;
8474 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8475 width
, height
, depth
,
8476 width
, height
, depth
,
8478 userLevel
, baseLevel
, maxLevel
,
8480 } /* gluBuild3DMipmapLevels() */
8483 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8484 GLsizei width
, GLsizei height
, GLsizei depth
,
8485 GLenum format
, GLenum type
, const void *data
)
8487 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8490 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8491 if (rc
!= 0) return rc
;
8493 if (width
< 1 || height
< 1 || depth
< 1) {
8494 return GLU_INVALID_VALUE
;
8497 if(type
== GL_BITMAP
) {
8498 return GLU_INVALID_ENUM
;
8501 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8502 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8504 levels
= computeLog(widthPowerOf2
);
8505 level
= computeLog(heightPowerOf2
);
8506 if (level
> levels
) levels
=level
;
8507 level
= computeLog(depthPowerOf2
);
8508 if (level
> levels
) levels
=level
;
8510 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8511 width
, height
, depth
,
8512 widthPowerOf2
, heightPowerOf2
,
8514 format
, type
, 0, 0, levels
,
8516 } /* gluBuild3DMipmaps() */
8518 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8520 isSwap
= isSwap
; /* turn off warnings */
8522 assert(*((const GLubyte
*)ubyte
) <= 255);
8524 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8525 } /* extractUbyte() */
8527 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8529 assert(0.0 <= value
&& value
< 256.0);
8531 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8532 } /* shoveUbyte() */
8534 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8536 isSwap
= isSwap
; /* turn off warnings */
8538 assert(*((const GLbyte
*)sbyte
) <= 127);
8540 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8541 } /* extractSbyte() */
8543 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8545 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8546 } /* shoveSbyte() */
8548 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8553 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8556 ushort
= *(const GLushort
*)uitem
;
8559 assert(ushort
<= 65535);
8561 return (GLdouble
)ushort
;
8562 } /* extractUshort() */
8564 static void shoveUshort(GLdouble value
, int index
, void *data
)
8566 assert(0.0 <= value
&& value
< 65536.0);
8568 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8569 } /* shoveUshort() */
8571 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8576 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8579 sshort
= *(const GLshort
*)sitem
;
8582 assert(sshort
<= 32767);
8584 return (GLdouble
)sshort
;
8585 } /* extractSshort() */
8587 static void shoveSshort(GLdouble value
, int index
, void *data
)
8589 assert(0.0 <= value
&& value
< 32768.0);
8591 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8592 } /* shoveSshort() */
8594 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8599 uint
= __GLU_SWAP_4_BYTES(uitem
);
8602 uint
= *(const GLuint
*)uitem
;
8605 assert(uint
<= 0xffffffff);
8607 return (GLdouble
)uint
;
8608 } /* extractUint() */
8610 static void shoveUint(GLdouble value
, int index
, void *data
)
8612 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8614 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8617 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8622 sint
= __GLU_SWAP_4_BYTES(sitem
);
8625 sint
= *(const GLint
*)sitem
;
8628 assert(sint
<= 0x7fffffff);
8630 return (GLdouble
)sint
;
8631 } /* extractSint() */
8633 static void shoveSint(GLdouble value
, int index
, void *data
)
8635 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8637 ((GLint
*)data
)[index
]= (GLint
)value
;
8640 static GLdouble
extractFloat(int isSwap
, const void *item
)
8645 ffloat
= __GLU_SWAP_4_BYTES(item
);
8648 ffloat
= *(const GLfloat
*)item
;
8651 assert(ffloat
<= 1.0);
8653 return (GLdouble
)ffloat
;
8654 } /* extractFloat() */
8656 static void shoveFloat(GLdouble value
, int index
, void *data
)
8658 assert(0.0 <= value
&& value
<= 1.0);
8660 ((GLfloat
*)data
)[index
]= value
;
8661 } /* shoveFloat() */
8663 static void halveImageSlice(int components
,
8664 GLdouble (*extract
)(int, const void *),
8665 void (*shove
)(GLdouble
, int, void *),
8666 GLint width
, GLint height
, GLint depth
,
8667 const void *dataIn
, void *dataOut
,
8668 GLint elementSizeInBytes
,
8669 GLint groupSizeInBytes
,
8670 GLint rowSizeInBytes
,
8671 GLint imageSizeInBytes
,
8675 int halfWidth
= width
/ 2;
8676 int halfHeight
= height
/ 2;
8677 int halfDepth
= depth
/ 2;
8678 const char *src
= (const char *)dataIn
;
8679 int rowPadBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8680 int imagePadBytes
= imageSizeInBytes
- (width
*height
*groupSizeInBytes
);
8683 assert((width
== 1 || height
== 1) && depth
>= 2);
8685 if (width
== height
) { /* a 1-pixel column viewed from top */
8686 /* printf("1-column\n");*/
8687 assert(width
== 1 && height
== 1);
8690 for (ii
= 0; ii
< halfDepth
; ii
++) {
8693 for (cc
= 0; cc
< components
; cc
++) {
8695 double extractTotals
[BOX2
][4];
8698 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8699 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8701 /* average 2 pixels since only a column */
8703 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8704 * totals[RED]/= 2.0;
8706 for (kk
= 0; kk
< BOX2
; kk
++) {
8707 totals
[cc
]+= extractTotals
[kk
][cc
];
8709 totals
[cc
]/= (double)BOX2
;
8711 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8713 src
+= elementSizeInBytes
;
8716 /* skip over to next group of 2 */
8717 src
+= rowSizeInBytes
;
8720 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8721 assert(outIndex
== halfDepth
* components
);
8723 else if (height
== 1) { /* horizontal slice viewed from top */
8724 /* printf("horizontal slice\n"); */
8727 for (ii
= 0; ii
< halfDepth
; ii
++) {
8728 for (jj
= 0; jj
< halfWidth
; jj
++) {
8731 for (cc
= 0; cc
< components
; cc
++) {
8734 double extractTotals
[BOX4
][4];
8736 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8737 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8738 (src
+groupSizeInBytes
));
8739 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8740 (src
+imageSizeInBytes
));
8741 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8742 (src
+imageSizeInBytes
+groupSizeInBytes
));
8744 /* grab 4 pixels to average */
8746 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8747 * extractTotals[2][RED]+extractTotals[3][RED];
8748 * totals[RED]/= 4.0;
8750 for (kk
= 0; kk
< BOX4
; kk
++) {
8751 totals
[cc
]+= extractTotals
[kk
][cc
];
8753 totals
[cc
]/= (double)BOX4
;
8755 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8758 src
+= elementSizeInBytes
;
8761 /* skip over to next horizontal square of 4 */
8762 src
+= groupSizeInBytes
;
8766 src
+= rowSizeInBytes
;
8769 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8770 assert(outIndex
== halfWidth
* halfDepth
* components
);
8772 else if (width
== 1) { /* vertical slice viewed from top */
8773 /* printf("vertical slice\n"); */
8774 assert(height
!= 1);
8776 for (ii
= 0; ii
< halfDepth
; ii
++) {
8777 for (jj
= 0; jj
< halfHeight
; jj
++) {
8780 for (cc
= 0; cc
< components
; cc
++) {
8783 double extractTotals
[BOX4
][4];
8785 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8786 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8787 (src
+rowSizeInBytes
));
8788 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8789 (src
+imageSizeInBytes
));
8790 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8791 (src
+imageSizeInBytes
+rowSizeInBytes
));
8793 /* grab 4 pixels to average */
8795 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8796 * extractTotals[2][RED]+extractTotals[3][RED];
8797 * totals[RED]/= 4.0;
8799 for (kk
= 0; kk
< BOX4
; kk
++) {
8800 totals
[cc
]+= extractTotals
[kk
][cc
];
8802 totals
[cc
]/= (double)BOX4
;
8804 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8807 src
+= elementSizeInBytes
;
8811 /* skip over to next vertical square of 4 */
8812 src
+= rowSizeInBytes
;
8814 src
+= imagePadBytes
;
8816 src
+= imageSizeInBytes
;
8819 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8820 assert(outIndex
== halfHeight
* halfDepth
* components
);
8823 } /* halveImageSlice() */
8825 static void halveImage3D(int components
,
8826 GLdouble (*extract
)(int, const void *),
8827 void (*shove
)(GLdouble
, int, void *),
8828 GLint width
, GLint height
, GLint depth
,
8829 const void *dataIn
, void *dataOut
,
8830 GLint elementSizeInBytes
,
8831 GLint groupSizeInBytes
,
8832 GLint rowSizeInBytes
,
8833 GLint imageSizeInBytes
,
8838 /* a horizontal/vertical/one-column slice viewed from top */
8839 if (width
== 1 || height
== 1) {
8842 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8843 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8844 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8850 int halfWidth
= width
/ 2;
8851 int halfHeight
= height
/ 2;
8852 int halfDepth
= depth
/ 2;
8853 const char *src
= (const char *) dataIn
;
8854 int rowPadBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8855 int imagePadBytes
= imageSizeInBytes
- (width
*height
*groupSizeInBytes
);
8858 for (dd
= 0; dd
< halfDepth
; dd
++) {
8859 for (ii
= 0; ii
< halfHeight
; ii
++) {
8860 for (jj
= 0; jj
< halfWidth
; jj
++) {
8863 for (cc
= 0; cc
< components
; cc
++) {
8866 double totals
[4]; /* 4 is maximum components */
8867 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8869 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8870 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8871 (src
+groupSizeInBytes
));
8872 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8873 (src
+rowSizeInBytes
));
8874 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8875 (src
+rowSizeInBytes
+groupSizeInBytes
));
8877 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8878 (src
+imageSizeInBytes
));
8880 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8881 (src
+groupSizeInBytes
+imageSizeInBytes
));
8882 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8883 (src
+rowSizeInBytes
+imageSizeInBytes
));
8884 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8885 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8889 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8890 * extractTotals[2][RED]+extractTotals[3][RED]+
8891 * extractTotals[4][RED]+extractTotals[5][RED]+
8892 * extractTotals[6][RED]+extractTotals[7][RED];
8893 * totals[RED]/= 8.0;
8895 for (kk
= 0; kk
< BOX8
; kk
++) {
8896 totals
[cc
]+= extractTotals
[kk
][cc
];
8898 totals
[cc
]/= (double)BOX8
;
8900 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8904 src
+= elementSizeInBytes
; /* go to next component */
8907 /* skip over to next square of 4 */
8908 src
+= groupSizeInBytes
;
8910 /* skip past pad bytes, if any, to get to next row */
8913 /* src is at beginning of a row here, but it's the second row of
8914 * the square block of 4 pixels that we just worked on so we
8915 * need to go one more row.
8923 src
+= rowSizeInBytes
;
8926 /* skip past pad bytes, if any, to get to next image */
8927 src
+= imagePadBytes
;
8929 src
+= imageSizeInBytes
;
8932 /* both pointers must reach one byte after the end */
8933 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8934 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8936 } /* halveImage3D() */