ntdll: Use cpu_info to check for AVX availability.
[wine.git] / dlls / glu32 / mipmap.c
blob6877e2f342cc70598a56539175f5f0a184f906b2
1 /*
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
23 * SOFTWARE.
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.
31 #include <assert.h>
32 #include <stdarg.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <limits.h>
36 #include <math.h>
38 #include "windef.h"
39 #include "winbase.h"
40 #include "wine/wgl.h"
41 #include "wine/glu.h"
43 #define GLU_INVALID_OPERATION GLU_INVALID_VALUE /* GLU_INVALID_OPERATION is missing on Windows */
45 typedef union {
46 unsigned char ub[4];
47 unsigned short us[2];
48 unsigned int ui;
49 char b[4];
50 short s[2];
51 int i;
52 float f;
53 } Type_Widget;
55 /* Pixel storage modes */
56 typedef struct {
57 GLint pack_alignment;
58 GLint pack_row_length;
59 GLint pack_skip_rows;
60 GLint pack_skip_pixels;
61 GLint pack_lsb_first;
62 GLint pack_swap_bytes;
63 GLint pack_skip_images;
64 GLint pack_image_height;
66 GLint unpack_alignment;
67 GLint unpack_row_length;
68 GLint unpack_skip_rows;
69 GLint unpack_skip_pixels;
70 GLint unpack_lsb_first;
71 GLint unpack_swap_bytes;
72 GLint unpack_skip_images;
73 GLint unpack_image_height;
74 } PixelStorageModes;
76 static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
77 GLsizei,
78 GLsizei,
79 GLenum, GLenum, GLint, GLint, GLint,
80 const void *);
81 static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
82 GLsizei, GLsizei,
83 GLsizei, GLsizei,
84 GLenum, GLenum, GLint, GLint, GLint,
85 const void *);
88 * internal function declarations
90 static GLfloat bytes_per_element(GLenum type);
91 static GLint elements_per_group(GLenum format, GLenum type);
92 static GLint is_index(GLenum format);
93 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
94 static void fill_image(const PixelStorageModes *,
95 GLint width, GLint height, GLenum format,
96 GLenum type, GLboolean index_format,
97 const void *userdata, GLushort *newimage);
98 static void empty_image(const PixelStorageModes *,
99 GLint width, GLint height, GLenum format,
100 GLenum type, GLboolean index_format,
101 const GLushort *oldimage, void *userdata);
102 static void scale_internal(GLint components, GLint widthin, GLint heightin,
103 const GLushort *datain,
104 GLint widthout, GLint heightout,
105 GLushort *dataout);
107 static void scale_internal_ubyte(GLint components, GLint widthin,
108 GLint heightin, const GLubyte *datain,
109 GLint widthout, GLint heightout,
110 GLubyte *dataout, GLint element_size,
111 GLint ysize, GLint group_size);
112 static void scale_internal_byte(GLint components, GLint widthin,
113 GLint heightin, const GLbyte *datain,
114 GLint widthout, GLint heightout,
115 GLbyte *dataout, GLint element_size,
116 GLint ysize, GLint group_size);
117 static void scale_internal_ushort(GLint components, GLint widthin,
118 GLint heightin, const GLushort *datain,
119 GLint widthout, GLint heightout,
120 GLushort *dataout, GLint element_size,
121 GLint ysize, GLint group_size,
122 GLint myswap_bytes);
123 static void scale_internal_short(GLint components, GLint widthin,
124 GLint heightin, const GLshort *datain,
125 GLint widthout, GLint heightout,
126 GLshort *dataout, GLint element_size,
127 GLint ysize, GLint group_size,
128 GLint myswap_bytes);
129 static void scale_internal_uint(GLint components, GLint widthin,
130 GLint heightin, const GLuint *datain,
131 GLint widthout, GLint heightout,
132 GLuint *dataout, GLint element_size,
133 GLint ysize, GLint group_size,
134 GLint myswap_bytes);
135 static void scale_internal_int(GLint components, GLint widthin,
136 GLint heightin, const GLint *datain,
137 GLint widthout, GLint heightout,
138 GLint *dataout, GLint element_size,
139 GLint ysize, GLint group_size,
140 GLint myswap_bytes);
141 static void scale_internal_float(GLint components, GLint widthin,
142 GLint heightin, const GLfloat *datain,
143 GLint widthout, GLint heightout,
144 GLfloat *dataout, GLint element_size,
145 GLint ysize, GLint group_size,
146 GLint myswap_bytes);
148 static int checkMipmapArgs(GLenum, GLenum, GLenum);
149 static GLboolean legalFormat(GLenum);
150 static GLboolean legalType(GLenum);
151 static GLboolean isTypePackedPixel(GLenum);
152 static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
153 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
154 GLint *, GLint *);
156 /* packedpixel type scale routines */
157 static void extract332(int,const void *, GLfloat []);
158 static void shove332(const GLfloat [],int ,void *);
159 static void extract233rev(int,const void *, GLfloat []);
160 static void shove233rev(const GLfloat [],int ,void *);
161 static void extract565(int,const void *, GLfloat []);
162 static void shove565(const GLfloat [],int ,void *);
163 static void extract565rev(int,const void *, GLfloat []);
164 static void shove565rev(const GLfloat [],int ,void *);
165 static void extract4444(int,const void *, GLfloat []);
166 static void shove4444(const GLfloat [],int ,void *);
167 static void extract4444rev(int,const void *, GLfloat []);
168 static void shove4444rev(const GLfloat [],int ,void *);
169 static void extract5551(int,const void *, GLfloat []);
170 static void shove5551(const GLfloat [],int ,void *);
171 static void extract1555rev(int,const void *, GLfloat []);
172 static void shove1555rev(const GLfloat [],int ,void *);
173 static void extract8888(int,const void *, GLfloat []);
174 static void shove8888(const GLfloat [],int ,void *);
175 static void extract8888rev(int,const void *, GLfloat []);
176 static void shove8888rev(const GLfloat [],int ,void *);
177 static void extract1010102(int,const void *, GLfloat []);
178 static void shove1010102(const GLfloat [],int ,void *);
179 static void extract2101010rev(int,const void *, GLfloat []);
180 static void shove2101010rev(const GLfloat [],int ,void *);
181 static void scaleInternalPackedPixel(int,
182 void (*)(int, const void *,GLfloat []),
183 void (*)(const GLfloat [],int, void *),
184 GLint,GLint, const void *,
185 GLint,GLint,void *,GLint,GLint,GLint);
186 static void halveImagePackedPixel(int,
187 void (*)(int, const void *,GLfloat []),
188 void (*)(const GLfloat [],int, void *),
189 GLint, GLint, const void *,
190 void *, GLint, GLint, GLint);
191 static void halve1DimagePackedPixel(int,
192 void (*)(int, const void *,GLfloat []),
193 void (*)(const GLfloat [],int, void *),
194 GLint, GLint, const void *,
195 void *, GLint, GLint, GLint);
197 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
198 GLubyte *, GLint, GLint, GLint);
199 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
200 GLint, GLint, GLint);
201 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
202 GLushort *, GLint, GLint, GLint, GLint);
203 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
204 GLint, GLint, GLint, GLint);
205 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
206 GLint, GLint, GLint, GLint);
207 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
208 GLint, GLint, GLint, GLint);
209 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
210 GLint, GLint, GLint, GLint);
212 static void retrieveStoreModes(PixelStorageModes *psm)
214 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
215 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
216 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
217 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
218 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
219 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
221 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
222 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
223 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
224 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
225 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
226 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
229 static int computeLog(GLuint value)
231 int i;
233 i = 0;
235 /* Error! */
236 if (value == 0) return -1;
238 for (;;) {
239 if (value & 1) {
240 /* Error ! */
241 if (value != 1) return -1;
242 return i;
244 value = value >> 1;
245 i++;
250 ** Compute the nearest power of 2 number. This algorithm is a little
251 ** strange, but it works quite well.
253 static int nearestPower(GLuint value)
255 int i;
257 i = 1;
259 /* Error! */
260 if (value == 0) return -1;
262 for (;;) {
263 if (value == 1) {
264 return i;
265 } else if (value == 3) {
266 return i*4;
268 value = value >> 1;
269 i *= 2;
273 #define __GLU_SWAP_2_BYTES(s)\
274 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
276 #define __GLU_SWAP_4_BYTES(s)\
277 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
278 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
279 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
281 static void halveImage(GLint components, GLuint width, GLuint height,
282 const GLushort *datain, GLushort *dataout)
284 int i, j, k;
285 int newwidth, newheight;
286 int delta;
287 GLushort *s;
288 const GLushort *t;
290 newwidth = width / 2;
291 newheight = height / 2;
292 delta = width * components;
293 s = dataout;
294 t = datain;
296 /* Piece o' cake! */
297 for (i = 0; i < newheight; i++) {
298 for (j = 0; j < newwidth; j++) {
299 for (k = 0; k < components; k++) {
300 s[0] = (t[0] + t[components] + t[delta] +
301 t[delta+components] + 2) / 4;
302 s++; t++;
304 t += components;
306 t += delta;
310 static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
311 const GLubyte *datain, GLubyte *dataout,
312 GLint element_size, GLint ysize, GLint group_size)
314 int i, j, k;
315 int newwidth, newheight;
316 int padBytes;
317 GLubyte *s;
318 const char *t;
320 /* handle case where there is only 1 column/row */
321 if (width == 1 || height == 1) {
322 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
323 halve1Dimage_ubyte(components,width,height,datain,dataout,
324 element_size,ysize,group_size);
325 return;
328 newwidth = width / 2;
329 newheight = height / 2;
330 padBytes = ysize - (width*group_size);
331 s = dataout;
332 t = (const char *)datain;
334 /* Piece o' cake! */
335 for (i = 0; i < newheight; i++) {
336 for (j = 0; j < newwidth; j++) {
337 for (k = 0; k < components; k++) {
338 s[0] = (*(const GLubyte*)t +
339 *(const GLubyte*)(t+group_size) +
340 *(const GLubyte*)(t+ysize) +
341 *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
342 s++; t += element_size;
344 t += group_size;
346 t += padBytes;
347 t += ysize;
351 /* */
352 static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
353 const GLubyte *dataIn, GLubyte *dataOut,
354 GLint element_size, GLint ysize,
355 GLint group_size)
357 GLint halfWidth= width / 2;
358 GLint halfHeight= height / 2;
359 const char *src= (const char *) dataIn;
360 GLubyte *dest= dataOut;
361 int jj;
363 assert(width == 1 || height == 1); /* must be 1D */
364 assert(width != height); /* can't be square */
366 if (height == 1) { /* 1 row */
367 assert(width != 1); /* widthxheight can't be 1x1 */
368 halfHeight= 1;
370 for (jj= 0; jj< halfWidth; jj++) {
371 int kk;
372 for (kk= 0; kk< components; kk++) {
373 *dest= (*(const GLubyte*)src +
374 *(const GLubyte*)(src+group_size)) / 2;
376 src+= element_size;
377 dest++;
379 src+= group_size; /* skip to next 2 */
382 int padBytes= ysize - (width*group_size);
383 src+= padBytes; /* for assertion only */
386 else if (width == 1) { /* 1 column */
387 int padBytes= ysize - (width * group_size);
388 assert(height != 1); /* widthxheight can't be 1x1 */
389 halfWidth= 1;
390 /* one vertical column with possible pad bytes per row */
391 /* average two at a time */
393 for (jj= 0; jj< halfHeight; jj++) {
394 int kk;
395 for (kk= 0; kk< components; kk++) {
396 *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
398 src+= element_size;
399 dest++;
401 src+= padBytes; /* add pad bytes, if any, to get to end to row */
402 src+= ysize;
406 assert(src == &((const char *)dataIn)[ysize*height]);
407 assert((char *)dest == &((char *)dataOut)
408 [components * element_size * halfWidth * halfHeight]);
409 } /* halve1Dimage_ubyte() */
411 static void halveImage_byte(GLint components, GLuint width, GLuint height,
412 const GLbyte *datain, GLbyte *dataout,
413 GLint element_size,
414 GLint ysize, GLint group_size)
416 int i, j, k;
417 int newwidth, newheight;
418 int padBytes;
419 GLbyte *s;
420 const char *t;
422 /* handle case where there is only 1 column/row */
423 if (width == 1 || height == 1) {
424 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
425 halve1Dimage_byte(components,width,height,datain,dataout,
426 element_size,ysize,group_size);
427 return;
430 newwidth = width / 2;
431 newheight = height / 2;
432 padBytes = ysize - (width*group_size);
433 s = dataout;
434 t = (const char *)datain;
436 /* Piece o' cake! */
437 for (i = 0; i < newheight; i++) {
438 for (j = 0; j < newwidth; j++) {
439 for (k = 0; k < components; k++) {
440 s[0] = (*(const GLbyte*)t +
441 *(const GLbyte*)(t+group_size) +
442 *(const GLbyte*)(t+ysize) +
443 *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
444 s++; t += element_size;
446 t += group_size;
448 t += padBytes;
449 t += ysize;
453 static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
454 const GLbyte *dataIn, GLbyte *dataOut,
455 GLint element_size,GLint ysize, GLint group_size)
457 GLint halfWidth= width / 2;
458 GLint halfHeight= height / 2;
459 const char *src= (const char *) dataIn;
460 GLbyte *dest= dataOut;
461 int jj;
463 assert(width == 1 || height == 1); /* must be 1D */
464 assert(width != height); /* can't be square */
466 if (height == 1) { /* 1 row */
467 assert(width != 1); /* widthxheight can't be 1x1 */
468 halfHeight= 1;
470 for (jj= 0; jj< halfWidth; jj++) {
471 int kk;
472 for (kk= 0; kk< components; kk++) {
473 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
475 src+= element_size;
476 dest++;
478 src+= group_size; /* skip to next 2 */
481 int padBytes= ysize - (width*group_size);
482 src+= padBytes; /* for assertion only */
485 else if (width == 1) { /* 1 column */
486 int padBytes= ysize - (width * group_size);
487 assert(height != 1); /* widthxheight can't be 1x1 */
488 halfWidth= 1;
489 /* one vertical column with possible pad bytes per row */
490 /* average two at a time */
492 for (jj= 0; jj< halfHeight; jj++) {
493 int kk;
494 for (kk= 0; kk< components; kk++) {
495 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
497 src+= element_size;
498 dest++;
500 src+= padBytes; /* add pad bytes, if any, to get to end to row */
501 src+= ysize;
504 assert(src == &((const char *)dataIn)[ysize*height]);
507 assert((char *)dest == &((char *)dataOut)
508 [components * element_size * halfWidth * halfHeight]);
509 } /* halve1Dimage_byte() */
511 static void halveImage_ushort(GLint components, GLuint width, GLuint height,
512 const GLushort *datain, GLushort *dataout,
513 GLint element_size, GLint ysize, GLint group_size,
514 GLint myswap_bytes)
516 int i, j, k;
517 int newwidth, newheight;
518 int padBytes;
519 GLushort *s;
520 const char *t;
522 /* handle case where there is only 1 column/row */
523 if (width == 1 || height == 1) {
524 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
525 halve1Dimage_ushort(components,width,height,datain,dataout,
526 element_size,ysize,group_size, myswap_bytes);
527 return;
530 newwidth = width / 2;
531 newheight = height / 2;
532 padBytes = ysize - (width*group_size);
533 s = dataout;
534 t = (const char *)datain;
536 /* Piece o' cake! */
537 if (!myswap_bytes)
538 for (i = 0; i < newheight; i++) {
539 for (j = 0; j < newwidth; j++) {
540 for (k = 0; k < components; k++) {
541 s[0] = (*(const GLushort*)t +
542 *(const GLushort*)(t+group_size) +
543 *(const GLushort*)(t+ysize) +
544 *(const GLushort*)(t+ysize+group_size) + 2) / 4;
545 s++; t += element_size;
547 t += group_size;
549 t += padBytes;
550 t += ysize;
552 else
553 for (i = 0; i < newheight; i++) {
554 for (j = 0; j < newwidth; j++) {
555 for (k = 0; k < components; k++) {
556 s[0] = (__GLU_SWAP_2_BYTES(t) +
557 __GLU_SWAP_2_BYTES(t+group_size) +
558 __GLU_SWAP_2_BYTES(t+ysize) +
559 __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
560 s++; t += element_size;
562 t += group_size;
564 t += padBytes;
565 t += ysize;
569 static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
570 const GLushort *dataIn, GLushort *dataOut,
571 GLint element_size, GLint ysize,
572 GLint group_size, GLint myswap_bytes)
574 GLint halfWidth= width / 2;
575 GLint halfHeight= height / 2;
576 const char *src= (const char *) dataIn;
577 GLushort *dest= dataOut;
578 int jj;
580 assert(width == 1 || height == 1); /* must be 1D */
581 assert(width != height); /* can't be square */
583 if (height == 1) { /* 1 row */
584 assert(width != 1); /* widthxheight can't be 1x1 */
585 halfHeight= 1;
587 for (jj= 0; jj< halfWidth; jj++) {
588 int kk;
589 for (kk= 0; kk< components; kk++) {
590 #define BOX2 2
591 GLushort ushort[BOX2];
592 if (myswap_bytes) {
593 ushort[0]= __GLU_SWAP_2_BYTES(src);
594 ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
596 else {
597 ushort[0]= *(const GLushort*)src;
598 ushort[1]= *(const GLushort*)(src+group_size);
601 *dest= (ushort[0] + ushort[1]) / 2;
602 src+= element_size;
603 dest++;
605 src+= group_size; /* skip to next 2 */
608 int padBytes= ysize - (width*group_size);
609 src+= padBytes; /* for assertion only */
612 else if (width == 1) { /* 1 column */
613 int padBytes= ysize - (width * group_size);
614 assert(height != 1); /* widthxheight can't be 1x1 */
615 halfWidth= 1;
616 /* one vertical column with possible pad bytes per row */
617 /* average two at a time */
619 for (jj= 0; jj< halfHeight; jj++) {
620 int kk;
621 for (kk= 0; kk< components; kk++) {
622 #define BOX2 2
623 GLushort ushort[BOX2];
624 if (myswap_bytes) {
625 ushort[0]= __GLU_SWAP_2_BYTES(src);
626 ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
628 else {
629 ushort[0]= *(const GLushort*)src;
630 ushort[1]= *(const GLushort*)(src+ysize);
632 *dest= (ushort[0] + ushort[1]) / 2;
634 src+= element_size;
635 dest++;
637 src+= padBytes; /* add pad bytes, if any, to get to end to row */
638 src+= ysize;
641 assert(src == &((const char *)dataIn)[ysize*height]);
644 assert((char *)dest == &((char *)dataOut)
645 [components * element_size * halfWidth * halfHeight]);
647 } /* halve1Dimage_ushort() */
650 static void halveImage_short(GLint components, GLuint width, GLuint height,
651 const GLshort *datain, GLshort *dataout,
652 GLint element_size, GLint ysize, GLint group_size,
653 GLint myswap_bytes)
655 int i, j, k;
656 int newwidth, newheight;
657 int padBytes;
658 GLshort *s;
659 const char *t;
661 /* handle case where there is only 1 column/row */
662 if (width == 1 || height == 1) {
663 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
664 halve1Dimage_short(components,width,height,datain,dataout,
665 element_size,ysize,group_size, myswap_bytes);
666 return;
669 newwidth = width / 2;
670 newheight = height / 2;
671 padBytes = ysize - (width*group_size);
672 s = dataout;
673 t = (const char *)datain;
675 /* Piece o' cake! */
676 if (!myswap_bytes)
677 for (i = 0; i < newheight; i++) {
678 for (j = 0; j < newwidth; j++) {
679 for (k = 0; k < components; k++) {
680 s[0] = (*(const GLshort*)t +
681 *(const GLshort*)(t+group_size) +
682 *(const GLshort*)(t+ysize) +
683 *(const GLshort*)(t+ysize+group_size) + 2) / 4;
684 s++; t += element_size;
686 t += group_size;
688 t += padBytes;
689 t += ysize;
691 else
692 for (i = 0; i < newheight; i++) {
693 for (j = 0; j < newwidth; j++) {
694 for (k = 0; k < components; k++) {
695 GLushort b;
696 GLint buf;
697 b = __GLU_SWAP_2_BYTES(t);
698 buf = *(const GLshort*)&b;
699 b = __GLU_SWAP_2_BYTES(t+group_size);
700 buf += *(const GLshort*)&b;
701 b = __GLU_SWAP_2_BYTES(t+ysize);
702 buf += *(const GLshort*)&b;
703 b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
704 buf += *(const GLshort*)&b;
705 s[0] = (GLshort)((buf+2)/4);
706 s++; t += element_size;
708 t += group_size;
710 t += padBytes;
711 t += ysize;
715 static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
716 const GLshort *dataIn, GLshort *dataOut,
717 GLint element_size, GLint ysize,
718 GLint group_size, GLint myswap_bytes)
720 GLint halfWidth= width / 2;
721 GLint halfHeight= height / 2;
722 const char *src= (const char *) dataIn;
723 GLshort *dest= dataOut;
724 int jj;
726 assert(width == 1 || height == 1); /* must be 1D */
727 assert(width != height); /* can't be square */
729 if (height == 1) { /* 1 row */
730 assert(width != 1); /* widthxheight can't be 1x1 */
731 halfHeight= 1;
733 for (jj= 0; jj< halfWidth; jj++) {
734 int kk;
735 for (kk= 0; kk< components; kk++) {
736 #define BOX2 2
737 GLshort sshort[BOX2];
738 if (myswap_bytes) {
739 sshort[0]= __GLU_SWAP_2_BYTES(src);
740 sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
742 else {
743 sshort[0]= *(const GLshort*)src;
744 sshort[1]= *(const GLshort*)(src+group_size);
747 *dest= (sshort[0] + sshort[1]) / 2;
748 src+= element_size;
749 dest++;
751 src+= group_size; /* skip to next 2 */
754 int padBytes= ysize - (width*group_size);
755 src+= padBytes; /* for assertion only */
758 else if (width == 1) { /* 1 column */
759 int padBytes= ysize - (width * group_size);
760 assert(height != 1); /* widthxheight can't be 1x1 */
761 halfWidth= 1;
762 /* one vertical column with possible pad bytes per row */
763 /* average two at a time */
765 for (jj= 0; jj< halfHeight; jj++) {
766 int kk;
767 for (kk= 0; kk< components; kk++) {
768 #define BOX2 2
769 GLshort sshort[BOX2];
770 if (myswap_bytes) {
771 sshort[0]= __GLU_SWAP_2_BYTES(src);
772 sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
774 else {
775 sshort[0]= *(const GLshort*)src;
776 sshort[1]= *(const GLshort*)(src+ysize);
778 *dest= (sshort[0] + sshort[1]) / 2;
780 src+= element_size;
781 dest++;
783 src+= padBytes; /* add pad bytes, if any, to get to end to row */
784 src+= ysize;
787 assert(src == &((const char *)dataIn)[ysize*height]);
790 assert((char *)dest == &((char *)dataOut)
791 [components * element_size * halfWidth * halfHeight]);
793 } /* halve1Dimage_short() */
796 static void halveImage_uint(GLint components, GLuint width, GLuint height,
797 const GLuint *datain, GLuint *dataout,
798 GLint element_size, GLint ysize, GLint group_size,
799 GLint myswap_bytes)
801 int i, j, k;
802 int newwidth, newheight;
803 int padBytes;
804 GLuint *s;
805 const char *t;
807 /* handle case where there is only 1 column/row */
808 if (width == 1 || height == 1) {
809 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
810 halve1Dimage_uint(components,width,height,datain,dataout,
811 element_size,ysize,group_size, myswap_bytes);
812 return;
815 newwidth = width / 2;
816 newheight = height / 2;
817 padBytes = ysize - (width*group_size);
818 s = dataout;
819 t = (const char *)datain;
821 /* Piece o' cake! */
822 if (!myswap_bytes)
823 for (i = 0; i < newheight; i++) {
824 for (j = 0; j < newwidth; j++) {
825 for (k = 0; k < components; k++) {
826 /* need to cast to double to hold large unsigned ints */
827 s[0] = ((double)*(const GLuint*)t +
828 (double)*(const GLuint*)(t+group_size) +
829 (double)*(const GLuint*)(t+ysize) +
830 (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
831 s++; t += element_size;
834 t += group_size;
836 t += padBytes;
837 t += ysize;
839 else
840 for (i = 0; i < newheight; i++) {
841 for (j = 0; j < newwidth; j++) {
842 for (k = 0; k < components; k++) {
843 /* need to cast to double to hold large unsigned ints */
844 GLdouble buf;
845 buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
846 (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
847 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
848 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
849 s[0] = (GLuint)(buf/4 + 0.5);
851 s++; t += element_size;
853 t += group_size;
855 t += padBytes;
856 t += ysize;
860 /* */
861 static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
862 const GLuint *dataIn, GLuint *dataOut,
863 GLint element_size, GLint ysize,
864 GLint group_size, GLint myswap_bytes)
866 GLint halfWidth= width / 2;
867 GLint halfHeight= height / 2;
868 const char *src= (const char *) dataIn;
869 GLuint *dest= dataOut;
870 int jj;
872 assert(width == 1 || height == 1); /* must be 1D */
873 assert(width != height); /* can't be square */
875 if (height == 1) { /* 1 row */
876 assert(width != 1); /* widthxheight can't be 1x1 */
877 halfHeight= 1;
879 for (jj= 0; jj< halfWidth; jj++) {
880 int kk;
881 for (kk= 0; kk< components; kk++) {
882 #define BOX2 2
883 GLuint uint[BOX2];
884 if (myswap_bytes) {
885 uint[0]= __GLU_SWAP_4_BYTES(src);
886 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
888 else {
889 uint[0]= *(const GLuint*)src;
890 uint[1]= *(const GLuint*)(src+group_size);
892 *dest= ((double)uint[0]+(double)uint[1])/2.0;
894 src+= element_size;
895 dest++;
897 src+= group_size; /* skip to next 2 */
900 int padBytes= ysize - (width*group_size);
901 src+= padBytes; /* for assertion only */
904 else if (width == 1) { /* 1 column */
905 int padBytes= ysize - (width * group_size);
906 assert(height != 1); /* widthxheight can't be 1x1 */
907 halfWidth= 1;
908 /* one vertical column with possible pad bytes per row */
909 /* average two at a time */
911 for (jj= 0; jj< halfHeight; jj++) {
912 int kk;
913 for (kk= 0; kk< components; kk++) {
914 #define BOX2 2
915 GLuint uint[BOX2];
916 if (myswap_bytes) {
917 uint[0]= __GLU_SWAP_4_BYTES(src);
918 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
920 else {
921 uint[0]= *(const GLuint*)src;
922 uint[1]= *(const GLuint*)(src+ysize);
924 *dest= ((double)uint[0]+(double)uint[1])/2.0;
926 src+= element_size;
927 dest++;
929 src+= padBytes; /* add pad bytes, if any, to get to end to row */
930 src+= ysize;
933 assert(src == &((const char *)dataIn)[ysize*height]);
936 assert((char *)dest == &((char *)dataOut)
937 [components * element_size * halfWidth * halfHeight]);
939 } /* halve1Dimage_uint() */
941 static void halveImage_int(GLint components, GLuint width, GLuint height,
942 const GLint *datain, GLint *dataout, GLint element_size,
943 GLint ysize, GLint group_size, GLint myswap_bytes)
945 int i, j, k;
946 int newwidth, newheight;
947 int padBytes;
948 GLint *s;
949 const char *t;
951 /* handle case where there is only 1 column/row */
952 if (width == 1 || height == 1) {
953 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
954 halve1Dimage_int(components,width,height,datain,dataout,
955 element_size,ysize,group_size, myswap_bytes);
956 return;
959 newwidth = width / 2;
960 newheight = height / 2;
961 padBytes = ysize - (width*group_size);
962 s = dataout;
963 t = (const char *)datain;
965 /* Piece o' cake! */
966 if (!myswap_bytes)
967 for (i = 0; i < newheight; i++) {
968 for (j = 0; j < newwidth; j++) {
969 for (k = 0; k < components; k++) {
970 s[0] = ((float)*(const GLint*)t +
971 (float)*(const GLint*)(t+group_size) +
972 (float)*(const GLint*)(t+ysize) +
973 (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
974 s++; t += element_size;
976 t += group_size;
978 t += padBytes;
979 t += ysize;
981 else
982 for (i = 0; i < newheight; i++) {
983 for (j = 0; j < newwidth; j++) {
984 for (k = 0; k < components; k++) {
985 GLuint b;
986 GLfloat buf;
987 b = __GLU_SWAP_4_BYTES(t);
988 buf = *(GLint*)&b;
989 b = __GLU_SWAP_4_BYTES(t+group_size);
990 buf += *(GLint*)&b;
991 b = __GLU_SWAP_4_BYTES(t+ysize);
992 buf += *(GLint*)&b;
993 b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
994 buf += *(GLint*)&b;
995 s[0] = (GLint)(buf/4 + 0.5);
997 s++; t += element_size;
999 t += group_size;
1001 t += padBytes;
1002 t += ysize;
1006 /* */
1007 static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
1008 const GLint *dataIn, GLint *dataOut,
1009 GLint element_size, GLint ysize,
1010 GLint group_size, GLint myswap_bytes)
1012 GLint halfWidth= width / 2;
1013 GLint halfHeight= height / 2;
1014 const char *src= (const char *) dataIn;
1015 GLint *dest= dataOut;
1016 int jj;
1018 assert(width == 1 || height == 1); /* must be 1D */
1019 assert(width != height); /* can't be square */
1021 if (height == 1) { /* 1 row */
1022 assert(width != 1); /* widthxheight can't be 1x1 */
1023 halfHeight= 1;
1025 for (jj= 0; jj< halfWidth; jj++) {
1026 int kk;
1027 for (kk= 0; kk< components; kk++) {
1028 #define BOX2 2
1029 GLuint uint[BOX2];
1030 if (myswap_bytes) {
1031 uint[0]= __GLU_SWAP_4_BYTES(src);
1032 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
1034 else {
1035 uint[0]= *(const GLuint*)src;
1036 uint[1]= *(const GLuint*)(src+group_size);
1038 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1040 src+= element_size;
1041 dest++;
1043 src+= group_size; /* skip to next 2 */
1046 int padBytes= ysize - (width*group_size);
1047 src+= padBytes; /* for assertion only */
1050 else if (width == 1) { /* 1 column */
1051 int padBytes= ysize - (width * group_size);
1052 assert(height != 1); /* widthxheight can't be 1x1 */
1053 halfWidth= 1;
1054 /* one vertical column with possible pad bytes per row */
1055 /* average two at a time */
1057 for (jj= 0; jj< halfHeight; jj++) {
1058 int kk;
1059 for (kk= 0; kk< components; kk++) {
1060 #define BOX2 2
1061 GLuint uint[BOX2];
1062 if (myswap_bytes) {
1063 uint[0]= __GLU_SWAP_4_BYTES(src);
1064 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
1066 else {
1067 uint[0]= *(const GLuint*)src;
1068 uint[1]= *(const GLuint*)(src+ysize);
1070 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1072 src+= element_size;
1073 dest++;
1075 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1076 src+= ysize;
1079 assert(src == &((const char *)dataIn)[ysize*height]);
1082 assert((char *)dest == &((char *)dataOut)
1083 [components * element_size * halfWidth * halfHeight]);
1085 } /* halve1Dimage_int() */
1088 static void halveImage_float(GLint components, GLuint width, GLuint height,
1089 const GLfloat *datain, GLfloat *dataout,
1090 GLint element_size, GLint ysize, GLint group_size,
1091 GLint myswap_bytes)
1093 int i, j, k;
1094 int newwidth, newheight;
1095 int padBytes;
1096 GLfloat *s;
1097 const char *t;
1099 /* handle case where there is only 1 column/row */
1100 if (width == 1 || height == 1) {
1101 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1102 halve1Dimage_float(components,width,height,datain,dataout,
1103 element_size,ysize,group_size, myswap_bytes);
1104 return;
1107 newwidth = width / 2;
1108 newheight = height / 2;
1109 padBytes = ysize - (width*group_size);
1110 s = dataout;
1111 t = (const char *)datain;
1113 /* Piece o' cake! */
1114 if (!myswap_bytes)
1115 for (i = 0; i < newheight; i++) {
1116 for (j = 0; j < newwidth; j++) {
1117 for (k = 0; k < components; k++) {
1118 s[0] = (*(const GLfloat*)t +
1119 *(const GLfloat*)(t+group_size) +
1120 *(const GLfloat*)(t+ysize) +
1121 *(const GLfloat*)(t+ysize+group_size)) / 4;
1122 s++; t += element_size;
1124 t += group_size;
1126 t += padBytes;
1127 t += ysize;
1129 else
1130 for (i = 0; i < newheight; i++) {
1131 for (j = 0; j < newwidth; j++) {
1132 for (k = 0; k < components; k++) {
1133 union { GLuint b; GLfloat f; } swapbuf;
1134 swapbuf.b = __GLU_SWAP_4_BYTES(t);
1135 s[0] = swapbuf.f;
1136 swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
1137 s[0] += swapbuf.f;
1138 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
1139 s[0] += swapbuf.f;
1140 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1141 s[0] += swapbuf.f;
1142 s[0] /= 4;
1143 s++; t += element_size;
1145 t += group_size;
1147 t += padBytes;
1148 t += ysize;
1152 /* */
1153 static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
1154 const GLfloat *dataIn, GLfloat *dataOut,
1155 GLint element_size, GLint ysize,
1156 GLint group_size, GLint myswap_bytes)
1158 GLint halfWidth= width / 2;
1159 GLint halfHeight= height / 2;
1160 const char *src= (const char *) dataIn;
1161 GLfloat *dest= dataOut;
1162 int jj;
1164 assert(width == 1 || height == 1); /* must be 1D */
1165 assert(width != height); /* can't be square */
1167 if (height == 1) { /* 1 row */
1168 assert(width != 1); /* widthxheight can't be 1x1 */
1169 halfHeight= 1;
1171 for (jj= 0; jj< halfWidth; jj++) {
1172 int kk;
1173 for (kk= 0; kk< components; kk++) {
1174 #define BOX2 2
1175 GLfloat sfloat[BOX2];
1176 if (myswap_bytes) {
1177 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1178 sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
1180 else {
1181 sfloat[0]= *(const GLfloat*)src;
1182 sfloat[1]= *(const GLfloat*)(src+group_size);
1185 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1186 src+= element_size;
1187 dest++;
1189 src+= group_size; /* skip to next 2 */
1192 int padBytes= ysize - (width*group_size);
1193 src+= padBytes; /* for assertion only */
1196 else if (width == 1) { /* 1 column */
1197 int padBytes= ysize - (width * group_size);
1198 assert(height != 1); /* widthxheight can't be 1x1 */
1199 halfWidth= 1;
1200 /* one vertical column with possible pad bytes per row */
1201 /* average two at a time */
1203 for (jj= 0; jj< halfHeight; jj++) {
1204 int kk;
1205 for (kk= 0; kk< components; kk++) {
1206 #define BOX2 2
1207 GLfloat sfloat[BOX2];
1208 if (myswap_bytes) {
1209 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1210 sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
1212 else {
1213 sfloat[0]= *(const GLfloat*)src;
1214 sfloat[1]= *(const GLfloat*)(src+ysize);
1216 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1218 src+= element_size;
1219 dest++;
1221 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1222 src+= ysize; /* skip to odd row */
1226 assert(src == &((const char *)dataIn)[ysize*height]);
1227 assert((char *)dest == &((char *)dataOut)
1228 [components * element_size * halfWidth * halfHeight]);
1229 } /* halve1Dimage_float() */
1231 static void scale_internal(GLint components, GLint widthin, GLint heightin,
1232 const GLushort *datain,
1233 GLint widthout, GLint heightout,
1234 GLushort *dataout)
1236 float x, lowx, highx, convx, halfconvx;
1237 float y, lowy, highy, convy, halfconvy;
1238 float xpercent,ypercent;
1239 float percent;
1240 /* Max components in a format is 4, so... */
1241 float totals[4];
1242 float area;
1243 int i,j,k,yint,xint,xindex,yindex;
1244 int temp;
1246 if (widthin == widthout*2 && heightin == heightout*2) {
1247 halveImage(components, widthin, heightin, datain, dataout);
1248 return;
1250 convy = (float) heightin/heightout;
1251 convx = (float) widthin/widthout;
1252 halfconvx = convx/2;
1253 halfconvy = convy/2;
1254 for (i = 0; i < heightout; i++) {
1255 y = convy * (i+0.5);
1256 if (heightin > heightout) {
1257 highy = y + halfconvy;
1258 lowy = y - halfconvy;
1259 } else {
1260 highy = y + 0.5;
1261 lowy = y - 0.5;
1263 for (j = 0; j < widthout; j++) {
1264 x = convx * (j+0.5);
1265 if (widthin > widthout) {
1266 highx = x + halfconvx;
1267 lowx = x - halfconvx;
1268 } else {
1269 highx = x + 0.5;
1270 lowx = x - 0.5;
1274 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1275 ** to (highx, highy) on input data into this pixel on output
1276 ** data.
1278 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1279 area = 0.0;
1281 y = lowy;
1282 yint = floor(y);
1283 while (y < highy) {
1284 yindex = (yint + heightin) % heightin;
1285 if (highy < yint+1) {
1286 ypercent = highy - y;
1287 } else {
1288 ypercent = yint+1 - y;
1291 x = lowx;
1292 xint = floor(x);
1294 while (x < highx) {
1295 xindex = (xint + widthin) % widthin;
1296 if (highx < xint+1) {
1297 xpercent = highx - x;
1298 } else {
1299 xpercent = xint+1 - x;
1302 percent = xpercent * ypercent;
1303 area += percent;
1304 temp = (xindex + (yindex * widthin)) * components;
1305 for (k = 0; k < components; k++) {
1306 totals[k] += datain[temp + k] * percent;
1309 xint++;
1310 x = xint;
1312 yint++;
1313 y = yint;
1316 temp = (j + (i * widthout)) * components;
1317 for (k = 0; k < components; k++) {
1318 /* totals[] should be rounded in the case of enlarging an RGB
1319 * ramp when the type is 332 or 4444
1321 dataout[temp + k] = (totals[k]+0.5)/area;
1327 static void scale_internal_ubyte(GLint components, GLint widthin,
1328 GLint heightin, const GLubyte *datain,
1329 GLint widthout, GLint heightout,
1330 GLubyte *dataout, GLint element_size,
1331 GLint ysize, GLint group_size)
1333 float convx;
1334 float convy;
1335 float percent;
1336 /* Max components in a format is 4, so... */
1337 float totals[4];
1338 float area;
1339 int i,j,k,xindex;
1341 const char *temp, *temp0;
1342 const char *temp_index;
1343 int outindex;
1345 int lowx_int, highx_int, lowy_int, highy_int;
1346 float x_percent, y_percent;
1347 float lowx_float, highx_float, lowy_float, highy_float;
1348 float convy_float, convx_float;
1349 int convy_int, convx_int;
1350 int l, m;
1351 const char *left, *right;
1353 if (widthin == widthout*2 && heightin == heightout*2) {
1354 halveImage_ubyte(components, widthin, heightin,
1355 (const GLubyte *)datain, (GLubyte *)dataout,
1356 element_size, ysize, group_size);
1357 return;
1359 convy = (float) heightin/heightout;
1360 convx = (float) widthin/widthout;
1361 convy_int = floor(convy);
1362 convy_float = convy - convy_int;
1363 convx_int = floor(convx);
1364 convx_float = convx - convx_int;
1366 area = convx * convy;
1368 lowy_int = 0;
1369 lowy_float = 0;
1370 highy_int = convy_int;
1371 highy_float = convy_float;
1373 for (i = 0; i < heightout; i++) {
1374 /* Clamp here to be sure we don't read beyond input buffer. */
1375 if (highy_int >= heightin)
1376 highy_int = heightin - 1;
1377 lowx_int = 0;
1378 lowx_float = 0;
1379 highx_int = convx_int;
1380 highx_float = convx_float;
1382 for (j = 0; j < widthout; j++) {
1385 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1386 ** to (highx, highy) on input data into this pixel on output
1387 ** data.
1389 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1391 /* calculate the value for pixels in the 1st row */
1392 xindex = lowx_int*group_size;
1393 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1395 y_percent = 1-lowy_float;
1396 temp = (const char *)datain + xindex + lowy_int * ysize;
1397 percent = y_percent * (1-lowx_float);
1398 for (k = 0, temp_index = temp; k < components;
1399 k++, temp_index += element_size) {
1400 totals[k] += (GLubyte)(*(temp_index)) * percent;
1402 left = temp;
1403 for(l = lowx_int+1; l < highx_int; l++) {
1404 temp += group_size;
1405 for (k = 0, temp_index = temp; k < components;
1406 k++, temp_index += element_size) {
1407 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1410 temp += group_size;
1411 right = temp;
1412 percent = y_percent * highx_float;
1413 for (k = 0, temp_index = temp; k < components;
1414 k++, temp_index += element_size) {
1415 totals[k] += (GLubyte)(*(temp_index)) * percent;
1418 /* calculate the value for pixels in the last row */
1419 y_percent = highy_float;
1420 percent = y_percent * (1-lowx_float);
1421 temp = (const char *)datain + xindex + highy_int * ysize;
1422 for (k = 0, temp_index = temp; k < components;
1423 k++, temp_index += element_size) {
1424 totals[k] += (GLubyte)(*(temp_index)) * percent;
1426 for(l = lowx_int+1; l < highx_int; l++) {
1427 temp += group_size;
1428 for (k = 0, temp_index = temp; k < components;
1429 k++, temp_index += element_size) {
1430 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1433 temp += group_size;
1434 percent = y_percent * highx_float;
1435 for (k = 0, temp_index = temp; k < components;
1436 k++, temp_index += element_size) {
1437 totals[k] += (GLubyte)(*(temp_index)) * percent;
1441 /* calculate the value for pixels in the 1st and last column */
1442 for(m = lowy_int+1; m < highy_int; m++) {
1443 left += ysize;
1444 right += ysize;
1445 for (k = 0; k < components;
1446 k++, left += element_size, right += element_size) {
1447 totals[k] += (GLubyte)(*(left))*(1-lowx_float)
1448 +(GLubyte)(*(right))*highx_float;
1451 } else if (highy_int > lowy_int) {
1452 x_percent = highx_float - lowx_float;
1453 percent = (1-lowy_float)*x_percent;
1454 temp = (const char *)datain + xindex + lowy_int*ysize;
1455 for (k = 0, temp_index = temp; k < components;
1456 k++, temp_index += element_size) {
1457 totals[k] += (GLubyte)(*(temp_index)) * percent;
1459 for(m = lowy_int+1; m < highy_int; m++) {
1460 temp += ysize;
1461 for (k = 0, temp_index = temp; k < components;
1462 k++, temp_index += element_size) {
1463 totals[k] += (GLubyte)(*(temp_index)) * x_percent;
1466 percent = x_percent * highy_float;
1467 temp += ysize;
1468 for (k = 0, temp_index = temp; k < components;
1469 k++, temp_index += element_size) {
1470 totals[k] += (GLubyte)(*(temp_index)) * percent;
1472 } else if (highx_int > lowx_int) {
1473 y_percent = highy_float - lowy_float;
1474 percent = (1-lowx_float)*y_percent;
1475 temp = (const char *)datain + xindex + lowy_int*ysize;
1476 for (k = 0, temp_index = temp; k < components;
1477 k++, temp_index += element_size) {
1478 totals[k] += (GLubyte)(*(temp_index)) * percent;
1480 for (l = lowx_int+1; l < highx_int; l++) {
1481 temp += group_size;
1482 for (k = 0, temp_index = temp; k < components;
1483 k++, temp_index += element_size) {
1484 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1487 temp += group_size;
1488 percent = y_percent * highx_float;
1489 for (k = 0, temp_index = temp; k < components;
1490 k++, temp_index += element_size) {
1491 totals[k] += (GLubyte)(*(temp_index)) * percent;
1493 } else {
1494 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1495 temp = (const char *)datain + xindex + lowy_int * ysize;
1496 for (k = 0, temp_index = temp; k < components;
1497 k++, temp_index += element_size) {
1498 totals[k] += (GLubyte)(*(temp_index)) * percent;
1504 /* this is for the pixels in the body */
1505 temp0 = (const char *)datain + xindex + group_size +
1506 (lowy_int+1)*ysize;
1507 for (m = lowy_int+1; m < highy_int; m++) {
1508 temp = temp0;
1509 for(l = lowx_int+1; l < highx_int; l++) {
1510 for (k = 0, temp_index = temp; k < components;
1511 k++, temp_index += element_size) {
1512 totals[k] += (GLubyte)(*(temp_index));
1514 temp += group_size;
1516 temp0 += ysize;
1519 outindex = (j + (i * widthout)) * components;
1520 for (k = 0; k < components; k++) {
1521 dataout[outindex + k] = totals[k]/area;
1522 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1524 lowx_int = highx_int;
1525 lowx_float = highx_float;
1526 highx_int += convx_int;
1527 highx_float += convx_float;
1528 if(highx_float > 1) {
1529 highx_float -= 1.0;
1530 highx_int++;
1533 lowy_int = highy_int;
1534 lowy_float = highy_float;
1535 highy_int += convy_int;
1536 highy_float += convy_float;
1537 if(highy_float > 1) {
1538 highy_float -= 1.0;
1539 highy_int++;
1544 static void scale_internal_byte(GLint components, GLint widthin,
1545 GLint heightin, const GLbyte *datain,
1546 GLint widthout, GLint heightout,
1547 GLbyte *dataout, GLint element_size,
1548 GLint ysize, GLint group_size)
1550 float convx;
1551 float convy;
1552 float percent;
1553 /* Max components in a format is 4, so... */
1554 float totals[4];
1555 float area;
1556 int i,j,k,xindex;
1558 const char *temp, *temp0;
1559 const char *temp_index;
1560 int outindex;
1562 int lowx_int, highx_int, lowy_int, highy_int;
1563 float x_percent, y_percent;
1564 float lowx_float, highx_float, lowy_float, highy_float;
1565 float convy_float, convx_float;
1566 int convy_int, convx_int;
1567 int l, m;
1568 const char *left, *right;
1570 if (widthin == widthout*2 && heightin == heightout*2) {
1571 halveImage_byte(components, widthin, heightin,
1572 (const GLbyte *)datain, (GLbyte *)dataout,
1573 element_size, ysize, group_size);
1574 return;
1576 convy = (float) heightin/heightout;
1577 convx = (float) widthin/widthout;
1578 convy_int = floor(convy);
1579 convy_float = convy - convy_int;
1580 convx_int = floor(convx);
1581 convx_float = convx - convx_int;
1583 area = convx * convy;
1585 lowy_int = 0;
1586 lowy_float = 0;
1587 highy_int = convy_int;
1588 highy_float = convy_float;
1590 for (i = 0; i < heightout; i++) {
1591 /* Clamp here to be sure we don't read beyond input buffer. */
1592 if (highy_int >= heightin)
1593 highy_int = heightin - 1;
1594 lowx_int = 0;
1595 lowx_float = 0;
1596 highx_int = convx_int;
1597 highx_float = convx_float;
1599 for (j = 0; j < widthout; j++) {
1602 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1603 ** to (highx, highy) on input data into this pixel on output
1604 ** data.
1606 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1608 /* calculate the value for pixels in the 1st row */
1609 xindex = lowx_int*group_size;
1610 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1612 y_percent = 1-lowy_float;
1613 temp = (const char *)datain + xindex + lowy_int * ysize;
1614 percent = y_percent * (1-lowx_float);
1615 for (k = 0, temp_index = temp; k < components;
1616 k++, temp_index += element_size) {
1617 totals[k] += (GLbyte)(*(temp_index)) * percent;
1619 left = temp;
1620 for(l = lowx_int+1; l < highx_int; l++) {
1621 temp += group_size;
1622 for (k = 0, temp_index = temp; k < components;
1623 k++, temp_index += element_size) {
1624 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1627 temp += group_size;
1628 right = temp;
1629 percent = y_percent * highx_float;
1630 for (k = 0, temp_index = temp; k < components;
1631 k++, temp_index += element_size) {
1632 totals[k] += (GLbyte)(*(temp_index)) * percent;
1635 /* calculate the value for pixels in the last row */
1636 y_percent = highy_float;
1637 percent = y_percent * (1-lowx_float);
1638 temp = (const char *)datain + xindex + highy_int * ysize;
1639 for (k = 0, temp_index = temp; k < components;
1640 k++, temp_index += element_size) {
1641 totals[k] += (GLbyte)(*(temp_index)) * percent;
1643 for(l = lowx_int+1; l < highx_int; l++) {
1644 temp += group_size;
1645 for (k = 0, temp_index = temp; k < components;
1646 k++, temp_index += element_size) {
1647 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1650 temp += group_size;
1651 percent = y_percent * highx_float;
1652 for (k = 0, temp_index = temp; k < components;
1653 k++, temp_index += element_size) {
1654 totals[k] += (GLbyte)(*(temp_index)) * percent;
1658 /* calculate the value for pixels in the 1st and last column */
1659 for(m = lowy_int+1; m < highy_int; m++) {
1660 left += ysize;
1661 right += ysize;
1662 for (k = 0; k < components;
1663 k++, left += element_size, right += element_size) {
1664 totals[k] += (GLbyte)(*(left))*(1-lowx_float)
1665 +(GLbyte)(*(right))*highx_float;
1668 } else if (highy_int > lowy_int) {
1669 x_percent = highx_float - lowx_float;
1670 percent = (1-lowy_float)*x_percent;
1671 temp = (const char *)datain + xindex + lowy_int*ysize;
1672 for (k = 0, temp_index = temp; k < components;
1673 k++, temp_index += element_size) {
1674 totals[k] += (GLbyte)(*(temp_index)) * percent;
1676 for(m = lowy_int+1; m < highy_int; m++) {
1677 temp += ysize;
1678 for (k = 0, temp_index = temp; k < components;
1679 k++, temp_index += element_size) {
1680 totals[k] += (GLbyte)(*(temp_index)) * x_percent;
1683 percent = x_percent * highy_float;
1684 temp += ysize;
1685 for (k = 0, temp_index = temp; k < components;
1686 k++, temp_index += element_size) {
1687 totals[k] += (GLbyte)(*(temp_index)) * percent;
1689 } else if (highx_int > lowx_int) {
1690 y_percent = highy_float - lowy_float;
1691 percent = (1-lowx_float)*y_percent;
1692 temp = (const char *)datain + xindex + lowy_int*ysize;
1693 for (k = 0, temp_index = temp; k < components;
1694 k++, temp_index += element_size) {
1695 totals[k] += (GLbyte)(*(temp_index)) * percent;
1697 for (l = lowx_int+1; l < highx_int; l++) {
1698 temp += group_size;
1699 for (k = 0, temp_index = temp; k < components;
1700 k++, temp_index += element_size) {
1701 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1704 temp += group_size;
1705 percent = y_percent * highx_float;
1706 for (k = 0, temp_index = temp; k < components;
1707 k++, temp_index += element_size) {
1708 totals[k] += (GLbyte)(*(temp_index)) * percent;
1710 } else {
1711 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1712 temp = (const char *)datain + xindex + lowy_int * ysize;
1713 for (k = 0, temp_index = temp; k < components;
1714 k++, temp_index += element_size) {
1715 totals[k] += (GLbyte)(*(temp_index)) * percent;
1721 /* this is for the pixels in the body */
1722 temp0 = (const char *)datain + xindex + group_size +
1723 (lowy_int+1)*ysize;
1724 for (m = lowy_int+1; m < highy_int; m++) {
1725 temp = temp0;
1726 for(l = lowx_int+1; l < highx_int; l++) {
1727 for (k = 0, temp_index = temp; k < components;
1728 k++, temp_index += element_size) {
1729 totals[k] += (GLbyte)(*(temp_index));
1731 temp += group_size;
1733 temp0 += ysize;
1736 outindex = (j + (i * widthout)) * components;
1737 for (k = 0; k < components; k++) {
1738 dataout[outindex + k] = totals[k]/area;
1739 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1741 lowx_int = highx_int;
1742 lowx_float = highx_float;
1743 highx_int += convx_int;
1744 highx_float += convx_float;
1745 if(highx_float > 1) {
1746 highx_float -= 1.0;
1747 highx_int++;
1750 lowy_int = highy_int;
1751 lowy_float = highy_float;
1752 highy_int += convy_int;
1753 highy_float += convy_float;
1754 if(highy_float > 1) {
1755 highy_float -= 1.0;
1756 highy_int++;
1761 static void scale_internal_ushort(GLint components, GLint widthin,
1762 GLint heightin, const GLushort *datain,
1763 GLint widthout, GLint heightout,
1764 GLushort *dataout, GLint element_size,
1765 GLint ysize, GLint group_size,
1766 GLint myswap_bytes)
1768 float convx;
1769 float convy;
1770 float percent;
1771 /* Max components in a format is 4, so... */
1772 float totals[4];
1773 float area;
1774 int i,j,k,xindex;
1776 const char *temp, *temp0;
1777 const char *temp_index;
1778 int outindex;
1780 int lowx_int, highx_int, lowy_int, highy_int;
1781 float x_percent, y_percent;
1782 float lowx_float, highx_float, lowy_float, highy_float;
1783 float convy_float, convx_float;
1784 int convy_int, convx_int;
1785 int l, m;
1786 const char *left, *right;
1788 if (widthin == widthout*2 && heightin == heightout*2) {
1789 halveImage_ushort(components, widthin, heightin,
1790 (const GLushort *)datain, (GLushort *)dataout,
1791 element_size, ysize, group_size, myswap_bytes);
1792 return;
1794 convy = (float) heightin/heightout;
1795 convx = (float) widthin/widthout;
1796 convy_int = floor(convy);
1797 convy_float = convy - convy_int;
1798 convx_int = floor(convx);
1799 convx_float = convx - convx_int;
1801 area = convx * convy;
1803 lowy_int = 0;
1804 lowy_float = 0;
1805 highy_int = convy_int;
1806 highy_float = convy_float;
1808 for (i = 0; i < heightout; i++) {
1809 /* Clamp here to be sure we don't read beyond input buffer. */
1810 if (highy_int >= heightin)
1811 highy_int = heightin - 1;
1812 lowx_int = 0;
1813 lowx_float = 0;
1814 highx_int = convx_int;
1815 highx_float = convx_float;
1817 for (j = 0; j < widthout; j++) {
1819 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1820 ** to (highx, highy) on input data into this pixel on output
1821 ** data.
1823 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1825 /* calculate the value for pixels in the 1st row */
1826 xindex = lowx_int*group_size;
1827 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1829 y_percent = 1-lowy_float;
1830 temp = (const char *)datain + xindex + lowy_int * ysize;
1831 percent = y_percent * (1-lowx_float);
1832 for (k = 0, temp_index = temp; k < components;
1833 k++, temp_index += element_size) {
1834 if (myswap_bytes) {
1835 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1836 } else {
1837 totals[k] += *(const GLushort*)temp_index * percent;
1840 left = temp;
1841 for(l = lowx_int+1; l < highx_int; l++) {
1842 temp += group_size;
1843 for (k = 0, temp_index = temp; k < components;
1844 k++, temp_index += element_size) {
1845 if (myswap_bytes) {
1846 totals[k] +=
1847 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1848 } else {
1849 totals[k] += *(const GLushort*)temp_index * y_percent;
1853 temp += group_size;
1854 right = temp;
1855 percent = y_percent * highx_float;
1856 for (k = 0, temp_index = temp; k < components;
1857 k++, temp_index += element_size) {
1858 if (myswap_bytes) {
1859 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1860 } else {
1861 totals[k] += *(const GLushort*)temp_index * percent;
1865 /* calculate the value for pixels in the last row */
1866 y_percent = highy_float;
1867 percent = y_percent * (1-lowx_float);
1868 temp = (const char *)datain + xindex + highy_int * ysize;
1869 for (k = 0, temp_index = temp; k < components;
1870 k++, temp_index += element_size) {
1871 if (myswap_bytes) {
1872 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1873 } else {
1874 totals[k] += *(const GLushort*)temp_index * percent;
1877 for(l = lowx_int+1; l < highx_int; l++) {
1878 temp += group_size;
1879 for (k = 0, temp_index = temp; k < components;
1880 k++, temp_index += element_size) {
1881 if (myswap_bytes) {
1882 totals[k] +=
1883 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1884 } else {
1885 totals[k] += *(const GLushort*)temp_index * y_percent;
1889 temp += group_size;
1890 percent = y_percent * highx_float;
1891 for (k = 0, temp_index = temp; k < components;
1892 k++, temp_index += element_size) {
1893 if (myswap_bytes) {
1894 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1895 } else {
1896 totals[k] += *(const GLushort*)temp_index * percent;
1900 /* calculate the value for pixels in the 1st and last column */
1901 for(m = lowy_int+1; m < highy_int; m++) {
1902 left += ysize;
1903 right += ysize;
1904 for (k = 0; k < components;
1905 k++, left += element_size, right += element_size) {
1906 if (myswap_bytes) {
1907 totals[k] +=
1908 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
1909 __GLU_SWAP_2_BYTES(right) * highx_float;
1910 } else {
1911 totals[k] += *(const GLushort*)left * (1-lowx_float)
1912 + *(const GLushort*)right * highx_float;
1916 } else if (highy_int > lowy_int) {
1917 x_percent = highx_float - lowx_float;
1918 percent = (1-lowy_float)*x_percent;
1919 temp = (const char *)datain + xindex + lowy_int*ysize;
1920 for (k = 0, temp_index = temp; k < components;
1921 k++, temp_index += element_size) {
1922 if (myswap_bytes) {
1923 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1924 } else {
1925 totals[k] += *(const GLushort*)temp_index * percent;
1928 for(m = lowy_int+1; m < highy_int; m++) {
1929 temp += ysize;
1930 for (k = 0, temp_index = temp; k < components;
1931 k++, temp_index += element_size) {
1932 if (myswap_bytes) {
1933 totals[k] +=
1934 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
1935 } else {
1936 totals[k] += *(const GLushort*)temp_index * x_percent;
1940 percent = x_percent * highy_float;
1941 temp += ysize;
1942 for (k = 0, temp_index = temp; k < components;
1943 k++, temp_index += element_size) {
1944 if (myswap_bytes) {
1945 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1946 } else {
1947 totals[k] += *(const GLushort*)temp_index * percent;
1950 } else if (highx_int > lowx_int) {
1951 y_percent = highy_float - lowy_float;
1952 percent = (1-lowx_float)*y_percent;
1953 temp = (const char *)datain + xindex + lowy_int*ysize;
1954 for (k = 0, temp_index = temp; k < components;
1955 k++, temp_index += element_size) {
1956 if (myswap_bytes) {
1957 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1958 } else {
1959 totals[k] += *(const GLushort*)temp_index * percent;
1962 for (l = lowx_int+1; l < highx_int; l++) {
1963 temp += group_size;
1964 for (k = 0, temp_index = temp; k < components;
1965 k++, temp_index += element_size) {
1966 if (myswap_bytes) {
1967 totals[k] +=
1968 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1969 } else {
1970 totals[k] += *(const GLushort*)temp_index * y_percent;
1974 temp += group_size;
1975 percent = y_percent * highx_float;
1976 for (k = 0, temp_index = temp; k < components;
1977 k++, temp_index += element_size) {
1978 if (myswap_bytes) {
1979 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1980 } else {
1981 totals[k] += *(const GLushort*)temp_index * percent;
1984 } else {
1985 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1986 temp = (const char *)datain + xindex + lowy_int * ysize;
1987 for (k = 0, temp_index = temp; k < components;
1988 k++, temp_index += element_size) {
1989 if (myswap_bytes) {
1990 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1991 } else {
1992 totals[k] += *(const GLushort*)temp_index * percent;
1997 /* this is for the pixels in the body */
1998 temp0 = (const char *)datain + xindex + group_size +
1999 (lowy_int+1)*ysize;
2000 for (m = lowy_int+1; m < highy_int; m++) {
2001 temp = temp0;
2002 for(l = lowx_int+1; l < highx_int; l++) {
2003 for (k = 0, temp_index = temp; k < components;
2004 k++, temp_index += element_size) {
2005 if (myswap_bytes) {
2006 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
2007 } else {
2008 totals[k] += *(const GLushort*)temp_index;
2011 temp += group_size;
2013 temp0 += ysize;
2016 outindex = (j + (i * widthout)) * components;
2017 for (k = 0; k < components; k++) {
2018 dataout[outindex + k] = totals[k]/area;
2019 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2021 lowx_int = highx_int;
2022 lowx_float = highx_float;
2023 highx_int += convx_int;
2024 highx_float += convx_float;
2025 if(highx_float > 1) {
2026 highx_float -= 1.0;
2027 highx_int++;
2030 lowy_int = highy_int;
2031 lowy_float = highy_float;
2032 highy_int += convy_int;
2033 highy_float += convy_float;
2034 if(highy_float > 1) {
2035 highy_float -= 1.0;
2036 highy_int++;
2041 static void scale_internal_short(GLint components, GLint widthin,
2042 GLint heightin, const GLshort *datain,
2043 GLint widthout, GLint heightout,
2044 GLshort *dataout, GLint element_size,
2045 GLint ysize, GLint group_size,
2046 GLint myswap_bytes)
2048 float convx;
2049 float convy;
2050 float percent;
2051 /* Max components in a format is 4, so... */
2052 float totals[4];
2053 float area;
2054 int i,j,k,xindex;
2056 const char *temp, *temp0;
2057 const char *temp_index;
2058 int outindex;
2060 int lowx_int, highx_int, lowy_int, highy_int;
2061 float x_percent, y_percent;
2062 float lowx_float, highx_float, lowy_float, highy_float;
2063 float convy_float, convx_float;
2064 int convy_int, convx_int;
2065 int l, m;
2066 const char *left, *right;
2068 GLushort swapbuf; /* unsigned buffer */
2070 if (widthin == widthout*2 && heightin == heightout*2) {
2071 halveImage_short(components, widthin, heightin,
2072 (const GLshort *)datain, (GLshort *)dataout,
2073 element_size, ysize, group_size, myswap_bytes);
2074 return;
2076 convy = (float) heightin/heightout;
2077 convx = (float) widthin/widthout;
2078 convy_int = floor(convy);
2079 convy_float = convy - convy_int;
2080 convx_int = floor(convx);
2081 convx_float = convx - convx_int;
2083 area = convx * convy;
2085 lowy_int = 0;
2086 lowy_float = 0;
2087 highy_int = convy_int;
2088 highy_float = convy_float;
2090 for (i = 0; i < heightout; i++) {
2091 /* Clamp here to be sure we don't read beyond input buffer. */
2092 if (highy_int >= heightin)
2093 highy_int = heightin - 1;
2094 lowx_int = 0;
2095 lowx_float = 0;
2096 highx_int = convx_int;
2097 highx_float = convx_float;
2099 for (j = 0; j < widthout; j++) {
2101 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2102 ** to (highx, highy) on input data into this pixel on output
2103 ** data.
2105 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2107 /* calculate the value for pixels in the 1st row */
2108 xindex = lowx_int*group_size;
2109 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2111 y_percent = 1-lowy_float;
2112 temp = (const char *)datain + xindex + lowy_int * ysize;
2113 percent = y_percent * (1-lowx_float);
2114 for (k = 0, temp_index = temp; k < components;
2115 k++, temp_index += element_size) {
2116 if (myswap_bytes) {
2117 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2118 totals[k] += *(const GLshort*)&swapbuf * percent;
2119 } else {
2120 totals[k] += *(const GLshort*)temp_index * percent;
2123 left = temp;
2124 for(l = lowx_int+1; l < highx_int; l++) {
2125 temp += group_size;
2126 for (k = 0, temp_index = temp; k < components;
2127 k++, temp_index += element_size) {
2128 if (myswap_bytes) {
2129 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2130 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2131 } else {
2132 totals[k] += *(const GLshort*)temp_index * y_percent;
2136 temp += group_size;
2137 right = temp;
2138 percent = y_percent * highx_float;
2139 for (k = 0, temp_index = temp; k < components;
2140 k++, temp_index += element_size) {
2141 if (myswap_bytes) {
2142 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2143 totals[k] += *(const GLshort*)&swapbuf * percent;
2144 } else {
2145 totals[k] += *(const GLshort*)temp_index * percent;
2149 /* calculate the value for pixels in the last row */
2150 y_percent = highy_float;
2151 percent = y_percent * (1-lowx_float);
2152 temp = (const char *)datain + xindex + highy_int * ysize;
2153 for (k = 0, temp_index = temp; k < components;
2154 k++, temp_index += element_size) {
2155 if (myswap_bytes) {
2156 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2157 totals[k] += *(const GLshort*)&swapbuf * percent;
2158 } else {
2159 totals[k] += *(const GLshort*)temp_index * percent;
2162 for(l = lowx_int+1; l < highx_int; l++) {
2163 temp += group_size;
2164 for (k = 0, temp_index = temp; k < components;
2165 k++, temp_index += element_size) {
2166 if (myswap_bytes) {
2167 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2168 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2169 } else {
2170 totals[k] += *(const GLshort*)temp_index * y_percent;
2174 temp += group_size;
2175 percent = y_percent * highx_float;
2176 for (k = 0, temp_index = temp; k < components;
2177 k++, temp_index += element_size) {
2178 if (myswap_bytes) {
2179 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2180 totals[k] += *(const GLshort*)&swapbuf * percent;
2181 } else {
2182 totals[k] += *(const GLshort*)temp_index * percent;
2186 /* calculate the value for pixels in the 1st and last column */
2187 for(m = lowy_int+1; m < highy_int; m++) {
2188 left += ysize;
2189 right += ysize;
2190 for (k = 0; k < components;
2191 k++, left += element_size, right += element_size) {
2192 if (myswap_bytes) {
2193 swapbuf = __GLU_SWAP_2_BYTES(left);
2194 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
2195 swapbuf = __GLU_SWAP_2_BYTES(right);
2196 totals[k] += *(const GLshort*)&swapbuf * highx_float;
2197 } else {
2198 totals[k] += *(const GLshort*)left * (1-lowx_float)
2199 + *(const GLshort*)right * highx_float;
2203 } else if (highy_int > lowy_int) {
2204 x_percent = highx_float - lowx_float;
2205 percent = (1-lowy_float)*x_percent;
2206 temp = (const char *)datain + xindex + lowy_int*ysize;
2207 for (k = 0, temp_index = temp; k < components;
2208 k++, temp_index += element_size) {
2209 if (myswap_bytes) {
2210 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2211 totals[k] += *(const GLshort*)&swapbuf * percent;
2212 } else {
2213 totals[k] += *(const GLshort*)temp_index * percent;
2216 for(m = lowy_int+1; m < highy_int; m++) {
2217 temp += ysize;
2218 for (k = 0, temp_index = temp; k < components;
2219 k++, temp_index += element_size) {
2220 if (myswap_bytes) {
2221 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2222 totals[k] += *(const GLshort*)&swapbuf * x_percent;
2223 } else {
2224 totals[k] += *(const GLshort*)temp_index * x_percent;
2228 percent = x_percent * highy_float;
2229 temp += ysize;
2230 for (k = 0, temp_index = temp; k < components;
2231 k++, temp_index += element_size) {
2232 if (myswap_bytes) {
2233 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2234 totals[k] += *(const GLshort*)&swapbuf * percent;
2235 } else {
2236 totals[k] += *(const GLshort*)temp_index * percent;
2239 } else if (highx_int > lowx_int) {
2240 y_percent = highy_float - lowy_float;
2241 percent = (1-lowx_float)*y_percent;
2243 temp = (const char *)datain + xindex + lowy_int*ysize;
2244 for (k = 0, temp_index = temp; k < components;
2245 k++, temp_index += element_size) {
2246 if (myswap_bytes) {
2247 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2248 totals[k] += *(const GLshort*)&swapbuf * percent;
2249 } else {
2250 totals[k] += *(const GLshort*)temp_index * percent;
2253 for (l = lowx_int+1; l < highx_int; l++) {
2254 temp += group_size;
2255 for (k = 0, temp_index = temp; k < components;
2256 k++, temp_index += element_size) {
2257 if (myswap_bytes) {
2258 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2259 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2260 } else {
2261 totals[k] += *(const GLshort*)temp_index * y_percent;
2265 temp += group_size;
2266 percent = y_percent * highx_float;
2267 for (k = 0, temp_index = temp; k < components;
2268 k++, temp_index += element_size) {
2269 if (myswap_bytes) {
2270 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2271 totals[k] += *(const GLshort*)&swapbuf * percent;
2272 } else {
2273 totals[k] += *(const GLshort*)temp_index * percent;
2276 } else {
2277 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2278 temp = (const char *)datain + xindex + lowy_int * ysize;
2279 for (k = 0, temp_index = temp; k < components;
2280 k++, temp_index += element_size) {
2281 if (myswap_bytes) {
2282 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2283 totals[k] += *(const GLshort*)&swapbuf * percent;
2284 } else {
2285 totals[k] += *(const GLshort*)temp_index * percent;
2290 /* this is for the pixels in the body */
2291 temp0 = (const char *)datain + xindex + group_size +
2292 (lowy_int+1)*ysize;
2293 for (m = lowy_int+1; m < highy_int; m++) {
2294 temp = temp0;
2295 for(l = lowx_int+1; l < highx_int; l++) {
2296 for (k = 0, temp_index = temp; k < components;
2297 k++, temp_index += element_size) {
2298 if (myswap_bytes) {
2299 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2300 totals[k] += *(const GLshort*)&swapbuf;
2301 } else {
2302 totals[k] += *(const GLshort*)temp_index;
2305 temp += group_size;
2307 temp0 += ysize;
2310 outindex = (j + (i * widthout)) * components;
2311 for (k = 0; k < components; k++) {
2312 dataout[outindex + k] = totals[k]/area;
2313 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2315 lowx_int = highx_int;
2316 lowx_float = highx_float;
2317 highx_int += convx_int;
2318 highx_float += convx_float;
2319 if(highx_float > 1) {
2320 highx_float -= 1.0;
2321 highx_int++;
2324 lowy_int = highy_int;
2325 lowy_float = highy_float;
2326 highy_int += convy_int;
2327 highy_float += convy_float;
2328 if(highy_float > 1) {
2329 highy_float -= 1.0;
2330 highy_int++;
2335 static void scale_internal_uint(GLint components, GLint widthin,
2336 GLint heightin, const GLuint *datain,
2337 GLint widthout, GLint heightout,
2338 GLuint *dataout, GLint element_size,
2339 GLint ysize, GLint group_size,
2340 GLint myswap_bytes)
2342 float convx;
2343 float convy;
2344 float percent;
2345 /* Max components in a format is 4, so... */
2346 float totals[4];
2347 float area;
2348 int i,j,k,xindex;
2350 const char *temp, *temp0;
2351 const char *temp_index;
2352 int outindex;
2354 int lowx_int, highx_int, lowy_int, highy_int;
2355 float x_percent, y_percent;
2356 float lowx_float, highx_float, lowy_float, highy_float;
2357 float convy_float, convx_float;
2358 int convy_int, convx_int;
2359 int l, m;
2360 const char *left, *right;
2362 if (widthin == widthout*2 && heightin == heightout*2) {
2363 halveImage_uint(components, widthin, heightin,
2364 (const GLuint *)datain, (GLuint *)dataout,
2365 element_size, ysize, group_size, myswap_bytes);
2366 return;
2368 convy = (float) heightin/heightout;
2369 convx = (float) widthin/widthout;
2370 convy_int = floor(convy);
2371 convy_float = convy - convy_int;
2372 convx_int = floor(convx);
2373 convx_float = convx - convx_int;
2375 area = convx * convy;
2377 lowy_int = 0;
2378 lowy_float = 0;
2379 highy_int = convy_int;
2380 highy_float = convy_float;
2382 for (i = 0; i < heightout; i++) {
2383 /* Clamp here to be sure we don't read beyond input buffer. */
2384 if (highy_int >= heightin)
2385 highy_int = heightin - 1;
2386 lowx_int = 0;
2387 lowx_float = 0;
2388 highx_int = convx_int;
2389 highx_float = convx_float;
2391 for (j = 0; j < widthout; j++) {
2393 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2394 ** to (highx, highy) on input data into this pixel on output
2395 ** data.
2397 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2399 /* calculate the value for pixels in the 1st row */
2400 xindex = lowx_int*group_size;
2401 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2403 y_percent = 1-lowy_float;
2404 temp = (const char *)datain + xindex + lowy_int * ysize;
2405 percent = y_percent * (1-lowx_float);
2406 for (k = 0, temp_index = temp; k < components;
2407 k++, temp_index += element_size) {
2408 if (myswap_bytes) {
2409 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2410 } else {
2411 totals[k] += *(const GLuint*)temp_index * percent;
2414 left = temp;
2415 for(l = lowx_int+1; l < highx_int; l++) {
2416 temp += group_size;
2417 for (k = 0, temp_index = temp; k < components;
2418 k++, temp_index += element_size) {
2419 if (myswap_bytes) {
2420 totals[k] +=
2421 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2422 } else {
2423 totals[k] += *(const GLuint*)temp_index * y_percent;
2427 temp += group_size;
2428 right = temp;
2429 percent = y_percent * highx_float;
2430 for (k = 0, temp_index = temp; k < components;
2431 k++, temp_index += element_size) {
2432 if (myswap_bytes) {
2433 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2434 } else {
2435 totals[k] += *(const GLuint*)temp_index * percent;
2439 /* calculate the value for pixels in the last row */
2440 y_percent = highy_float;
2441 percent = y_percent * (1-lowx_float);
2442 temp = (const char *)datain + xindex + highy_int * ysize;
2443 for (k = 0, temp_index = temp; k < components;
2444 k++, temp_index += element_size) {
2445 if (myswap_bytes) {
2446 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2447 } else {
2448 totals[k] += *(const GLuint*)temp_index * percent;
2451 for(l = lowx_int+1; l < highx_int; l++) {
2452 temp += group_size;
2453 for (k = 0, temp_index = temp; k < components;
2454 k++, temp_index += element_size) {
2455 if (myswap_bytes) {
2456 totals[k] +=
2457 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2458 } else {
2459 totals[k] += *(const GLuint*)temp_index * y_percent;
2463 temp += group_size;
2464 percent = y_percent * highx_float;
2465 for (k = 0, temp_index = temp; k < components;
2466 k++, temp_index += element_size) {
2467 if (myswap_bytes) {
2468 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2469 } else {
2470 totals[k] += *(const GLuint*)temp_index * percent;
2474 /* calculate the value for pixels in the 1st and last column */
2475 for(m = lowy_int+1; m < highy_int; m++) {
2476 left += ysize;
2477 right += ysize;
2478 for (k = 0; k < components;
2479 k++, left += element_size, right += element_size) {
2480 if (myswap_bytes) {
2481 totals[k] +=
2482 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
2483 + __GLU_SWAP_4_BYTES(right) * highx_float;
2484 } else {
2485 totals[k] += *(const GLuint*)left * (1-lowx_float)
2486 + *(const GLuint*)right * highx_float;
2490 } else if (highy_int > lowy_int) {
2491 x_percent = highx_float - lowx_float;
2492 percent = (1-lowy_float)*x_percent;
2493 temp = (const char *)datain + xindex + lowy_int*ysize;
2494 for (k = 0, temp_index = temp; k < components;
2495 k++, temp_index += element_size) {
2496 if (myswap_bytes) {
2497 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2498 } else {
2499 totals[k] += *(const GLuint*)temp_index * percent;
2502 for(m = lowy_int+1; m < highy_int; m++) {
2503 temp += ysize;
2504 for (k = 0, temp_index = temp; k < components;
2505 k++, temp_index += element_size) {
2506 if (myswap_bytes) {
2507 totals[k] +=
2508 __GLU_SWAP_4_BYTES(temp_index) * x_percent;
2509 } else {
2510 totals[k] += *(const GLuint*)temp_index * x_percent;
2514 percent = x_percent * highy_float;
2515 temp += ysize;
2516 for (k = 0, temp_index = temp; k < components;
2517 k++, temp_index += element_size) {
2518 if (myswap_bytes) {
2519 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2520 } else {
2521 totals[k] += *(const GLuint*)temp_index * percent;
2524 } else if (highx_int > lowx_int) {
2525 y_percent = highy_float - lowy_float;
2526 percent = (1-lowx_float)*y_percent;
2528 temp = (const char *)datain + xindex + lowy_int*ysize;
2529 for (k = 0, temp_index = temp; k < components;
2530 k++, temp_index += element_size) {
2531 if (myswap_bytes) {
2532 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2533 } else {
2534 totals[k] += *(const GLuint*)temp_index * percent;
2537 for (l = lowx_int+1; l < highx_int; l++) {
2538 temp += group_size;
2539 for (k = 0, temp_index = temp; k < components;
2540 k++, temp_index += element_size) {
2541 if (myswap_bytes) {
2542 totals[k] +=
2543 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2544 } else {
2545 totals[k] += *(const GLuint*)temp_index * y_percent;
2549 temp += group_size;
2550 percent = y_percent * highx_float;
2551 for (k = 0, temp_index = temp; k < components;
2552 k++, temp_index += element_size) {
2553 if (myswap_bytes) {
2554 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2555 } else {
2556 totals[k] += *(const GLuint*)temp_index * percent;
2559 } else {
2560 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2561 temp = (const char *)datain + xindex + lowy_int * ysize;
2562 for (k = 0, temp_index = temp; k < components;
2563 k++, temp_index += element_size) {
2564 if (myswap_bytes) {
2565 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2566 } else {
2567 totals[k] += *(const GLuint*)temp_index * percent;
2572 /* this is for the pixels in the body */
2573 temp0 = (const char *)datain + xindex + group_size +
2574 (lowy_int+1)*ysize;
2575 for (m = lowy_int+1; m < highy_int; m++) {
2576 temp = temp0;
2577 for(l = lowx_int+1; l < highx_int; l++) {
2578 for (k = 0, temp_index = temp; k < components;
2579 k++, temp_index += element_size) {
2580 if (myswap_bytes) {
2581 totals[k] += __GLU_SWAP_4_BYTES(temp_index);
2582 } else {
2583 totals[k] += *(const GLuint*)temp_index;
2586 temp += group_size;
2588 temp0 += ysize;
2591 outindex = (j + (i * widthout)) * components;
2592 for (k = 0; k < components; k++) {
2593 /* clamp at UINT_MAX */
2594 float value= totals[k]/area;
2595 if (value >= (float) UINT_MAX) { /* need '=' */
2596 dataout[outindex + k] = UINT_MAX;
2598 else dataout[outindex + k] = value;
2600 lowx_int = highx_int;
2601 lowx_float = highx_float;
2602 highx_int += convx_int;
2603 highx_float += convx_float;
2604 if(highx_float > 1) {
2605 highx_float -= 1.0;
2606 highx_int++;
2609 lowy_int = highy_int;
2610 lowy_float = highy_float;
2611 highy_int += convy_int;
2612 highy_float += convy_float;
2613 if(highy_float > 1) {
2614 highy_float -= 1.0;
2615 highy_int++;
2622 static void scale_internal_int(GLint components, GLint widthin,
2623 GLint heightin, const GLint *datain,
2624 GLint widthout, GLint heightout,
2625 GLint *dataout, GLint element_size,
2626 GLint ysize, GLint group_size,
2627 GLint myswap_bytes)
2629 float convx;
2630 float convy;
2631 float percent;
2632 /* Max components in a format is 4, so... */
2633 float totals[4];
2634 float area;
2635 int i,j,k,xindex;
2637 const char *temp, *temp0;
2638 const char *temp_index;
2639 int outindex;
2641 int lowx_int, highx_int, lowy_int, highy_int;
2642 float x_percent, y_percent;
2643 float lowx_float, highx_float, lowy_float, highy_float;
2644 float convy_float, convx_float;
2645 int convy_int, convx_int;
2646 int l, m;
2647 const char *left, *right;
2649 GLuint swapbuf; /* unsigned buffer */
2651 if (widthin == widthout*2 && heightin == heightout*2) {
2652 halveImage_int(components, widthin, heightin,
2653 (const GLint *)datain, (GLint *)dataout,
2654 element_size, ysize, group_size, myswap_bytes);
2655 return;
2657 convy = (float) heightin/heightout;
2658 convx = (float) widthin/widthout;
2659 convy_int = floor(convy);
2660 convy_float = convy - convy_int;
2661 convx_int = floor(convx);
2662 convx_float = convx - convx_int;
2664 area = convx * convy;
2666 lowy_int = 0;
2667 lowy_float = 0;
2668 highy_int = convy_int;
2669 highy_float = convy_float;
2671 for (i = 0; i < heightout; i++) {
2672 /* Clamp here to be sure we don't read beyond input buffer. */
2673 if (highy_int >= heightin)
2674 highy_int = heightin - 1;
2675 lowx_int = 0;
2676 lowx_float = 0;
2677 highx_int = convx_int;
2678 highx_float = convx_float;
2680 for (j = 0; j < widthout; j++) {
2682 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2683 ** to (highx, highy) on input data into this pixel on output
2684 ** data.
2686 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2688 /* calculate the value for pixels in the 1st row */
2689 xindex = lowx_int*group_size;
2690 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2692 y_percent = 1-lowy_float;
2693 temp = (const char *)datain + xindex + lowy_int * ysize;
2694 percent = y_percent * (1-lowx_float);
2695 for (k = 0, temp_index = temp; k < components;
2696 k++, temp_index += element_size) {
2697 if (myswap_bytes) {
2698 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2699 totals[k] += *(const GLint*)&swapbuf * percent;
2700 } else {
2701 totals[k] += *(const GLint*)temp_index * percent;
2704 left = temp;
2705 for(l = lowx_int+1; l < highx_int; l++) {
2706 temp += group_size;
2707 for (k = 0, temp_index = temp; k < components;
2708 k++, temp_index += element_size) {
2709 if (myswap_bytes) {
2710 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2711 totals[k] += *(const GLint*)&swapbuf * y_percent;
2712 } else {
2713 totals[k] += *(const GLint*)temp_index * y_percent;
2717 temp += group_size;
2718 right = temp;
2719 percent = y_percent * highx_float;
2720 for (k = 0, temp_index = temp; k < components;
2721 k++, temp_index += element_size) {
2722 if (myswap_bytes) {
2723 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2724 totals[k] += *(const GLint*)&swapbuf * percent;
2725 } else {
2726 totals[k] += *(const GLint*)temp_index * percent;
2730 /* calculate the value for pixels in the last row */
2731 y_percent = highy_float;
2732 percent = y_percent * (1-lowx_float);
2733 temp = (const char *)datain + xindex + highy_int * ysize;
2734 for (k = 0, temp_index = temp; k < components;
2735 k++, temp_index += element_size) {
2736 if (myswap_bytes) {
2737 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2738 totals[k] += *(const GLint*)&swapbuf * percent;
2739 } else {
2740 totals[k] += *(const GLint*)temp_index * percent;
2743 for(l = lowx_int+1; l < highx_int; l++) {
2744 temp += group_size;
2745 for (k = 0, temp_index = temp; k < components;
2746 k++, temp_index += element_size) {
2747 if (myswap_bytes) {
2748 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2749 totals[k] += *(const GLint*)&swapbuf * y_percent;
2750 } else {
2751 totals[k] += *(const GLint*)temp_index * y_percent;
2755 temp += group_size;
2756 percent = y_percent * highx_float;
2757 for (k = 0, temp_index = temp; k < components;
2758 k++, temp_index += element_size) {
2759 if (myswap_bytes) {
2760 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2761 totals[k] += *(const GLint*)&swapbuf * percent;
2762 } else {
2763 totals[k] += *(const GLint*)temp_index * percent;
2767 /* calculate the value for pixels in the 1st and last column */
2768 for(m = lowy_int+1; m < highy_int; m++) {
2769 left += ysize;
2770 right += ysize;
2771 for (k = 0; k < components;
2772 k++, left += element_size, right += element_size) {
2773 if (myswap_bytes) {
2774 swapbuf = __GLU_SWAP_4_BYTES(left);
2775 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
2776 swapbuf = __GLU_SWAP_4_BYTES(right);
2777 totals[k] += *(const GLint*)&swapbuf * highx_float;
2778 } else {
2779 totals[k] += *(const GLint*)left * (1-lowx_float)
2780 + *(const GLint*)right * highx_float;
2784 } else if (highy_int > lowy_int) {
2785 x_percent = highx_float - lowx_float;
2786 percent = (1-lowy_float)*x_percent;
2787 temp = (const char *)datain + xindex + lowy_int*ysize;
2788 for (k = 0, temp_index = temp; k < components;
2789 k++, temp_index += element_size) {
2790 if (myswap_bytes) {
2791 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2792 totals[k] += *(const GLint*)&swapbuf * percent;
2793 } else {
2794 totals[k] += *(const GLint*)temp_index * percent;
2797 for(m = lowy_int+1; m < highy_int; m++) {
2798 temp += ysize;
2799 for (k = 0, temp_index = temp; k < components;
2800 k++, temp_index += element_size) {
2801 if (myswap_bytes) {
2802 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2803 totals[k] += *(const GLint*)&swapbuf * x_percent;
2804 } else {
2805 totals[k] += *(const GLint*)temp_index * x_percent;
2809 percent = x_percent * highy_float;
2810 temp += ysize;
2811 for (k = 0, temp_index = temp; k < components;
2812 k++, temp_index += element_size) {
2813 if (myswap_bytes) {
2814 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2815 totals[k] += *(const GLint*)&swapbuf * percent;
2816 } else {
2817 totals[k] += *(const GLint*)temp_index * percent;
2820 } else if (highx_int > lowx_int) {
2821 y_percent = highy_float - lowy_float;
2822 percent = (1-lowx_float)*y_percent;
2824 temp = (const char *)datain + xindex + lowy_int*ysize;
2825 for (k = 0, temp_index = temp; k < components;
2826 k++, temp_index += element_size) {
2827 if (myswap_bytes) {
2828 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2829 totals[k] += *(const GLint*)&swapbuf * percent;
2830 } else {
2831 totals[k] += *(const GLint*)temp_index * percent;
2834 for (l = lowx_int+1; l < highx_int; l++) {
2835 temp += group_size;
2836 for (k = 0, temp_index = temp; k < components;
2837 k++, temp_index += element_size) {
2838 if (myswap_bytes) {
2839 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2840 totals[k] += *(const GLint*)&swapbuf * y_percent;
2841 } else {
2842 totals[k] += *(const GLint*)temp_index * y_percent;
2846 temp += group_size;
2847 percent = y_percent * highx_float;
2848 for (k = 0, temp_index = temp; k < components;
2849 k++, temp_index += element_size) {
2850 if (myswap_bytes) {
2851 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2852 totals[k] += *(const GLint*)&swapbuf * percent;
2853 } else {
2854 totals[k] += *(const GLint*)temp_index * percent;
2857 } else {
2858 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2859 temp = (const char *)datain + xindex + lowy_int * ysize;
2860 for (k = 0, temp_index = temp; k < components;
2861 k++, temp_index += element_size) {
2862 if (myswap_bytes) {
2863 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2864 totals[k] += *(const GLint*)&swapbuf * percent;
2865 } else {
2866 totals[k] += *(const GLint*)temp_index * percent;
2871 /* this is for the pixels in the body */
2872 temp0 = (const char *)datain + xindex + group_size +
2873 (lowy_int+1)*ysize;
2874 for (m = lowy_int+1; m < highy_int; m++) {
2875 temp = temp0;
2876 for(l = lowx_int+1; l < highx_int; l++) {
2877 for (k = 0, temp_index = temp; k < components;
2878 k++, temp_index += element_size) {
2879 if (myswap_bytes) {
2880 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2881 totals[k] += *(const GLint*)&swapbuf;
2882 } else {
2883 totals[k] += *(const GLint*)temp_index;
2886 temp += group_size;
2888 temp0 += ysize;
2891 outindex = (j + (i * widthout)) * components;
2892 for (k = 0; k < components; k++) {
2893 dataout[outindex + k] = totals[k]/area;
2894 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2896 lowx_int = highx_int;
2897 lowx_float = highx_float;
2898 highx_int += convx_int;
2899 highx_float += convx_float;
2900 if(highx_float > 1) {
2901 highx_float -= 1.0;
2902 highx_int++;
2905 lowy_int = highy_int;
2906 lowy_float = highy_float;
2907 highy_int += convy_int;
2908 highy_float += convy_float;
2909 if(highy_float > 1) {
2910 highy_float -= 1.0;
2911 highy_int++;
2918 static void scale_internal_float(GLint components, GLint widthin,
2919 GLint heightin, const GLfloat *datain,
2920 GLint widthout, GLint heightout,
2921 GLfloat *dataout, GLint element_size,
2922 GLint ysize, GLint group_size,
2923 GLint myswap_bytes)
2925 float convx;
2926 float convy;
2927 float percent;
2928 /* Max components in a format is 4, so... */
2929 float totals[4];
2930 float area;
2931 int i,j,k,xindex;
2933 const char *temp, *temp0;
2934 const char *temp_index;
2935 int outindex;
2937 int lowx_int, highx_int, lowy_int, highy_int;
2938 float x_percent, y_percent;
2939 float lowx_float, highx_float, lowy_float, highy_float;
2940 float convy_float, convx_float;
2941 int convy_int, convx_int;
2942 int l, m;
2943 const char *left, *right;
2945 union { GLuint b; GLfloat f; } swapbuf;
2947 if (widthin == widthout*2 && heightin == heightout*2) {
2948 halveImage_float(components, widthin, heightin,
2949 (const GLfloat *)datain, (GLfloat *)dataout,
2950 element_size, ysize, group_size, myswap_bytes);
2951 return;
2953 convy = (float) heightin/heightout;
2954 convx = (float) widthin/widthout;
2955 convy_int = floor(convy);
2956 convy_float = convy - convy_int;
2957 convx_int = floor(convx);
2958 convx_float = convx - convx_int;
2960 area = convx * convy;
2962 lowy_int = 0;
2963 lowy_float = 0;
2964 highy_int = convy_int;
2965 highy_float = convy_float;
2967 for (i = 0; i < heightout; i++) {
2968 /* Clamp here to be sure we don't read beyond input buffer. */
2969 if (highy_int >= heightin)
2970 highy_int = heightin - 1;
2971 lowx_int = 0;
2972 lowx_float = 0;
2973 highx_int = convx_int;
2974 highx_float = convx_float;
2976 for (j = 0; j < widthout; j++) {
2978 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2979 ** to (highx, highy) on input data into this pixel on output
2980 ** data.
2982 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2984 /* calculate the value for pixels in the 1st row */
2985 xindex = lowx_int*group_size;
2986 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2988 y_percent = 1-lowy_float;
2989 temp = (const char *)datain + xindex + lowy_int * ysize;
2990 percent = y_percent * (1-lowx_float);
2991 for (k = 0, temp_index = temp; k < components;
2992 k++, temp_index += element_size) {
2993 if (myswap_bytes) {
2994 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
2995 totals[k] += swapbuf.f * percent;
2996 } else {
2997 totals[k] += *(const GLfloat*)temp_index * percent;
3000 left = temp;
3001 for(l = lowx_int+1; l < highx_int; l++) {
3002 temp += group_size;
3003 for (k = 0, temp_index = temp; k < components;
3004 k++, temp_index += element_size) {
3005 if (myswap_bytes) {
3006 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3007 totals[k] += swapbuf.f * y_percent;
3008 } else {
3009 totals[k] += *(const GLfloat*)temp_index * y_percent;
3013 temp += group_size;
3014 right = temp;
3015 percent = y_percent * highx_float;
3016 for (k = 0, temp_index = temp; k < components;
3017 k++, temp_index += element_size) {
3018 if (myswap_bytes) {
3019 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3020 totals[k] += swapbuf.f * percent;
3021 } else {
3022 totals[k] += *(const GLfloat*)temp_index * percent;
3026 /* calculate the value for pixels in the last row */
3027 y_percent = highy_float;
3028 percent = y_percent * (1-lowx_float);
3029 temp = (const char *)datain + xindex + highy_int * ysize;
3030 for (k = 0, temp_index = temp; k < components;
3031 k++, temp_index += element_size) {
3032 if (myswap_bytes) {
3033 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3034 totals[k] += swapbuf.f * percent;
3035 } else {
3036 totals[k] += *(const GLfloat*)temp_index * percent;
3039 for(l = lowx_int+1; l < highx_int; l++) {
3040 temp += group_size;
3041 for (k = 0, temp_index = temp; k < components;
3042 k++, temp_index += element_size) {
3043 if (myswap_bytes) {
3044 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3045 totals[k] += swapbuf.f * y_percent;
3046 } else {
3047 totals[k] += *(const GLfloat*)temp_index * y_percent;
3051 temp += group_size;
3052 percent = y_percent * highx_float;
3053 for (k = 0, temp_index = temp; k < components;
3054 k++, temp_index += element_size) {
3055 if (myswap_bytes) {
3056 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3057 totals[k] += swapbuf.f * percent;
3058 } else {
3059 totals[k] += *(const GLfloat*)temp_index * percent;
3063 /* calculate the value for pixels in the 1st and last column */
3064 for(m = lowy_int+1; m < highy_int; m++) {
3065 left += ysize;
3066 right += ysize;
3067 for (k = 0; k < components;
3068 k++, left += element_size, right += element_size) {
3069 if (myswap_bytes) {
3070 swapbuf.b = __GLU_SWAP_4_BYTES(left);
3071 totals[k] += swapbuf.f * (1-lowx_float);
3072 swapbuf.b = __GLU_SWAP_4_BYTES(right);
3073 totals[k] += swapbuf.f * highx_float;
3074 } else {
3075 totals[k] += *(const GLfloat*)left * (1-lowx_float)
3076 + *(const GLfloat*)right * highx_float;
3080 } else if (highy_int > lowy_int) {
3081 x_percent = highx_float - lowx_float;
3082 percent = (1-lowy_float)*x_percent;
3083 temp = (const char *)datain + xindex + lowy_int*ysize;
3084 for (k = 0, temp_index = temp; k < components;
3085 k++, temp_index += element_size) {
3086 if (myswap_bytes) {
3087 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3088 totals[k] += swapbuf.f * percent;
3089 } else {
3090 totals[k] += *(const GLfloat*)temp_index * percent;
3093 for(m = lowy_int+1; m < highy_int; m++) {
3094 temp += ysize;
3095 for (k = 0, temp_index = temp; k < components;
3096 k++, temp_index += element_size) {
3097 if (myswap_bytes) {
3098 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3099 totals[k] += swapbuf.f * x_percent;
3100 } else {
3101 totals[k] += *(const GLfloat*)temp_index * x_percent;
3105 percent = x_percent * highy_float;
3106 temp += ysize;
3107 for (k = 0, temp_index = temp; k < components;
3108 k++, temp_index += element_size) {
3109 if (myswap_bytes) {
3110 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3111 totals[k] += swapbuf.f * percent;
3112 } else {
3113 totals[k] += *(const GLfloat*)temp_index * percent;
3116 } else if (highx_int > lowx_int) {
3117 y_percent = highy_float - lowy_float;
3118 percent = (1-lowx_float)*y_percent;
3120 temp = (const char *)datain + xindex + lowy_int*ysize;
3121 for (k = 0, temp_index = temp; k < components;
3122 k++, temp_index += element_size) {
3123 if (myswap_bytes) {
3124 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3125 totals[k] += swapbuf.f * percent;
3126 } else {
3127 totals[k] += *(const GLfloat*)temp_index * percent;
3130 for (l = lowx_int+1; l < highx_int; l++) {
3131 temp += group_size;
3132 for (k = 0, temp_index = temp; k < components;
3133 k++, temp_index += element_size) {
3134 if (myswap_bytes) {
3135 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3136 totals[k] += swapbuf.f * y_percent;
3137 } else {
3138 totals[k] += *(const GLfloat*)temp_index * y_percent;
3142 temp += group_size;
3143 percent = y_percent * highx_float;
3144 for (k = 0, temp_index = temp; k < components;
3145 k++, temp_index += element_size) {
3146 if (myswap_bytes) {
3147 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3148 totals[k] += swapbuf.f * percent;
3149 } else {
3150 totals[k] += *(const GLfloat*)temp_index * percent;
3153 } else {
3154 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
3155 temp = (const char *)datain + xindex + lowy_int * ysize;
3156 for (k = 0, temp_index = temp; k < components;
3157 k++, temp_index += element_size) {
3158 if (myswap_bytes) {
3159 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3160 totals[k] += swapbuf.f * percent;
3161 } else {
3162 totals[k] += *(const GLfloat*)temp_index * percent;
3167 /* this is for the pixels in the body */
3168 temp0 = (const char *)datain + xindex + group_size +
3169 (lowy_int+1)*ysize;
3170 for (m = lowy_int+1; m < highy_int; m++) {
3171 temp = temp0;
3172 for(l = lowx_int+1; l < highx_int; l++) {
3173 for (k = 0, temp_index = temp; k < components;
3174 k++, temp_index += element_size) {
3175 if (myswap_bytes) {
3176 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3177 totals[k] += swapbuf.f;
3178 } else {
3179 totals[k] += *(const GLfloat*)temp_index;
3182 temp += group_size;
3184 temp0 += ysize;
3187 outindex = (j + (i * widthout)) * components;
3188 for (k = 0; k < components; k++) {
3189 dataout[outindex + k] = totals[k]/area;
3190 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3192 lowx_int = highx_int;
3193 lowx_float = highx_float;
3194 highx_int += convx_int;
3195 highx_float += convx_float;
3196 if(highx_float > 1) {
3197 highx_float -= 1.0;
3198 highx_int++;
3201 lowy_int = highy_int;
3202 lowy_float = highy_float;
3203 highy_int += convy_int;
3204 highy_float += convy_float;
3205 if(highy_float > 1) {
3206 highy_float -= 1.0;
3207 highy_int++;
3212 static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
3214 if (!legalFormat(format) || !legalType(type)) {
3215 return GLU_INVALID_ENUM;
3217 if (format == GL_STENCIL_INDEX) {
3218 return GLU_INVALID_ENUM;
3221 if (!isLegalFormatForPackedPixelType(format, type)) {
3222 return GLU_INVALID_OPERATION;
3225 return 0;
3226 } /* checkMipmapArgs() */
3228 static GLboolean legalFormat(GLenum format)
3230 switch(format) {
3231 case GL_COLOR_INDEX:
3232 case GL_STENCIL_INDEX:
3233 case GL_DEPTH_COMPONENT:
3234 case GL_RED:
3235 case GL_GREEN:
3236 case GL_BLUE:
3237 case GL_ALPHA:
3238 case GL_RGB:
3239 case GL_RGBA:
3240 case GL_LUMINANCE:
3241 case GL_LUMINANCE_ALPHA:
3242 case GL_BGR:
3243 case GL_BGRA:
3244 return GL_TRUE;
3245 default:
3246 return GL_FALSE;
3251 static GLboolean legalType(GLenum type)
3253 switch(type) {
3254 case GL_BITMAP:
3255 case GL_BYTE:
3256 case GL_UNSIGNED_BYTE:
3257 case GL_SHORT:
3258 case GL_UNSIGNED_SHORT:
3259 case GL_INT:
3260 case GL_UNSIGNED_INT:
3261 case GL_FLOAT:
3262 case GL_UNSIGNED_BYTE_3_3_2:
3263 case GL_UNSIGNED_BYTE_2_3_3_REV:
3264 case GL_UNSIGNED_SHORT_5_6_5:
3265 case GL_UNSIGNED_SHORT_5_6_5_REV:
3266 case GL_UNSIGNED_SHORT_4_4_4_4:
3267 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3268 case GL_UNSIGNED_SHORT_5_5_5_1:
3269 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3270 case GL_UNSIGNED_INT_8_8_8_8:
3271 case GL_UNSIGNED_INT_8_8_8_8_REV:
3272 case GL_UNSIGNED_INT_10_10_10_2:
3273 case GL_UNSIGNED_INT_2_10_10_10_REV:
3274 return GL_TRUE;
3275 default:
3276 return GL_FALSE;
3280 /* */
3281 static GLboolean isTypePackedPixel(GLenum type)
3283 assert(legalType(type));
3285 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
3286 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
3287 type == GL_UNSIGNED_SHORT_5_6_5 ||
3288 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
3289 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3290 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3291 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3292 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3293 type == GL_UNSIGNED_INT_8_8_8_8 ||
3294 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3295 type == GL_UNSIGNED_INT_10_10_10_2 ||
3296 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
3297 return 1;
3299 else return 0;
3300 } /* isTypePackedPixel() */
3302 /* Determines if the packed pixel type is compatible with the format */
3303 static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
3305 /* if not a packed pixel type then return true */
3306 if (!isTypePackedPixel(type)) {
3307 return GL_TRUE;
3310 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3311 if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
3312 type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
3313 && format != GL_RGB)
3314 return GL_FALSE;
3316 /* 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 &
3317 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3319 if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3320 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3321 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3322 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3323 type == GL_UNSIGNED_INT_8_8_8_8 ||
3324 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3325 type == GL_UNSIGNED_INT_10_10_10_2 ||
3326 type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
3327 (format != GL_RGBA &&
3328 format != GL_BGRA)) {
3329 return GL_FALSE;
3332 return GL_TRUE;
3333 } /* isLegalFormatForPackedPixelType() */
3335 /* Given user requested texture size, determine if it fits. If it
3336 * doesn't then halve both sides and make the determination again
3337 * until it does fit (for IR only).
3338 * Note that proxy textures are not implemented in RE* even though
3339 * they advertise the texture extension.
3340 * Note that proxy textures are implemented but not according to spec in
3341 * IMPACT*.
3343 static void closestFit(GLenum target, GLint width, GLint height,
3344 GLint internalFormat, GLenum format, GLenum type,
3345 GLint *newWidth, GLint *newHeight)
3347 /* Use proxy textures if OpenGL version is >= 1.1 */
3348 if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
3350 GLint widthPowerOf2= nearestPower(width);
3351 GLint heightPowerOf2= nearestPower(height);
3352 GLint proxyWidth;
3354 do {
3355 /* compute level 1 width & height, clamping each at 1 */
3356 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
3357 widthPowerOf2 >> 1 :
3358 widthPowerOf2;
3359 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
3360 heightPowerOf2 >> 1 :
3361 heightPowerOf2;
3362 GLenum proxyTarget;
3363 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
3365 /* does width x height at level 1 & all their mipmaps fit? */
3366 if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
3367 proxyTarget = GL_PROXY_TEXTURE_2D;
3368 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3369 internalFormat,
3370 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3371 } else
3372 if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
3373 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
3374 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
3375 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
3376 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
3377 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
3378 proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3379 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3380 internalFormat,
3381 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3382 } else
3384 assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
3385 proxyTarget = GL_PROXY_TEXTURE_1D;
3386 glTexImage1D(proxyTarget, 1, /* must be non-zero */
3387 internalFormat,widthAtLevelOne,0,format,type,NULL);
3389 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
3390 /* does it fit??? */
3391 if (proxyWidth == 0) { /* nope, so try again with these sizes */
3392 if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
3393 /* An 1x1 texture couldn't fit for some reason, so
3394 * break out. This should never happen. But things
3395 * happen. The disadvantage with this if-statement is
3396 * that we will never be aware of when this happens
3397 * since it will silently branch out.
3399 goto noProxyTextures;
3401 widthPowerOf2= widthAtLevelOne;
3402 heightPowerOf2= heightAtLevelOne;
3404 /* else it does fit */
3405 } while (proxyWidth == 0);
3406 /* loop must terminate! */
3408 /* return the width & height at level 0 that fits */
3409 *newWidth= widthPowerOf2;
3410 *newHeight= heightPowerOf2;
3411 /*printf("Proxy Textures\n");*/
3412 } /* if gluCheckExtension() */
3413 else { /* no texture extension, so do this instead */
3414 GLint maxsize;
3416 noProxyTextures:
3418 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3419 /* clamp user's texture sizes to maximum sizes, if necessary */
3420 *newWidth = nearestPower(width);
3421 if (*newWidth > maxsize) *newWidth = maxsize;
3422 *newHeight = nearestPower(height);
3423 if (*newHeight > maxsize) *newHeight = maxsize;
3424 /*printf("NO proxy textures\n");*/
3426 } /* closestFit() */
3429 /***********************************************************************
3430 * gluScaleImage (GLU32.@)
3432 GLint WINAPI gluScaleImage( GLenum format, GLint widthin, GLint heightin, GLenum typein, const void *datain,
3433 GLint widthout, GLint heightout, GLenum typeout, void *dataout )
3435 int components;
3436 GLushort *beforeImage;
3437 GLushort *afterImage;
3438 PixelStorageModes psm;
3440 if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
3441 return 0;
3443 if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
3444 return GLU_INVALID_VALUE;
3446 if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
3447 return GLU_INVALID_ENUM;
3449 if (!isLegalFormatForPackedPixelType(format, typein)) {
3450 return GLU_INVALID_OPERATION;
3452 if (!isLegalFormatForPackedPixelType(format, typeout)) {
3453 return GLU_INVALID_OPERATION;
3455 beforeImage =
3456 HeapAlloc(GetProcessHeap(), 0, image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
3457 afterImage =
3458 HeapAlloc(GetProcessHeap(), 0, image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
3459 if (beforeImage == NULL || afterImage == NULL) {
3460 HeapFree(GetProcessHeap(), 0, beforeImage);
3461 HeapFree(GetProcessHeap(), 0, afterImage);
3462 return GLU_OUT_OF_MEMORY;
3465 retrieveStoreModes(&psm);
3466 fill_image(&psm,widthin, heightin, format, typein, is_index(format),
3467 datain, beforeImage);
3468 components = elements_per_group(format, 0);
3469 scale_internal(components, widthin, heightin, beforeImage,
3470 widthout, heightout, afterImage);
3471 empty_image(&psm,widthout, heightout, format, typeout,
3472 is_index(format), afterImage, dataout);
3473 HeapFree(GetProcessHeap(), 0, beforeImage);
3474 HeapFree(GetProcessHeap(), 0, afterImage);
3476 return 0;
3479 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
3480 GLsizei width,
3481 GLsizei widthPowerOf2,
3482 GLenum format, GLenum type,
3483 GLint userLevel, GLint baseLevel,GLint maxLevel,
3484 const void *data)
3486 GLint newwidth;
3487 GLint level, levels;
3488 GLushort *newImage;
3489 GLint newImage_width;
3490 GLushort *otherImage;
3491 GLushort *imageTemp;
3492 GLint memreq;
3493 GLint cmpts;
3494 PixelStorageModes psm;
3496 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3497 assert(width >= 1);
3499 otherImage = NULL;
3501 newwidth= widthPowerOf2;
3502 levels = computeLog(newwidth);
3504 levels+= userLevel;
3506 retrieveStoreModes(&psm);
3507 newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, 1, format, GL_UNSIGNED_SHORT));
3508 newImage_width = width;
3509 if (newImage == NULL) {
3510 return GLU_OUT_OF_MEMORY;
3512 fill_image(&psm,width, 1, format, type, is_index(format),
3513 data, newImage);
3514 cmpts = elements_per_group(format,type);
3515 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3516 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3517 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3518 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3520 ** If swap_bytes was set, swapping occurred in fill_image.
3522 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3524 for (level = userLevel; level <= levels; level++) {
3525 if (newImage_width == newwidth) {
3526 /* Use newImage for this level */
3527 if (baseLevel <= level && level <= maxLevel) {
3528 glTexImage1D(target, level, internalFormat, newImage_width,
3529 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3531 } else {
3532 if (otherImage == NULL) {
3533 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
3534 otherImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3535 if (otherImage == NULL) {
3536 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3537 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3538 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3539 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3540 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3541 HeapFree(GetProcessHeap(), 0, newImage);
3542 return GLU_OUT_OF_MEMORY;
3545 scale_internal(cmpts, newImage_width, 1, newImage,
3546 newwidth, 1, otherImage);
3547 /* Swap newImage and otherImage */
3548 imageTemp = otherImage;
3549 otherImage = newImage;
3550 newImage = imageTemp;
3552 newImage_width = newwidth;
3553 if (baseLevel <= level && level <= maxLevel) {
3554 glTexImage1D(target, level, internalFormat, newImage_width,
3555 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3558 if (newwidth > 1) newwidth /= 2;
3560 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3561 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3562 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3563 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3564 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3566 HeapFree(GetProcessHeap(), 0, newImage);
3567 HeapFree(GetProcessHeap(), 0, otherImage);
3568 return 0;
3572 /***********************************************************************
3573 * gluBuild1DMipmaps (GLU32.@)
3575 GLint WINAPI gluBuild1DMipmaps( GLenum target, GLint internalFormat, GLsizei width,
3576 GLenum format, GLenum type, const void *data )
3578 GLint widthPowerOf2;
3579 int levels;
3580 GLint dummy;
3582 int rc= checkMipmapArgs(internalFormat,format,type);
3583 if (rc != 0) return rc;
3585 if (width < 1) {
3586 return GLU_INVALID_VALUE;
3589 closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
3590 levels = computeLog(widthPowerOf2);
3592 return gluBuild1DMipmapLevelsCore(target,internalFormat,
3593 width,
3594 widthPowerOf2,
3595 format,type,0,0,levels,data);
3598 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
3599 GLint width, GLint height, GLenum format,
3600 GLenum type, const void *data)
3602 GLint newwidth, newheight;
3603 GLint level, levels;
3604 GLushort *newImage;
3605 GLint newImage_width;
3606 GLint newImage_height;
3607 GLushort *otherImage;
3608 GLushort *imageTemp;
3609 GLint memreq;
3610 GLint cmpts;
3611 PixelStorageModes psm;
3613 retrieveStoreModes(&psm);
3615 #if 0
3616 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3617 newwidth = nearestPower(width);
3618 if (newwidth > maxsize) newwidth = maxsize;
3619 newheight = nearestPower(height);
3620 if (newheight > maxsize) newheight = maxsize;
3621 #else
3622 closestFit(target,width,height,internalFormat,format,type,
3623 &newwidth,&newheight);
3624 #endif
3625 levels = computeLog(newwidth);
3626 level = computeLog(newheight);
3627 if (level > levels) levels=level;
3629 otherImage = NULL;
3630 newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, height, format, GL_UNSIGNED_SHORT));
3631 newImage_width = width;
3632 newImage_height = height;
3633 if (newImage == NULL) {
3634 return GLU_OUT_OF_MEMORY;
3637 fill_image(&psm,width, height, format, type, is_index(format),
3638 data, newImage);
3640 cmpts = elements_per_group(format,type);
3641 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3642 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3643 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3644 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3646 ** If swap_bytes was set, swapping occurred in fill_image.
3648 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3650 for (level = 0; level <= levels; level++) {
3651 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
3652 glTexImage2D(target, level, internalFormat, newImage_width,
3653 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3654 (void *) newImage);
3655 } else {
3656 if (otherImage == NULL) {
3657 memreq =
3658 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
3659 otherImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3660 if (otherImage == NULL) {
3661 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3662 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3663 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3664 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3665 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3666 HeapFree(GetProcessHeap(), 0, newImage);
3667 return GLU_OUT_OF_MEMORY;
3670 scale_internal(cmpts, newImage_width, newImage_height, newImage,
3671 newwidth, newheight, otherImage);
3672 /* Swap newImage and otherImage */
3673 imageTemp = otherImage;
3674 otherImage = newImage;
3675 newImage = imageTemp;
3677 newImage_width = newwidth;
3678 newImage_height = newheight;
3679 glTexImage2D(target, level, internalFormat, newImage_width,
3680 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3681 (void *) newImage);
3683 if (newwidth > 1) newwidth /= 2;
3684 if (newheight > 1) newheight /= 2;
3686 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3687 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3688 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3689 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3690 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3692 HeapFree(GetProcessHeap(), 0, newImage);
3693 HeapFree(GetProcessHeap(), 0, otherImage);
3694 return 0;
3697 /* To make swapping images less error prone */
3698 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3699 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3701 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3702 GLsizei width, GLsizei height,
3703 GLsizei widthPowerOf2,
3704 GLsizei heightPowerOf2,
3705 GLenum format, GLenum type,
3706 GLint userLevel,
3707 GLint baseLevel,GLint maxLevel,
3708 const void *data)
3710 GLint newwidth, newheight;
3711 GLint level, levels;
3712 const void *usersImage; /* passed from user. Don't touch! */
3713 void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3714 __GLU_INIT_SWAP_IMAGE;
3715 GLint memreq;
3716 GLint cmpts;
3718 GLint myswap_bytes, groups_per_line, element_size, group_size;
3719 GLint rowsize, padding;
3720 PixelStorageModes psm;
3722 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3723 assert(width >= 1 && height >= 1);
3725 if(type == GL_BITMAP) {
3726 return bitmapBuild2DMipmaps(target, internalFormat, width, height,
3727 format, type, data);
3730 srcImage = dstImage = NULL;
3732 newwidth= widthPowerOf2;
3733 newheight= heightPowerOf2;
3734 levels = computeLog(newwidth);
3735 level = computeLog(newheight);
3736 if (level > levels) levels=level;
3738 levels+= userLevel;
3740 retrieveStoreModes(&psm);
3741 myswap_bytes = psm.unpack_swap_bytes;
3742 cmpts = elements_per_group(format,type);
3743 if (psm.unpack_row_length > 0) {
3744 groups_per_line = psm.unpack_row_length;
3745 } else {
3746 groups_per_line = width;
3749 element_size = bytes_per_element(type);
3750 group_size = element_size * cmpts;
3751 if (element_size == 1) myswap_bytes = 0;
3753 rowsize = groups_per_line * group_size;
3754 padding = (rowsize % psm.unpack_alignment);
3755 if (padding) {
3756 rowsize += psm.unpack_alignment - padding;
3758 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3759 psm.unpack_skip_pixels * group_size;
3761 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3762 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3763 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3765 level = userLevel;
3767 /* already power-of-two square */
3768 if (width == newwidth && height == newheight) {
3769 /* Use usersImage for level userLevel */
3770 if (baseLevel <= level && level <= maxLevel) {
3771 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3772 glTexImage2D(target, level, internalFormat, width,
3773 height, 0, format, type,
3774 usersImage);
3776 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3777 if(levels == 0) { /* we're done. clean up and return */
3778 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3779 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3780 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3781 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3782 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3783 return 0;
3786 int nextWidth= newwidth/2;
3787 int nextHeight= newheight/2;
3789 /* clamp to 1 */
3790 if (nextWidth < 1) nextWidth= 1;
3791 if (nextHeight < 1) nextHeight= 1;
3792 memreq = image_size(nextWidth, nextHeight, format, type);
3795 switch(type) {
3796 case GL_UNSIGNED_BYTE:
3797 case GL_BYTE:
3798 case GL_UNSIGNED_SHORT:
3799 case GL_SHORT:
3800 case GL_UNSIGNED_INT:
3801 case GL_INT:
3802 case GL_FLOAT:
3803 case GL_UNSIGNED_BYTE_3_3_2:
3804 case GL_UNSIGNED_BYTE_2_3_3_REV:
3805 case GL_UNSIGNED_SHORT_5_6_5:
3806 case GL_UNSIGNED_SHORT_5_6_5_REV:
3807 case GL_UNSIGNED_SHORT_4_4_4_4:
3808 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3809 case GL_UNSIGNED_SHORT_5_5_5_1:
3810 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3811 case GL_UNSIGNED_INT_8_8_8_8:
3812 case GL_UNSIGNED_INT_8_8_8_8_REV:
3813 case GL_UNSIGNED_INT_10_10_10_2:
3814 case GL_UNSIGNED_INT_2_10_10_10_REV:
3815 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3816 break;
3817 default:
3818 return GLU_INVALID_ENUM;
3820 if (dstImage == NULL) {
3821 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3822 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3823 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3824 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3825 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3826 return GLU_OUT_OF_MEMORY;
3828 else
3829 switch(type) {
3830 case GL_UNSIGNED_BYTE:
3831 halveImage_ubyte(cmpts, width, height,
3832 (const GLubyte *)usersImage, (GLubyte *)dstImage,
3833 element_size, rowsize, group_size);
3834 break;
3835 case GL_BYTE:
3836 halveImage_byte(cmpts, width, height,
3837 (const GLbyte *)usersImage, (GLbyte *)dstImage,
3838 element_size, rowsize, group_size);
3839 break;
3840 case GL_UNSIGNED_SHORT:
3841 halveImage_ushort(cmpts, width, height,
3842 (const GLushort *)usersImage, (GLushort *)dstImage,
3843 element_size, rowsize, group_size, myswap_bytes);
3844 break;
3845 case GL_SHORT:
3846 halveImage_short(cmpts, width, height,
3847 (const GLshort *)usersImage, (GLshort *)dstImage,
3848 element_size, rowsize, group_size, myswap_bytes);
3849 break;
3850 case GL_UNSIGNED_INT:
3851 halveImage_uint(cmpts, width, height,
3852 (const GLuint *)usersImage, (GLuint *)dstImage,
3853 element_size, rowsize, group_size, myswap_bytes);
3854 break;
3855 case GL_INT:
3856 halveImage_int(cmpts, width, height,
3857 (const GLint *)usersImage, (GLint *)dstImage,
3858 element_size, rowsize, group_size, myswap_bytes);
3859 break;
3860 case GL_FLOAT:
3861 halveImage_float(cmpts, width, height,
3862 (const GLfloat *)usersImage, (GLfloat *)dstImage,
3863 element_size, rowsize, group_size, myswap_bytes);
3864 break;
3865 case GL_UNSIGNED_BYTE_3_3_2:
3866 assert(format == GL_RGB);
3867 halveImagePackedPixel(3,extract332,shove332,
3868 width,height,usersImage,dstImage,
3869 element_size,rowsize,myswap_bytes);
3870 break;
3871 case GL_UNSIGNED_BYTE_2_3_3_REV:
3872 assert(format == GL_RGB);
3873 halveImagePackedPixel(3,extract233rev,shove233rev,
3874 width,height,usersImage,dstImage,
3875 element_size,rowsize,myswap_bytes);
3876 break;
3877 case GL_UNSIGNED_SHORT_5_6_5:
3878 halveImagePackedPixel(3,extract565,shove565,
3879 width,height,usersImage,dstImage,
3880 element_size,rowsize,myswap_bytes);
3881 break;
3882 case GL_UNSIGNED_SHORT_5_6_5_REV:
3883 halveImagePackedPixel(3,extract565rev,shove565rev,
3884 width,height,usersImage,dstImage,
3885 element_size,rowsize,myswap_bytes);
3886 break;
3887 case GL_UNSIGNED_SHORT_4_4_4_4:
3888 halveImagePackedPixel(4,extract4444,shove4444,
3889 width,height,usersImage,dstImage,
3890 element_size,rowsize,myswap_bytes);
3891 break;
3892 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3893 halveImagePackedPixel(4,extract4444rev,shove4444rev,
3894 width,height,usersImage,dstImage,
3895 element_size,rowsize,myswap_bytes);
3896 break;
3897 case GL_UNSIGNED_SHORT_5_5_5_1:
3898 halveImagePackedPixel(4,extract5551,shove5551,
3899 width,height,usersImage,dstImage,
3900 element_size,rowsize,myswap_bytes);
3901 break;
3902 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3903 halveImagePackedPixel(4,extract1555rev,shove1555rev,
3904 width,height,usersImage,dstImage,
3905 element_size,rowsize,myswap_bytes);
3906 break;
3907 case GL_UNSIGNED_INT_8_8_8_8:
3908 halveImagePackedPixel(4,extract8888,shove8888,
3909 width,height,usersImage,dstImage,
3910 element_size,rowsize,myswap_bytes);
3911 break;
3912 case GL_UNSIGNED_INT_8_8_8_8_REV:
3913 halveImagePackedPixel(4,extract8888rev,shove8888rev,
3914 width,height,usersImage,dstImage,
3915 element_size,rowsize,myswap_bytes);
3916 break;
3917 case GL_UNSIGNED_INT_10_10_10_2:
3918 halveImagePackedPixel(4,extract1010102,shove1010102,
3919 width,height,usersImage,dstImage,
3920 element_size,rowsize,myswap_bytes);
3921 break;
3922 case GL_UNSIGNED_INT_2_10_10_10_REV:
3923 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
3924 width,height,usersImage,dstImage,
3925 element_size,rowsize,myswap_bytes);
3926 break;
3927 default:
3928 assert(0);
3929 break;
3931 newwidth = width/2;
3932 newheight = height/2;
3933 /* clamp to 1 */
3934 if (newwidth < 1) newwidth= 1;
3935 if (newheight < 1) newheight= 1;
3937 myswap_bytes = 0;
3938 rowsize = newwidth * group_size;
3939 memreq = image_size(newwidth, newheight, format, type);
3940 /* Swap srcImage and dstImage */
3941 __GLU_SWAP_IMAGE(srcImage,dstImage);
3942 switch(type) {
3943 case GL_UNSIGNED_BYTE:
3944 case GL_BYTE:
3945 case GL_UNSIGNED_SHORT:
3946 case GL_SHORT:
3947 case GL_UNSIGNED_INT:
3948 case GL_INT:
3949 case GL_FLOAT:
3950 case GL_UNSIGNED_BYTE_3_3_2:
3951 case GL_UNSIGNED_BYTE_2_3_3_REV:
3952 case GL_UNSIGNED_SHORT_5_6_5:
3953 case GL_UNSIGNED_SHORT_5_6_5_REV:
3954 case GL_UNSIGNED_SHORT_4_4_4_4:
3955 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3956 case GL_UNSIGNED_SHORT_5_5_5_1:
3957 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3958 case GL_UNSIGNED_INT_8_8_8_8:
3959 case GL_UNSIGNED_INT_8_8_8_8_REV:
3960 case GL_UNSIGNED_INT_10_10_10_2:
3961 case GL_UNSIGNED_INT_2_10_10_10_REV:
3962 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3963 break;
3964 default:
3965 return GLU_INVALID_ENUM;
3967 if (dstImage == NULL) {
3968 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3969 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3970 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3971 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3972 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3973 HeapFree(GetProcessHeap(), 0, srcImage);
3974 return GLU_OUT_OF_MEMORY;
3976 /* level userLevel+1 is in srcImage; level userLevel already saved */
3977 level = userLevel+1;
3978 } else { /* user's image is *not* nice power-of-2 sized square */
3979 memreq = image_size(newwidth, newheight, format, type);
3980 switch(type) {
3981 case GL_UNSIGNED_BYTE:
3982 case GL_BYTE:
3983 case GL_UNSIGNED_SHORT:
3984 case GL_SHORT:
3985 case GL_UNSIGNED_INT:
3986 case GL_INT:
3987 case GL_FLOAT:
3988 case GL_UNSIGNED_BYTE_3_3_2:
3989 case GL_UNSIGNED_BYTE_2_3_3_REV:
3990 case GL_UNSIGNED_SHORT_5_6_5:
3991 case GL_UNSIGNED_SHORT_5_6_5_REV:
3992 case GL_UNSIGNED_SHORT_4_4_4_4:
3993 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3994 case GL_UNSIGNED_SHORT_5_5_5_1:
3995 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3996 case GL_UNSIGNED_INT_8_8_8_8:
3997 case GL_UNSIGNED_INT_8_8_8_8_REV:
3998 case GL_UNSIGNED_INT_10_10_10_2:
3999 case GL_UNSIGNED_INT_2_10_10_10_REV:
4000 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
4001 break;
4002 default:
4003 return GLU_INVALID_ENUM;
4006 if (dstImage == NULL) {
4007 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4008 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4009 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4010 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4011 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4012 return GLU_OUT_OF_MEMORY;
4015 switch(type) {
4016 case GL_UNSIGNED_BYTE:
4017 scale_internal_ubyte(cmpts, width, height,
4018 (const GLubyte *)usersImage, newwidth, newheight,
4019 (GLubyte *)dstImage, element_size,
4020 rowsize, group_size);
4021 break;
4022 case GL_BYTE:
4023 scale_internal_byte(cmpts, width, height,
4024 (const GLbyte *)usersImage, newwidth, newheight,
4025 (GLbyte *)dstImage, element_size,
4026 rowsize, group_size);
4027 break;
4028 case GL_UNSIGNED_SHORT:
4029 scale_internal_ushort(cmpts, width, height,
4030 (const GLushort *)usersImage, newwidth, newheight,
4031 (GLushort *)dstImage, element_size,
4032 rowsize, group_size, myswap_bytes);
4033 break;
4034 case GL_SHORT:
4035 scale_internal_short(cmpts, width, height,
4036 (const GLshort *)usersImage, newwidth, newheight,
4037 (GLshort *)dstImage, element_size,
4038 rowsize, group_size, myswap_bytes);
4039 break;
4040 case GL_UNSIGNED_INT:
4041 scale_internal_uint(cmpts, width, height,
4042 (const GLuint *)usersImage, newwidth, newheight,
4043 (GLuint *)dstImage, element_size,
4044 rowsize, group_size, myswap_bytes);
4045 break;
4046 case GL_INT:
4047 scale_internal_int(cmpts, width, height,
4048 (const GLint *)usersImage, newwidth, newheight,
4049 (GLint *)dstImage, element_size,
4050 rowsize, group_size, myswap_bytes);
4051 break;
4052 case GL_FLOAT:
4053 scale_internal_float(cmpts, width, height,
4054 (const GLfloat *)usersImage, newwidth, newheight,
4055 (GLfloat *)dstImage, element_size,
4056 rowsize, group_size, myswap_bytes);
4057 break;
4058 case GL_UNSIGNED_BYTE_3_3_2:
4059 scaleInternalPackedPixel(3,extract332,shove332,
4060 width, height,usersImage,
4061 newwidth,newheight,(void *)dstImage,
4062 element_size,rowsize,myswap_bytes);
4063 break;
4064 case GL_UNSIGNED_BYTE_2_3_3_REV:
4065 scaleInternalPackedPixel(3,extract233rev,shove233rev,
4066 width, height,usersImage,
4067 newwidth,newheight,(void *)dstImage,
4068 element_size,rowsize,myswap_bytes);
4069 break;
4070 case GL_UNSIGNED_SHORT_5_6_5:
4071 scaleInternalPackedPixel(3,extract565,shove565,
4072 width, height,usersImage,
4073 newwidth,newheight,(void *)dstImage,
4074 element_size,rowsize,myswap_bytes);
4075 break;
4076 case GL_UNSIGNED_SHORT_5_6_5_REV:
4077 scaleInternalPackedPixel(3,extract565rev,shove565rev,
4078 width, height,usersImage,
4079 newwidth,newheight,(void *)dstImage,
4080 element_size,rowsize,myswap_bytes);
4081 break;
4082 case GL_UNSIGNED_SHORT_4_4_4_4:
4083 scaleInternalPackedPixel(4,extract4444,shove4444,
4084 width, height,usersImage,
4085 newwidth,newheight,(void *)dstImage,
4086 element_size,rowsize,myswap_bytes);
4087 break;
4088 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4089 scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4090 width, height,usersImage,
4091 newwidth,newheight,(void *)dstImage,
4092 element_size,rowsize,myswap_bytes);
4093 break;
4094 case GL_UNSIGNED_SHORT_5_5_5_1:
4095 scaleInternalPackedPixel(4,extract5551,shove5551,
4096 width, height,usersImage,
4097 newwidth,newheight,(void *)dstImage,
4098 element_size,rowsize,myswap_bytes);
4099 break;
4100 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4101 scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4102 width, height,usersImage,
4103 newwidth,newheight,(void *)dstImage,
4104 element_size,rowsize,myswap_bytes);
4105 break;
4106 case GL_UNSIGNED_INT_8_8_8_8:
4107 scaleInternalPackedPixel(4,extract8888,shove8888,
4108 width, height,usersImage,
4109 newwidth,newheight,(void *)dstImage,
4110 element_size,rowsize,myswap_bytes);
4111 break;
4112 case GL_UNSIGNED_INT_8_8_8_8_REV:
4113 scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4114 width, height,usersImage,
4115 newwidth,newheight,(void *)dstImage,
4116 element_size,rowsize,myswap_bytes);
4117 break;
4118 case GL_UNSIGNED_INT_10_10_10_2:
4119 scaleInternalPackedPixel(4,extract1010102,shove1010102,
4120 width, height,usersImage,
4121 newwidth,newheight,(void *)dstImage,
4122 element_size,rowsize,myswap_bytes);
4123 break;
4124 case GL_UNSIGNED_INT_2_10_10_10_REV:
4125 scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
4126 width, height,usersImage,
4127 newwidth,newheight,(void *)dstImage,
4128 element_size,rowsize,myswap_bytes);
4129 break;
4130 default:
4131 assert(0);
4132 break;
4134 myswap_bytes = 0;
4135 rowsize = newwidth * group_size;
4136 /* Swap dstImage and srcImage */
4137 __GLU_SWAP_IMAGE(srcImage,dstImage);
4139 if(levels != 0) { /* use as little memory as possible */
4141 int nextWidth= newwidth/2;
4142 int nextHeight= newheight/2;
4143 if (nextWidth < 1) nextWidth= 1;
4144 if (nextHeight < 1) nextHeight= 1;
4146 memreq = image_size(nextWidth, nextHeight, format, type);
4149 switch(type) {
4150 case GL_UNSIGNED_BYTE:
4151 case GL_BYTE:
4152 case GL_UNSIGNED_SHORT:
4153 case GL_SHORT:
4154 case GL_UNSIGNED_INT:
4155 case GL_INT:
4156 case GL_FLOAT:
4157 case GL_UNSIGNED_BYTE_3_3_2:
4158 case GL_UNSIGNED_BYTE_2_3_3_REV:
4159 case GL_UNSIGNED_SHORT_5_6_5:
4160 case GL_UNSIGNED_SHORT_5_6_5_REV:
4161 case GL_UNSIGNED_SHORT_4_4_4_4:
4162 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4163 case GL_UNSIGNED_SHORT_5_5_5_1:
4164 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4165 case GL_UNSIGNED_INT_8_8_8_8:
4166 case GL_UNSIGNED_INT_8_8_8_8_REV:
4167 case GL_UNSIGNED_INT_10_10_10_2:
4168 case GL_UNSIGNED_INT_2_10_10_10_REV:
4169 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
4170 break;
4171 default:
4172 return GLU_INVALID_ENUM;
4174 if (dstImage == NULL) {
4175 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4176 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4177 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4178 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4179 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4180 HeapFree(GetProcessHeap(), 0, srcImage);
4181 return GLU_OUT_OF_MEMORY;
4184 /* level userLevel is in srcImage; nothing saved yet */
4185 level = userLevel;
4188 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4189 if (baseLevel <= level && level <= maxLevel) {
4190 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4191 format, type, (void *)srcImage);
4194 level++; /* update current level for the loop */
4195 for (; level <= levels; level++) {
4196 switch(type) {
4197 case GL_UNSIGNED_BYTE:
4198 halveImage_ubyte(cmpts, newwidth, newheight,
4199 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4200 rowsize, group_size);
4201 break;
4202 case GL_BYTE:
4203 halveImage_byte(cmpts, newwidth, newheight,
4204 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4205 rowsize, group_size);
4206 break;
4207 case GL_UNSIGNED_SHORT:
4208 halveImage_ushort(cmpts, newwidth, newheight,
4209 (GLushort *)srcImage, (GLushort *)dstImage, element_size,
4210 rowsize, group_size, myswap_bytes);
4211 break;
4212 case GL_SHORT:
4213 halveImage_short(cmpts, newwidth, newheight,
4214 (GLshort *)srcImage, (GLshort *)dstImage, element_size,
4215 rowsize, group_size, myswap_bytes);
4216 break;
4217 case GL_UNSIGNED_INT:
4218 halveImage_uint(cmpts, newwidth, newheight,
4219 (GLuint *)srcImage, (GLuint *)dstImage, element_size,
4220 rowsize, group_size, myswap_bytes);
4221 break;
4222 case GL_INT:
4223 halveImage_int(cmpts, newwidth, newheight,
4224 (GLint *)srcImage, (GLint *)dstImage, element_size,
4225 rowsize, group_size, myswap_bytes);
4226 break;
4227 case GL_FLOAT:
4228 halveImage_float(cmpts, newwidth, newheight,
4229 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4230 rowsize, group_size, myswap_bytes);
4231 break;
4232 case GL_UNSIGNED_BYTE_3_3_2:
4233 halveImagePackedPixel(3,extract332,shove332,
4234 newwidth,newheight,
4235 srcImage,dstImage,element_size,rowsize,
4236 myswap_bytes);
4237 break;
4238 case GL_UNSIGNED_BYTE_2_3_3_REV:
4239 halveImagePackedPixel(3,extract233rev,shove233rev,
4240 newwidth,newheight,
4241 srcImage,dstImage,element_size,rowsize,
4242 myswap_bytes);
4243 break;
4244 case GL_UNSIGNED_SHORT_5_6_5:
4245 halveImagePackedPixel(3,extract565,shove565,
4246 newwidth,newheight,
4247 srcImage,dstImage,element_size,rowsize,
4248 myswap_bytes);
4249 break;
4250 case GL_UNSIGNED_SHORT_5_6_5_REV:
4251 halveImagePackedPixel(3,extract565rev,shove565rev,
4252 newwidth,newheight,
4253 srcImage,dstImage,element_size,rowsize,
4254 myswap_bytes);
4255 break;
4256 case GL_UNSIGNED_SHORT_4_4_4_4:
4257 halveImagePackedPixel(4,extract4444,shove4444,
4258 newwidth,newheight,
4259 srcImage,dstImage,element_size,rowsize,
4260 myswap_bytes);
4261 break;
4262 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4263 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4264 newwidth,newheight,
4265 srcImage,dstImage,element_size,rowsize,
4266 myswap_bytes);
4267 break;
4268 case GL_UNSIGNED_SHORT_5_5_5_1:
4269 halveImagePackedPixel(4,extract5551,shove5551,
4270 newwidth,newheight,
4271 srcImage,dstImage,element_size,rowsize,
4272 myswap_bytes);
4273 break;
4274 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4275 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4276 newwidth,newheight,
4277 srcImage,dstImage,element_size,rowsize,
4278 myswap_bytes);
4279 break;
4280 case GL_UNSIGNED_INT_8_8_8_8:
4281 halveImagePackedPixel(4,extract8888,shove8888,
4282 newwidth,newheight,
4283 srcImage,dstImage,element_size,rowsize,
4284 myswap_bytes);
4285 break;
4286 case GL_UNSIGNED_INT_8_8_8_8_REV:
4287 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4288 newwidth,newheight,
4289 srcImage,dstImage,element_size,rowsize,
4290 myswap_bytes);
4291 break;
4292 case GL_UNSIGNED_INT_10_10_10_2:
4293 halveImagePackedPixel(4,extract1010102,shove1010102,
4294 newwidth,newheight,
4295 srcImage,dstImage,element_size,rowsize,
4296 myswap_bytes);
4297 break;
4298 case GL_UNSIGNED_INT_2_10_10_10_REV:
4299 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4300 newwidth,newheight,
4301 srcImage,dstImage,element_size,rowsize,
4302 myswap_bytes);
4303 break;
4304 default:
4305 assert(0);
4306 break;
4309 __GLU_SWAP_IMAGE(srcImage,dstImage);
4311 if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4312 if (newheight > 1) newheight /= 2;
4314 /* compute amount to pad per row, if any */
4315 int rowPad= rowsize % psm.unpack_alignment;
4317 /* should row be padded? */
4318 if (rowPad == 0) { /* nope, row should not be padded */
4319 /* call tex image with srcImage untouched since it's not padded */
4320 if (baseLevel <= level && level <= maxLevel) {
4321 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4322 format, type, (void *) srcImage);
4325 else { /* yes, row should be padded */
4326 /* compute length of new row in bytes, including padding */
4327 int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4328 int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4330 /* allocate new image for mipmap of size newRowLength x newheight */
4331 void *newMipmapImage= HeapAlloc(GetProcessHeap(), 0, (size_t) (newRowLength*newheight));
4332 if (newMipmapImage == NULL) {
4333 /* out of memory so return */
4334 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4335 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4336 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4337 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4338 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4339 return GLU_OUT_OF_MEMORY;
4342 /* copy image from srcImage into newMipmapImage by rows */
4343 for (ii= 0,
4344 dstTrav= (unsigned char *) newMipmapImage,
4345 srcTrav= (unsigned char *) srcImage;
4346 ii< newheight;
4347 ii++,
4348 dstTrav+= newRowLength, /* make sure the correct distance... */
4349 srcTrav+= rowsize) { /* ...is skipped */
4350 memcpy(dstTrav,srcTrav,rowsize);
4351 /* note that the pad bytes are not visited and will contain
4352 * garbage, which is ok.
4356 /* ...and use this new image for mipmapping instead */
4357 if (baseLevel <= level && level <= maxLevel) {
4358 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4359 format, type, newMipmapImage);
4361 HeapFree(GetProcessHeap(), 0, newMipmapImage); /* don't forget to free it! */
4362 } /* else */
4364 } /* for level */
4365 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4366 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4367 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4368 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4369 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4371 HeapFree(GetProcessHeap(), 0, srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4372 HeapFree(GetProcessHeap(), 0, dstImage);
4373 return 0;
4374 } /* gluBuild2DMipmapLevelsCore() */
4377 /***********************************************************************
4378 * gluBuild2DMipmaps (GLU32.@)
4380 GLint WINAPI gluBuild2DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height,
4381 GLenum format, GLenum type, const void *data )
4383 GLint widthPowerOf2, heightPowerOf2;
4384 int level, levels;
4386 int rc= checkMipmapArgs(internalFormat,format,type);
4387 if (rc != 0) return rc;
4389 if (width < 1 || height < 1) {
4390 return GLU_INVALID_VALUE;
4393 closestFit(target,width,height,internalFormat,format,type,
4394 &widthPowerOf2,&heightPowerOf2);
4396 levels = computeLog(widthPowerOf2);
4397 level = computeLog(heightPowerOf2);
4398 if (level > levels) levels=level;
4400 return gluBuild2DMipmapLevelsCore(target,internalFormat,
4401 width, height,
4402 widthPowerOf2,heightPowerOf2,
4403 format,type,
4404 0,0,levels,data);
4405 } /* gluBuild2DMipmaps() */
4409 * Utility Routines
4411 static GLint elements_per_group(GLenum format, GLenum type)
4414 * Return the number of elements per group of a specified format
4417 /* If the type is packedpixels then answer is 1 (ignore format) */
4418 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4419 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4420 type == GL_UNSIGNED_SHORT_5_6_5 ||
4421 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4422 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4423 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4424 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
4425 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
4426 type == GL_UNSIGNED_INT_8_8_8_8 ||
4427 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4428 type == GL_UNSIGNED_INT_10_10_10_2 ||
4429 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
4430 return 1;
4433 /* Types are not packed pixels, so get elements per group */
4434 switch(format) {
4435 case GL_RGB:
4436 case GL_BGR:
4437 return 3;
4438 case GL_LUMINANCE_ALPHA:
4439 return 2;
4440 case GL_RGBA:
4441 case GL_BGRA:
4442 return 4;
4443 default:
4444 return 1;
4448 static GLfloat bytes_per_element(GLenum type)
4451 * Return the number of bytes per element, based on the element type
4453 switch(type) {
4454 case GL_BITMAP:
4455 return 1.0 / 8.0;
4456 case GL_UNSIGNED_SHORT:
4457 return(sizeof(GLushort));
4458 case GL_SHORT:
4459 return(sizeof(GLshort));
4460 case GL_UNSIGNED_BYTE:
4461 return(sizeof(GLubyte));
4462 case GL_BYTE:
4463 return(sizeof(GLbyte));
4464 case GL_INT:
4465 return(sizeof(GLint));
4466 case GL_UNSIGNED_INT:
4467 return(sizeof(GLuint));
4468 case GL_FLOAT:
4469 return(sizeof(GLfloat));
4470 case GL_UNSIGNED_BYTE_3_3_2:
4471 case GL_UNSIGNED_BYTE_2_3_3_REV:
4472 return(sizeof(GLubyte));
4473 case GL_UNSIGNED_SHORT_5_6_5:
4474 case GL_UNSIGNED_SHORT_5_6_5_REV:
4475 case GL_UNSIGNED_SHORT_4_4_4_4:
4476 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4477 case GL_UNSIGNED_SHORT_5_5_5_1:
4478 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4479 return(sizeof(GLushort));
4480 case GL_UNSIGNED_INT_8_8_8_8:
4481 case GL_UNSIGNED_INT_8_8_8_8_REV:
4482 case GL_UNSIGNED_INT_10_10_10_2:
4483 case GL_UNSIGNED_INT_2_10_10_10_REV:
4484 return(sizeof(GLuint));
4485 default:
4486 return 4;
4490 static GLint is_index(GLenum format)
4492 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4496 ** Compute memory required for internal packed array of data of given type
4497 ** and format.
4499 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4501 int bytes_per_row;
4502 int components;
4504 assert(width > 0);
4505 assert(height > 0);
4506 components = elements_per_group(format,type);
4507 if (type == GL_BITMAP) {
4508 bytes_per_row = (width + 7) / 8;
4509 } else {
4510 bytes_per_row = bytes_per_element(type) * width;
4512 return bytes_per_row * height * components;
4516 ** Extract array from user's data applying all pixel store modes.
4517 ** The internal format used is an array of unsigned shorts.
4519 static void fill_image(const PixelStorageModes *psm,
4520 GLint width, GLint height, GLenum format,
4521 GLenum type, GLboolean index_format,
4522 const void *userdata, GLushort *newimage)
4524 GLint components;
4525 GLint element_size;
4526 GLint rowsize;
4527 GLint padding;
4528 GLint groups_per_line;
4529 GLint group_size;
4530 GLint elements_per_line;
4531 const GLubyte *start;
4532 const GLubyte *iter;
4533 GLushort *iter2;
4534 GLint i, j, k;
4535 GLint myswap_bytes;
4537 myswap_bytes = psm->unpack_swap_bytes;
4538 components = elements_per_group(format,type);
4539 if (psm->unpack_row_length > 0) {
4540 groups_per_line = psm->unpack_row_length;
4541 } else {
4542 groups_per_line = width;
4545 /* All formats except GL_BITMAP fall out trivially */
4546 if (type == GL_BITMAP) {
4547 GLint bit_offset;
4548 GLint current_bit;
4550 rowsize = (groups_per_line * components + 7) / 8;
4551 padding = (rowsize % psm->unpack_alignment);
4552 if (padding) {
4553 rowsize += psm->unpack_alignment - padding;
4555 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4556 (psm->unpack_skip_pixels * components / 8);
4557 elements_per_line = width * components;
4558 iter2 = newimage;
4559 for (i = 0; i < height; i++) {
4560 iter = start;
4561 bit_offset = (psm->unpack_skip_pixels * components) % 8;
4562 for (j = 0; j < elements_per_line; j++) {
4563 /* Retrieve bit */
4564 if (psm->unpack_lsb_first) {
4565 current_bit = iter[0] & (1 << bit_offset);
4566 } else {
4567 current_bit = iter[0] & (1 << (7 - bit_offset));
4569 if (current_bit) {
4570 if (index_format) {
4571 *iter2 = 1;
4572 } else {
4573 *iter2 = 65535;
4575 } else {
4576 *iter2 = 0;
4578 bit_offset++;
4579 if (bit_offset == 8) {
4580 bit_offset = 0;
4581 iter++;
4583 iter2++;
4585 start += rowsize;
4587 } else {
4588 element_size = bytes_per_element(type);
4589 group_size = element_size * components;
4590 if (element_size == 1) myswap_bytes = 0;
4592 rowsize = groups_per_line * group_size;
4593 padding = (rowsize % psm->unpack_alignment);
4594 if (padding) {
4595 rowsize += psm->unpack_alignment - padding;
4597 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4598 psm->unpack_skip_pixels * group_size;
4599 elements_per_line = width * components;
4601 iter2 = newimage;
4602 for (i = 0; i < height; i++) {
4603 iter = start;
4604 for (j = 0; j < elements_per_line; j++) {
4605 Type_Widget widget;
4606 float extractComponents[4];
4608 switch(type) {
4609 case GL_UNSIGNED_BYTE_3_3_2:
4610 extract332(0,iter,extractComponents);
4611 for (k = 0; k < 3; k++) {
4612 *iter2++ = (GLushort)(extractComponents[k]*65535);
4614 break;
4615 case GL_UNSIGNED_BYTE_2_3_3_REV:
4616 extract233rev(0,iter,extractComponents);
4617 for (k = 0; k < 3; k++) {
4618 *iter2++ = (GLushort)(extractComponents[k]*65535);
4620 break;
4621 case GL_UNSIGNED_BYTE:
4622 if (index_format) {
4623 *iter2++ = *iter;
4624 } else {
4625 *iter2++ = (*iter) * 257;
4627 break;
4628 case GL_BYTE:
4629 if (index_format) {
4630 *iter2++ = *((const GLbyte *) iter);
4631 } else {
4632 /* rough approx */
4633 *iter2++ = (*((const GLbyte *) iter)) * 516;
4635 break;
4636 case GL_UNSIGNED_SHORT_5_6_5:
4637 extract565(myswap_bytes,iter,extractComponents);
4638 for (k = 0; k < 3; k++) {
4639 *iter2++ = (GLushort)(extractComponents[k]*65535);
4641 break;
4642 case GL_UNSIGNED_SHORT_5_6_5_REV:
4643 extract565rev(myswap_bytes,iter,extractComponents);
4644 for (k = 0; k < 3; k++) {
4645 *iter2++ = (GLushort)(extractComponents[k]*65535);
4647 break;
4648 case GL_UNSIGNED_SHORT_4_4_4_4:
4649 extract4444(myswap_bytes,iter,extractComponents);
4650 for (k = 0; k < 4; k++) {
4651 *iter2++ = (GLushort)(extractComponents[k]*65535);
4653 break;
4654 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4655 extract4444rev(myswap_bytes,iter,extractComponents);
4656 for (k = 0; k < 4; k++) {
4657 *iter2++ = (GLushort)(extractComponents[k]*65535);
4659 break;
4660 case GL_UNSIGNED_SHORT_5_5_5_1:
4661 extract5551(myswap_bytes,iter,extractComponents);
4662 for (k = 0; k < 4; k++) {
4663 *iter2++ = (GLushort)(extractComponents[k]*65535);
4665 break;
4666 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4667 extract1555rev(myswap_bytes,iter,extractComponents);
4668 for (k = 0; k < 4; k++) {
4669 *iter2++ = (GLushort)(extractComponents[k]*65535);
4671 break;
4672 case GL_UNSIGNED_SHORT:
4673 case GL_SHORT:
4674 if (myswap_bytes) {
4675 widget.ub[0] = iter[1];
4676 widget.ub[1] = iter[0];
4677 } else {
4678 widget.ub[0] = iter[0];
4679 widget.ub[1] = iter[1];
4681 if (type == GL_SHORT) {
4682 if (index_format) {
4683 *iter2++ = widget.s[0];
4684 } else {
4685 /* rough approx */
4686 *iter2++ = widget.s[0]*2;
4688 } else {
4689 *iter2++ = widget.us[0];
4691 break;
4692 case GL_UNSIGNED_INT_8_8_8_8:
4693 extract8888(myswap_bytes,iter,extractComponents);
4694 for (k = 0; k < 4; k++) {
4695 *iter2++ = (GLushort)(extractComponents[k]*65535);
4697 break;
4698 case GL_UNSIGNED_INT_8_8_8_8_REV:
4699 extract8888rev(myswap_bytes,iter,extractComponents);
4700 for (k = 0; k < 4; k++) {
4701 *iter2++ = (GLushort)(extractComponents[k]*65535);
4703 break;
4704 case GL_UNSIGNED_INT_10_10_10_2:
4705 extract1010102(myswap_bytes,iter,extractComponents);
4706 for (k = 0; k < 4; k++) {
4707 *iter2++ = (GLushort)(extractComponents[k]*65535);
4709 break;
4710 case GL_UNSIGNED_INT_2_10_10_10_REV:
4711 extract2101010rev(myswap_bytes,iter,extractComponents);
4712 for (k = 0; k < 4; k++) {
4713 *iter2++ = (GLushort)(extractComponents[k]*65535);
4715 break;
4716 case GL_INT:
4717 case GL_UNSIGNED_INT:
4718 case GL_FLOAT:
4719 if (myswap_bytes) {
4720 widget.ub[0] = iter[3];
4721 widget.ub[1] = iter[2];
4722 widget.ub[2] = iter[1];
4723 widget.ub[3] = iter[0];
4724 } else {
4725 widget.ub[0] = iter[0];
4726 widget.ub[1] = iter[1];
4727 widget.ub[2] = iter[2];
4728 widget.ub[3] = iter[3];
4730 if (type == GL_FLOAT) {
4731 if (index_format) {
4732 *iter2++ = widget.f;
4733 } else {
4734 *iter2++ = 65535 * widget.f;
4736 } else if (type == GL_UNSIGNED_INT) {
4737 if (index_format) {
4738 *iter2++ = widget.ui;
4739 } else {
4740 *iter2++ = widget.ui >> 16;
4742 } else {
4743 if (index_format) {
4744 *iter2++ = widget.i;
4745 } else {
4746 *iter2++ = widget.i >> 15;
4749 break;
4751 iter += element_size;
4752 } /* for j */
4753 start += rowsize;
4754 #if 1
4755 /* want 'iter' pointing at start, not within, row for assertion
4756 * purposes
4758 iter= start;
4759 #endif
4760 } /* for i */
4762 /* iterators should be one byte past end */
4763 if (!isTypePackedPixel(type)) {
4764 assert(iter2 == &newimage[width*height*components]);
4766 else {
4767 assert(iter2 == &newimage[width*height*
4768 elements_per_group(format,0)]);
4770 } /* else */
4771 } /* fill_image() */
4774 ** Insert array into user's data applying all pixel store modes.
4775 ** The internal format is an array of unsigned shorts.
4776 ** empty_image() because it is the opposite of fill_image().
4778 static void empty_image(const PixelStorageModes *psm,
4779 GLint width, GLint height, GLenum format,
4780 GLenum type, GLboolean index_format,
4781 const GLushort *oldimage, void *userdata)
4783 GLint components;
4784 GLint element_size;
4785 GLint rowsize;
4786 GLint padding;
4787 GLint groups_per_line;
4788 GLint group_size;
4789 GLint elements_per_line;
4790 GLubyte *start;
4791 GLubyte *iter;
4792 const GLushort *iter2;
4793 GLint i, j, k;
4794 GLint myswap_bytes;
4796 myswap_bytes = psm->pack_swap_bytes;
4797 components = elements_per_group(format,type);
4798 if (psm->pack_row_length > 0) {
4799 groups_per_line = psm->pack_row_length;
4800 } else {
4801 groups_per_line = width;
4804 /* All formats except GL_BITMAP fall out trivially */
4805 if (type == GL_BITMAP) {
4806 GLint bit_offset;
4807 GLint current_bit;
4809 rowsize = (groups_per_line * components + 7) / 8;
4810 padding = (rowsize % psm->pack_alignment);
4811 if (padding) {
4812 rowsize += psm->pack_alignment - padding;
4814 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
4815 (psm->pack_skip_pixels * components / 8);
4816 elements_per_line = width * components;
4817 iter2 = oldimage;
4818 for (i = 0; i < height; i++) {
4819 iter = start;
4820 bit_offset = (psm->pack_skip_pixels * components) % 8;
4821 for (j = 0; j < elements_per_line; j++) {
4822 if (index_format) {
4823 current_bit = iter2[0] & 1;
4824 } else {
4825 if (iter2[0] > 32767) {
4826 current_bit = 1;
4827 } else {
4828 current_bit = 0;
4832 if (current_bit) {
4833 if (psm->pack_lsb_first) {
4834 *iter |= (1 << bit_offset);
4835 } else {
4836 *iter |= (1 << (7 - bit_offset));
4838 } else {
4839 if (psm->pack_lsb_first) {
4840 *iter &= ~(1 << bit_offset);
4841 } else {
4842 *iter &= ~(1 << (7 - bit_offset));
4846 bit_offset++;
4847 if (bit_offset == 8) {
4848 bit_offset = 0;
4849 iter++;
4851 iter2++;
4853 start += rowsize;
4855 } else {
4856 float shoveComponents[4];
4858 element_size = bytes_per_element(type);
4859 group_size = element_size * components;
4860 if (element_size == 1) myswap_bytes = 0;
4862 rowsize = groups_per_line * group_size;
4863 padding = (rowsize % psm->pack_alignment);
4864 if (padding) {
4865 rowsize += psm->pack_alignment - padding;
4867 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
4868 psm->pack_skip_pixels * group_size;
4869 elements_per_line = width * components;
4871 iter2 = oldimage;
4872 for (i = 0; i < height; i++) {
4873 iter = start;
4874 for (j = 0; j < elements_per_line; j++) {
4875 Type_Widget widget;
4877 switch(type) {
4878 case GL_UNSIGNED_BYTE_3_3_2:
4879 for (k = 0; k < 3; k++) {
4880 shoveComponents[k]= *iter2++ / 65535.0;
4882 shove332(shoveComponents,0,(void *)iter);
4883 break;
4884 case GL_UNSIGNED_BYTE_2_3_3_REV:
4885 for (k = 0; k < 3; k++) {
4886 shoveComponents[k]= *iter2++ / 65535.0;
4888 shove233rev(shoveComponents,0,(void *)iter);
4889 break;
4890 case GL_UNSIGNED_BYTE:
4891 if (index_format) {
4892 *iter = *iter2++;
4893 } else {
4894 *iter = *iter2++ >> 8;
4896 break;
4897 case GL_BYTE:
4898 if (index_format) {
4899 *((GLbyte *) iter) = *iter2++;
4900 } else {
4901 *((GLbyte *) iter) = *iter2++ >> 9;
4903 break;
4904 case GL_UNSIGNED_SHORT_5_6_5:
4905 for (k = 0; k < 3; k++) {
4906 shoveComponents[k]= *iter2++ / 65535.0;
4908 shove565(shoveComponents,0,(void *)&widget.us[0]);
4909 if (myswap_bytes) {
4910 iter[0] = widget.ub[1];
4911 iter[1] = widget.ub[0];
4913 else {
4914 *(GLushort *)iter = widget.us[0];
4916 break;
4917 case GL_UNSIGNED_SHORT_5_6_5_REV:
4918 for (k = 0; k < 3; k++) {
4919 shoveComponents[k]= *iter2++ / 65535.0;
4921 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
4922 if (myswap_bytes) {
4923 iter[0] = widget.ub[1];
4924 iter[1] = widget.ub[0];
4926 else {
4927 *(GLushort *)iter = widget.us[0];
4929 break;
4930 case GL_UNSIGNED_SHORT_4_4_4_4:
4931 for (k = 0; k < 4; k++) {
4932 shoveComponents[k]= *iter2++ / 65535.0;
4934 shove4444(shoveComponents,0,(void *)&widget.us[0]);
4935 if (myswap_bytes) {
4936 iter[0] = widget.ub[1];
4937 iter[1] = widget.ub[0];
4938 } else {
4939 *(GLushort *)iter = widget.us[0];
4941 break;
4942 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4943 for (k = 0; k < 4; k++) {
4944 shoveComponents[k]= *iter2++ / 65535.0;
4946 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
4947 if (myswap_bytes) {
4948 iter[0] = widget.ub[1];
4949 iter[1] = widget.ub[0];
4950 } else {
4951 *(GLushort *)iter = widget.us[0];
4953 break;
4954 case GL_UNSIGNED_SHORT_5_5_5_1:
4955 for (k = 0; k < 4; k++) {
4956 shoveComponents[k]= *iter2++ / 65535.0;
4958 shove5551(shoveComponents,0,(void *)&widget.us[0]);
4959 if (myswap_bytes) {
4960 iter[0] = widget.ub[1];
4961 iter[1] = widget.ub[0];
4962 } else {
4963 *(GLushort *)iter = widget.us[0];
4965 break;
4966 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4967 for (k = 0; k < 4; k++) {
4968 shoveComponents[k]= *iter2++ / 65535.0;
4970 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
4971 if (myswap_bytes) {
4972 iter[0] = widget.ub[1];
4973 iter[1] = widget.ub[0];
4974 } else {
4975 *(GLushort *)iter = widget.us[0];
4977 break;
4978 case GL_UNSIGNED_SHORT:
4979 case GL_SHORT:
4980 if (type == GL_SHORT) {
4981 if (index_format) {
4982 widget.s[0] = *iter2++;
4983 } else {
4984 widget.s[0] = *iter2++ >> 1;
4986 } else {
4987 widget.us[0] = *iter2++;
4989 if (myswap_bytes) {
4990 iter[0] = widget.ub[1];
4991 iter[1] = widget.ub[0];
4992 } else {
4993 iter[0] = widget.ub[0];
4994 iter[1] = widget.ub[1];
4996 break;
4997 case GL_UNSIGNED_INT_8_8_8_8:
4998 for (k = 0; k < 4; k++) {
4999 shoveComponents[k]= *iter2++ / 65535.0;
5001 shove8888(shoveComponents,0,(void *)&widget.ui);
5002 if (myswap_bytes) {
5003 iter[3] = widget.ub[0];
5004 iter[2] = widget.ub[1];
5005 iter[1] = widget.ub[2];
5006 iter[0] = widget.ub[3];
5007 } else {
5008 *(GLuint *)iter= widget.ui;
5011 break;
5012 case GL_UNSIGNED_INT_8_8_8_8_REV:
5013 for (k = 0; k < 4; k++) {
5014 shoveComponents[k]= *iter2++ / 65535.0;
5016 shove8888rev(shoveComponents,0,(void *)&widget.ui);
5017 if (myswap_bytes) {
5018 iter[3] = widget.ub[0];
5019 iter[2] = widget.ub[1];
5020 iter[1] = widget.ub[2];
5021 iter[0] = widget.ub[3];
5022 } else {
5023 *(GLuint *)iter= widget.ui;
5025 break;
5026 case GL_UNSIGNED_INT_10_10_10_2:
5027 for (k = 0; k < 4; k++) {
5028 shoveComponents[k]= *iter2++ / 65535.0;
5030 shove1010102(shoveComponents,0,(void *)&widget.ui);
5031 if (myswap_bytes) {
5032 iter[3] = widget.ub[0];
5033 iter[2] = widget.ub[1];
5034 iter[1] = widget.ub[2];
5035 iter[0] = widget.ub[3];
5036 } else {
5037 *(GLuint *)iter= widget.ui;
5039 break;
5040 case GL_UNSIGNED_INT_2_10_10_10_REV:
5041 for (k = 0; k < 4; k++) {
5042 shoveComponents[k]= *iter2++ / 65535.0;
5044 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5045 if (myswap_bytes) {
5046 iter[3] = widget.ub[0];
5047 iter[2] = widget.ub[1];
5048 iter[1] = widget.ub[2];
5049 iter[0] = widget.ub[3];
5050 } else {
5051 *(GLuint *)iter= widget.ui;
5053 break;
5054 case GL_INT:
5055 case GL_UNSIGNED_INT:
5056 case GL_FLOAT:
5057 if (type == GL_FLOAT) {
5058 if (index_format) {
5059 widget.f = *iter2++;
5060 } else {
5061 widget.f = *iter2++ / (float) 65535.0;
5063 } else if (type == GL_UNSIGNED_INT) {
5064 if (index_format) {
5065 widget.ui = *iter2++;
5066 } else {
5067 widget.ui = (unsigned int) *iter2++ * 65537;
5069 } else {
5070 if (index_format) {
5071 widget.i = *iter2++;
5072 } else {
5073 widget.i = ((unsigned int) *iter2++ * 65537)/2;
5076 if (myswap_bytes) {
5077 iter[3] = widget.ub[0];
5078 iter[2] = widget.ub[1];
5079 iter[1] = widget.ub[2];
5080 iter[0] = widget.ub[3];
5081 } else {
5082 iter[0] = widget.ub[0];
5083 iter[1] = widget.ub[1];
5084 iter[2] = widget.ub[2];
5085 iter[3] = widget.ub[3];
5087 break;
5089 iter += element_size;
5090 } /* for j */
5091 start += rowsize;
5092 #if 1
5093 /* want 'iter' pointing at start, not within, row for assertion
5094 * purposes
5096 iter= start;
5097 #endif
5098 } /* for i */
5100 /* iterators should be one byte past end */
5101 if (!isTypePackedPixel(type)) {
5102 assert(iter2 == &oldimage[width*height*components]);
5104 else {
5105 assert(iter2 == &oldimage[width*height*
5106 elements_per_group(format,0)]);
5108 assert( iter == &((GLubyte *)userdata)[rowsize*height +
5109 psm->pack_skip_rows * rowsize +
5110 psm->pack_skip_pixels * group_size] );
5112 } /* else */
5113 } /* empty_image() */
5115 /*--------------------------------------------------------------------------
5116 * Decimation of packed pixel types
5117 *--------------------------------------------------------------------------
5119 static void extract332(int isSwap,
5120 const void *packedPixel, GLfloat extractComponents[])
5122 GLubyte ubyte= *(const GLubyte *)packedPixel;
5124 /* 11100000 == 0xe0 */
5125 /* 00011100 == 0x1c */
5126 /* 00000011 == 0x03 */
5128 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0;
5129 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5130 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */
5131 } /* extract332() */
5133 static void shove332(const GLfloat shoveComponents[],
5134 int index, void *packedPixel)
5136 /* 11100000 == 0xe0 */
5137 /* 00011100 == 0x1c */
5138 /* 00000011 == 0x03 */
5140 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5141 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5142 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5144 /* due to limited precision, need to round before shoving */
5145 ((GLubyte *)packedPixel)[index] =
5146 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0;
5147 ((GLubyte *)packedPixel)[index] |=
5148 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c;
5149 ((GLubyte *)packedPixel)[index] |=
5150 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03;
5151 } /* shove332() */
5153 static void extract233rev(int isSwap,
5154 const void *packedPixel, GLfloat extractComponents[])
5156 GLubyte ubyte= *(const GLubyte *)packedPixel;
5158 /* 0000,0111 == 0x07 */
5159 /* 0011,1000 == 0x38 */
5160 /* 1100,0000 == 0xC0 */
5162 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0;
5163 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5164 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5165 } /* extract233rev() */
5167 static void shove233rev(const GLfloat shoveComponents[],
5168 int index, void *packedPixel)
5170 /* 0000,0111 == 0x07 */
5171 /* 0011,1000 == 0x38 */
5172 /* 1100,0000 == 0xC0 */
5174 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5175 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5176 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5178 /* due to limited precision, need to round before shoving */
5179 ((GLubyte *)packedPixel)[index] =
5180 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07;
5181 ((GLubyte *)packedPixel)[index]|=
5182 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5183 ((GLubyte *)packedPixel)[index]|=
5184 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5185 } /* shove233rev() */
5187 static void extract565(int isSwap,
5188 const void *packedPixel, GLfloat extractComponents[])
5190 GLushort ushort;
5192 if (isSwap) {
5193 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5195 else {
5196 ushort= *(const GLushort *)packedPixel;
5199 /* 11111000,00000000 == 0xf800 */
5200 /* 00000111,11100000 == 0x07e0 */
5201 /* 00000000,00011111 == 0x001f */
5203 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5204 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5205 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0;
5206 } /* extract565() */
5208 static void shove565(const GLfloat shoveComponents[],
5209 int index,void *packedPixel)
5211 /* 11111000,00000000 == 0xf800 */
5212 /* 00000111,11100000 == 0x07e0 */
5213 /* 00000000,00011111 == 0x001f */
5215 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5216 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5217 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5219 /* due to limited precision, need to round before shoving */
5220 ((GLushort *)packedPixel)[index] =
5221 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5222 ((GLushort *)packedPixel)[index]|=
5223 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0;
5224 ((GLushort *)packedPixel)[index]|=
5225 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f;
5226 } /* shove565() */
5228 static void extract565rev(int isSwap,
5229 const void *packedPixel, GLfloat extractComponents[])
5231 GLushort ushort;
5233 if (isSwap) {
5234 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5236 else {
5237 ushort= *(const GLushort *)packedPixel;
5240 /* 00000000,00011111 == 0x001f */
5241 /* 00000111,11100000 == 0x07e0 */
5242 /* 11111000,00000000 == 0xf800 */
5244 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5245 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0;
5246 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5247 } /* extract565rev() */
5249 static void shove565rev(const GLfloat shoveComponents[],
5250 int index,void *packedPixel)
5252 /* 00000000,00011111 == 0x001f */
5253 /* 00000111,11100000 == 0x07e0 */
5254 /* 11111000,00000000 == 0xf800 */
5256 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5257 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5258 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5260 /* due to limited precision, need to round before shoving */
5261 ((GLushort *)packedPixel)[index] =
5262 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F;
5263 ((GLushort *)packedPixel)[index]|=
5264 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0;
5265 ((GLushort *)packedPixel)[index]|=
5266 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5267 } /* shove565rev() */
5269 static void extract4444(int isSwap,const void *packedPixel,
5270 GLfloat extractComponents[])
5272 GLushort ushort;
5274 if (isSwap) {
5275 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5277 else {
5278 ushort= *(const GLushort *)packedPixel;
5281 /* 11110000,00000000 == 0xf000 */
5282 /* 00001111,00000000 == 0x0f00 */
5283 /* 00000000,11110000 == 0x00f0 */
5284 /* 00000000,00001111 == 0x000f */
5286 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5287 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0;
5288 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0;
5289 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0;
5290 } /* extract4444() */
5292 static void shove4444(const GLfloat shoveComponents[],
5293 int index,void *packedPixel)
5295 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5296 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5297 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5298 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5300 /* due to limited precision, need to round before shoving */
5301 ((GLushort *)packedPixel)[index] =
5302 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5303 ((GLushort *)packedPixel)[index]|=
5304 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00;
5305 ((GLushort *)packedPixel)[index]|=
5306 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0;
5307 ((GLushort *)packedPixel)[index]|=
5308 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f;
5309 } /* shove4444() */
5311 static void extract4444rev(int isSwap,const void *packedPixel,
5312 GLfloat extractComponents[])
5314 GLushort ushort;
5316 if (isSwap) {
5317 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5319 else {
5320 ushort= *(const GLushort *)packedPixel;
5323 /* 00000000,00001111 == 0x000f */
5324 /* 00000000,11110000 == 0x00f0 */
5325 /* 00001111,00000000 == 0x0f00 */
5326 /* 11110000,00000000 == 0xf000 */
5328 /* 15 = 2^4-1 */
5329 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0;
5330 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0;
5331 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0;
5332 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5333 } /* extract4444rev() */
5335 static void shove4444rev(const GLfloat shoveComponents[],
5336 int index,void *packedPixel)
5338 /* 00000000,00001111 == 0x000f */
5339 /* 00000000,11110000 == 0x00f0 */
5340 /* 00001111,00000000 == 0x0f00 */
5341 /* 11110000,00000000 == 0xf000 */
5343 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5344 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5345 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5346 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5348 /* due to limited precision, need to round before shoving */
5349 ((GLushort *)packedPixel)[index] =
5350 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F;
5351 ((GLushort *)packedPixel)[index]|=
5352 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0;
5353 ((GLushort *)packedPixel)[index]|=
5354 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00;
5355 ((GLushort *)packedPixel)[index]|=
5356 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5357 } /* shove4444rev() */
5359 static void extract5551(int isSwap,const void *packedPixel,
5360 GLfloat extractComponents[])
5362 GLushort ushort;
5364 if (isSwap) {
5365 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5367 else {
5368 ushort= *(const GLushort *)packedPixel;
5371 /* 11111000,00000000 == 0xf800 */
5372 /* 00000111,11000000 == 0x07c0 */
5373 /* 00000000,00111110 == 0x003e */
5374 /* 00000000,00000001 == 0x0001 */
5376 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5377 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0;
5378 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0;
5379 extractComponents[3]=(float)((ushort & 0x0001) );
5380 } /* extract5551() */
5382 static void shove5551(const GLfloat shoveComponents[],
5383 int index,void *packedPixel)
5385 /* 11111000,00000000 == 0xf800 */
5386 /* 00000111,11000000 == 0x07c0 */
5387 /* 00000000,00111110 == 0x003e */
5388 /* 00000000,00000001 == 0x0001 */
5390 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5391 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5392 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5393 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5395 /* due to limited precision, need to round before shoving */
5396 ((GLushort *)packedPixel)[index] =
5397 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5398 ((GLushort *)packedPixel)[index]|=
5399 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0;
5400 ((GLushort *)packedPixel)[index]|=
5401 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e;
5402 ((GLushort *)packedPixel)[index]|=
5403 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001;
5404 } /* shove5551() */
5406 static void extract1555rev(int isSwap,const void *packedPixel,
5407 GLfloat extractComponents[])
5409 GLushort ushort;
5411 if (isSwap) {
5412 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5414 else {
5415 ushort= *(const GLushort *)packedPixel;
5418 /* 00000000,00011111 == 0x001F */
5419 /* 00000011,11100000 == 0x03E0 */
5420 /* 01111100,00000000 == 0x7C00 */
5421 /* 10000000,00000000 == 0x8000 */
5423 /* 31 = 2^5-1 */
5424 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5425 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0;
5426 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5427 extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5428 } /* extract1555rev() */
5430 static void shove1555rev(const GLfloat shoveComponents[],
5431 int index,void *packedPixel)
5433 /* 00000000,00011111 == 0x001F */
5434 /* 00000011,11100000 == 0x03E0 */
5435 /* 01111100,00000000 == 0x7C00 */
5436 /* 10000000,00000000 == 0x8000 */
5438 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5439 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5440 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5441 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5443 /* due to limited precision, need to round before shoving */
5444 ((GLushort *)packedPixel)[index] =
5445 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F;
5446 ((GLushort *)packedPixel)[index]|=
5447 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0;
5448 ((GLushort *)packedPixel)[index]|=
5449 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5450 ((GLushort *)packedPixel)[index]|=
5451 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000;
5452 } /* shove1555rev() */
5454 static void extract8888(int isSwap,
5455 const void *packedPixel, GLfloat extractComponents[])
5457 GLuint uint;
5459 if (isSwap) {
5460 uint= __GLU_SWAP_4_BYTES(packedPixel);
5462 else {
5463 uint= *(const GLuint *)packedPixel;
5466 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5467 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5468 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5469 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5471 /* 255 = 2^8-1 */
5472 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5473 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5474 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0;
5475 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0;
5476 } /* extract8888() */
5478 static void shove8888(const GLfloat shoveComponents[],
5479 int index,void *packedPixel)
5481 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5482 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5483 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5484 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5486 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5487 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5488 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5489 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5491 /* due to limited precision, need to round before shoving */
5492 ((GLuint *)packedPixel)[index] =
5493 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5494 ((GLuint *)packedPixel)[index]|=
5495 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5496 ((GLuint *)packedPixel)[index]|=
5497 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00;
5498 ((GLuint *)packedPixel)[index]|=
5499 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff;
5500 } /* shove8888() */
5502 static void extract8888rev(int isSwap,
5503 const void *packedPixel,GLfloat extractComponents[])
5505 GLuint uint;
5507 if (isSwap) {
5508 uint= __GLU_SWAP_4_BYTES(packedPixel);
5510 else {
5511 uint= *(const GLuint *)packedPixel;
5514 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5515 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5516 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5517 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5519 /* 255 = 2^8-1 */
5520 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0;
5521 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0;
5522 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5523 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5524 } /* extract8888rev() */
5526 static void shove8888rev(const GLfloat shoveComponents[],
5527 int index,void *packedPixel)
5529 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5530 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5531 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5532 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5534 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5535 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5536 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5537 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5539 /* due to limited precision, need to round before shoving */
5540 ((GLuint *)packedPixel)[index] =
5541 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF;
5542 ((GLuint *)packedPixel)[index]|=
5543 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00;
5544 ((GLuint *)packedPixel)[index]|=
5545 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5546 ((GLuint *)packedPixel)[index]|=
5547 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5548 } /* shove8888rev() */
5550 static void extract1010102(int isSwap,
5551 const void *packedPixel,GLfloat extractComponents[])
5553 GLuint uint;
5555 if (isSwap) {
5556 uint= __GLU_SWAP_4_BYTES(packedPixel);
5558 else {
5559 uint= *(const GLuint *)packedPixel;
5562 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5563 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5564 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5565 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5567 /* 1023 = 2^10-1 */
5568 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5569 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5570 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0;
5571 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0;
5572 } /* extract1010102() */
5574 static void shove1010102(const GLfloat shoveComponents[],
5575 int index,void *packedPixel)
5577 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5578 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5579 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5580 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5582 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5583 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5584 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5585 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5587 /* due to limited precision, need to round before shoving */
5588 ((GLuint *)packedPixel)[index] =
5589 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5590 ((GLuint *)packedPixel)[index]|=
5591 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5592 ((GLuint *)packedPixel)[index]|=
5593 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc;
5594 ((GLuint *)packedPixel)[index]|=
5595 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003;
5596 } /* shove1010102() */
5598 static void extract2101010rev(int isSwap,
5599 const void *packedPixel,
5600 GLfloat extractComponents[])
5602 GLuint uint;
5604 if (isSwap) {
5605 uint= __GLU_SWAP_4_BYTES(packedPixel);
5607 else {
5608 uint= *(const GLuint *)packedPixel;
5611 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5612 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5613 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5614 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5616 /* 1023 = 2^10-1 */
5617 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0;
5618 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5619 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5620 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5621 /* 3 = 2^2-1 */
5622 } /* extract2101010rev() */
5624 static void shove2101010rev(const GLfloat shoveComponents[],
5625 int index,void *packedPixel)
5627 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5628 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5629 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5630 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5632 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5633 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5634 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5635 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5637 /* due to limited precision, need to round before shoving */
5638 ((GLuint *)packedPixel)[index] =
5639 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF;
5640 ((GLuint *)packedPixel)[index]|=
5641 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
5642 ((GLuint *)packedPixel)[index]|=
5643 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
5644 ((GLuint *)packedPixel)[index]|=
5645 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000;
5646 } /* shove2101010rev() */
5648 static void scaleInternalPackedPixel(int components,
5649 void (*extractPackedPixel)
5650 (int, const void *,GLfloat []),
5651 void (*shovePackedPixel)
5652 (const GLfloat [], int, void *),
5653 GLint widthIn,GLint heightIn,
5654 const void *dataIn,
5655 GLint widthOut,GLint heightOut,
5656 void *dataOut,
5657 GLint pixelSizeInBytes,
5658 GLint rowSizeInBytes,GLint isSwap)
5660 float convx;
5661 float convy;
5662 float percent;
5664 /* Max components in a format is 4, so... */
5665 float totals[4];
5666 float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
5668 float area;
5669 int i,j,k,xindex;
5671 const char *temp, *temp0;
5672 int outindex;
5674 int lowx_int, highx_int, lowy_int, highy_int;
5675 float x_percent, y_percent;
5676 float lowx_float, highx_float, lowy_float, highy_float;
5677 float convy_float, convx_float;
5678 int convy_int, convx_int;
5679 int l, m;
5680 const char *left, *right;
5682 if (widthIn == widthOut*2 && heightIn == heightOut*2) {
5683 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
5684 widthIn, heightIn, dataIn, dataOut,
5685 pixelSizeInBytes,rowSizeInBytes,isSwap);
5686 return;
5688 convy = (float) heightIn/heightOut;
5689 convx = (float) widthIn/widthOut;
5690 convy_int = floor(convy);
5691 convy_float = convy - convy_int;
5692 convx_int = floor(convx);
5693 convx_float = convx - convx_int;
5695 area = convx * convy;
5697 lowy_int = 0;
5698 lowy_float = 0;
5699 highy_int = convy_int;
5700 highy_float = convy_float;
5702 for (i = 0; i < heightOut; i++) {
5703 lowx_int = 0;
5704 lowx_float = 0;
5705 highx_int = convx_int;
5706 highx_float = convx_float;
5708 for (j = 0; j < widthOut; j++) {
5710 ** Ok, now apply box filter to box that goes from (lowx, lowy)
5711 ** to (highx, highy) on input data into this pixel on output
5712 ** data.
5714 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
5716 /* calculate the value for pixels in the 1st row */
5717 xindex = lowx_int*pixelSizeInBytes;
5718 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
5720 y_percent = 1-lowy_float;
5721 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
5722 percent = y_percent * (1-lowx_float);
5723 #if 0
5724 for (k = 0, temp_index = temp; k < components;
5725 k++, temp_index += element_size) {
5726 if (myswap_bytes) {
5727 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5728 } else {
5729 totals[k] += *(const GLushort*)temp_index * percent;
5732 #else
5733 (*extractPackedPixel)(isSwap,temp,extractTotals);
5734 for (k = 0; k < components; k++) {
5735 totals[k]+= extractTotals[k] * percent;
5737 #endif
5738 left = temp;
5739 for(l = lowx_int+1; l < highx_int; l++) {
5740 temp += pixelSizeInBytes;
5741 #if 0
5742 for (k = 0, temp_index = temp; k < components;
5743 k++, temp_index += element_size) {
5744 if (myswap_bytes) {
5745 totals[k] +=
5746 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5747 } else {
5748 totals[k] += *(const GLushort*)temp_index * y_percent;
5751 #else
5752 (*extractPackedPixel)(isSwap,temp,extractTotals);
5753 for (k = 0; k < components; k++) {
5754 totals[k]+= extractTotals[k] * y_percent;
5756 #endif
5758 temp += pixelSizeInBytes;
5759 right = temp;
5760 percent = y_percent * highx_float;
5761 #if 0
5762 for (k = 0, temp_index = temp; k < components;
5763 k++, temp_index += element_size) {
5764 if (myswap_bytes) {
5765 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5766 } else {
5767 totals[k] += *(const GLushort*)temp_index * percent;
5770 #else
5771 (*extractPackedPixel)(isSwap,temp,extractTotals);
5772 for (k = 0; k < components; k++) {
5773 totals[k]+= extractTotals[k] * percent;
5775 #endif
5777 /* calculate the value for pixels in the last row */
5779 y_percent = highy_float;
5780 percent = y_percent * (1-lowx_float);
5781 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
5782 #if 0
5783 for (k = 0, temp_index = temp; k < components;
5784 k++, temp_index += element_size) {
5785 if (myswap_bytes) {
5786 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5787 } else {
5788 totals[k] += *(const GLushort*)temp_index * percent;
5791 #else
5792 (*extractPackedPixel)(isSwap,temp,extractTotals);
5793 for (k = 0; k < components; k++) {
5794 totals[k]+= extractTotals[k] * percent;
5796 #endif
5797 for(l = lowx_int+1; l < highx_int; l++) {
5798 temp += pixelSizeInBytes;
5799 #if 0
5800 for (k = 0, temp_index = temp; k < components;
5801 k++, temp_index += element_size) {
5802 if (myswap_bytes) {
5803 totals[k] +=
5804 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5805 } else {
5806 totals[k] += *(const GLushort*)temp_index * y_percent;
5809 #else
5810 (*extractPackedPixel)(isSwap,temp,extractTotals);
5811 for (k = 0; k < components; k++) {
5812 totals[k]+= extractTotals[k] * y_percent;
5814 #endif
5817 temp += pixelSizeInBytes;
5818 percent = y_percent * highx_float;
5819 #if 0
5820 for (k = 0, temp_index = temp; k < components;
5821 k++, temp_index += element_size) {
5822 if (myswap_bytes) {
5823 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5824 } else {
5825 totals[k] += *(const GLushort*)temp_index * percent;
5828 #else
5829 (*extractPackedPixel)(isSwap,temp,extractTotals);
5830 for (k = 0; k < components; k++) {
5831 totals[k]+= extractTotals[k] * percent;
5833 #endif
5835 /* calculate the value for pixels in the 1st and last column */
5836 for(m = lowy_int+1; m < highy_int; m++) {
5837 left += rowSizeInBytes;
5838 right += rowSizeInBytes;
5839 #if 0
5840 for (k = 0; k < components;
5841 k++, left += element_size, right += element_size) {
5842 if (myswap_bytes) {
5843 totals[k] +=
5844 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
5845 __GLU_SWAP_2_BYTES(right) * highx_float;
5846 } else {
5847 totals[k] += *(const GLushort*)left * (1-lowx_float)
5848 + *(const GLushort*)right * highx_float;
5851 #else
5852 (*extractPackedPixel)(isSwap,left,extractTotals);
5853 (*extractPackedPixel)(isSwap,right,extractMoreTotals);
5854 for (k = 0; k < components; k++) {
5855 totals[k]+= (extractTotals[k]*(1-lowx_float) +
5856 extractMoreTotals[k]*highx_float);
5858 #endif
5860 } else if (highy_int > lowy_int) {
5861 x_percent = highx_float - lowx_float;
5862 percent = (1-lowy_float)*x_percent;
5863 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
5864 #if 0
5865 for (k = 0, temp_index = temp; k < components;
5866 k++, temp_index += element_size) {
5867 if (myswap_bytes) {
5868 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5869 } else {
5870 totals[k] += *(const GLushort*)temp_index * percent;
5873 #else
5874 (*extractPackedPixel)(isSwap,temp,extractTotals);
5875 for (k = 0; k < components; k++) {
5876 totals[k]+= extractTotals[k] * percent;
5878 #endif
5879 for(m = lowy_int+1; m < highy_int; m++) {
5880 temp += rowSizeInBytes;
5881 #if 0
5882 for (k = 0, temp_index = temp; k < components;
5883 k++, temp_index += element_size) {
5884 if (myswap_bytes) {
5885 totals[k] +=
5886 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
5887 } else {
5888 totals[k] += *(const GLushort*)temp_index * x_percent;
5891 #else
5892 (*extractPackedPixel)(isSwap,temp,extractTotals);
5893 for (k = 0; k < components; k++) {
5894 totals[k]+= extractTotals[k] * x_percent;
5896 #endif
5898 percent = x_percent * highy_float;
5899 temp += rowSizeInBytes;
5900 #if 0
5901 for (k = 0, temp_index = temp; k < components;
5902 k++, temp_index += element_size) {
5903 if (myswap_bytes) {
5904 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5905 } else {
5906 totals[k] += *(const GLushort*)temp_index * percent;
5909 #else
5910 (*extractPackedPixel)(isSwap,temp,extractTotals);
5911 for (k = 0; k < components; k++) {
5912 totals[k]+= extractTotals[k] * percent;
5914 #endif
5915 } else if (highx_int > lowx_int) {
5916 y_percent = highy_float - lowy_float;
5917 percent = (1-lowx_float)*y_percent;
5918 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
5919 #if 0
5920 for (k = 0, temp_index = temp; k < components;
5921 k++, temp_index += element_size) {
5922 if (myswap_bytes) {
5923 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5924 } else {
5925 totals[k] += *(const GLushort*)temp_index * percent;
5928 #else
5929 (*extractPackedPixel)(isSwap,temp,extractTotals);
5930 for (k = 0; k < components; k++) {
5931 totals[k]+= extractTotals[k] * percent;
5933 #endif
5934 for (l = lowx_int+1; l < highx_int; l++) {
5935 temp += pixelSizeInBytes;
5936 #if 0
5937 for (k = 0, temp_index = temp; k < components;
5938 k++, temp_index += element_size) {
5939 if (myswap_bytes) {
5940 totals[k] +=
5941 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5942 } else {
5943 totals[k] += *(const GLushort*)temp_index * y_percent;
5946 #else
5947 (*extractPackedPixel)(isSwap,temp,extractTotals);
5948 for (k = 0; k < components; k++) {
5949 totals[k]+= extractTotals[k] * y_percent;
5951 #endif
5953 temp += pixelSizeInBytes;
5954 percent = y_percent * highx_float;
5955 #if 0
5956 for (k = 0, temp_index = temp; k < components;
5957 k++, temp_index += element_size) {
5958 if (myswap_bytes) {
5959 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5960 } else {
5961 totals[k] += *(const GLushort*)temp_index * percent;
5964 #else
5965 (*extractPackedPixel)(isSwap,temp,extractTotals);
5966 for (k = 0; k < components; k++) {
5967 totals[k]+= extractTotals[k] * percent;
5969 #endif
5970 } else {
5971 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
5972 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
5973 #if 0
5974 for (k = 0, temp_index = temp; k < components;
5975 k++, temp_index += element_size) {
5976 if (myswap_bytes) {
5977 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5978 } else {
5979 totals[k] += *(const GLushort*)temp_index * percent;
5982 #else
5983 (*extractPackedPixel)(isSwap,temp,extractTotals);
5984 for (k = 0; k < components; k++) {
5985 totals[k]+= extractTotals[k] * percent;
5987 #endif
5990 /* this is for the pixels in the body */
5991 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
5992 for (m = lowy_int+1; m < highy_int; m++) {
5993 temp = temp0;
5994 for(l = lowx_int+1; l < highx_int; l++) {
5995 #if 0
5996 for (k = 0, temp_index = temp; k < components;
5997 k++, temp_index += element_size) {
5998 if (myswap_bytes) {
5999 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6000 } else {
6001 totals[k] += *(const GLushort*)temp_index;
6004 #else
6005 (*extractPackedPixel)(isSwap,temp,extractTotals);
6006 for (k = 0; k < components; k++) {
6007 totals[k]+= extractTotals[k];
6009 #endif
6010 temp += pixelSizeInBytes;
6012 temp0 += rowSizeInBytes;
6015 outindex = (j + (i * widthOut)); /* * (components == 1) */
6016 #if 0
6017 for (k = 0; k < components; k++) {
6018 dataout[outindex + k] = totals[k]/area;
6019 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6021 #else
6022 for (k = 0; k < components; k++) {
6023 shoveTotals[k]= totals[k]/area;
6025 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6026 #endif
6027 lowx_int = highx_int;
6028 lowx_float = highx_float;
6029 highx_int += convx_int;
6030 highx_float += convx_float;
6031 if(highx_float > 1) {
6032 highx_float -= 1.0;
6033 highx_int++;
6036 lowy_int = highy_int;
6037 lowy_float = highy_float;
6038 highy_int += convy_int;
6039 highy_float += convy_float;
6040 if(highy_float > 1) {
6041 highy_float -= 1.0;
6042 highy_int++;
6045 } /* scaleInternalPackedPixel() */
6047 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6048 * inputs; not always equal. Output NEVER has row padding.
6050 static void halveImagePackedPixel(int components,
6051 void (*extractPackedPixel)
6052 (int, const void *,GLfloat []),
6053 void (*shovePackedPixel)
6054 (const GLfloat [],int, void *),
6055 GLint width, GLint height,
6056 const void *dataIn, void *dataOut,
6057 GLint pixelSizeInBytes,
6058 GLint rowSizeInBytes, GLint isSwap)
6060 /* handle case where there is only 1 column/row */
6061 if (width == 1 || height == 1) {
6062 assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6063 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6064 width,height,dataIn,dataOut,pixelSizeInBytes,
6065 rowSizeInBytes,isSwap);
6066 return;
6070 int ii, jj;
6072 int halfWidth= width / 2;
6073 int halfHeight= height / 2;
6074 const char *src= (const char *) dataIn;
6075 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6076 int outIndex= 0;
6078 for (ii= 0; ii< halfHeight; ii++) {
6079 for (jj= 0; jj< halfWidth; jj++) {
6080 #define BOX4 4
6081 float totals[4]; /* 4 is maximum components */
6082 float extractTotals[BOX4][4]; /* 4 is maximum components */
6083 int cc;
6085 (*extractPackedPixel)(isSwap,src,
6086 &extractTotals[0][0]);
6087 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6088 &extractTotals[1][0]);
6089 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6090 &extractTotals[2][0]);
6091 (*extractPackedPixel)(isSwap,
6092 (src+rowSizeInBytes+pixelSizeInBytes),
6093 &extractTotals[3][0]);
6094 for (cc = 0; cc < components; cc++) {
6095 int kk;
6097 /* grab 4 pixels to average */
6098 totals[cc]= 0.0;
6099 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6100 * extractTotals[2][RED]+extractTotals[3][RED];
6101 * totals[RED]/= 4.0;
6103 for (kk = 0; kk < BOX4; kk++) {
6104 totals[cc]+= extractTotals[kk][cc];
6106 totals[cc]/= (float)BOX4;
6108 (*shovePackedPixel)(totals,outIndex,dataOut);
6110 outIndex++;
6111 /* skip over to next square of 4 */
6112 src+= pixelSizeInBytes + pixelSizeInBytes;
6114 /* skip past pad bytes, if any, to get to next row */
6115 src+= padBytes;
6117 /* src is at beginning of a row here, but it's the second row of
6118 * the square block of 4 pixels that we just worked on so we
6119 * need to go one more row.
6120 * i.e.,
6121 * OO...
6122 * here -->OO...
6123 * but want -->OO...
6124 * OO...
6125 * ...
6127 src+= rowSizeInBytes;
6130 /* both pointers must reach one byte after the end */
6131 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6132 assert(outIndex == halfWidth * halfHeight);
6134 } /* halveImagePackedPixel() */
6136 static void halve1DimagePackedPixel(int components,
6137 void (*extractPackedPixel)
6138 (int, const void *,GLfloat []),
6139 void (*shovePackedPixel)
6140 (const GLfloat [],int, void *),
6141 GLint width, GLint height,
6142 const void *dataIn, void *dataOut,
6143 GLint pixelSizeInBytes,
6144 GLint rowSizeInBytes, GLint isSwap)
6146 int halfWidth= width / 2;
6147 int halfHeight= height / 2;
6148 const char *src= (const char *) dataIn;
6149 int jj;
6151 assert(width == 1 || height == 1); /* must be 1D */
6152 assert(width != height); /* can't be square */
6154 if (height == 1) { /* 1 row */
6155 int outIndex= 0;
6157 assert(width != 1); /* widthxheight can't be 1x1 */
6158 halfHeight= 1;
6160 /* one horizontal row with possible pad bytes */
6162 for (jj= 0; jj< halfWidth; jj++) {
6163 #define BOX2 2
6164 float totals[4]; /* 4 is maximum components */
6165 float extractTotals[BOX2][4]; /* 4 is maximum components */
6166 int cc;
6168 /* average two at a time, instead of four */
6169 (*extractPackedPixel)(isSwap,src,
6170 &extractTotals[0][0]);
6171 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6172 &extractTotals[1][0]);
6173 for (cc = 0; cc < components; cc++) {
6174 int kk;
6176 /* grab 2 pixels to average */
6177 totals[cc]= 0.0;
6178 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6179 * totals[RED]/= 2.0;
6181 for (kk = 0; kk < BOX2; kk++) {
6182 totals[cc]+= extractTotals[kk][cc];
6184 totals[cc]/= (float)BOX2;
6186 (*shovePackedPixel)(totals,outIndex,dataOut);
6188 outIndex++;
6189 /* skip over to next group of 2 */
6190 src+= pixelSizeInBytes + pixelSizeInBytes;
6194 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6195 src+= padBytes; /* for assertion only */
6197 assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6198 assert(outIndex == halfWidth * halfHeight);
6200 else if (width == 1) { /* 1 column */
6201 int outIndex= 0;
6203 assert(height != 1); /* widthxheight can't be 1x1 */
6204 halfWidth= 1;
6205 /* one vertical column with possible pad bytes per row */
6206 /* average two at a time */
6208 for (jj= 0; jj< halfHeight; jj++) {
6209 #define BOX2 2
6210 float totals[4]; /* 4 is maximum components */
6211 float extractTotals[BOX2][4]; /* 4 is maximum components */
6212 int cc;
6214 /* average two at a time, instead of four */
6215 (*extractPackedPixel)(isSwap,src,
6216 &extractTotals[0][0]);
6217 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6218 &extractTotals[1][0]);
6219 for (cc = 0; cc < components; cc++) {
6220 int kk;
6222 /* grab 2 pixels to average */
6223 totals[cc]= 0.0;
6224 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6225 * totals[RED]/= 2.0;
6227 for (kk = 0; kk < BOX2; kk++) {
6228 totals[cc]+= extractTotals[kk][cc];
6230 totals[cc]/= (float)BOX2;
6232 (*shovePackedPixel)(totals,outIndex,dataOut);
6234 outIndex++;
6235 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6238 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6239 assert(outIndex == halfWidth * halfHeight);
6241 } /* halve1DimagePackedPixel() */