urlmon/tests: Add basic tests for CoInternetParseUrl(PARSE_CANONICALIZE).
[wine.git] / dlls / glu32 / mipmap.c
blobb0854f2fca899750d4ca1d8dd65f8ba3b1798b55
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 "wingdi.h"
41 #include "wine/wgl.h"
42 #include "wine/glu.h"
44 #define GLU_INVALID_OPERATION GLU_INVALID_VALUE /* GLU_INVALID_OPERATION is missing on Windows */
46 typedef union {
47 unsigned char ub[4];
48 unsigned short us[2];
49 unsigned int ui;
50 char b[4];
51 short s[2];
52 int i;
53 float f;
54 } Type_Widget;
56 /* Pixel storage modes */
57 typedef struct {
58 GLint pack_alignment;
59 GLint pack_row_length;
60 GLint pack_skip_rows;
61 GLint pack_skip_pixels;
62 GLint pack_lsb_first;
63 GLint pack_swap_bytes;
64 GLint pack_skip_images;
65 GLint pack_image_height;
67 GLint unpack_alignment;
68 GLint unpack_row_length;
69 GLint unpack_skip_rows;
70 GLint unpack_skip_pixels;
71 GLint unpack_lsb_first;
72 GLint unpack_swap_bytes;
73 GLint unpack_skip_images;
74 GLint unpack_image_height;
75 } PixelStorageModes;
77 static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
78 GLsizei,
79 GLsizei,
80 GLenum, GLenum, GLint, GLint, GLint,
81 const void *);
82 static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
83 GLsizei, GLsizei,
84 GLsizei, GLsizei,
85 GLenum, GLenum, GLint, GLint, GLint,
86 const void *);
89 * internal function declarations
91 static GLfloat bytes_per_element(GLenum type);
92 static GLint elements_per_group(GLenum format, GLenum type);
93 static GLint is_index(GLenum format);
94 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
95 static void fill_image(const PixelStorageModes *,
96 GLint width, GLint height, GLenum format,
97 GLenum type, GLboolean index_format,
98 const void *userdata, GLushort *newimage);
99 static void empty_image(const PixelStorageModes *,
100 GLint width, GLint height, GLenum format,
101 GLenum type, GLboolean index_format,
102 const GLushort *oldimage, void *userdata);
103 static void scale_internal(GLint components, GLint widthin, GLint heightin,
104 const GLushort *datain,
105 GLint widthout, GLint heightout,
106 GLushort *dataout);
108 static void scale_internal_ubyte(GLint components, GLint widthin,
109 GLint heightin, const GLubyte *datain,
110 GLint widthout, GLint heightout,
111 GLubyte *dataout, GLint element_size,
112 GLint ysize, GLint group_size);
113 static void scale_internal_byte(GLint components, GLint widthin,
114 GLint heightin, const GLbyte *datain,
115 GLint widthout, GLint heightout,
116 GLbyte *dataout, GLint element_size,
117 GLint ysize, GLint group_size);
118 static void scale_internal_ushort(GLint components, GLint widthin,
119 GLint heightin, const GLushort *datain,
120 GLint widthout, GLint heightout,
121 GLushort *dataout, GLint element_size,
122 GLint ysize, GLint group_size,
123 GLint myswap_bytes);
124 static void scale_internal_short(GLint components, GLint widthin,
125 GLint heightin, const GLshort *datain,
126 GLint widthout, GLint heightout,
127 GLshort *dataout, GLint element_size,
128 GLint ysize, GLint group_size,
129 GLint myswap_bytes);
130 static void scale_internal_uint(GLint components, GLint widthin,
131 GLint heightin, const GLuint *datain,
132 GLint widthout, GLint heightout,
133 GLuint *dataout, GLint element_size,
134 GLint ysize, GLint group_size,
135 GLint myswap_bytes);
136 static void scale_internal_int(GLint components, GLint widthin,
137 GLint heightin, const GLint *datain,
138 GLint widthout, GLint heightout,
139 GLint *dataout, GLint element_size,
140 GLint ysize, GLint group_size,
141 GLint myswap_bytes);
142 static void scale_internal_float(GLint components, GLint widthin,
143 GLint heightin, const GLfloat *datain,
144 GLint widthout, GLint heightout,
145 GLfloat *dataout, GLint element_size,
146 GLint ysize, GLint group_size,
147 GLint myswap_bytes);
149 static int checkMipmapArgs(GLenum, GLenum, GLenum);
150 static GLboolean legalFormat(GLenum);
151 static GLboolean legalType(GLenum);
152 static GLboolean isTypePackedPixel(GLenum);
153 static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
154 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
155 GLint *, GLint *);
157 /* packedpixel type scale routines */
158 static void extract332(int,const void *, GLfloat []);
159 static void shove332(const GLfloat [],int ,void *);
160 static void extract233rev(int,const void *, GLfloat []);
161 static void shove233rev(const GLfloat [],int ,void *);
162 static void extract565(int,const void *, GLfloat []);
163 static void shove565(const GLfloat [],int ,void *);
164 static void extract565rev(int,const void *, GLfloat []);
165 static void shove565rev(const GLfloat [],int ,void *);
166 static void extract4444(int,const void *, GLfloat []);
167 static void shove4444(const GLfloat [],int ,void *);
168 static void extract4444rev(int,const void *, GLfloat []);
169 static void shove4444rev(const GLfloat [],int ,void *);
170 static void extract5551(int,const void *, GLfloat []);
171 static void shove5551(const GLfloat [],int ,void *);
172 static void extract1555rev(int,const void *, GLfloat []);
173 static void shove1555rev(const GLfloat [],int ,void *);
174 static void extract8888(int,const void *, GLfloat []);
175 static void shove8888(const GLfloat [],int ,void *);
176 static void extract8888rev(int,const void *, GLfloat []);
177 static void shove8888rev(const GLfloat [],int ,void *);
178 static void extract1010102(int,const void *, GLfloat []);
179 static void shove1010102(const GLfloat [],int ,void *);
180 static void extract2101010rev(int,const void *, GLfloat []);
181 static void shove2101010rev(const GLfloat [],int ,void *);
182 static void scaleInternalPackedPixel(int,
183 void (*)(int, const void *,GLfloat []),
184 void (*)(const GLfloat [],int, void *),
185 GLint,GLint, const void *,
186 GLint,GLint,void *,GLint,GLint,GLint);
187 static void halveImagePackedPixel(int,
188 void (*)(int, const void *,GLfloat []),
189 void (*)(const GLfloat [],int, void *),
190 GLint, GLint, const void *,
191 void *, GLint, GLint, GLint);
192 static void halve1DimagePackedPixel(int,
193 void (*)(int, const void *,GLfloat []),
194 void (*)(const GLfloat [],int, void *),
195 GLint, GLint, const void *,
196 void *, GLint, GLint, GLint);
198 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
199 GLubyte *, GLint, GLint, GLint);
200 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
201 GLint, GLint, GLint);
202 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
203 GLushort *, GLint, GLint, GLint, GLint);
204 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
205 GLint, GLint, GLint, GLint);
206 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
207 GLint, GLint, GLint, GLint);
208 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
209 GLint, GLint, GLint, GLint);
210 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
211 GLint, GLint, GLint, GLint);
213 static void retrieveStoreModes(PixelStorageModes *psm)
215 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
216 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
217 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
218 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
219 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
220 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
222 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
223 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
224 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
225 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
226 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
227 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
230 static int computeLog(GLuint value)
232 int i;
234 i = 0;
236 /* Error! */
237 if (value == 0) return -1;
239 for (;;) {
240 if (value & 1) {
241 /* Error ! */
242 if (value != 1) return -1;
243 return i;
245 value = value >> 1;
246 i++;
251 ** Compute the nearest power of 2 number. This algorithm is a little
252 ** strange, but it works quite well.
254 static int nearestPower(GLuint value)
256 int i;
258 i = 1;
260 /* Error! */
261 if (value == 0) return -1;
263 for (;;) {
264 if (value == 1) {
265 return i;
266 } else if (value == 3) {
267 return i*4;
269 value = value >> 1;
270 i *= 2;
274 #define __GLU_SWAP_2_BYTES(s)\
275 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
277 #define __GLU_SWAP_4_BYTES(s)\
278 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
279 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
280 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
282 static void halveImage(GLint components, GLuint width, GLuint height,
283 const GLushort *datain, GLushort *dataout)
285 int i, j, k;
286 int newwidth, newheight;
287 int delta;
288 GLushort *s;
289 const GLushort *t;
291 newwidth = width / 2;
292 newheight = height / 2;
293 delta = width * components;
294 s = dataout;
295 t = datain;
297 /* Piece o' cake! */
298 for (i = 0; i < newheight; i++) {
299 for (j = 0; j < newwidth; j++) {
300 for (k = 0; k < components; k++) {
301 s[0] = (t[0] + t[components] + t[delta] +
302 t[delta+components] + 2) / 4;
303 s++; t++;
305 t += components;
307 t += delta;
311 static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
312 const GLubyte *datain, GLubyte *dataout,
313 GLint element_size, GLint ysize, GLint group_size)
315 int i, j, k;
316 int newwidth, newheight;
317 int padBytes;
318 GLubyte *s;
319 const char *t;
321 /* handle case where there is only 1 column/row */
322 if (width == 1 || height == 1) {
323 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
324 halve1Dimage_ubyte(components,width,height,datain,dataout,
325 element_size,ysize,group_size);
326 return;
329 newwidth = width / 2;
330 newheight = height / 2;
331 padBytes = ysize - (width*group_size);
332 s = dataout;
333 t = (const char *)datain;
335 /* Piece o' cake! */
336 for (i = 0; i < newheight; i++) {
337 for (j = 0; j < newwidth; j++) {
338 for (k = 0; k < components; k++) {
339 s[0] = (*(const GLubyte*)t +
340 *(const GLubyte*)(t+group_size) +
341 *(const GLubyte*)(t+ysize) +
342 *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
343 s++; t += element_size;
345 t += group_size;
347 t += padBytes;
348 t += ysize;
352 /* */
353 static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
354 const GLubyte *dataIn, GLubyte *dataOut,
355 GLint element_size, GLint ysize,
356 GLint group_size)
358 GLint halfWidth= width / 2;
359 GLint halfHeight= height / 2;
360 const char *src= (const char *) dataIn;
361 GLubyte *dest= dataOut;
362 int jj;
364 assert(width == 1 || height == 1); /* must be 1D */
365 assert(width != height); /* can't be square */
367 if (height == 1) { /* 1 row */
368 assert(width != 1); /* widthxheight can't be 1x1 */
369 halfHeight= 1;
371 for (jj= 0; jj< halfWidth; jj++) {
372 int kk;
373 for (kk= 0; kk< components; kk++) {
374 *dest= (*(const GLubyte*)src +
375 *(const GLubyte*)(src+group_size)) / 2;
377 src+= element_size;
378 dest++;
380 src+= group_size; /* skip to next 2 */
383 int padBytes= ysize - (width*group_size);
384 src+= padBytes; /* for assertion only */
387 else if (width == 1) { /* 1 column */
388 int padBytes= ysize - (width * group_size);
389 assert(height != 1); /* widthxheight can't be 1x1 */
390 halfWidth= 1;
391 /* one vertical column with possible pad bytes per row */
392 /* average two at a time */
394 for (jj= 0; jj< halfHeight; jj++) {
395 int kk;
396 for (kk= 0; kk< components; kk++) {
397 *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
399 src+= element_size;
400 dest++;
402 src+= padBytes; /* add pad bytes, if any, to get to end to row */
403 src+= ysize;
407 assert(src == &((const char *)dataIn)[ysize*height]);
408 assert((char *)dest == &((char *)dataOut)
409 [components * element_size * halfWidth * halfHeight]);
410 } /* halve1Dimage_ubyte() */
412 static void halveImage_byte(GLint components, GLuint width, GLuint height,
413 const GLbyte *datain, GLbyte *dataout,
414 GLint element_size,
415 GLint ysize, GLint group_size)
417 int i, j, k;
418 int newwidth, newheight;
419 int padBytes;
420 GLbyte *s;
421 const char *t;
423 /* handle case where there is only 1 column/row */
424 if (width == 1 || height == 1) {
425 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
426 halve1Dimage_byte(components,width,height,datain,dataout,
427 element_size,ysize,group_size);
428 return;
431 newwidth = width / 2;
432 newheight = height / 2;
433 padBytes = ysize - (width*group_size);
434 s = dataout;
435 t = (const char *)datain;
437 /* Piece o' cake! */
438 for (i = 0; i < newheight; i++) {
439 for (j = 0; j < newwidth; j++) {
440 for (k = 0; k < components; k++) {
441 s[0] = (*(const GLbyte*)t +
442 *(const GLbyte*)(t+group_size) +
443 *(const GLbyte*)(t+ysize) +
444 *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
445 s++; t += element_size;
447 t += group_size;
449 t += padBytes;
450 t += ysize;
454 static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
455 const GLbyte *dataIn, GLbyte *dataOut,
456 GLint element_size,GLint ysize, GLint group_size)
458 GLint halfWidth= width / 2;
459 GLint halfHeight= height / 2;
460 const char *src= (const char *) dataIn;
461 GLbyte *dest= dataOut;
462 int jj;
464 assert(width == 1 || height == 1); /* must be 1D */
465 assert(width != height); /* can't be square */
467 if (height == 1) { /* 1 row */
468 assert(width != 1); /* widthxheight can't be 1x1 */
469 halfHeight= 1;
471 for (jj= 0; jj< halfWidth; jj++) {
472 int kk;
473 for (kk= 0; kk< components; kk++) {
474 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
476 src+= element_size;
477 dest++;
479 src+= group_size; /* skip to next 2 */
482 int padBytes= ysize - (width*group_size);
483 src+= padBytes; /* for assertion only */
486 else if (width == 1) { /* 1 column */
487 int padBytes= ysize - (width * group_size);
488 assert(height != 1); /* widthxheight can't be 1x1 */
489 halfWidth= 1;
490 /* one vertical column with possible pad bytes per row */
491 /* average two at a time */
493 for (jj= 0; jj< halfHeight; jj++) {
494 int kk;
495 for (kk= 0; kk< components; kk++) {
496 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
498 src+= element_size;
499 dest++;
501 src+= padBytes; /* add pad bytes, if any, to get to end to row */
502 src+= ysize;
505 assert(src == &((const char *)dataIn)[ysize*height]);
508 assert((char *)dest == &((char *)dataOut)
509 [components * element_size * halfWidth * halfHeight]);
510 } /* halve1Dimage_byte() */
512 static void halveImage_ushort(GLint components, GLuint width, GLuint height,
513 const GLushort *datain, GLushort *dataout,
514 GLint element_size, GLint ysize, GLint group_size,
515 GLint myswap_bytes)
517 int i, j, k;
518 int newwidth, newheight;
519 int padBytes;
520 GLushort *s;
521 const char *t;
523 /* handle case where there is only 1 column/row */
524 if (width == 1 || height == 1) {
525 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
526 halve1Dimage_ushort(components,width,height,datain,dataout,
527 element_size,ysize,group_size, myswap_bytes);
528 return;
531 newwidth = width / 2;
532 newheight = height / 2;
533 padBytes = ysize - (width*group_size);
534 s = dataout;
535 t = (const char *)datain;
537 /* Piece o' cake! */
538 if (!myswap_bytes)
539 for (i = 0; i < newheight; i++) {
540 for (j = 0; j < newwidth; j++) {
541 for (k = 0; k < components; k++) {
542 s[0] = (*(const GLushort*)t +
543 *(const GLushort*)(t+group_size) +
544 *(const GLushort*)(t+ysize) +
545 *(const GLushort*)(t+ysize+group_size) + 2) / 4;
546 s++; t += element_size;
548 t += group_size;
550 t += padBytes;
551 t += ysize;
553 else
554 for (i = 0; i < newheight; i++) {
555 for (j = 0; j < newwidth; j++) {
556 for (k = 0; k < components; k++) {
557 s[0] = (__GLU_SWAP_2_BYTES(t) +
558 __GLU_SWAP_2_BYTES(t+group_size) +
559 __GLU_SWAP_2_BYTES(t+ysize) +
560 __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
561 s++; t += element_size;
563 t += group_size;
565 t += padBytes;
566 t += ysize;
570 static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
571 const GLushort *dataIn, GLushort *dataOut,
572 GLint element_size, GLint ysize,
573 GLint group_size, GLint myswap_bytes)
575 GLint halfWidth= width / 2;
576 GLint halfHeight= height / 2;
577 const char *src= (const char *) dataIn;
578 GLushort *dest= dataOut;
579 int jj;
581 assert(width == 1 || height == 1); /* must be 1D */
582 assert(width != height); /* can't be square */
584 if (height == 1) { /* 1 row */
585 assert(width != 1); /* widthxheight can't be 1x1 */
586 halfHeight= 1;
588 for (jj= 0; jj< halfWidth; jj++) {
589 int kk;
590 for (kk= 0; kk< components; kk++) {
591 #define BOX2 2
592 GLushort ushort[BOX2];
593 if (myswap_bytes) {
594 ushort[0]= __GLU_SWAP_2_BYTES(src);
595 ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
597 else {
598 ushort[0]= *(const GLushort*)src;
599 ushort[1]= *(const GLushort*)(src+group_size);
602 *dest= (ushort[0] + ushort[1]) / 2;
603 src+= element_size;
604 dest++;
606 src+= group_size; /* skip to next 2 */
609 int padBytes= ysize - (width*group_size);
610 src+= padBytes; /* for assertion only */
613 else if (width == 1) { /* 1 column */
614 int padBytes= ysize - (width * group_size);
615 assert(height != 1); /* widthxheight can't be 1x1 */
616 halfWidth= 1;
617 /* one vertical column with possible pad bytes per row */
618 /* average two at a time */
620 for (jj= 0; jj< halfHeight; jj++) {
621 int kk;
622 for (kk= 0; kk< components; kk++) {
623 #define BOX2 2
624 GLushort ushort[BOX2];
625 if (myswap_bytes) {
626 ushort[0]= __GLU_SWAP_2_BYTES(src);
627 ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
629 else {
630 ushort[0]= *(const GLushort*)src;
631 ushort[1]= *(const GLushort*)(src+ysize);
633 *dest= (ushort[0] + ushort[1]) / 2;
635 src+= element_size;
636 dest++;
638 src+= padBytes; /* add pad bytes, if any, to get to end to row */
639 src+= ysize;
642 assert(src == &((const char *)dataIn)[ysize*height]);
645 assert((char *)dest == &((char *)dataOut)
646 [components * element_size * halfWidth * halfHeight]);
648 } /* halve1Dimage_ushort() */
651 static void halveImage_short(GLint components, GLuint width, GLuint height,
652 const GLshort *datain, GLshort *dataout,
653 GLint element_size, GLint ysize, GLint group_size,
654 GLint myswap_bytes)
656 int i, j, k;
657 int newwidth, newheight;
658 int padBytes;
659 GLshort *s;
660 const char *t;
662 /* handle case where there is only 1 column/row */
663 if (width == 1 || height == 1) {
664 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
665 halve1Dimage_short(components,width,height,datain,dataout,
666 element_size,ysize,group_size, myswap_bytes);
667 return;
670 newwidth = width / 2;
671 newheight = height / 2;
672 padBytes = ysize - (width*group_size);
673 s = dataout;
674 t = (const char *)datain;
676 /* Piece o' cake! */
677 if (!myswap_bytes)
678 for (i = 0; i < newheight; i++) {
679 for (j = 0; j < newwidth; j++) {
680 for (k = 0; k < components; k++) {
681 s[0] = (*(const GLshort*)t +
682 *(const GLshort*)(t+group_size) +
683 *(const GLshort*)(t+ysize) +
684 *(const GLshort*)(t+ysize+group_size) + 2) / 4;
685 s++; t += element_size;
687 t += group_size;
689 t += padBytes;
690 t += ysize;
692 else
693 for (i = 0; i < newheight; i++) {
694 for (j = 0; j < newwidth; j++) {
695 for (k = 0; k < components; k++) {
696 GLushort b;
697 GLint buf;
698 b = __GLU_SWAP_2_BYTES(t);
699 buf = *(const GLshort*)&b;
700 b = __GLU_SWAP_2_BYTES(t+group_size);
701 buf += *(const GLshort*)&b;
702 b = __GLU_SWAP_2_BYTES(t+ysize);
703 buf += *(const GLshort*)&b;
704 b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
705 buf += *(const GLshort*)&b;
706 s[0] = (GLshort)((buf+2)/4);
707 s++; t += element_size;
709 t += group_size;
711 t += padBytes;
712 t += ysize;
716 static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
717 const GLshort *dataIn, GLshort *dataOut,
718 GLint element_size, GLint ysize,
719 GLint group_size, GLint myswap_bytes)
721 GLint halfWidth= width / 2;
722 GLint halfHeight= height / 2;
723 const char *src= (const char *) dataIn;
724 GLshort *dest= dataOut;
725 int jj;
727 assert(width == 1 || height == 1); /* must be 1D */
728 assert(width != height); /* can't be square */
730 if (height == 1) { /* 1 row */
731 assert(width != 1); /* widthxheight can't be 1x1 */
732 halfHeight= 1;
734 for (jj= 0; jj< halfWidth; jj++) {
735 int kk;
736 for (kk= 0; kk< components; kk++) {
737 #define BOX2 2
738 GLshort sshort[BOX2];
739 if (myswap_bytes) {
740 sshort[0]= __GLU_SWAP_2_BYTES(src);
741 sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
743 else {
744 sshort[0]= *(const GLshort*)src;
745 sshort[1]= *(const GLshort*)(src+group_size);
748 *dest= (sshort[0] + sshort[1]) / 2;
749 src+= element_size;
750 dest++;
752 src+= group_size; /* skip to next 2 */
755 int padBytes= ysize - (width*group_size);
756 src+= padBytes; /* for assertion only */
759 else if (width == 1) { /* 1 column */
760 int padBytes= ysize - (width * group_size);
761 assert(height != 1); /* widthxheight can't be 1x1 */
762 halfWidth= 1;
763 /* one vertical column with possible pad bytes per row */
764 /* average two at a time */
766 for (jj= 0; jj< halfHeight; jj++) {
767 int kk;
768 for (kk= 0; kk< components; kk++) {
769 #define BOX2 2
770 GLshort sshort[BOX2];
771 if (myswap_bytes) {
772 sshort[0]= __GLU_SWAP_2_BYTES(src);
773 sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
775 else {
776 sshort[0]= *(const GLshort*)src;
777 sshort[1]= *(const GLshort*)(src+ysize);
779 *dest= (sshort[0] + sshort[1]) / 2;
781 src+= element_size;
782 dest++;
784 src+= padBytes; /* add pad bytes, if any, to get to end to row */
785 src+= ysize;
788 assert(src == &((const char *)dataIn)[ysize*height]);
791 assert((char *)dest == &((char *)dataOut)
792 [components * element_size * halfWidth * halfHeight]);
794 } /* halve1Dimage_short() */
797 static void halveImage_uint(GLint components, GLuint width, GLuint height,
798 const GLuint *datain, GLuint *dataout,
799 GLint element_size, GLint ysize, GLint group_size,
800 GLint myswap_bytes)
802 int i, j, k;
803 int newwidth, newheight;
804 int padBytes;
805 GLuint *s;
806 const char *t;
808 /* handle case where there is only 1 column/row */
809 if (width == 1 || height == 1) {
810 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
811 halve1Dimage_uint(components,width,height,datain,dataout,
812 element_size,ysize,group_size, myswap_bytes);
813 return;
816 newwidth = width / 2;
817 newheight = height / 2;
818 padBytes = ysize - (width*group_size);
819 s = dataout;
820 t = (const char *)datain;
822 /* Piece o' cake! */
823 if (!myswap_bytes)
824 for (i = 0; i < newheight; i++) {
825 for (j = 0; j < newwidth; j++) {
826 for (k = 0; k < components; k++) {
827 /* need to cast to double to hold large unsigned ints */
828 s[0] = ((double)*(const GLuint*)t +
829 (double)*(const GLuint*)(t+group_size) +
830 (double)*(const GLuint*)(t+ysize) +
831 (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
832 s++; t += element_size;
835 t += group_size;
837 t += padBytes;
838 t += ysize;
840 else
841 for (i = 0; i < newheight; i++) {
842 for (j = 0; j < newwidth; j++) {
843 for (k = 0; k < components; k++) {
844 /* need to cast to double to hold large unsigned ints */
845 GLdouble buf;
846 buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
847 (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
848 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
849 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
850 s[0] = (GLuint)(buf/4 + 0.5);
852 s++; t += element_size;
854 t += group_size;
856 t += padBytes;
857 t += ysize;
861 /* */
862 static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
863 const GLuint *dataIn, GLuint *dataOut,
864 GLint element_size, GLint ysize,
865 GLint group_size, GLint myswap_bytes)
867 GLint halfWidth= width / 2;
868 GLint halfHeight= height / 2;
869 const char *src= (const char *) dataIn;
870 GLuint *dest= dataOut;
871 int jj;
873 assert(width == 1 || height == 1); /* must be 1D */
874 assert(width != height); /* can't be square */
876 if (height == 1) { /* 1 row */
877 assert(width != 1); /* widthxheight can't be 1x1 */
878 halfHeight= 1;
880 for (jj= 0; jj< halfWidth; jj++) {
881 int kk;
882 for (kk= 0; kk< components; kk++) {
883 #define BOX2 2
884 GLuint uint[BOX2];
885 if (myswap_bytes) {
886 uint[0]= __GLU_SWAP_4_BYTES(src);
887 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
889 else {
890 uint[0]= *(const GLuint*)src;
891 uint[1]= *(const GLuint*)(src+group_size);
893 *dest= ((double)uint[0]+(double)uint[1])/2.0;
895 src+= element_size;
896 dest++;
898 src+= group_size; /* skip to next 2 */
901 int padBytes= ysize - (width*group_size);
902 src+= padBytes; /* for assertion only */
905 else if (width == 1) { /* 1 column */
906 int padBytes= ysize - (width * group_size);
907 assert(height != 1); /* widthxheight can't be 1x1 */
908 halfWidth= 1;
909 /* one vertical column with possible pad bytes per row */
910 /* average two at a time */
912 for (jj= 0; jj< halfHeight; jj++) {
913 int kk;
914 for (kk= 0; kk< components; kk++) {
915 #define BOX2 2
916 GLuint uint[BOX2];
917 if (myswap_bytes) {
918 uint[0]= __GLU_SWAP_4_BYTES(src);
919 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
921 else {
922 uint[0]= *(const GLuint*)src;
923 uint[1]= *(const GLuint*)(src+ysize);
925 *dest= ((double)uint[0]+(double)uint[1])/2.0;
927 src+= element_size;
928 dest++;
930 src+= padBytes; /* add pad bytes, if any, to get to end to row */
931 src+= ysize;
934 assert(src == &((const char *)dataIn)[ysize*height]);
937 assert((char *)dest == &((char *)dataOut)
938 [components * element_size * halfWidth * halfHeight]);
940 } /* halve1Dimage_uint() */
942 static void halveImage_int(GLint components, GLuint width, GLuint height,
943 const GLint *datain, GLint *dataout, GLint element_size,
944 GLint ysize, GLint group_size, GLint myswap_bytes)
946 int i, j, k;
947 int newwidth, newheight;
948 int padBytes;
949 GLint *s;
950 const char *t;
952 /* handle case where there is only 1 column/row */
953 if (width == 1 || height == 1) {
954 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
955 halve1Dimage_int(components,width,height,datain,dataout,
956 element_size,ysize,group_size, myswap_bytes);
957 return;
960 newwidth = width / 2;
961 newheight = height / 2;
962 padBytes = ysize - (width*group_size);
963 s = dataout;
964 t = (const char *)datain;
966 /* Piece o' cake! */
967 if (!myswap_bytes)
968 for (i = 0; i < newheight; i++) {
969 for (j = 0; j < newwidth; j++) {
970 for (k = 0; k < components; k++) {
971 s[0] = ((float)*(const GLint*)t +
972 (float)*(const GLint*)(t+group_size) +
973 (float)*(const GLint*)(t+ysize) +
974 (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
975 s++; t += element_size;
977 t += group_size;
979 t += padBytes;
980 t += ysize;
982 else
983 for (i = 0; i < newheight; i++) {
984 for (j = 0; j < newwidth; j++) {
985 for (k = 0; k < components; k++) {
986 GLuint b;
987 GLfloat buf;
988 b = __GLU_SWAP_4_BYTES(t);
989 buf = *(GLint*)&b;
990 b = __GLU_SWAP_4_BYTES(t+group_size);
991 buf += *(GLint*)&b;
992 b = __GLU_SWAP_4_BYTES(t+ysize);
993 buf += *(GLint*)&b;
994 b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
995 buf += *(GLint*)&b;
996 s[0] = (GLint)(buf/4 + 0.5);
998 s++; t += element_size;
1000 t += group_size;
1002 t += padBytes;
1003 t += ysize;
1007 /* */
1008 static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
1009 const GLint *dataIn, GLint *dataOut,
1010 GLint element_size, GLint ysize,
1011 GLint group_size, GLint myswap_bytes)
1013 GLint halfWidth= width / 2;
1014 GLint halfHeight= height / 2;
1015 const char *src= (const char *) dataIn;
1016 GLint *dest= dataOut;
1017 int jj;
1019 assert(width == 1 || height == 1); /* must be 1D */
1020 assert(width != height); /* can't be square */
1022 if (height == 1) { /* 1 row */
1023 assert(width != 1); /* widthxheight can't be 1x1 */
1024 halfHeight= 1;
1026 for (jj= 0; jj< halfWidth; jj++) {
1027 int kk;
1028 for (kk= 0; kk< components; kk++) {
1029 #define BOX2 2
1030 GLuint uint[BOX2];
1031 if (myswap_bytes) {
1032 uint[0]= __GLU_SWAP_4_BYTES(src);
1033 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
1035 else {
1036 uint[0]= *(const GLuint*)src;
1037 uint[1]= *(const GLuint*)(src+group_size);
1039 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1041 src+= element_size;
1042 dest++;
1044 src+= group_size; /* skip to next 2 */
1047 int padBytes= ysize - (width*group_size);
1048 src+= padBytes; /* for assertion only */
1051 else if (width == 1) { /* 1 column */
1052 int padBytes= ysize - (width * group_size);
1053 assert(height != 1); /* widthxheight can't be 1x1 */
1054 halfWidth= 1;
1055 /* one vertical column with possible pad bytes per row */
1056 /* average two at a time */
1058 for (jj= 0; jj< halfHeight; jj++) {
1059 int kk;
1060 for (kk= 0; kk< components; kk++) {
1061 #define BOX2 2
1062 GLuint uint[BOX2];
1063 if (myswap_bytes) {
1064 uint[0]= __GLU_SWAP_4_BYTES(src);
1065 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
1067 else {
1068 uint[0]= *(const GLuint*)src;
1069 uint[1]= *(const GLuint*)(src+ysize);
1071 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1073 src+= element_size;
1074 dest++;
1076 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1077 src+= ysize;
1080 assert(src == &((const char *)dataIn)[ysize*height]);
1083 assert((char *)dest == &((char *)dataOut)
1084 [components * element_size * halfWidth * halfHeight]);
1086 } /* halve1Dimage_int() */
1089 static void halveImage_float(GLint components, GLuint width, GLuint height,
1090 const GLfloat *datain, GLfloat *dataout,
1091 GLint element_size, GLint ysize, GLint group_size,
1092 GLint myswap_bytes)
1094 int i, j, k;
1095 int newwidth, newheight;
1096 int padBytes;
1097 GLfloat *s;
1098 const char *t;
1100 /* handle case where there is only 1 column/row */
1101 if (width == 1 || height == 1) {
1102 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1103 halve1Dimage_float(components,width,height,datain,dataout,
1104 element_size,ysize,group_size, myswap_bytes);
1105 return;
1108 newwidth = width / 2;
1109 newheight = height / 2;
1110 padBytes = ysize - (width*group_size);
1111 s = dataout;
1112 t = (const char *)datain;
1114 /* Piece o' cake! */
1115 if (!myswap_bytes)
1116 for (i = 0; i < newheight; i++) {
1117 for (j = 0; j < newwidth; j++) {
1118 for (k = 0; k < components; k++) {
1119 s[0] = (*(const GLfloat*)t +
1120 *(const GLfloat*)(t+group_size) +
1121 *(const GLfloat*)(t+ysize) +
1122 *(const GLfloat*)(t+ysize+group_size)) / 4;
1123 s++; t += element_size;
1125 t += group_size;
1127 t += padBytes;
1128 t += ysize;
1130 else
1131 for (i = 0; i < newheight; i++) {
1132 for (j = 0; j < newwidth; j++) {
1133 for (k = 0; k < components; k++) {
1134 union { GLuint b; GLfloat f; } swapbuf;
1135 swapbuf.b = __GLU_SWAP_4_BYTES(t);
1136 s[0] = swapbuf.f;
1137 swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
1138 s[0] += swapbuf.f;
1139 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
1140 s[0] += swapbuf.f;
1141 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1142 s[0] += swapbuf.f;
1143 s[0] /= 4;
1144 s++; t += element_size;
1146 t += group_size;
1148 t += padBytes;
1149 t += ysize;
1153 /* */
1154 static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
1155 const GLfloat *dataIn, GLfloat *dataOut,
1156 GLint element_size, GLint ysize,
1157 GLint group_size, GLint myswap_bytes)
1159 GLint halfWidth= width / 2;
1160 GLint halfHeight= height / 2;
1161 const char *src= (const char *) dataIn;
1162 GLfloat *dest= dataOut;
1163 int jj;
1165 assert(width == 1 || height == 1); /* must be 1D */
1166 assert(width != height); /* can't be square */
1168 if (height == 1) { /* 1 row */
1169 assert(width != 1); /* widthxheight can't be 1x1 */
1170 halfHeight= 1;
1172 for (jj= 0; jj< halfWidth; jj++) {
1173 int kk;
1174 for (kk= 0; kk< components; kk++) {
1175 #define BOX2 2
1176 GLfloat sfloat[BOX2];
1177 if (myswap_bytes) {
1178 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1179 sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
1181 else {
1182 sfloat[0]= *(const GLfloat*)src;
1183 sfloat[1]= *(const GLfloat*)(src+group_size);
1186 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1187 src+= element_size;
1188 dest++;
1190 src+= group_size; /* skip to next 2 */
1193 int padBytes= ysize - (width*group_size);
1194 src+= padBytes; /* for assertion only */
1197 else if (width == 1) { /* 1 column */
1198 int padBytes= ysize - (width * group_size);
1199 assert(height != 1); /* widthxheight can't be 1x1 */
1200 halfWidth= 1;
1201 /* one vertical column with possible pad bytes per row */
1202 /* average two at a time */
1204 for (jj= 0; jj< halfHeight; jj++) {
1205 int kk;
1206 for (kk= 0; kk< components; kk++) {
1207 #define BOX2 2
1208 GLfloat sfloat[BOX2];
1209 if (myswap_bytes) {
1210 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1211 sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
1213 else {
1214 sfloat[0]= *(const GLfloat*)src;
1215 sfloat[1]= *(const GLfloat*)(src+ysize);
1217 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1219 src+= element_size;
1220 dest++;
1222 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1223 src+= ysize; /* skip to odd row */
1227 assert(src == &((const char *)dataIn)[ysize*height]);
1228 assert((char *)dest == &((char *)dataOut)
1229 [components * element_size * halfWidth * halfHeight]);
1230 } /* halve1Dimage_float() */
1232 static void scale_internal(GLint components, GLint widthin, GLint heightin,
1233 const GLushort *datain,
1234 GLint widthout, GLint heightout,
1235 GLushort *dataout)
1237 float x, lowx, highx, convx, halfconvx;
1238 float y, lowy, highy, convy, halfconvy;
1239 float xpercent,ypercent;
1240 float percent;
1241 /* Max components in a format is 4, so... */
1242 float totals[4];
1243 float area;
1244 int i,j,k,yint,xint,xindex,yindex;
1245 int temp;
1247 if (widthin == widthout*2 && heightin == heightout*2) {
1248 halveImage(components, widthin, heightin, datain, dataout);
1249 return;
1251 convy = (float) heightin/heightout;
1252 convx = (float) widthin/widthout;
1253 halfconvx = convx/2;
1254 halfconvy = convy/2;
1255 for (i = 0; i < heightout; i++) {
1256 y = convy * (i+0.5);
1257 if (heightin > heightout) {
1258 highy = y + halfconvy;
1259 lowy = y - halfconvy;
1260 } else {
1261 highy = y + 0.5;
1262 lowy = y - 0.5;
1264 for (j = 0; j < widthout; j++) {
1265 x = convx * (j+0.5);
1266 if (widthin > widthout) {
1267 highx = x + halfconvx;
1268 lowx = x - halfconvx;
1269 } else {
1270 highx = x + 0.5;
1271 lowx = x - 0.5;
1275 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1276 ** to (highx, highy) on input data into this pixel on output
1277 ** data.
1279 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1280 area = 0.0;
1282 y = lowy;
1283 yint = floor(y);
1284 while (y < highy) {
1285 yindex = (yint + heightin) % heightin;
1286 if (highy < yint+1) {
1287 ypercent = highy - y;
1288 } else {
1289 ypercent = yint+1 - y;
1292 x = lowx;
1293 xint = floor(x);
1295 while (x < highx) {
1296 xindex = (xint + widthin) % widthin;
1297 if (highx < xint+1) {
1298 xpercent = highx - x;
1299 } else {
1300 xpercent = xint+1 - x;
1303 percent = xpercent * ypercent;
1304 area += percent;
1305 temp = (xindex + (yindex * widthin)) * components;
1306 for (k = 0; k < components; k++) {
1307 totals[k] += datain[temp + k] * percent;
1310 xint++;
1311 x = xint;
1313 yint++;
1314 y = yint;
1317 temp = (j + (i * widthout)) * components;
1318 for (k = 0; k < components; k++) {
1319 /* totals[] should be rounded in the case of enlarging an RGB
1320 * ramp when the type is 332 or 4444
1322 dataout[temp + k] = (totals[k]+0.5)/area;
1328 static void scale_internal_ubyte(GLint components, GLint widthin,
1329 GLint heightin, const GLubyte *datain,
1330 GLint widthout, GLint heightout,
1331 GLubyte *dataout, GLint element_size,
1332 GLint ysize, GLint group_size)
1334 float convx;
1335 float convy;
1336 float percent;
1337 /* Max components in a format is 4, so... */
1338 float totals[4];
1339 float area;
1340 int i,j,k,xindex;
1342 const char *temp, *temp0;
1343 const char *temp_index;
1344 int outindex;
1346 int lowx_int, highx_int, lowy_int, highy_int;
1347 float x_percent, y_percent;
1348 float lowx_float, highx_float, lowy_float, highy_float;
1349 float convy_float, convx_float;
1350 int convy_int, convx_int;
1351 int l, m;
1352 const char *left, *right;
1354 if (widthin == widthout*2 && heightin == heightout*2) {
1355 halveImage_ubyte(components, widthin, heightin,
1356 (const GLubyte *)datain, (GLubyte *)dataout,
1357 element_size, ysize, group_size);
1358 return;
1360 convy = (float) heightin/heightout;
1361 convx = (float) widthin/widthout;
1362 convy_int = floor(convy);
1363 convy_float = convy - convy_int;
1364 convx_int = floor(convx);
1365 convx_float = convx - convx_int;
1367 area = convx * convy;
1369 lowy_int = 0;
1370 lowy_float = 0;
1371 highy_int = convy_int;
1372 highy_float = convy_float;
1374 for (i = 0; i < heightout; i++) {
1375 /* Clamp here to be sure we don't read beyond input buffer. */
1376 if (highy_int >= heightin)
1377 highy_int = heightin - 1;
1378 lowx_int = 0;
1379 lowx_float = 0;
1380 highx_int = convx_int;
1381 highx_float = convx_float;
1383 for (j = 0; j < widthout; j++) {
1386 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1387 ** to (highx, highy) on input data into this pixel on output
1388 ** data.
1390 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1392 /* calculate the value for pixels in the 1st row */
1393 xindex = lowx_int*group_size;
1394 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1396 y_percent = 1-lowy_float;
1397 temp = (const char *)datain + xindex + lowy_int * ysize;
1398 percent = y_percent * (1-lowx_float);
1399 for (k = 0, temp_index = temp; k < components;
1400 k++, temp_index += element_size) {
1401 totals[k] += (GLubyte)(*(temp_index)) * percent;
1403 left = temp;
1404 for(l = lowx_int+1; l < highx_int; l++) {
1405 temp += group_size;
1406 for (k = 0, temp_index = temp; k < components;
1407 k++, temp_index += element_size) {
1408 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1411 temp += group_size;
1412 right = temp;
1413 percent = y_percent * highx_float;
1414 for (k = 0, temp_index = temp; k < components;
1415 k++, temp_index += element_size) {
1416 totals[k] += (GLubyte)(*(temp_index)) * percent;
1419 /* calculate the value for pixels in the last row */
1420 y_percent = highy_float;
1421 percent = y_percent * (1-lowx_float);
1422 temp = (const char *)datain + xindex + highy_int * ysize;
1423 for (k = 0, temp_index = temp; k < components;
1424 k++, temp_index += element_size) {
1425 totals[k] += (GLubyte)(*(temp_index)) * percent;
1427 for(l = lowx_int+1; l < highx_int; l++) {
1428 temp += group_size;
1429 for (k = 0, temp_index = temp; k < components;
1430 k++, temp_index += element_size) {
1431 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1434 temp += group_size;
1435 percent = y_percent * highx_float;
1436 for (k = 0, temp_index = temp; k < components;
1437 k++, temp_index += element_size) {
1438 totals[k] += (GLubyte)(*(temp_index)) * percent;
1442 /* calculate the value for pixels in the 1st and last column */
1443 for(m = lowy_int+1; m < highy_int; m++) {
1444 left += ysize;
1445 right += ysize;
1446 for (k = 0; k < components;
1447 k++, left += element_size, right += element_size) {
1448 totals[k] += (GLubyte)(*(left))*(1-lowx_float)
1449 +(GLubyte)(*(right))*highx_float;
1452 } else if (highy_int > lowy_int) {
1453 x_percent = highx_float - lowx_float;
1454 percent = (1-lowy_float)*x_percent;
1455 temp = (const char *)datain + xindex + lowy_int*ysize;
1456 for (k = 0, temp_index = temp; k < components;
1457 k++, temp_index += element_size) {
1458 totals[k] += (GLubyte)(*(temp_index)) * percent;
1460 for(m = lowy_int+1; m < highy_int; m++) {
1461 temp += ysize;
1462 for (k = 0, temp_index = temp; k < components;
1463 k++, temp_index += element_size) {
1464 totals[k] += (GLubyte)(*(temp_index)) * x_percent;
1467 percent = x_percent * highy_float;
1468 temp += ysize;
1469 for (k = 0, temp_index = temp; k < components;
1470 k++, temp_index += element_size) {
1471 totals[k] += (GLubyte)(*(temp_index)) * percent;
1473 } else if (highx_int > lowx_int) {
1474 y_percent = highy_float - lowy_float;
1475 percent = (1-lowx_float)*y_percent;
1476 temp = (const char *)datain + xindex + lowy_int*ysize;
1477 for (k = 0, temp_index = temp; k < components;
1478 k++, temp_index += element_size) {
1479 totals[k] += (GLubyte)(*(temp_index)) * percent;
1481 for (l = lowx_int+1; l < highx_int; l++) {
1482 temp += group_size;
1483 for (k = 0, temp_index = temp; k < components;
1484 k++, temp_index += element_size) {
1485 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1488 temp += group_size;
1489 percent = y_percent * highx_float;
1490 for (k = 0, temp_index = temp; k < components;
1491 k++, temp_index += element_size) {
1492 totals[k] += (GLubyte)(*(temp_index)) * percent;
1494 } else {
1495 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1496 temp = (const char *)datain + xindex + lowy_int * ysize;
1497 for (k = 0, temp_index = temp; k < components;
1498 k++, temp_index += element_size) {
1499 totals[k] += (GLubyte)(*(temp_index)) * percent;
1505 /* this is for the pixels in the body */
1506 temp0 = (const char *)datain + xindex + group_size +
1507 (lowy_int+1)*ysize;
1508 for (m = lowy_int+1; m < highy_int; m++) {
1509 temp = temp0;
1510 for(l = lowx_int+1; l < highx_int; l++) {
1511 for (k = 0, temp_index = temp; k < components;
1512 k++, temp_index += element_size) {
1513 totals[k] += (GLubyte)(*(temp_index));
1515 temp += group_size;
1517 temp0 += ysize;
1520 outindex = (j + (i * widthout)) * components;
1521 for (k = 0; k < components; k++) {
1522 dataout[outindex + k] = totals[k]/area;
1523 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1525 lowx_int = highx_int;
1526 lowx_float = highx_float;
1527 highx_int += convx_int;
1528 highx_float += convx_float;
1529 if(highx_float > 1) {
1530 highx_float -= 1.0;
1531 highx_int++;
1534 lowy_int = highy_int;
1535 lowy_float = highy_float;
1536 highy_int += convy_int;
1537 highy_float += convy_float;
1538 if(highy_float > 1) {
1539 highy_float -= 1.0;
1540 highy_int++;
1545 static void scale_internal_byte(GLint components, GLint widthin,
1546 GLint heightin, const GLbyte *datain,
1547 GLint widthout, GLint heightout,
1548 GLbyte *dataout, GLint element_size,
1549 GLint ysize, GLint group_size)
1551 float convx;
1552 float convy;
1553 float percent;
1554 /* Max components in a format is 4, so... */
1555 float totals[4];
1556 float area;
1557 int i,j,k,xindex;
1559 const char *temp, *temp0;
1560 const char *temp_index;
1561 int outindex;
1563 int lowx_int, highx_int, lowy_int, highy_int;
1564 float x_percent, y_percent;
1565 float lowx_float, highx_float, lowy_float, highy_float;
1566 float convy_float, convx_float;
1567 int convy_int, convx_int;
1568 int l, m;
1569 const char *left, *right;
1571 if (widthin == widthout*2 && heightin == heightout*2) {
1572 halveImage_byte(components, widthin, heightin,
1573 (const GLbyte *)datain, (GLbyte *)dataout,
1574 element_size, ysize, group_size);
1575 return;
1577 convy = (float) heightin/heightout;
1578 convx = (float) widthin/widthout;
1579 convy_int = floor(convy);
1580 convy_float = convy - convy_int;
1581 convx_int = floor(convx);
1582 convx_float = convx - convx_int;
1584 area = convx * convy;
1586 lowy_int = 0;
1587 lowy_float = 0;
1588 highy_int = convy_int;
1589 highy_float = convy_float;
1591 for (i = 0; i < heightout; i++) {
1592 /* Clamp here to be sure we don't read beyond input buffer. */
1593 if (highy_int >= heightin)
1594 highy_int = heightin - 1;
1595 lowx_int = 0;
1596 lowx_float = 0;
1597 highx_int = convx_int;
1598 highx_float = convx_float;
1600 for (j = 0; j < widthout; j++) {
1603 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1604 ** to (highx, highy) on input data into this pixel on output
1605 ** data.
1607 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1609 /* calculate the value for pixels in the 1st row */
1610 xindex = lowx_int*group_size;
1611 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1613 y_percent = 1-lowy_float;
1614 temp = (const char *)datain + xindex + lowy_int * ysize;
1615 percent = y_percent * (1-lowx_float);
1616 for (k = 0, temp_index = temp; k < components;
1617 k++, temp_index += element_size) {
1618 totals[k] += (GLbyte)(*(temp_index)) * percent;
1620 left = temp;
1621 for(l = lowx_int+1; l < highx_int; l++) {
1622 temp += group_size;
1623 for (k = 0, temp_index = temp; k < components;
1624 k++, temp_index += element_size) {
1625 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1628 temp += group_size;
1629 right = temp;
1630 percent = y_percent * highx_float;
1631 for (k = 0, temp_index = temp; k < components;
1632 k++, temp_index += element_size) {
1633 totals[k] += (GLbyte)(*(temp_index)) * percent;
1636 /* calculate the value for pixels in the last row */
1637 y_percent = highy_float;
1638 percent = y_percent * (1-lowx_float);
1639 temp = (const char *)datain + xindex + highy_int * ysize;
1640 for (k = 0, temp_index = temp; k < components;
1641 k++, temp_index += element_size) {
1642 totals[k] += (GLbyte)(*(temp_index)) * percent;
1644 for(l = lowx_int+1; l < highx_int; l++) {
1645 temp += group_size;
1646 for (k = 0, temp_index = temp; k < components;
1647 k++, temp_index += element_size) {
1648 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1651 temp += group_size;
1652 percent = y_percent * highx_float;
1653 for (k = 0, temp_index = temp; k < components;
1654 k++, temp_index += element_size) {
1655 totals[k] += (GLbyte)(*(temp_index)) * percent;
1659 /* calculate the value for pixels in the 1st and last column */
1660 for(m = lowy_int+1; m < highy_int; m++) {
1661 left += ysize;
1662 right += ysize;
1663 for (k = 0; k < components;
1664 k++, left += element_size, right += element_size) {
1665 totals[k] += (GLbyte)(*(left))*(1-lowx_float)
1666 +(GLbyte)(*(right))*highx_float;
1669 } else if (highy_int > lowy_int) {
1670 x_percent = highx_float - lowx_float;
1671 percent = (1-lowy_float)*x_percent;
1672 temp = (const char *)datain + xindex + lowy_int*ysize;
1673 for (k = 0, temp_index = temp; k < components;
1674 k++, temp_index += element_size) {
1675 totals[k] += (GLbyte)(*(temp_index)) * percent;
1677 for(m = lowy_int+1; m < highy_int; m++) {
1678 temp += ysize;
1679 for (k = 0, temp_index = temp; k < components;
1680 k++, temp_index += element_size) {
1681 totals[k] += (GLbyte)(*(temp_index)) * x_percent;
1684 percent = x_percent * highy_float;
1685 temp += ysize;
1686 for (k = 0, temp_index = temp; k < components;
1687 k++, temp_index += element_size) {
1688 totals[k] += (GLbyte)(*(temp_index)) * percent;
1690 } else if (highx_int > lowx_int) {
1691 y_percent = highy_float - lowy_float;
1692 percent = (1-lowx_float)*y_percent;
1693 temp = (const char *)datain + xindex + lowy_int*ysize;
1694 for (k = 0, temp_index = temp; k < components;
1695 k++, temp_index += element_size) {
1696 totals[k] += (GLbyte)(*(temp_index)) * percent;
1698 for (l = lowx_int+1; l < highx_int; l++) {
1699 temp += group_size;
1700 for (k = 0, temp_index = temp; k < components;
1701 k++, temp_index += element_size) {
1702 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1705 temp += group_size;
1706 percent = y_percent * highx_float;
1707 for (k = 0, temp_index = temp; k < components;
1708 k++, temp_index += element_size) {
1709 totals[k] += (GLbyte)(*(temp_index)) * percent;
1711 } else {
1712 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1713 temp = (const char *)datain + xindex + lowy_int * ysize;
1714 for (k = 0, temp_index = temp; k < components;
1715 k++, temp_index += element_size) {
1716 totals[k] += (GLbyte)(*(temp_index)) * percent;
1722 /* this is for the pixels in the body */
1723 temp0 = (const char *)datain + xindex + group_size +
1724 (lowy_int+1)*ysize;
1725 for (m = lowy_int+1; m < highy_int; m++) {
1726 temp = temp0;
1727 for(l = lowx_int+1; l < highx_int; l++) {
1728 for (k = 0, temp_index = temp; k < components;
1729 k++, temp_index += element_size) {
1730 totals[k] += (GLbyte)(*(temp_index));
1732 temp += group_size;
1734 temp0 += ysize;
1737 outindex = (j + (i * widthout)) * components;
1738 for (k = 0; k < components; k++) {
1739 dataout[outindex + k] = totals[k]/area;
1740 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1742 lowx_int = highx_int;
1743 lowx_float = highx_float;
1744 highx_int += convx_int;
1745 highx_float += convx_float;
1746 if(highx_float > 1) {
1747 highx_float -= 1.0;
1748 highx_int++;
1751 lowy_int = highy_int;
1752 lowy_float = highy_float;
1753 highy_int += convy_int;
1754 highy_float += convy_float;
1755 if(highy_float > 1) {
1756 highy_float -= 1.0;
1757 highy_int++;
1762 static void scale_internal_ushort(GLint components, GLint widthin,
1763 GLint heightin, const GLushort *datain,
1764 GLint widthout, GLint heightout,
1765 GLushort *dataout, GLint element_size,
1766 GLint ysize, GLint group_size,
1767 GLint myswap_bytes)
1769 float convx;
1770 float convy;
1771 float percent;
1772 /* Max components in a format is 4, so... */
1773 float totals[4];
1774 float area;
1775 int i,j,k,xindex;
1777 const char *temp, *temp0;
1778 const char *temp_index;
1779 int outindex;
1781 int lowx_int, highx_int, lowy_int, highy_int;
1782 float x_percent, y_percent;
1783 float lowx_float, highx_float, lowy_float, highy_float;
1784 float convy_float, convx_float;
1785 int convy_int, convx_int;
1786 int l, m;
1787 const char *left, *right;
1789 if (widthin == widthout*2 && heightin == heightout*2) {
1790 halveImage_ushort(components, widthin, heightin,
1791 (const GLushort *)datain, (GLushort *)dataout,
1792 element_size, ysize, group_size, myswap_bytes);
1793 return;
1795 convy = (float) heightin/heightout;
1796 convx = (float) widthin/widthout;
1797 convy_int = floor(convy);
1798 convy_float = convy - convy_int;
1799 convx_int = floor(convx);
1800 convx_float = convx - convx_int;
1802 area = convx * convy;
1804 lowy_int = 0;
1805 lowy_float = 0;
1806 highy_int = convy_int;
1807 highy_float = convy_float;
1809 for (i = 0; i < heightout; i++) {
1810 /* Clamp here to be sure we don't read beyond input buffer. */
1811 if (highy_int >= heightin)
1812 highy_int = heightin - 1;
1813 lowx_int = 0;
1814 lowx_float = 0;
1815 highx_int = convx_int;
1816 highx_float = convx_float;
1818 for (j = 0; j < widthout; j++) {
1820 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1821 ** to (highx, highy) on input data into this pixel on output
1822 ** data.
1824 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1826 /* calculate the value for pixels in the 1st row */
1827 xindex = lowx_int*group_size;
1828 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1830 y_percent = 1-lowy_float;
1831 temp = (const char *)datain + xindex + lowy_int * ysize;
1832 percent = y_percent * (1-lowx_float);
1833 for (k = 0, temp_index = temp; k < components;
1834 k++, temp_index += element_size) {
1835 if (myswap_bytes) {
1836 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1837 } else {
1838 totals[k] += *(const GLushort*)temp_index * percent;
1841 left = temp;
1842 for(l = lowx_int+1; l < highx_int; l++) {
1843 temp += group_size;
1844 for (k = 0, temp_index = temp; k < components;
1845 k++, temp_index += element_size) {
1846 if (myswap_bytes) {
1847 totals[k] +=
1848 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1849 } else {
1850 totals[k] += *(const GLushort*)temp_index * y_percent;
1854 temp += group_size;
1855 right = temp;
1856 percent = y_percent * highx_float;
1857 for (k = 0, temp_index = temp; k < components;
1858 k++, temp_index += element_size) {
1859 if (myswap_bytes) {
1860 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1861 } else {
1862 totals[k] += *(const GLushort*)temp_index * percent;
1866 /* calculate the value for pixels in the last row */
1867 y_percent = highy_float;
1868 percent = y_percent * (1-lowx_float);
1869 temp = (const char *)datain + xindex + highy_int * ysize;
1870 for (k = 0, temp_index = temp; k < components;
1871 k++, temp_index += element_size) {
1872 if (myswap_bytes) {
1873 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1874 } else {
1875 totals[k] += *(const GLushort*)temp_index * percent;
1878 for(l = lowx_int+1; l < highx_int; l++) {
1879 temp += group_size;
1880 for (k = 0, temp_index = temp; k < components;
1881 k++, temp_index += element_size) {
1882 if (myswap_bytes) {
1883 totals[k] +=
1884 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1885 } else {
1886 totals[k] += *(const GLushort*)temp_index * y_percent;
1890 temp += group_size;
1891 percent = y_percent * highx_float;
1892 for (k = 0, temp_index = temp; k < components;
1893 k++, temp_index += element_size) {
1894 if (myswap_bytes) {
1895 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1896 } else {
1897 totals[k] += *(const GLushort*)temp_index * percent;
1901 /* calculate the value for pixels in the 1st and last column */
1902 for(m = lowy_int+1; m < highy_int; m++) {
1903 left += ysize;
1904 right += ysize;
1905 for (k = 0; k < components;
1906 k++, left += element_size, right += element_size) {
1907 if (myswap_bytes) {
1908 totals[k] +=
1909 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
1910 __GLU_SWAP_2_BYTES(right) * highx_float;
1911 } else {
1912 totals[k] += *(const GLushort*)left * (1-lowx_float)
1913 + *(const GLushort*)right * highx_float;
1917 } else if (highy_int > lowy_int) {
1918 x_percent = highx_float - lowx_float;
1919 percent = (1-lowy_float)*x_percent;
1920 temp = (const char *)datain + xindex + lowy_int*ysize;
1921 for (k = 0, temp_index = temp; k < components;
1922 k++, temp_index += element_size) {
1923 if (myswap_bytes) {
1924 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1925 } else {
1926 totals[k] += *(const GLushort*)temp_index * percent;
1929 for(m = lowy_int+1; m < highy_int; m++) {
1930 temp += ysize;
1931 for (k = 0, temp_index = temp; k < components;
1932 k++, temp_index += element_size) {
1933 if (myswap_bytes) {
1934 totals[k] +=
1935 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
1936 } else {
1937 totals[k] += *(const GLushort*)temp_index * x_percent;
1941 percent = x_percent * highy_float;
1942 temp += ysize;
1943 for (k = 0, temp_index = temp; k < components;
1944 k++, temp_index += element_size) {
1945 if (myswap_bytes) {
1946 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1947 } else {
1948 totals[k] += *(const GLushort*)temp_index * percent;
1951 } else if (highx_int > lowx_int) {
1952 y_percent = highy_float - lowy_float;
1953 percent = (1-lowx_float)*y_percent;
1954 temp = (const char *)datain + xindex + lowy_int*ysize;
1955 for (k = 0, temp_index = temp; k < components;
1956 k++, temp_index += element_size) {
1957 if (myswap_bytes) {
1958 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1959 } else {
1960 totals[k] += *(const GLushort*)temp_index * percent;
1963 for (l = lowx_int+1; l < highx_int; l++) {
1964 temp += group_size;
1965 for (k = 0, temp_index = temp; k < components;
1966 k++, temp_index += element_size) {
1967 if (myswap_bytes) {
1968 totals[k] +=
1969 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1970 } else {
1971 totals[k] += *(const GLushort*)temp_index * y_percent;
1975 temp += group_size;
1976 percent = y_percent * highx_float;
1977 for (k = 0, temp_index = temp; k < components;
1978 k++, temp_index += element_size) {
1979 if (myswap_bytes) {
1980 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1981 } else {
1982 totals[k] += *(const GLushort*)temp_index * percent;
1985 } else {
1986 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1987 temp = (const char *)datain + xindex + lowy_int * ysize;
1988 for (k = 0, temp_index = temp; k < components;
1989 k++, temp_index += element_size) {
1990 if (myswap_bytes) {
1991 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1992 } else {
1993 totals[k] += *(const GLushort*)temp_index * percent;
1998 /* this is for the pixels in the body */
1999 temp0 = (const char *)datain + xindex + group_size +
2000 (lowy_int+1)*ysize;
2001 for (m = lowy_int+1; m < highy_int; m++) {
2002 temp = temp0;
2003 for(l = lowx_int+1; l < highx_int; l++) {
2004 for (k = 0, temp_index = temp; k < components;
2005 k++, temp_index += element_size) {
2006 if (myswap_bytes) {
2007 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
2008 } else {
2009 totals[k] += *(const GLushort*)temp_index;
2012 temp += group_size;
2014 temp0 += ysize;
2017 outindex = (j + (i * widthout)) * components;
2018 for (k = 0; k < components; k++) {
2019 dataout[outindex + k] = totals[k]/area;
2020 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2022 lowx_int = highx_int;
2023 lowx_float = highx_float;
2024 highx_int += convx_int;
2025 highx_float += convx_float;
2026 if(highx_float > 1) {
2027 highx_float -= 1.0;
2028 highx_int++;
2031 lowy_int = highy_int;
2032 lowy_float = highy_float;
2033 highy_int += convy_int;
2034 highy_float += convy_float;
2035 if(highy_float > 1) {
2036 highy_float -= 1.0;
2037 highy_int++;
2042 static void scale_internal_short(GLint components, GLint widthin,
2043 GLint heightin, const GLshort *datain,
2044 GLint widthout, GLint heightout,
2045 GLshort *dataout, GLint element_size,
2046 GLint ysize, GLint group_size,
2047 GLint myswap_bytes)
2049 float convx;
2050 float convy;
2051 float percent;
2052 /* Max components in a format is 4, so... */
2053 float totals[4];
2054 float area;
2055 int i,j,k,xindex;
2057 const char *temp, *temp0;
2058 const char *temp_index;
2059 int outindex;
2061 int lowx_int, highx_int, lowy_int, highy_int;
2062 float x_percent, y_percent;
2063 float lowx_float, highx_float, lowy_float, highy_float;
2064 float convy_float, convx_float;
2065 int convy_int, convx_int;
2066 int l, m;
2067 const char *left, *right;
2069 GLushort swapbuf; /* unsigned buffer */
2071 if (widthin == widthout*2 && heightin == heightout*2) {
2072 halveImage_short(components, widthin, heightin,
2073 (const GLshort *)datain, (GLshort *)dataout,
2074 element_size, ysize, group_size, myswap_bytes);
2075 return;
2077 convy = (float) heightin/heightout;
2078 convx = (float) widthin/widthout;
2079 convy_int = floor(convy);
2080 convy_float = convy - convy_int;
2081 convx_int = floor(convx);
2082 convx_float = convx - convx_int;
2084 area = convx * convy;
2086 lowy_int = 0;
2087 lowy_float = 0;
2088 highy_int = convy_int;
2089 highy_float = convy_float;
2091 for (i = 0; i < heightout; i++) {
2092 /* Clamp here to be sure we don't read beyond input buffer. */
2093 if (highy_int >= heightin)
2094 highy_int = heightin - 1;
2095 lowx_int = 0;
2096 lowx_float = 0;
2097 highx_int = convx_int;
2098 highx_float = convx_float;
2100 for (j = 0; j < widthout; j++) {
2102 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2103 ** to (highx, highy) on input data into this pixel on output
2104 ** data.
2106 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2108 /* calculate the value for pixels in the 1st row */
2109 xindex = lowx_int*group_size;
2110 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2112 y_percent = 1-lowy_float;
2113 temp = (const char *)datain + xindex + lowy_int * ysize;
2114 percent = y_percent * (1-lowx_float);
2115 for (k = 0, temp_index = temp; k < components;
2116 k++, temp_index += element_size) {
2117 if (myswap_bytes) {
2118 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2119 totals[k] += *(const GLshort*)&swapbuf * percent;
2120 } else {
2121 totals[k] += *(const GLshort*)temp_index * percent;
2124 left = temp;
2125 for(l = lowx_int+1; l < highx_int; l++) {
2126 temp += group_size;
2127 for (k = 0, temp_index = temp; k < components;
2128 k++, temp_index += element_size) {
2129 if (myswap_bytes) {
2130 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2131 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2132 } else {
2133 totals[k] += *(const GLshort*)temp_index * y_percent;
2137 temp += group_size;
2138 right = temp;
2139 percent = y_percent * highx_float;
2140 for (k = 0, temp_index = temp; k < components;
2141 k++, temp_index += element_size) {
2142 if (myswap_bytes) {
2143 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2144 totals[k] += *(const GLshort*)&swapbuf * percent;
2145 } else {
2146 totals[k] += *(const GLshort*)temp_index * percent;
2150 /* calculate the value for pixels in the last row */
2151 y_percent = highy_float;
2152 percent = y_percent * (1-lowx_float);
2153 temp = (const char *)datain + xindex + highy_int * ysize;
2154 for (k = 0, temp_index = temp; k < components;
2155 k++, temp_index += element_size) {
2156 if (myswap_bytes) {
2157 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2158 totals[k] += *(const GLshort*)&swapbuf * percent;
2159 } else {
2160 totals[k] += *(const GLshort*)temp_index * percent;
2163 for(l = lowx_int+1; l < highx_int; l++) {
2164 temp += group_size;
2165 for (k = 0, temp_index = temp; k < components;
2166 k++, temp_index += element_size) {
2167 if (myswap_bytes) {
2168 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2169 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2170 } else {
2171 totals[k] += *(const GLshort*)temp_index * y_percent;
2175 temp += group_size;
2176 percent = y_percent * highx_float;
2177 for (k = 0, temp_index = temp; k < components;
2178 k++, temp_index += element_size) {
2179 if (myswap_bytes) {
2180 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2181 totals[k] += *(const GLshort*)&swapbuf * percent;
2182 } else {
2183 totals[k] += *(const GLshort*)temp_index * percent;
2187 /* calculate the value for pixels in the 1st and last column */
2188 for(m = lowy_int+1; m < highy_int; m++) {
2189 left += ysize;
2190 right += ysize;
2191 for (k = 0; k < components;
2192 k++, left += element_size, right += element_size) {
2193 if (myswap_bytes) {
2194 swapbuf = __GLU_SWAP_2_BYTES(left);
2195 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
2196 swapbuf = __GLU_SWAP_2_BYTES(right);
2197 totals[k] += *(const GLshort*)&swapbuf * highx_float;
2198 } else {
2199 totals[k] += *(const GLshort*)left * (1-lowx_float)
2200 + *(const GLshort*)right * highx_float;
2204 } else if (highy_int > lowy_int) {
2205 x_percent = highx_float - lowx_float;
2206 percent = (1-lowy_float)*x_percent;
2207 temp = (const char *)datain + xindex + lowy_int*ysize;
2208 for (k = 0, temp_index = temp; k < components;
2209 k++, temp_index += element_size) {
2210 if (myswap_bytes) {
2211 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2212 totals[k] += *(const GLshort*)&swapbuf * percent;
2213 } else {
2214 totals[k] += *(const GLshort*)temp_index * percent;
2217 for(m = lowy_int+1; m < highy_int; m++) {
2218 temp += ysize;
2219 for (k = 0, temp_index = temp; k < components;
2220 k++, temp_index += element_size) {
2221 if (myswap_bytes) {
2222 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2223 totals[k] += *(const GLshort*)&swapbuf * x_percent;
2224 } else {
2225 totals[k] += *(const GLshort*)temp_index * x_percent;
2229 percent = x_percent * highy_float;
2230 temp += ysize;
2231 for (k = 0, temp_index = temp; k < components;
2232 k++, temp_index += element_size) {
2233 if (myswap_bytes) {
2234 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2235 totals[k] += *(const GLshort*)&swapbuf * percent;
2236 } else {
2237 totals[k] += *(const GLshort*)temp_index * percent;
2240 } else if (highx_int > lowx_int) {
2241 y_percent = highy_float - lowy_float;
2242 percent = (1-lowx_float)*y_percent;
2244 temp = (const char *)datain + xindex + lowy_int*ysize;
2245 for (k = 0, temp_index = temp; k < components;
2246 k++, temp_index += element_size) {
2247 if (myswap_bytes) {
2248 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2249 totals[k] += *(const GLshort*)&swapbuf * percent;
2250 } else {
2251 totals[k] += *(const GLshort*)temp_index * percent;
2254 for (l = lowx_int+1; l < highx_int; l++) {
2255 temp += group_size;
2256 for (k = 0, temp_index = temp; k < components;
2257 k++, temp_index += element_size) {
2258 if (myswap_bytes) {
2259 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2260 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2261 } else {
2262 totals[k] += *(const GLshort*)temp_index * y_percent;
2266 temp += group_size;
2267 percent = y_percent * highx_float;
2268 for (k = 0, temp_index = temp; k < components;
2269 k++, temp_index += element_size) {
2270 if (myswap_bytes) {
2271 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2272 totals[k] += *(const GLshort*)&swapbuf * percent;
2273 } else {
2274 totals[k] += *(const GLshort*)temp_index * percent;
2277 } else {
2278 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2279 temp = (const char *)datain + xindex + lowy_int * ysize;
2280 for (k = 0, temp_index = temp; k < components;
2281 k++, temp_index += element_size) {
2282 if (myswap_bytes) {
2283 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2284 totals[k] += *(const GLshort*)&swapbuf * percent;
2285 } else {
2286 totals[k] += *(const GLshort*)temp_index * percent;
2291 /* this is for the pixels in the body */
2292 temp0 = (const char *)datain + xindex + group_size +
2293 (lowy_int+1)*ysize;
2294 for (m = lowy_int+1; m < highy_int; m++) {
2295 temp = temp0;
2296 for(l = lowx_int+1; l < highx_int; l++) {
2297 for (k = 0, temp_index = temp; k < components;
2298 k++, temp_index += element_size) {
2299 if (myswap_bytes) {
2300 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2301 totals[k] += *(const GLshort*)&swapbuf;
2302 } else {
2303 totals[k] += *(const GLshort*)temp_index;
2306 temp += group_size;
2308 temp0 += ysize;
2311 outindex = (j + (i * widthout)) * components;
2312 for (k = 0; k < components; k++) {
2313 dataout[outindex + k] = totals[k]/area;
2314 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2316 lowx_int = highx_int;
2317 lowx_float = highx_float;
2318 highx_int += convx_int;
2319 highx_float += convx_float;
2320 if(highx_float > 1) {
2321 highx_float -= 1.0;
2322 highx_int++;
2325 lowy_int = highy_int;
2326 lowy_float = highy_float;
2327 highy_int += convy_int;
2328 highy_float += convy_float;
2329 if(highy_float > 1) {
2330 highy_float -= 1.0;
2331 highy_int++;
2336 static void scale_internal_uint(GLint components, GLint widthin,
2337 GLint heightin, const GLuint *datain,
2338 GLint widthout, GLint heightout,
2339 GLuint *dataout, GLint element_size,
2340 GLint ysize, GLint group_size,
2341 GLint myswap_bytes)
2343 float convx;
2344 float convy;
2345 float percent;
2346 /* Max components in a format is 4, so... */
2347 float totals[4];
2348 float area;
2349 int i,j,k,xindex;
2351 const char *temp, *temp0;
2352 const char *temp_index;
2353 int outindex;
2355 int lowx_int, highx_int, lowy_int, highy_int;
2356 float x_percent, y_percent;
2357 float lowx_float, highx_float, lowy_float, highy_float;
2358 float convy_float, convx_float;
2359 int convy_int, convx_int;
2360 int l, m;
2361 const char *left, *right;
2363 if (widthin == widthout*2 && heightin == heightout*2) {
2364 halveImage_uint(components, widthin, heightin,
2365 (const GLuint *)datain, (GLuint *)dataout,
2366 element_size, ysize, group_size, myswap_bytes);
2367 return;
2369 convy = (float) heightin/heightout;
2370 convx = (float) widthin/widthout;
2371 convy_int = floor(convy);
2372 convy_float = convy - convy_int;
2373 convx_int = floor(convx);
2374 convx_float = convx - convx_int;
2376 area = convx * convy;
2378 lowy_int = 0;
2379 lowy_float = 0;
2380 highy_int = convy_int;
2381 highy_float = convy_float;
2383 for (i = 0; i < heightout; i++) {
2384 /* Clamp here to be sure we don't read beyond input buffer. */
2385 if (highy_int >= heightin)
2386 highy_int = heightin - 1;
2387 lowx_int = 0;
2388 lowx_float = 0;
2389 highx_int = convx_int;
2390 highx_float = convx_float;
2392 for (j = 0; j < widthout; j++) {
2394 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2395 ** to (highx, highy) on input data into this pixel on output
2396 ** data.
2398 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2400 /* calculate the value for pixels in the 1st row */
2401 xindex = lowx_int*group_size;
2402 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2404 y_percent = 1-lowy_float;
2405 temp = (const char *)datain + xindex + lowy_int * ysize;
2406 percent = y_percent * (1-lowx_float);
2407 for (k = 0, temp_index = temp; k < components;
2408 k++, temp_index += element_size) {
2409 if (myswap_bytes) {
2410 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2411 } else {
2412 totals[k] += *(const GLuint*)temp_index * percent;
2415 left = temp;
2416 for(l = lowx_int+1; l < highx_int; l++) {
2417 temp += group_size;
2418 for (k = 0, temp_index = temp; k < components;
2419 k++, temp_index += element_size) {
2420 if (myswap_bytes) {
2421 totals[k] +=
2422 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2423 } else {
2424 totals[k] += *(const GLuint*)temp_index * y_percent;
2428 temp += group_size;
2429 right = temp;
2430 percent = y_percent * highx_float;
2431 for (k = 0, temp_index = temp; k < components;
2432 k++, temp_index += element_size) {
2433 if (myswap_bytes) {
2434 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2435 } else {
2436 totals[k] += *(const GLuint*)temp_index * percent;
2440 /* calculate the value for pixels in the last row */
2441 y_percent = highy_float;
2442 percent = y_percent * (1-lowx_float);
2443 temp = (const char *)datain + xindex + highy_int * ysize;
2444 for (k = 0, temp_index = temp; k < components;
2445 k++, temp_index += element_size) {
2446 if (myswap_bytes) {
2447 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2448 } else {
2449 totals[k] += *(const GLuint*)temp_index * percent;
2452 for(l = lowx_int+1; l < highx_int; l++) {
2453 temp += group_size;
2454 for (k = 0, temp_index = temp; k < components;
2455 k++, temp_index += element_size) {
2456 if (myswap_bytes) {
2457 totals[k] +=
2458 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2459 } else {
2460 totals[k] += *(const GLuint*)temp_index * y_percent;
2464 temp += group_size;
2465 percent = y_percent * highx_float;
2466 for (k = 0, temp_index = temp; k < components;
2467 k++, temp_index += element_size) {
2468 if (myswap_bytes) {
2469 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2470 } else {
2471 totals[k] += *(const GLuint*)temp_index * percent;
2475 /* calculate the value for pixels in the 1st and last column */
2476 for(m = lowy_int+1; m < highy_int; m++) {
2477 left += ysize;
2478 right += ysize;
2479 for (k = 0; k < components;
2480 k++, left += element_size, right += element_size) {
2481 if (myswap_bytes) {
2482 totals[k] +=
2483 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
2484 + __GLU_SWAP_4_BYTES(right) * highx_float;
2485 } else {
2486 totals[k] += *(const GLuint*)left * (1-lowx_float)
2487 + *(const GLuint*)right * highx_float;
2491 } else if (highy_int > lowy_int) {
2492 x_percent = highx_float - lowx_float;
2493 percent = (1-lowy_float)*x_percent;
2494 temp = (const char *)datain + xindex + lowy_int*ysize;
2495 for (k = 0, temp_index = temp; k < components;
2496 k++, temp_index += element_size) {
2497 if (myswap_bytes) {
2498 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2499 } else {
2500 totals[k] += *(const GLuint*)temp_index * percent;
2503 for(m = lowy_int+1; m < highy_int; m++) {
2504 temp += ysize;
2505 for (k = 0, temp_index = temp; k < components;
2506 k++, temp_index += element_size) {
2507 if (myswap_bytes) {
2508 totals[k] +=
2509 __GLU_SWAP_4_BYTES(temp_index) * x_percent;
2510 } else {
2511 totals[k] += *(const GLuint*)temp_index * x_percent;
2515 percent = x_percent * highy_float;
2516 temp += ysize;
2517 for (k = 0, temp_index = temp; k < components;
2518 k++, temp_index += element_size) {
2519 if (myswap_bytes) {
2520 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2521 } else {
2522 totals[k] += *(const GLuint*)temp_index * percent;
2525 } else if (highx_int > lowx_int) {
2526 y_percent = highy_float - lowy_float;
2527 percent = (1-lowx_float)*y_percent;
2529 temp = (const char *)datain + xindex + lowy_int*ysize;
2530 for (k = 0, temp_index = temp; k < components;
2531 k++, temp_index += element_size) {
2532 if (myswap_bytes) {
2533 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2534 } else {
2535 totals[k] += *(const GLuint*)temp_index * percent;
2538 for (l = lowx_int+1; l < highx_int; l++) {
2539 temp += group_size;
2540 for (k = 0, temp_index = temp; k < components;
2541 k++, temp_index += element_size) {
2542 if (myswap_bytes) {
2543 totals[k] +=
2544 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2545 } else {
2546 totals[k] += *(const GLuint*)temp_index * y_percent;
2550 temp += group_size;
2551 percent = y_percent * highx_float;
2552 for (k = 0, temp_index = temp; k < components;
2553 k++, temp_index += element_size) {
2554 if (myswap_bytes) {
2555 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2556 } else {
2557 totals[k] += *(const GLuint*)temp_index * percent;
2560 } else {
2561 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2562 temp = (const char *)datain + xindex + lowy_int * ysize;
2563 for (k = 0, temp_index = temp; k < components;
2564 k++, temp_index += element_size) {
2565 if (myswap_bytes) {
2566 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2567 } else {
2568 totals[k] += *(const GLuint*)temp_index * percent;
2573 /* this is for the pixels in the body */
2574 temp0 = (const char *)datain + xindex + group_size +
2575 (lowy_int+1)*ysize;
2576 for (m = lowy_int+1; m < highy_int; m++) {
2577 temp = temp0;
2578 for(l = lowx_int+1; l < highx_int; l++) {
2579 for (k = 0, temp_index = temp; k < components;
2580 k++, temp_index += element_size) {
2581 if (myswap_bytes) {
2582 totals[k] += __GLU_SWAP_4_BYTES(temp_index);
2583 } else {
2584 totals[k] += *(const GLuint*)temp_index;
2587 temp += group_size;
2589 temp0 += ysize;
2592 outindex = (j + (i * widthout)) * components;
2593 for (k = 0; k < components; k++) {
2594 /* clamp at UINT_MAX */
2595 float value= totals[k]/area;
2596 if (value >= (float) UINT_MAX) { /* need '=' */
2597 dataout[outindex + k] = UINT_MAX;
2599 else dataout[outindex + k] = value;
2601 lowx_int = highx_int;
2602 lowx_float = highx_float;
2603 highx_int += convx_int;
2604 highx_float += convx_float;
2605 if(highx_float > 1) {
2606 highx_float -= 1.0;
2607 highx_int++;
2610 lowy_int = highy_int;
2611 lowy_float = highy_float;
2612 highy_int += convy_int;
2613 highy_float += convy_float;
2614 if(highy_float > 1) {
2615 highy_float -= 1.0;
2616 highy_int++;
2623 static void scale_internal_int(GLint components, GLint widthin,
2624 GLint heightin, const GLint *datain,
2625 GLint widthout, GLint heightout,
2626 GLint *dataout, GLint element_size,
2627 GLint ysize, GLint group_size,
2628 GLint myswap_bytes)
2630 float convx;
2631 float convy;
2632 float percent;
2633 /* Max components in a format is 4, so... */
2634 float totals[4];
2635 float area;
2636 int i,j,k,xindex;
2638 const char *temp, *temp0;
2639 const char *temp_index;
2640 int outindex;
2642 int lowx_int, highx_int, lowy_int, highy_int;
2643 float x_percent, y_percent;
2644 float lowx_float, highx_float, lowy_float, highy_float;
2645 float convy_float, convx_float;
2646 int convy_int, convx_int;
2647 int l, m;
2648 const char *left, *right;
2650 GLuint swapbuf; /* unsigned buffer */
2652 if (widthin == widthout*2 && heightin == heightout*2) {
2653 halveImage_int(components, widthin, heightin,
2654 (const GLint *)datain, (GLint *)dataout,
2655 element_size, ysize, group_size, myswap_bytes);
2656 return;
2658 convy = (float) heightin/heightout;
2659 convx = (float) widthin/widthout;
2660 convy_int = floor(convy);
2661 convy_float = convy - convy_int;
2662 convx_int = floor(convx);
2663 convx_float = convx - convx_int;
2665 area = convx * convy;
2667 lowy_int = 0;
2668 lowy_float = 0;
2669 highy_int = convy_int;
2670 highy_float = convy_float;
2672 for (i = 0; i < heightout; i++) {
2673 /* Clamp here to be sure we don't read beyond input buffer. */
2674 if (highy_int >= heightin)
2675 highy_int = heightin - 1;
2676 lowx_int = 0;
2677 lowx_float = 0;
2678 highx_int = convx_int;
2679 highx_float = convx_float;
2681 for (j = 0; j < widthout; j++) {
2683 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2684 ** to (highx, highy) on input data into this pixel on output
2685 ** data.
2687 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2689 /* calculate the value for pixels in the 1st row */
2690 xindex = lowx_int*group_size;
2691 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2693 y_percent = 1-lowy_float;
2694 temp = (const char *)datain + xindex + lowy_int * ysize;
2695 percent = y_percent * (1-lowx_float);
2696 for (k = 0, temp_index = temp; k < components;
2697 k++, temp_index += element_size) {
2698 if (myswap_bytes) {
2699 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2700 totals[k] += *(const GLint*)&swapbuf * percent;
2701 } else {
2702 totals[k] += *(const GLint*)temp_index * percent;
2705 left = temp;
2706 for(l = lowx_int+1; l < highx_int; l++) {
2707 temp += group_size;
2708 for (k = 0, temp_index = temp; k < components;
2709 k++, temp_index += element_size) {
2710 if (myswap_bytes) {
2711 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2712 totals[k] += *(const GLint*)&swapbuf * y_percent;
2713 } else {
2714 totals[k] += *(const GLint*)temp_index * y_percent;
2718 temp += group_size;
2719 right = temp;
2720 percent = y_percent * highx_float;
2721 for (k = 0, temp_index = temp; k < components;
2722 k++, temp_index += element_size) {
2723 if (myswap_bytes) {
2724 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2725 totals[k] += *(const GLint*)&swapbuf * percent;
2726 } else {
2727 totals[k] += *(const GLint*)temp_index * percent;
2731 /* calculate the value for pixels in the last row */
2732 y_percent = highy_float;
2733 percent = y_percent * (1-lowx_float);
2734 temp = (const char *)datain + xindex + highy_int * ysize;
2735 for (k = 0, temp_index = temp; k < components;
2736 k++, temp_index += element_size) {
2737 if (myswap_bytes) {
2738 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2739 totals[k] += *(const GLint*)&swapbuf * percent;
2740 } else {
2741 totals[k] += *(const GLint*)temp_index * percent;
2744 for(l = lowx_int+1; l < highx_int; l++) {
2745 temp += group_size;
2746 for (k = 0, temp_index = temp; k < components;
2747 k++, temp_index += element_size) {
2748 if (myswap_bytes) {
2749 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2750 totals[k] += *(const GLint*)&swapbuf * y_percent;
2751 } else {
2752 totals[k] += *(const GLint*)temp_index * y_percent;
2756 temp += group_size;
2757 percent = y_percent * highx_float;
2758 for (k = 0, temp_index = temp; k < components;
2759 k++, temp_index += element_size) {
2760 if (myswap_bytes) {
2761 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2762 totals[k] += *(const GLint*)&swapbuf * percent;
2763 } else {
2764 totals[k] += *(const GLint*)temp_index * percent;
2768 /* calculate the value for pixels in the 1st and last column */
2769 for(m = lowy_int+1; m < highy_int; m++) {
2770 left += ysize;
2771 right += ysize;
2772 for (k = 0; k < components;
2773 k++, left += element_size, right += element_size) {
2774 if (myswap_bytes) {
2775 swapbuf = __GLU_SWAP_4_BYTES(left);
2776 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
2777 swapbuf = __GLU_SWAP_4_BYTES(right);
2778 totals[k] += *(const GLint*)&swapbuf * highx_float;
2779 } else {
2780 totals[k] += *(const GLint*)left * (1-lowx_float)
2781 + *(const GLint*)right * highx_float;
2785 } else if (highy_int > lowy_int) {
2786 x_percent = highx_float - lowx_float;
2787 percent = (1-lowy_float)*x_percent;
2788 temp = (const char *)datain + xindex + lowy_int*ysize;
2789 for (k = 0, temp_index = temp; k < components;
2790 k++, temp_index += element_size) {
2791 if (myswap_bytes) {
2792 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2793 totals[k] += *(const GLint*)&swapbuf * percent;
2794 } else {
2795 totals[k] += *(const GLint*)temp_index * percent;
2798 for(m = lowy_int+1; m < highy_int; m++) {
2799 temp += ysize;
2800 for (k = 0, temp_index = temp; k < components;
2801 k++, temp_index += element_size) {
2802 if (myswap_bytes) {
2803 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2804 totals[k] += *(const GLint*)&swapbuf * x_percent;
2805 } else {
2806 totals[k] += *(const GLint*)temp_index * x_percent;
2810 percent = x_percent * highy_float;
2811 temp += ysize;
2812 for (k = 0, temp_index = temp; k < components;
2813 k++, temp_index += element_size) {
2814 if (myswap_bytes) {
2815 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2816 totals[k] += *(const GLint*)&swapbuf * percent;
2817 } else {
2818 totals[k] += *(const GLint*)temp_index * percent;
2821 } else if (highx_int > lowx_int) {
2822 y_percent = highy_float - lowy_float;
2823 percent = (1-lowx_float)*y_percent;
2825 temp = (const char *)datain + xindex + lowy_int*ysize;
2826 for (k = 0, temp_index = temp; k < components;
2827 k++, temp_index += element_size) {
2828 if (myswap_bytes) {
2829 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2830 totals[k] += *(const GLint*)&swapbuf * percent;
2831 } else {
2832 totals[k] += *(const GLint*)temp_index * percent;
2835 for (l = lowx_int+1; l < highx_int; l++) {
2836 temp += group_size;
2837 for (k = 0, temp_index = temp; k < components;
2838 k++, temp_index += element_size) {
2839 if (myswap_bytes) {
2840 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2841 totals[k] += *(const GLint*)&swapbuf * y_percent;
2842 } else {
2843 totals[k] += *(const GLint*)temp_index * y_percent;
2847 temp += group_size;
2848 percent = y_percent * highx_float;
2849 for (k = 0, temp_index = temp; k < components;
2850 k++, temp_index += element_size) {
2851 if (myswap_bytes) {
2852 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2853 totals[k] += *(const GLint*)&swapbuf * percent;
2854 } else {
2855 totals[k] += *(const GLint*)temp_index * percent;
2858 } else {
2859 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2860 temp = (const char *)datain + xindex + lowy_int * ysize;
2861 for (k = 0, temp_index = temp; k < components;
2862 k++, temp_index += element_size) {
2863 if (myswap_bytes) {
2864 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2865 totals[k] += *(const GLint*)&swapbuf * percent;
2866 } else {
2867 totals[k] += *(const GLint*)temp_index * percent;
2872 /* this is for the pixels in the body */
2873 temp0 = (const char *)datain + xindex + group_size +
2874 (lowy_int+1)*ysize;
2875 for (m = lowy_int+1; m < highy_int; m++) {
2876 temp = temp0;
2877 for(l = lowx_int+1; l < highx_int; l++) {
2878 for (k = 0, temp_index = temp; k < components;
2879 k++, temp_index += element_size) {
2880 if (myswap_bytes) {
2881 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2882 totals[k] += *(const GLint*)&swapbuf;
2883 } else {
2884 totals[k] += *(const GLint*)temp_index;
2887 temp += group_size;
2889 temp0 += ysize;
2892 outindex = (j + (i * widthout)) * components;
2893 for (k = 0; k < components; k++) {
2894 dataout[outindex + k] = totals[k]/area;
2895 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2897 lowx_int = highx_int;
2898 lowx_float = highx_float;
2899 highx_int += convx_int;
2900 highx_float += convx_float;
2901 if(highx_float > 1) {
2902 highx_float -= 1.0;
2903 highx_int++;
2906 lowy_int = highy_int;
2907 lowy_float = highy_float;
2908 highy_int += convy_int;
2909 highy_float += convy_float;
2910 if(highy_float > 1) {
2911 highy_float -= 1.0;
2912 highy_int++;
2919 static void scale_internal_float(GLint components, GLint widthin,
2920 GLint heightin, const GLfloat *datain,
2921 GLint widthout, GLint heightout,
2922 GLfloat *dataout, GLint element_size,
2923 GLint ysize, GLint group_size,
2924 GLint myswap_bytes)
2926 float convx;
2927 float convy;
2928 float percent;
2929 /* Max components in a format is 4, so... */
2930 float totals[4];
2931 float area;
2932 int i,j,k,xindex;
2934 const char *temp, *temp0;
2935 const char *temp_index;
2936 int outindex;
2938 int lowx_int, highx_int, lowy_int, highy_int;
2939 float x_percent, y_percent;
2940 float lowx_float, highx_float, lowy_float, highy_float;
2941 float convy_float, convx_float;
2942 int convy_int, convx_int;
2943 int l, m;
2944 const char *left, *right;
2946 union { GLuint b; GLfloat f; } swapbuf;
2948 if (widthin == widthout*2 && heightin == heightout*2) {
2949 halveImage_float(components, widthin, heightin,
2950 (const GLfloat *)datain, (GLfloat *)dataout,
2951 element_size, ysize, group_size, myswap_bytes);
2952 return;
2954 convy = (float) heightin/heightout;
2955 convx = (float) widthin/widthout;
2956 convy_int = floor(convy);
2957 convy_float = convy - convy_int;
2958 convx_int = floor(convx);
2959 convx_float = convx - convx_int;
2961 area = convx * convy;
2963 lowy_int = 0;
2964 lowy_float = 0;
2965 highy_int = convy_int;
2966 highy_float = convy_float;
2968 for (i = 0; i < heightout; i++) {
2969 /* Clamp here to be sure we don't read beyond input buffer. */
2970 if (highy_int >= heightin)
2971 highy_int = heightin - 1;
2972 lowx_int = 0;
2973 lowx_float = 0;
2974 highx_int = convx_int;
2975 highx_float = convx_float;
2977 for (j = 0; j < widthout; j++) {
2979 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2980 ** to (highx, highy) on input data into this pixel on output
2981 ** data.
2983 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2985 /* calculate the value for pixels in the 1st row */
2986 xindex = lowx_int*group_size;
2987 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2989 y_percent = 1-lowy_float;
2990 temp = (const char *)datain + xindex + lowy_int * ysize;
2991 percent = y_percent * (1-lowx_float);
2992 for (k = 0, temp_index = temp; k < components;
2993 k++, temp_index += element_size) {
2994 if (myswap_bytes) {
2995 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
2996 totals[k] += swapbuf.f * percent;
2997 } else {
2998 totals[k] += *(const GLfloat*)temp_index * percent;
3001 left = temp;
3002 for(l = lowx_int+1; l < highx_int; l++) {
3003 temp += group_size;
3004 for (k = 0, temp_index = temp; k < components;
3005 k++, temp_index += element_size) {
3006 if (myswap_bytes) {
3007 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3008 totals[k] += swapbuf.f * y_percent;
3009 } else {
3010 totals[k] += *(const GLfloat*)temp_index * y_percent;
3014 temp += group_size;
3015 right = temp;
3016 percent = y_percent * highx_float;
3017 for (k = 0, temp_index = temp; k < components;
3018 k++, temp_index += element_size) {
3019 if (myswap_bytes) {
3020 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3021 totals[k] += swapbuf.f * percent;
3022 } else {
3023 totals[k] += *(const GLfloat*)temp_index * percent;
3027 /* calculate the value for pixels in the last row */
3028 y_percent = highy_float;
3029 percent = y_percent * (1-lowx_float);
3030 temp = (const char *)datain + xindex + highy_int * ysize;
3031 for (k = 0, temp_index = temp; k < components;
3032 k++, temp_index += element_size) {
3033 if (myswap_bytes) {
3034 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3035 totals[k] += swapbuf.f * percent;
3036 } else {
3037 totals[k] += *(const GLfloat*)temp_index * percent;
3040 for(l = lowx_int+1; l < highx_int; l++) {
3041 temp += group_size;
3042 for (k = 0, temp_index = temp; k < components;
3043 k++, temp_index += element_size) {
3044 if (myswap_bytes) {
3045 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3046 totals[k] += swapbuf.f * y_percent;
3047 } else {
3048 totals[k] += *(const GLfloat*)temp_index * y_percent;
3052 temp += group_size;
3053 percent = y_percent * highx_float;
3054 for (k = 0, temp_index = temp; k < components;
3055 k++, temp_index += element_size) {
3056 if (myswap_bytes) {
3057 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3058 totals[k] += swapbuf.f * percent;
3059 } else {
3060 totals[k] += *(const GLfloat*)temp_index * percent;
3064 /* calculate the value for pixels in the 1st and last column */
3065 for(m = lowy_int+1; m < highy_int; m++) {
3066 left += ysize;
3067 right += ysize;
3068 for (k = 0; k < components;
3069 k++, left += element_size, right += element_size) {
3070 if (myswap_bytes) {
3071 swapbuf.b = __GLU_SWAP_4_BYTES(left);
3072 totals[k] += swapbuf.f * (1-lowx_float);
3073 swapbuf.b = __GLU_SWAP_4_BYTES(right);
3074 totals[k] += swapbuf.f * highx_float;
3075 } else {
3076 totals[k] += *(const GLfloat*)left * (1-lowx_float)
3077 + *(const GLfloat*)right * highx_float;
3081 } else if (highy_int > lowy_int) {
3082 x_percent = highx_float - lowx_float;
3083 percent = (1-lowy_float)*x_percent;
3084 temp = (const char *)datain + xindex + lowy_int*ysize;
3085 for (k = 0, temp_index = temp; k < components;
3086 k++, temp_index += element_size) {
3087 if (myswap_bytes) {
3088 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3089 totals[k] += swapbuf.f * percent;
3090 } else {
3091 totals[k] += *(const GLfloat*)temp_index * percent;
3094 for(m = lowy_int+1; m < highy_int; m++) {
3095 temp += ysize;
3096 for (k = 0, temp_index = temp; k < components;
3097 k++, temp_index += element_size) {
3098 if (myswap_bytes) {
3099 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3100 totals[k] += swapbuf.f * x_percent;
3101 } else {
3102 totals[k] += *(const GLfloat*)temp_index * x_percent;
3106 percent = x_percent * highy_float;
3107 temp += ysize;
3108 for (k = 0, temp_index = temp; k < components;
3109 k++, temp_index += element_size) {
3110 if (myswap_bytes) {
3111 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3112 totals[k] += swapbuf.f * percent;
3113 } else {
3114 totals[k] += *(const GLfloat*)temp_index * percent;
3117 } else if (highx_int > lowx_int) {
3118 y_percent = highy_float - lowy_float;
3119 percent = (1-lowx_float)*y_percent;
3121 temp = (const char *)datain + xindex + lowy_int*ysize;
3122 for (k = 0, temp_index = temp; k < components;
3123 k++, temp_index += element_size) {
3124 if (myswap_bytes) {
3125 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3126 totals[k] += swapbuf.f * percent;
3127 } else {
3128 totals[k] += *(const GLfloat*)temp_index * percent;
3131 for (l = lowx_int+1; l < highx_int; l++) {
3132 temp += group_size;
3133 for (k = 0, temp_index = temp; k < components;
3134 k++, temp_index += element_size) {
3135 if (myswap_bytes) {
3136 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3137 totals[k] += swapbuf.f * y_percent;
3138 } else {
3139 totals[k] += *(const GLfloat*)temp_index * y_percent;
3143 temp += group_size;
3144 percent = y_percent * highx_float;
3145 for (k = 0, temp_index = temp; k < components;
3146 k++, temp_index += element_size) {
3147 if (myswap_bytes) {
3148 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3149 totals[k] += swapbuf.f * percent;
3150 } else {
3151 totals[k] += *(const GLfloat*)temp_index * percent;
3154 } else {
3155 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
3156 temp = (const char *)datain + xindex + lowy_int * ysize;
3157 for (k = 0, temp_index = temp; k < components;
3158 k++, temp_index += element_size) {
3159 if (myswap_bytes) {
3160 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3161 totals[k] += swapbuf.f * percent;
3162 } else {
3163 totals[k] += *(const GLfloat*)temp_index * percent;
3168 /* this is for the pixels in the body */
3169 temp0 = (const char *)datain + xindex + group_size +
3170 (lowy_int+1)*ysize;
3171 for (m = lowy_int+1; m < highy_int; m++) {
3172 temp = temp0;
3173 for(l = lowx_int+1; l < highx_int; l++) {
3174 for (k = 0, temp_index = temp; k < components;
3175 k++, temp_index += element_size) {
3176 if (myswap_bytes) {
3177 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3178 totals[k] += swapbuf.f;
3179 } else {
3180 totals[k] += *(const GLfloat*)temp_index;
3183 temp += group_size;
3185 temp0 += ysize;
3188 outindex = (j + (i * widthout)) * components;
3189 for (k = 0; k < components; k++) {
3190 dataout[outindex + k] = totals[k]/area;
3191 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3193 lowx_int = highx_int;
3194 lowx_float = highx_float;
3195 highx_int += convx_int;
3196 highx_float += convx_float;
3197 if(highx_float > 1) {
3198 highx_float -= 1.0;
3199 highx_int++;
3202 lowy_int = highy_int;
3203 lowy_float = highy_float;
3204 highy_int += convy_int;
3205 highy_float += convy_float;
3206 if(highy_float > 1) {
3207 highy_float -= 1.0;
3208 highy_int++;
3213 static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
3215 if (!legalFormat(format) || !legalType(type)) {
3216 return GLU_INVALID_ENUM;
3218 if (format == GL_STENCIL_INDEX) {
3219 return GLU_INVALID_ENUM;
3222 if (!isLegalFormatForPackedPixelType(format, type)) {
3223 return GLU_INVALID_OPERATION;
3226 return 0;
3227 } /* checkMipmapArgs() */
3229 static GLboolean legalFormat(GLenum format)
3231 switch(format) {
3232 case GL_COLOR_INDEX:
3233 case GL_STENCIL_INDEX:
3234 case GL_DEPTH_COMPONENT:
3235 case GL_RED:
3236 case GL_GREEN:
3237 case GL_BLUE:
3238 case GL_ALPHA:
3239 case GL_RGB:
3240 case GL_RGBA:
3241 case GL_LUMINANCE:
3242 case GL_LUMINANCE_ALPHA:
3243 case GL_BGR:
3244 case GL_BGRA:
3245 return GL_TRUE;
3246 default:
3247 return GL_FALSE;
3252 static GLboolean legalType(GLenum type)
3254 switch(type) {
3255 case GL_BITMAP:
3256 case GL_BYTE:
3257 case GL_UNSIGNED_BYTE:
3258 case GL_SHORT:
3259 case GL_UNSIGNED_SHORT:
3260 case GL_INT:
3261 case GL_UNSIGNED_INT:
3262 case GL_FLOAT:
3263 case GL_UNSIGNED_BYTE_3_3_2:
3264 case GL_UNSIGNED_BYTE_2_3_3_REV:
3265 case GL_UNSIGNED_SHORT_5_6_5:
3266 case GL_UNSIGNED_SHORT_5_6_5_REV:
3267 case GL_UNSIGNED_SHORT_4_4_4_4:
3268 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3269 case GL_UNSIGNED_SHORT_5_5_5_1:
3270 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3271 case GL_UNSIGNED_INT_8_8_8_8:
3272 case GL_UNSIGNED_INT_8_8_8_8_REV:
3273 case GL_UNSIGNED_INT_10_10_10_2:
3274 case GL_UNSIGNED_INT_2_10_10_10_REV:
3275 return GL_TRUE;
3276 default:
3277 return GL_FALSE;
3281 /* */
3282 static GLboolean isTypePackedPixel(GLenum type)
3284 assert(legalType(type));
3286 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
3287 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
3288 type == GL_UNSIGNED_SHORT_5_6_5 ||
3289 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
3290 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3291 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3292 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3293 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3294 type == GL_UNSIGNED_INT_8_8_8_8 ||
3295 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3296 type == GL_UNSIGNED_INT_10_10_10_2 ||
3297 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
3298 return 1;
3300 else return 0;
3301 } /* isTypePackedPixel() */
3303 /* Determines if the packed pixel type is compatible with the format */
3304 static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
3306 /* if not a packed pixel type then return true */
3307 if (!isTypePackedPixel(type)) {
3308 return GL_TRUE;
3311 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3312 if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
3313 type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
3314 && format != GL_RGB)
3315 return GL_FALSE;
3317 /* 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 &
3318 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3320 if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3321 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3322 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3323 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3324 type == GL_UNSIGNED_INT_8_8_8_8 ||
3325 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3326 type == GL_UNSIGNED_INT_10_10_10_2 ||
3327 type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
3328 (format != GL_RGBA &&
3329 format != GL_BGRA)) {
3330 return GL_FALSE;
3333 return GL_TRUE;
3334 } /* isLegalFormatForPackedPixelType() */
3336 /* Given user requested texture size, determine if it fits. If it
3337 * doesn't then halve both sides and make the determination again
3338 * until it does fit (for IR only).
3339 * Note that proxy textures are not implemented in RE* even though
3340 * they advertise the texture extension.
3341 * Note that proxy textures are implemented but not according to spec in
3342 * IMPACT*.
3344 static void closestFit(GLenum target, GLint width, GLint height,
3345 GLint internalFormat, GLenum format, GLenum type,
3346 GLint *newWidth, GLint *newHeight)
3348 /* Use proxy textures if OpenGL version is >= 1.1 */
3349 if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
3351 GLint widthPowerOf2= nearestPower(width);
3352 GLint heightPowerOf2= nearestPower(height);
3353 GLint proxyWidth;
3355 do {
3356 /* compute level 1 width & height, clamping each at 1 */
3357 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
3358 widthPowerOf2 >> 1 :
3359 widthPowerOf2;
3360 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
3361 heightPowerOf2 >> 1 :
3362 heightPowerOf2;
3363 GLenum proxyTarget;
3364 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
3366 /* does width x height at level 1 & all their mipmaps fit? */
3367 if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
3368 proxyTarget = GL_PROXY_TEXTURE_2D;
3369 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3370 internalFormat,
3371 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3372 } else
3373 if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
3374 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
3375 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
3376 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
3377 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
3378 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
3379 proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3380 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3381 internalFormat,
3382 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3383 } else
3385 assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
3386 proxyTarget = GL_PROXY_TEXTURE_1D;
3387 glTexImage1D(proxyTarget, 1, /* must be non-zero */
3388 internalFormat,widthAtLevelOne,0,format,type,NULL);
3390 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
3391 /* does it fit??? */
3392 if (proxyWidth == 0) { /* nope, so try again with these sizes */
3393 if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
3394 /* An 1x1 texture couldn't fit for some reason, so
3395 * break out. This should never happen. But things
3396 * happen. The disadvantage with this if-statement is
3397 * that we will never be aware of when this happens
3398 * since it will silently branch out.
3400 goto noProxyTextures;
3402 widthPowerOf2= widthAtLevelOne;
3403 heightPowerOf2= heightAtLevelOne;
3405 /* else it does fit */
3406 } while (proxyWidth == 0);
3407 /* loop must terminate! */
3409 /* return the width & height at level 0 that fits */
3410 *newWidth= widthPowerOf2;
3411 *newHeight= heightPowerOf2;
3412 /*printf("Proxy Textures\n");*/
3413 } /* if gluCheckExtension() */
3414 else { /* no texture extension, so do this instead */
3415 GLint maxsize;
3417 noProxyTextures:
3419 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3420 /* clamp user's texture sizes to maximum sizes, if necessary */
3421 *newWidth = nearestPower(width);
3422 if (*newWidth > maxsize) *newWidth = maxsize;
3423 *newHeight = nearestPower(height);
3424 if (*newHeight > maxsize) *newHeight = maxsize;
3425 /*printf("NO proxy textures\n");*/
3427 } /* closestFit() */
3430 /***********************************************************************
3431 * gluScaleImage (GLU32.@)
3433 GLint WINAPI gluScaleImage( GLenum format, GLint widthin, GLint heightin, GLenum typein, const void *datain,
3434 GLint widthout, GLint heightout, GLenum typeout, void *dataout )
3436 int components;
3437 GLushort *beforeImage;
3438 GLushort *afterImage;
3439 PixelStorageModes psm;
3441 if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
3442 return 0;
3444 if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
3445 return GLU_INVALID_VALUE;
3447 if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
3448 return GLU_INVALID_ENUM;
3450 if (!isLegalFormatForPackedPixelType(format, typein)) {
3451 return GLU_INVALID_ENUM;
3453 if (!isLegalFormatForPackedPixelType(format, typeout)) {
3454 return GLU_INVALID_ENUM;
3456 if (!wglGetCurrentContext()) {
3457 return GL_OUT_OF_MEMORY; /* windows returns this if no gl context (not glu error) */
3460 beforeImage =
3461 HeapAlloc(GetProcessHeap(), 0, image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
3462 afterImage =
3463 HeapAlloc(GetProcessHeap(), 0, image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
3464 if (beforeImage == NULL || afterImage == NULL) {
3465 HeapFree(GetProcessHeap(), 0, beforeImage);
3466 HeapFree(GetProcessHeap(), 0, afterImage);
3467 return GLU_OUT_OF_MEMORY;
3470 retrieveStoreModes(&psm);
3471 fill_image(&psm,widthin, heightin, format, typein, is_index(format),
3472 datain, beforeImage);
3473 components = elements_per_group(format, 0);
3474 scale_internal(components, widthin, heightin, beforeImage,
3475 widthout, heightout, afterImage);
3476 empty_image(&psm,widthout, heightout, format, typeout,
3477 is_index(format), afterImage, dataout);
3478 HeapFree(GetProcessHeap(), 0, beforeImage);
3479 HeapFree(GetProcessHeap(), 0, afterImage);
3481 return 0;
3484 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
3485 GLsizei width,
3486 GLsizei widthPowerOf2,
3487 GLenum format, GLenum type,
3488 GLint userLevel, GLint baseLevel,GLint maxLevel,
3489 const void *data)
3491 GLint newwidth;
3492 GLint level, levels;
3493 GLushort *newImage;
3494 GLint newImage_width;
3495 GLushort *otherImage;
3496 GLushort *imageTemp;
3497 GLint memreq;
3498 GLint cmpts;
3499 PixelStorageModes psm;
3501 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3502 assert(width >= 1);
3504 otherImage = NULL;
3506 newwidth= widthPowerOf2;
3507 levels = computeLog(newwidth);
3509 levels+= userLevel;
3511 retrieveStoreModes(&psm);
3512 newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, 1, format, GL_UNSIGNED_SHORT));
3513 newImage_width = width;
3514 if (newImage == NULL) {
3515 return GLU_OUT_OF_MEMORY;
3517 fill_image(&psm,width, 1, format, type, is_index(format),
3518 data, newImage);
3519 cmpts = elements_per_group(format,type);
3520 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3521 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3522 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3523 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3525 ** If swap_bytes was set, swapping occurred in fill_image.
3527 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3529 for (level = userLevel; level <= levels; level++) {
3530 if (newImage_width == newwidth) {
3531 /* Use newImage for this level */
3532 if (baseLevel <= level && level <= maxLevel) {
3533 glTexImage1D(target, level, internalFormat, newImage_width,
3534 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3536 } else {
3537 if (otherImage == NULL) {
3538 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
3539 otherImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3540 if (otherImage == NULL) {
3541 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3542 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3543 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3544 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3545 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3546 HeapFree(GetProcessHeap(), 0, newImage);
3547 return GLU_OUT_OF_MEMORY;
3550 scale_internal(cmpts, newImage_width, 1, newImage,
3551 newwidth, 1, otherImage);
3552 /* Swap newImage and otherImage */
3553 imageTemp = otherImage;
3554 otherImage = newImage;
3555 newImage = imageTemp;
3557 newImage_width = newwidth;
3558 if (baseLevel <= level && level <= maxLevel) {
3559 glTexImage1D(target, level, internalFormat, newImage_width,
3560 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3563 if (newwidth > 1) newwidth /= 2;
3565 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3566 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3567 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3568 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3569 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3571 HeapFree(GetProcessHeap(), 0, newImage);
3572 HeapFree(GetProcessHeap(), 0, otherImage);
3573 return 0;
3577 /***********************************************************************
3578 * gluBuild1DMipmaps (GLU32.@)
3580 GLint WINAPI gluBuild1DMipmaps( GLenum target, GLint internalFormat, GLsizei width,
3581 GLenum format, GLenum type, const void *data )
3583 GLint widthPowerOf2;
3584 int levels;
3585 GLint dummy;
3587 int rc= checkMipmapArgs(internalFormat,format,type);
3588 if (rc != 0) return rc;
3590 if (width < 1) {
3591 return GLU_INVALID_VALUE;
3594 closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
3595 levels = computeLog(widthPowerOf2);
3597 return gluBuild1DMipmapLevelsCore(target,internalFormat,
3598 width,
3599 widthPowerOf2,
3600 format,type,0,0,levels,data);
3603 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
3604 GLint width, GLint height, GLenum format,
3605 GLenum type, const void *data)
3607 GLint newwidth, newheight;
3608 GLint level, levels;
3609 GLushort *newImage;
3610 GLint newImage_width;
3611 GLint newImage_height;
3612 GLushort *otherImage;
3613 GLushort *imageTemp;
3614 GLint memreq;
3615 GLint cmpts;
3616 PixelStorageModes psm;
3618 retrieveStoreModes(&psm);
3620 #if 0
3621 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3622 newwidth = nearestPower(width);
3623 if (newwidth > maxsize) newwidth = maxsize;
3624 newheight = nearestPower(height);
3625 if (newheight > maxsize) newheight = maxsize;
3626 #else
3627 closestFit(target,width,height,internalFormat,format,type,
3628 &newwidth,&newheight);
3629 #endif
3630 levels = computeLog(newwidth);
3631 level = computeLog(newheight);
3632 if (level > levels) levels=level;
3634 otherImage = NULL;
3635 newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, height, format, GL_UNSIGNED_SHORT));
3636 newImage_width = width;
3637 newImage_height = height;
3638 if (newImage == NULL) {
3639 return GLU_OUT_OF_MEMORY;
3642 fill_image(&psm,width, height, format, type, is_index(format),
3643 data, newImage);
3645 cmpts = elements_per_group(format,type);
3646 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3647 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3648 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3649 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3651 ** If swap_bytes was set, swapping occurred in fill_image.
3653 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3655 for (level = 0; level <= levels; level++) {
3656 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
3657 glTexImage2D(target, level, internalFormat, newImage_width,
3658 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3659 (void *) newImage);
3660 } else {
3661 if (otherImage == NULL) {
3662 memreq =
3663 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
3664 otherImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3665 if (otherImage == NULL) {
3666 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3667 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3668 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3669 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3670 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3671 HeapFree(GetProcessHeap(), 0, newImage);
3672 return GLU_OUT_OF_MEMORY;
3675 scale_internal(cmpts, newImage_width, newImage_height, newImage,
3676 newwidth, newheight, otherImage);
3677 /* Swap newImage and otherImage */
3678 imageTemp = otherImage;
3679 otherImage = newImage;
3680 newImage = imageTemp;
3682 newImage_width = newwidth;
3683 newImage_height = newheight;
3684 glTexImage2D(target, level, internalFormat, newImage_width,
3685 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3686 (void *) newImage);
3688 if (newwidth > 1) newwidth /= 2;
3689 if (newheight > 1) newheight /= 2;
3691 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3692 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3693 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3694 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3695 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3697 HeapFree(GetProcessHeap(), 0, newImage);
3698 HeapFree(GetProcessHeap(), 0, otherImage);
3699 return 0;
3702 /* To make swapping images less error prone */
3703 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3704 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3706 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3707 GLsizei width, GLsizei height,
3708 GLsizei widthPowerOf2,
3709 GLsizei heightPowerOf2,
3710 GLenum format, GLenum type,
3711 GLint userLevel,
3712 GLint baseLevel,GLint maxLevel,
3713 const void *data)
3715 GLint newwidth, newheight;
3716 GLint level, levels;
3717 const void *usersImage; /* passed from user. Don't touch! */
3718 void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3719 __GLU_INIT_SWAP_IMAGE;
3720 GLint memreq;
3721 GLint cmpts;
3723 GLint myswap_bytes, groups_per_line, element_size, group_size;
3724 GLint rowsize, padding;
3725 PixelStorageModes psm;
3727 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3728 assert(width >= 1 && height >= 1);
3730 if(type == GL_BITMAP) {
3731 return bitmapBuild2DMipmaps(target, internalFormat, width, height,
3732 format, type, data);
3735 srcImage = dstImage = NULL;
3737 newwidth= widthPowerOf2;
3738 newheight= heightPowerOf2;
3739 levels = computeLog(newwidth);
3740 level = computeLog(newheight);
3741 if (level > levels) levels=level;
3743 levels+= userLevel;
3745 retrieveStoreModes(&psm);
3746 myswap_bytes = psm.unpack_swap_bytes;
3747 cmpts = elements_per_group(format,type);
3748 if (psm.unpack_row_length > 0) {
3749 groups_per_line = psm.unpack_row_length;
3750 } else {
3751 groups_per_line = width;
3754 element_size = bytes_per_element(type);
3755 group_size = element_size * cmpts;
3756 if (element_size == 1) myswap_bytes = 0;
3758 rowsize = groups_per_line * group_size;
3759 padding = (rowsize % psm.unpack_alignment);
3760 if (padding) {
3761 rowsize += psm.unpack_alignment - padding;
3763 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3764 psm.unpack_skip_pixels * group_size;
3766 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3767 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3768 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3770 level = userLevel;
3772 /* already power-of-two square */
3773 if (width == newwidth && height == newheight) {
3774 /* Use usersImage for level userLevel */
3775 if (baseLevel <= level && level <= maxLevel) {
3776 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3777 glTexImage2D(target, level, internalFormat, width,
3778 height, 0, format, type,
3779 usersImage);
3781 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3782 if(levels == 0) { /* we're done. clean up and return */
3783 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3784 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3785 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3786 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3787 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3788 return 0;
3791 int nextWidth= newwidth/2;
3792 int nextHeight= newheight/2;
3794 /* clamp to 1 */
3795 if (nextWidth < 1) nextWidth= 1;
3796 if (nextHeight < 1) nextHeight= 1;
3797 memreq = image_size(nextWidth, nextHeight, format, type);
3800 switch(type) {
3801 case GL_UNSIGNED_BYTE:
3802 case GL_BYTE:
3803 case GL_UNSIGNED_SHORT:
3804 case GL_SHORT:
3805 case GL_UNSIGNED_INT:
3806 case GL_INT:
3807 case GL_FLOAT:
3808 case GL_UNSIGNED_BYTE_3_3_2:
3809 case GL_UNSIGNED_BYTE_2_3_3_REV:
3810 case GL_UNSIGNED_SHORT_5_6_5:
3811 case GL_UNSIGNED_SHORT_5_6_5_REV:
3812 case GL_UNSIGNED_SHORT_4_4_4_4:
3813 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3814 case GL_UNSIGNED_SHORT_5_5_5_1:
3815 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3816 case GL_UNSIGNED_INT_8_8_8_8:
3817 case GL_UNSIGNED_INT_8_8_8_8_REV:
3818 case GL_UNSIGNED_INT_10_10_10_2:
3819 case GL_UNSIGNED_INT_2_10_10_10_REV:
3820 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3821 break;
3822 default:
3823 return GLU_INVALID_ENUM;
3825 if (dstImage == NULL) {
3826 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3827 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3828 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3829 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3830 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3831 return GLU_OUT_OF_MEMORY;
3833 else
3834 switch(type) {
3835 case GL_UNSIGNED_BYTE:
3836 halveImage_ubyte(cmpts, width, height,
3837 (const GLubyte *)usersImage, (GLubyte *)dstImage,
3838 element_size, rowsize, group_size);
3839 break;
3840 case GL_BYTE:
3841 halveImage_byte(cmpts, width, height,
3842 (const GLbyte *)usersImage, (GLbyte *)dstImage,
3843 element_size, rowsize, group_size);
3844 break;
3845 case GL_UNSIGNED_SHORT:
3846 halveImage_ushort(cmpts, width, height,
3847 (const GLushort *)usersImage, (GLushort *)dstImage,
3848 element_size, rowsize, group_size, myswap_bytes);
3849 break;
3850 case GL_SHORT:
3851 halveImage_short(cmpts, width, height,
3852 (const GLshort *)usersImage, (GLshort *)dstImage,
3853 element_size, rowsize, group_size, myswap_bytes);
3854 break;
3855 case GL_UNSIGNED_INT:
3856 halveImage_uint(cmpts, width, height,
3857 (const GLuint *)usersImage, (GLuint *)dstImage,
3858 element_size, rowsize, group_size, myswap_bytes);
3859 break;
3860 case GL_INT:
3861 halveImage_int(cmpts, width, height,
3862 (const GLint *)usersImage, (GLint *)dstImage,
3863 element_size, rowsize, group_size, myswap_bytes);
3864 break;
3865 case GL_FLOAT:
3866 halveImage_float(cmpts, width, height,
3867 (const GLfloat *)usersImage, (GLfloat *)dstImage,
3868 element_size, rowsize, group_size, myswap_bytes);
3869 break;
3870 case GL_UNSIGNED_BYTE_3_3_2:
3871 assert(format == GL_RGB);
3872 halveImagePackedPixel(3,extract332,shove332,
3873 width,height,usersImage,dstImage,
3874 element_size,rowsize,myswap_bytes);
3875 break;
3876 case GL_UNSIGNED_BYTE_2_3_3_REV:
3877 assert(format == GL_RGB);
3878 halveImagePackedPixel(3,extract233rev,shove233rev,
3879 width,height,usersImage,dstImage,
3880 element_size,rowsize,myswap_bytes);
3881 break;
3882 case GL_UNSIGNED_SHORT_5_6_5:
3883 halveImagePackedPixel(3,extract565,shove565,
3884 width,height,usersImage,dstImage,
3885 element_size,rowsize,myswap_bytes);
3886 break;
3887 case GL_UNSIGNED_SHORT_5_6_5_REV:
3888 halveImagePackedPixel(3,extract565rev,shove565rev,
3889 width,height,usersImage,dstImage,
3890 element_size,rowsize,myswap_bytes);
3891 break;
3892 case GL_UNSIGNED_SHORT_4_4_4_4:
3893 halveImagePackedPixel(4,extract4444,shove4444,
3894 width,height,usersImage,dstImage,
3895 element_size,rowsize,myswap_bytes);
3896 break;
3897 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3898 halveImagePackedPixel(4,extract4444rev,shove4444rev,
3899 width,height,usersImage,dstImage,
3900 element_size,rowsize,myswap_bytes);
3901 break;
3902 case GL_UNSIGNED_SHORT_5_5_5_1:
3903 halveImagePackedPixel(4,extract5551,shove5551,
3904 width,height,usersImage,dstImage,
3905 element_size,rowsize,myswap_bytes);
3906 break;
3907 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3908 halveImagePackedPixel(4,extract1555rev,shove1555rev,
3909 width,height,usersImage,dstImage,
3910 element_size,rowsize,myswap_bytes);
3911 break;
3912 case GL_UNSIGNED_INT_8_8_8_8:
3913 halveImagePackedPixel(4,extract8888,shove8888,
3914 width,height,usersImage,dstImage,
3915 element_size,rowsize,myswap_bytes);
3916 break;
3917 case GL_UNSIGNED_INT_8_8_8_8_REV:
3918 halveImagePackedPixel(4,extract8888rev,shove8888rev,
3919 width,height,usersImage,dstImage,
3920 element_size,rowsize,myswap_bytes);
3921 break;
3922 case GL_UNSIGNED_INT_10_10_10_2:
3923 halveImagePackedPixel(4,extract1010102,shove1010102,
3924 width,height,usersImage,dstImage,
3925 element_size,rowsize,myswap_bytes);
3926 break;
3927 case GL_UNSIGNED_INT_2_10_10_10_REV:
3928 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
3929 width,height,usersImage,dstImage,
3930 element_size,rowsize,myswap_bytes);
3931 break;
3932 default:
3933 assert(0);
3934 break;
3936 newwidth = width/2;
3937 newheight = height/2;
3938 /* clamp to 1 */
3939 if (newwidth < 1) newwidth= 1;
3940 if (newheight < 1) newheight= 1;
3942 myswap_bytes = 0;
3943 rowsize = newwidth * group_size;
3944 memreq = image_size(newwidth, newheight, format, type);
3945 /* Swap srcImage and dstImage */
3946 __GLU_SWAP_IMAGE(srcImage,dstImage);
3947 switch(type) {
3948 case GL_UNSIGNED_BYTE:
3949 case GL_BYTE:
3950 case GL_UNSIGNED_SHORT:
3951 case GL_SHORT:
3952 case GL_UNSIGNED_INT:
3953 case GL_INT:
3954 case GL_FLOAT:
3955 case GL_UNSIGNED_BYTE_3_3_2:
3956 case GL_UNSIGNED_BYTE_2_3_3_REV:
3957 case GL_UNSIGNED_SHORT_5_6_5:
3958 case GL_UNSIGNED_SHORT_5_6_5_REV:
3959 case GL_UNSIGNED_SHORT_4_4_4_4:
3960 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3961 case GL_UNSIGNED_SHORT_5_5_5_1:
3962 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3963 case GL_UNSIGNED_INT_8_8_8_8:
3964 case GL_UNSIGNED_INT_8_8_8_8_REV:
3965 case GL_UNSIGNED_INT_10_10_10_2:
3966 case GL_UNSIGNED_INT_2_10_10_10_REV:
3967 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3968 break;
3969 default:
3970 return GLU_INVALID_ENUM;
3972 if (dstImage == NULL) {
3973 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3974 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3975 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3976 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3977 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3978 HeapFree(GetProcessHeap(), 0, srcImage);
3979 return GLU_OUT_OF_MEMORY;
3981 /* level userLevel+1 is in srcImage; level userLevel already saved */
3982 level = userLevel+1;
3983 } else { /* user's image is *not* nice power-of-2 sized square */
3984 memreq = image_size(newwidth, newheight, format, type);
3985 switch(type) {
3986 case GL_UNSIGNED_BYTE:
3987 case GL_BYTE:
3988 case GL_UNSIGNED_SHORT:
3989 case GL_SHORT:
3990 case GL_UNSIGNED_INT:
3991 case GL_INT:
3992 case GL_FLOAT:
3993 case GL_UNSIGNED_BYTE_3_3_2:
3994 case GL_UNSIGNED_BYTE_2_3_3_REV:
3995 case GL_UNSIGNED_SHORT_5_6_5:
3996 case GL_UNSIGNED_SHORT_5_6_5_REV:
3997 case GL_UNSIGNED_SHORT_4_4_4_4:
3998 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3999 case GL_UNSIGNED_SHORT_5_5_5_1:
4000 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4001 case GL_UNSIGNED_INT_8_8_8_8:
4002 case GL_UNSIGNED_INT_8_8_8_8_REV:
4003 case GL_UNSIGNED_INT_10_10_10_2:
4004 case GL_UNSIGNED_INT_2_10_10_10_REV:
4005 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
4006 break;
4007 default:
4008 return GLU_INVALID_ENUM;
4011 if (dstImage == NULL) {
4012 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4013 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4014 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4015 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4016 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4017 return GLU_OUT_OF_MEMORY;
4020 switch(type) {
4021 case GL_UNSIGNED_BYTE:
4022 scale_internal_ubyte(cmpts, width, height,
4023 (const GLubyte *)usersImage, newwidth, newheight,
4024 (GLubyte *)dstImage, element_size,
4025 rowsize, group_size);
4026 break;
4027 case GL_BYTE:
4028 scale_internal_byte(cmpts, width, height,
4029 (const GLbyte *)usersImage, newwidth, newheight,
4030 (GLbyte *)dstImage, element_size,
4031 rowsize, group_size);
4032 break;
4033 case GL_UNSIGNED_SHORT:
4034 scale_internal_ushort(cmpts, width, height,
4035 (const GLushort *)usersImage, newwidth, newheight,
4036 (GLushort *)dstImage, element_size,
4037 rowsize, group_size, myswap_bytes);
4038 break;
4039 case GL_SHORT:
4040 scale_internal_short(cmpts, width, height,
4041 (const GLshort *)usersImage, newwidth, newheight,
4042 (GLshort *)dstImage, element_size,
4043 rowsize, group_size, myswap_bytes);
4044 break;
4045 case GL_UNSIGNED_INT:
4046 scale_internal_uint(cmpts, width, height,
4047 (const GLuint *)usersImage, newwidth, newheight,
4048 (GLuint *)dstImage, element_size,
4049 rowsize, group_size, myswap_bytes);
4050 break;
4051 case GL_INT:
4052 scale_internal_int(cmpts, width, height,
4053 (const GLint *)usersImage, newwidth, newheight,
4054 (GLint *)dstImage, element_size,
4055 rowsize, group_size, myswap_bytes);
4056 break;
4057 case GL_FLOAT:
4058 scale_internal_float(cmpts, width, height,
4059 (const GLfloat *)usersImage, newwidth, newheight,
4060 (GLfloat *)dstImage, element_size,
4061 rowsize, group_size, myswap_bytes);
4062 break;
4063 case GL_UNSIGNED_BYTE_3_3_2:
4064 scaleInternalPackedPixel(3,extract332,shove332,
4065 width, height,usersImage,
4066 newwidth,newheight,(void *)dstImage,
4067 element_size,rowsize,myswap_bytes);
4068 break;
4069 case GL_UNSIGNED_BYTE_2_3_3_REV:
4070 scaleInternalPackedPixel(3,extract233rev,shove233rev,
4071 width, height,usersImage,
4072 newwidth,newheight,(void *)dstImage,
4073 element_size,rowsize,myswap_bytes);
4074 break;
4075 case GL_UNSIGNED_SHORT_5_6_5:
4076 scaleInternalPackedPixel(3,extract565,shove565,
4077 width, height,usersImage,
4078 newwidth,newheight,(void *)dstImage,
4079 element_size,rowsize,myswap_bytes);
4080 break;
4081 case GL_UNSIGNED_SHORT_5_6_5_REV:
4082 scaleInternalPackedPixel(3,extract565rev,shove565rev,
4083 width, height,usersImage,
4084 newwidth,newheight,(void *)dstImage,
4085 element_size,rowsize,myswap_bytes);
4086 break;
4087 case GL_UNSIGNED_SHORT_4_4_4_4:
4088 scaleInternalPackedPixel(4,extract4444,shove4444,
4089 width, height,usersImage,
4090 newwidth,newheight,(void *)dstImage,
4091 element_size,rowsize,myswap_bytes);
4092 break;
4093 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4094 scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4095 width, height,usersImage,
4096 newwidth,newheight,(void *)dstImage,
4097 element_size,rowsize,myswap_bytes);
4098 break;
4099 case GL_UNSIGNED_SHORT_5_5_5_1:
4100 scaleInternalPackedPixel(4,extract5551,shove5551,
4101 width, height,usersImage,
4102 newwidth,newheight,(void *)dstImage,
4103 element_size,rowsize,myswap_bytes);
4104 break;
4105 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4106 scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4107 width, height,usersImage,
4108 newwidth,newheight,(void *)dstImage,
4109 element_size,rowsize,myswap_bytes);
4110 break;
4111 case GL_UNSIGNED_INT_8_8_8_8:
4112 scaleInternalPackedPixel(4,extract8888,shove8888,
4113 width, height,usersImage,
4114 newwidth,newheight,(void *)dstImage,
4115 element_size,rowsize,myswap_bytes);
4116 break;
4117 case GL_UNSIGNED_INT_8_8_8_8_REV:
4118 scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4119 width, height,usersImage,
4120 newwidth,newheight,(void *)dstImage,
4121 element_size,rowsize,myswap_bytes);
4122 break;
4123 case GL_UNSIGNED_INT_10_10_10_2:
4124 scaleInternalPackedPixel(4,extract1010102,shove1010102,
4125 width, height,usersImage,
4126 newwidth,newheight,(void *)dstImage,
4127 element_size,rowsize,myswap_bytes);
4128 break;
4129 case GL_UNSIGNED_INT_2_10_10_10_REV:
4130 scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
4131 width, height,usersImage,
4132 newwidth,newheight,(void *)dstImage,
4133 element_size,rowsize,myswap_bytes);
4134 break;
4135 default:
4136 assert(0);
4137 break;
4139 myswap_bytes = 0;
4140 rowsize = newwidth * group_size;
4141 /* Swap dstImage and srcImage */
4142 __GLU_SWAP_IMAGE(srcImage,dstImage);
4144 if(levels != 0) { /* use as little memory as possible */
4146 int nextWidth= newwidth/2;
4147 int nextHeight= newheight/2;
4148 if (nextWidth < 1) nextWidth= 1;
4149 if (nextHeight < 1) nextHeight= 1;
4151 memreq = image_size(nextWidth, nextHeight, format, type);
4154 switch(type) {
4155 case GL_UNSIGNED_BYTE:
4156 case GL_BYTE:
4157 case GL_UNSIGNED_SHORT:
4158 case GL_SHORT:
4159 case GL_UNSIGNED_INT:
4160 case GL_INT:
4161 case GL_FLOAT:
4162 case GL_UNSIGNED_BYTE_3_3_2:
4163 case GL_UNSIGNED_BYTE_2_3_3_REV:
4164 case GL_UNSIGNED_SHORT_5_6_5:
4165 case GL_UNSIGNED_SHORT_5_6_5_REV:
4166 case GL_UNSIGNED_SHORT_4_4_4_4:
4167 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4168 case GL_UNSIGNED_SHORT_5_5_5_1:
4169 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4170 case GL_UNSIGNED_INT_8_8_8_8:
4171 case GL_UNSIGNED_INT_8_8_8_8_REV:
4172 case GL_UNSIGNED_INT_10_10_10_2:
4173 case GL_UNSIGNED_INT_2_10_10_10_REV:
4174 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
4175 break;
4176 default:
4177 return GLU_INVALID_ENUM;
4179 if (dstImage == NULL) {
4180 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4181 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4182 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4183 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4184 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4185 HeapFree(GetProcessHeap(), 0, srcImage);
4186 return GLU_OUT_OF_MEMORY;
4189 /* level userLevel is in srcImage; nothing saved yet */
4190 level = userLevel;
4193 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4194 if (baseLevel <= level && level <= maxLevel) {
4195 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4196 format, type, (void *)srcImage);
4199 level++; /* update current level for the loop */
4200 for (; level <= levels; level++) {
4201 switch(type) {
4202 case GL_UNSIGNED_BYTE:
4203 halveImage_ubyte(cmpts, newwidth, newheight,
4204 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4205 rowsize, group_size);
4206 break;
4207 case GL_BYTE:
4208 halveImage_byte(cmpts, newwidth, newheight,
4209 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4210 rowsize, group_size);
4211 break;
4212 case GL_UNSIGNED_SHORT:
4213 halveImage_ushort(cmpts, newwidth, newheight,
4214 (GLushort *)srcImage, (GLushort *)dstImage, element_size,
4215 rowsize, group_size, myswap_bytes);
4216 break;
4217 case GL_SHORT:
4218 halveImage_short(cmpts, newwidth, newheight,
4219 (GLshort *)srcImage, (GLshort *)dstImage, element_size,
4220 rowsize, group_size, myswap_bytes);
4221 break;
4222 case GL_UNSIGNED_INT:
4223 halveImage_uint(cmpts, newwidth, newheight,
4224 (GLuint *)srcImage, (GLuint *)dstImage, element_size,
4225 rowsize, group_size, myswap_bytes);
4226 break;
4227 case GL_INT:
4228 halveImage_int(cmpts, newwidth, newheight,
4229 (GLint *)srcImage, (GLint *)dstImage, element_size,
4230 rowsize, group_size, myswap_bytes);
4231 break;
4232 case GL_FLOAT:
4233 halveImage_float(cmpts, newwidth, newheight,
4234 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4235 rowsize, group_size, myswap_bytes);
4236 break;
4237 case GL_UNSIGNED_BYTE_3_3_2:
4238 halveImagePackedPixel(3,extract332,shove332,
4239 newwidth,newheight,
4240 srcImage,dstImage,element_size,rowsize,
4241 myswap_bytes);
4242 break;
4243 case GL_UNSIGNED_BYTE_2_3_3_REV:
4244 halveImagePackedPixel(3,extract233rev,shove233rev,
4245 newwidth,newheight,
4246 srcImage,dstImage,element_size,rowsize,
4247 myswap_bytes);
4248 break;
4249 case GL_UNSIGNED_SHORT_5_6_5:
4250 halveImagePackedPixel(3,extract565,shove565,
4251 newwidth,newheight,
4252 srcImage,dstImage,element_size,rowsize,
4253 myswap_bytes);
4254 break;
4255 case GL_UNSIGNED_SHORT_5_6_5_REV:
4256 halveImagePackedPixel(3,extract565rev,shove565rev,
4257 newwidth,newheight,
4258 srcImage,dstImage,element_size,rowsize,
4259 myswap_bytes);
4260 break;
4261 case GL_UNSIGNED_SHORT_4_4_4_4:
4262 halveImagePackedPixel(4,extract4444,shove4444,
4263 newwidth,newheight,
4264 srcImage,dstImage,element_size,rowsize,
4265 myswap_bytes);
4266 break;
4267 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4268 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4269 newwidth,newheight,
4270 srcImage,dstImage,element_size,rowsize,
4271 myswap_bytes);
4272 break;
4273 case GL_UNSIGNED_SHORT_5_5_5_1:
4274 halveImagePackedPixel(4,extract5551,shove5551,
4275 newwidth,newheight,
4276 srcImage,dstImage,element_size,rowsize,
4277 myswap_bytes);
4278 break;
4279 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4280 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4281 newwidth,newheight,
4282 srcImage,dstImage,element_size,rowsize,
4283 myswap_bytes);
4284 break;
4285 case GL_UNSIGNED_INT_8_8_8_8:
4286 halveImagePackedPixel(4,extract8888,shove8888,
4287 newwidth,newheight,
4288 srcImage,dstImage,element_size,rowsize,
4289 myswap_bytes);
4290 break;
4291 case GL_UNSIGNED_INT_8_8_8_8_REV:
4292 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4293 newwidth,newheight,
4294 srcImage,dstImage,element_size,rowsize,
4295 myswap_bytes);
4296 break;
4297 case GL_UNSIGNED_INT_10_10_10_2:
4298 halveImagePackedPixel(4,extract1010102,shove1010102,
4299 newwidth,newheight,
4300 srcImage,dstImage,element_size,rowsize,
4301 myswap_bytes);
4302 break;
4303 case GL_UNSIGNED_INT_2_10_10_10_REV:
4304 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4305 newwidth,newheight,
4306 srcImage,dstImage,element_size,rowsize,
4307 myswap_bytes);
4308 break;
4309 default:
4310 assert(0);
4311 break;
4314 __GLU_SWAP_IMAGE(srcImage,dstImage);
4316 if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4317 if (newheight > 1) newheight /= 2;
4319 /* compute amount to pad per row, if any */
4320 int rowPad= rowsize % psm.unpack_alignment;
4322 /* should row be padded? */
4323 if (rowPad == 0) { /* nope, row should not be padded */
4324 /* call tex image with srcImage untouched since it's not padded */
4325 if (baseLevel <= level && level <= maxLevel) {
4326 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4327 format, type, (void *) srcImage);
4330 else { /* yes, row should be padded */
4331 /* compute length of new row in bytes, including padding */
4332 int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4333 int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4335 /* allocate new image for mipmap of size newRowLength x newheight */
4336 void *newMipmapImage= HeapAlloc(GetProcessHeap(), 0, (size_t) (newRowLength*newheight));
4337 if (newMipmapImage == NULL) {
4338 /* out of memory so return */
4339 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4340 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4341 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4342 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4343 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4344 return GLU_OUT_OF_MEMORY;
4347 /* copy image from srcImage into newMipmapImage by rows */
4348 for (ii= 0,
4349 dstTrav= (unsigned char *) newMipmapImage,
4350 srcTrav= (unsigned char *) srcImage;
4351 ii< newheight;
4352 ii++,
4353 dstTrav+= newRowLength, /* make sure the correct distance... */
4354 srcTrav+= rowsize) { /* ...is skipped */
4355 memcpy(dstTrav,srcTrav,rowsize);
4356 /* note that the pad bytes are not visited and will contain
4357 * garbage, which is ok.
4361 /* ...and use this new image for mipmapping instead */
4362 if (baseLevel <= level && level <= maxLevel) {
4363 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4364 format, type, newMipmapImage);
4366 HeapFree(GetProcessHeap(), 0, newMipmapImage); /* don't forget to free it! */
4367 } /* else */
4369 } /* for level */
4370 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4371 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4372 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4373 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4374 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4376 HeapFree(GetProcessHeap(), 0, srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4377 HeapFree(GetProcessHeap(), 0, dstImage);
4378 return 0;
4379 } /* gluBuild2DMipmapLevelsCore() */
4382 /***********************************************************************
4383 * gluBuild2DMipmaps (GLU32.@)
4385 GLint WINAPI gluBuild2DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height,
4386 GLenum format, GLenum type, const void *data )
4388 GLint widthPowerOf2, heightPowerOf2;
4389 int level, levels;
4391 int rc= checkMipmapArgs(internalFormat,format,type);
4392 if (rc != 0) return rc;
4394 if (width < 1 || height < 1) {
4395 return GLU_INVALID_VALUE;
4398 closestFit(target,width,height,internalFormat,format,type,
4399 &widthPowerOf2,&heightPowerOf2);
4401 levels = computeLog(widthPowerOf2);
4402 level = computeLog(heightPowerOf2);
4403 if (level > levels) levels=level;
4405 return gluBuild2DMipmapLevelsCore(target,internalFormat,
4406 width, height,
4407 widthPowerOf2,heightPowerOf2,
4408 format,type,
4409 0,0,levels,data);
4410 } /* gluBuild2DMipmaps() */
4414 * Utility Routines
4416 static GLint elements_per_group(GLenum format, GLenum type)
4419 * Return the number of elements per group of a specified format
4422 /* If the type is packedpixels then answer is 1 (ignore format) */
4423 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4424 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4425 type == GL_UNSIGNED_SHORT_5_6_5 ||
4426 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4427 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4428 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4429 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
4430 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
4431 type == GL_UNSIGNED_INT_8_8_8_8 ||
4432 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4433 type == GL_UNSIGNED_INT_10_10_10_2 ||
4434 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
4435 return 1;
4438 /* Types are not packed pixels, so get elements per group */
4439 switch(format) {
4440 case GL_RGB:
4441 case GL_BGR:
4442 return 3;
4443 case GL_LUMINANCE_ALPHA:
4444 return 2;
4445 case GL_RGBA:
4446 case GL_BGRA:
4447 return 4;
4448 default:
4449 return 1;
4453 static GLfloat bytes_per_element(GLenum type)
4456 * Return the number of bytes per element, based on the element type
4458 switch(type) {
4459 case GL_BITMAP:
4460 return 1.0 / 8.0;
4461 case GL_UNSIGNED_SHORT:
4462 return(sizeof(GLushort));
4463 case GL_SHORT:
4464 return(sizeof(GLshort));
4465 case GL_UNSIGNED_BYTE:
4466 return(sizeof(GLubyte));
4467 case GL_BYTE:
4468 return(sizeof(GLbyte));
4469 case GL_INT:
4470 return(sizeof(GLint));
4471 case GL_UNSIGNED_INT:
4472 return(sizeof(GLuint));
4473 case GL_FLOAT:
4474 return(sizeof(GLfloat));
4475 case GL_UNSIGNED_BYTE_3_3_2:
4476 case GL_UNSIGNED_BYTE_2_3_3_REV:
4477 return(sizeof(GLubyte));
4478 case GL_UNSIGNED_SHORT_5_6_5:
4479 case GL_UNSIGNED_SHORT_5_6_5_REV:
4480 case GL_UNSIGNED_SHORT_4_4_4_4:
4481 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4482 case GL_UNSIGNED_SHORT_5_5_5_1:
4483 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4484 return(sizeof(GLushort));
4485 case GL_UNSIGNED_INT_8_8_8_8:
4486 case GL_UNSIGNED_INT_8_8_8_8_REV:
4487 case GL_UNSIGNED_INT_10_10_10_2:
4488 case GL_UNSIGNED_INT_2_10_10_10_REV:
4489 return(sizeof(GLuint));
4490 default:
4491 return 4;
4495 static GLint is_index(GLenum format)
4497 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4501 ** Compute memory required for internal packed array of data of given type
4502 ** and format.
4504 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4506 int bytes_per_row;
4507 int components;
4509 assert(width > 0);
4510 assert(height > 0);
4511 components = elements_per_group(format,type);
4512 if (type == GL_BITMAP) {
4513 bytes_per_row = (width + 7) / 8;
4514 } else {
4515 bytes_per_row = bytes_per_element(type) * width;
4517 return bytes_per_row * height * components;
4521 ** Extract array from user's data applying all pixel store modes.
4522 ** The internal format used is an array of unsigned shorts.
4524 static void fill_image(const PixelStorageModes *psm,
4525 GLint width, GLint height, GLenum format,
4526 GLenum type, GLboolean index_format,
4527 const void *userdata, GLushort *newimage)
4529 GLint components;
4530 GLint element_size;
4531 GLint rowsize;
4532 GLint padding;
4533 GLint groups_per_line;
4534 GLint group_size;
4535 GLint elements_per_line;
4536 const GLubyte *start;
4537 const GLubyte *iter;
4538 GLushort *iter2;
4539 GLint i, j, k;
4540 GLint myswap_bytes;
4542 myswap_bytes = psm->unpack_swap_bytes;
4543 components = elements_per_group(format,type);
4544 if (psm->unpack_row_length > 0) {
4545 groups_per_line = psm->unpack_row_length;
4546 } else {
4547 groups_per_line = width;
4550 /* All formats except GL_BITMAP fall out trivially */
4551 if (type == GL_BITMAP) {
4552 GLint bit_offset;
4553 GLint current_bit;
4555 rowsize = (groups_per_line * components + 7) / 8;
4556 padding = (rowsize % psm->unpack_alignment);
4557 if (padding) {
4558 rowsize += psm->unpack_alignment - padding;
4560 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4561 (psm->unpack_skip_pixels * components / 8);
4562 elements_per_line = width * components;
4563 iter2 = newimage;
4564 for (i = 0; i < height; i++) {
4565 iter = start;
4566 bit_offset = (psm->unpack_skip_pixels * components) % 8;
4567 for (j = 0; j < elements_per_line; j++) {
4568 /* Retrieve bit */
4569 if (psm->unpack_lsb_first) {
4570 current_bit = iter[0] & (1 << bit_offset);
4571 } else {
4572 current_bit = iter[0] & (1 << (7 - bit_offset));
4574 if (current_bit) {
4575 if (index_format) {
4576 *iter2 = 1;
4577 } else {
4578 *iter2 = 65535;
4580 } else {
4581 *iter2 = 0;
4583 bit_offset++;
4584 if (bit_offset == 8) {
4585 bit_offset = 0;
4586 iter++;
4588 iter2++;
4590 start += rowsize;
4592 } else {
4593 element_size = bytes_per_element(type);
4594 group_size = element_size * components;
4595 if (element_size == 1) myswap_bytes = 0;
4597 rowsize = groups_per_line * group_size;
4598 padding = (rowsize % psm->unpack_alignment);
4599 if (padding) {
4600 rowsize += psm->unpack_alignment - padding;
4602 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4603 psm->unpack_skip_pixels * group_size;
4604 elements_per_line = width * components;
4606 iter2 = newimage;
4607 for (i = 0; i < height; i++) {
4608 iter = start;
4609 for (j = 0; j < elements_per_line; j++) {
4610 Type_Widget widget;
4611 float extractComponents[4];
4613 switch(type) {
4614 case GL_UNSIGNED_BYTE_3_3_2:
4615 extract332(0,iter,extractComponents);
4616 for (k = 0; k < 3; k++) {
4617 *iter2++ = (GLushort)(extractComponents[k]*65535);
4619 break;
4620 case GL_UNSIGNED_BYTE_2_3_3_REV:
4621 extract233rev(0,iter,extractComponents);
4622 for (k = 0; k < 3; k++) {
4623 *iter2++ = (GLushort)(extractComponents[k]*65535);
4625 break;
4626 case GL_UNSIGNED_BYTE:
4627 if (index_format) {
4628 *iter2++ = *iter;
4629 } else {
4630 *iter2++ = (*iter) * 257;
4632 break;
4633 case GL_BYTE:
4634 if (index_format) {
4635 *iter2++ = *((const GLbyte *) iter);
4636 } else {
4637 /* rough approx */
4638 *iter2++ = (*((const GLbyte *) iter)) * 516;
4640 break;
4641 case GL_UNSIGNED_SHORT_5_6_5:
4642 extract565(myswap_bytes,iter,extractComponents);
4643 for (k = 0; k < 3; k++) {
4644 *iter2++ = (GLushort)(extractComponents[k]*65535);
4646 break;
4647 case GL_UNSIGNED_SHORT_5_6_5_REV:
4648 extract565rev(myswap_bytes,iter,extractComponents);
4649 for (k = 0; k < 3; k++) {
4650 *iter2++ = (GLushort)(extractComponents[k]*65535);
4652 break;
4653 case GL_UNSIGNED_SHORT_4_4_4_4:
4654 extract4444(myswap_bytes,iter,extractComponents);
4655 for (k = 0; k < 4; k++) {
4656 *iter2++ = (GLushort)(extractComponents[k]*65535);
4658 break;
4659 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4660 extract4444rev(myswap_bytes,iter,extractComponents);
4661 for (k = 0; k < 4; k++) {
4662 *iter2++ = (GLushort)(extractComponents[k]*65535);
4664 break;
4665 case GL_UNSIGNED_SHORT_5_5_5_1:
4666 extract5551(myswap_bytes,iter,extractComponents);
4667 for (k = 0; k < 4; k++) {
4668 *iter2++ = (GLushort)(extractComponents[k]*65535);
4670 break;
4671 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4672 extract1555rev(myswap_bytes,iter,extractComponents);
4673 for (k = 0; k < 4; k++) {
4674 *iter2++ = (GLushort)(extractComponents[k]*65535);
4676 break;
4677 case GL_UNSIGNED_SHORT:
4678 case GL_SHORT:
4679 if (myswap_bytes) {
4680 widget.ub[0] = iter[1];
4681 widget.ub[1] = iter[0];
4682 } else {
4683 widget.ub[0] = iter[0];
4684 widget.ub[1] = iter[1];
4686 if (type == GL_SHORT) {
4687 if (index_format) {
4688 *iter2++ = widget.s[0];
4689 } else {
4690 /* rough approx */
4691 *iter2++ = widget.s[0]*2;
4693 } else {
4694 *iter2++ = widget.us[0];
4696 break;
4697 case GL_UNSIGNED_INT_8_8_8_8:
4698 extract8888(myswap_bytes,iter,extractComponents);
4699 for (k = 0; k < 4; k++) {
4700 *iter2++ = (GLushort)(extractComponents[k]*65535);
4702 break;
4703 case GL_UNSIGNED_INT_8_8_8_8_REV:
4704 extract8888rev(myswap_bytes,iter,extractComponents);
4705 for (k = 0; k < 4; k++) {
4706 *iter2++ = (GLushort)(extractComponents[k]*65535);
4708 break;
4709 case GL_UNSIGNED_INT_10_10_10_2:
4710 extract1010102(myswap_bytes,iter,extractComponents);
4711 for (k = 0; k < 4; k++) {
4712 *iter2++ = (GLushort)(extractComponents[k]*65535);
4714 break;
4715 case GL_UNSIGNED_INT_2_10_10_10_REV:
4716 extract2101010rev(myswap_bytes,iter,extractComponents);
4717 for (k = 0; k < 4; k++) {
4718 *iter2++ = (GLushort)(extractComponents[k]*65535);
4720 break;
4721 case GL_INT:
4722 case GL_UNSIGNED_INT:
4723 case GL_FLOAT:
4724 if (myswap_bytes) {
4725 widget.ub[0] = iter[3];
4726 widget.ub[1] = iter[2];
4727 widget.ub[2] = iter[1];
4728 widget.ub[3] = iter[0];
4729 } else {
4730 widget.ub[0] = iter[0];
4731 widget.ub[1] = iter[1];
4732 widget.ub[2] = iter[2];
4733 widget.ub[3] = iter[3];
4735 if (type == GL_FLOAT) {
4736 if (index_format) {
4737 *iter2++ = widget.f;
4738 } else {
4739 *iter2++ = 65535 * widget.f;
4741 } else if (type == GL_UNSIGNED_INT) {
4742 if (index_format) {
4743 *iter2++ = widget.ui;
4744 } else {
4745 *iter2++ = widget.ui >> 16;
4747 } else {
4748 if (index_format) {
4749 *iter2++ = widget.i;
4750 } else {
4751 *iter2++ = widget.i >> 15;
4754 break;
4756 iter += element_size;
4757 } /* for j */
4758 start += rowsize;
4759 #if 1
4760 /* want 'iter' pointing at start, not within, row for assertion
4761 * purposes
4763 iter= start;
4764 #endif
4765 } /* for i */
4767 /* iterators should be one byte past end */
4768 if (!isTypePackedPixel(type)) {
4769 assert(iter2 == &newimage[width*height*components]);
4771 else {
4772 assert(iter2 == &newimage[width*height*
4773 elements_per_group(format,0)]);
4775 } /* else */
4776 } /* fill_image() */
4779 ** Insert array into user's data applying all pixel store modes.
4780 ** The internal format is an array of unsigned shorts.
4781 ** empty_image() because it is the opposite of fill_image().
4783 static void empty_image(const PixelStorageModes *psm,
4784 GLint width, GLint height, GLenum format,
4785 GLenum type, GLboolean index_format,
4786 const GLushort *oldimage, void *userdata)
4788 GLint components;
4789 GLint element_size;
4790 GLint rowsize;
4791 GLint padding;
4792 GLint groups_per_line;
4793 GLint group_size;
4794 GLint elements_per_line;
4795 GLubyte *start;
4796 GLubyte *iter;
4797 const GLushort *iter2;
4798 GLint i, j, k;
4799 GLint myswap_bytes;
4801 myswap_bytes = psm->pack_swap_bytes;
4802 components = elements_per_group(format,type);
4803 if (psm->pack_row_length > 0) {
4804 groups_per_line = psm->pack_row_length;
4805 } else {
4806 groups_per_line = width;
4809 /* All formats except GL_BITMAP fall out trivially */
4810 if (type == GL_BITMAP) {
4811 GLint bit_offset;
4812 GLint current_bit;
4814 rowsize = (groups_per_line * components + 7) / 8;
4815 padding = (rowsize % psm->pack_alignment);
4816 if (padding) {
4817 rowsize += psm->pack_alignment - padding;
4819 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
4820 (psm->pack_skip_pixels * components / 8);
4821 elements_per_line = width * components;
4822 iter2 = oldimage;
4823 for (i = 0; i < height; i++) {
4824 iter = start;
4825 bit_offset = (psm->pack_skip_pixels * components) % 8;
4826 for (j = 0; j < elements_per_line; j++) {
4827 if (index_format) {
4828 current_bit = iter2[0] & 1;
4829 } else {
4830 if (iter2[0] > 32767) {
4831 current_bit = 1;
4832 } else {
4833 current_bit = 0;
4837 if (current_bit) {
4838 if (psm->pack_lsb_first) {
4839 *iter |= (1 << bit_offset);
4840 } else {
4841 *iter |= (1 << (7 - bit_offset));
4843 } else {
4844 if (psm->pack_lsb_first) {
4845 *iter &= ~(1 << bit_offset);
4846 } else {
4847 *iter &= ~(1 << (7 - bit_offset));
4851 bit_offset++;
4852 if (bit_offset == 8) {
4853 bit_offset = 0;
4854 iter++;
4856 iter2++;
4858 start += rowsize;
4860 } else {
4861 float shoveComponents[4];
4863 element_size = bytes_per_element(type);
4864 group_size = element_size * components;
4865 if (element_size == 1) myswap_bytes = 0;
4867 rowsize = groups_per_line * group_size;
4868 padding = (rowsize % psm->pack_alignment);
4869 if (padding) {
4870 rowsize += psm->pack_alignment - padding;
4872 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
4873 psm->pack_skip_pixels * group_size;
4874 elements_per_line = width * components;
4876 iter2 = oldimage;
4877 for (i = 0; i < height; i++) {
4878 iter = start;
4879 for (j = 0; j < elements_per_line; j++) {
4880 Type_Widget widget;
4882 switch(type) {
4883 case GL_UNSIGNED_BYTE_3_3_2:
4884 for (k = 0; k < 3; k++) {
4885 shoveComponents[k]= *iter2++ / 65535.0;
4887 shove332(shoveComponents,0,(void *)iter);
4888 break;
4889 case GL_UNSIGNED_BYTE_2_3_3_REV:
4890 for (k = 0; k < 3; k++) {
4891 shoveComponents[k]= *iter2++ / 65535.0;
4893 shove233rev(shoveComponents,0,(void *)iter);
4894 break;
4895 case GL_UNSIGNED_BYTE:
4896 if (index_format) {
4897 *iter = *iter2++;
4898 } else {
4899 *iter = *iter2++ >> 8;
4901 break;
4902 case GL_BYTE:
4903 if (index_format) {
4904 *((GLbyte *) iter) = *iter2++;
4905 } else {
4906 *((GLbyte *) iter) = *iter2++ >> 9;
4908 break;
4909 case GL_UNSIGNED_SHORT_5_6_5:
4910 for (k = 0; k < 3; k++) {
4911 shoveComponents[k]= *iter2++ / 65535.0;
4913 shove565(shoveComponents,0,(void *)&widget.us[0]);
4914 if (myswap_bytes) {
4915 iter[0] = widget.ub[1];
4916 iter[1] = widget.ub[0];
4918 else {
4919 *(GLushort *)iter = widget.us[0];
4921 break;
4922 case GL_UNSIGNED_SHORT_5_6_5_REV:
4923 for (k = 0; k < 3; k++) {
4924 shoveComponents[k]= *iter2++ / 65535.0;
4926 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
4927 if (myswap_bytes) {
4928 iter[0] = widget.ub[1];
4929 iter[1] = widget.ub[0];
4931 else {
4932 *(GLushort *)iter = widget.us[0];
4934 break;
4935 case GL_UNSIGNED_SHORT_4_4_4_4:
4936 for (k = 0; k < 4; k++) {
4937 shoveComponents[k]= *iter2++ / 65535.0;
4939 shove4444(shoveComponents,0,(void *)&widget.us[0]);
4940 if (myswap_bytes) {
4941 iter[0] = widget.ub[1];
4942 iter[1] = widget.ub[0];
4943 } else {
4944 *(GLushort *)iter = widget.us[0];
4946 break;
4947 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4948 for (k = 0; k < 4; k++) {
4949 shoveComponents[k]= *iter2++ / 65535.0;
4951 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
4952 if (myswap_bytes) {
4953 iter[0] = widget.ub[1];
4954 iter[1] = widget.ub[0];
4955 } else {
4956 *(GLushort *)iter = widget.us[0];
4958 break;
4959 case GL_UNSIGNED_SHORT_5_5_5_1:
4960 for (k = 0; k < 4; k++) {
4961 shoveComponents[k]= *iter2++ / 65535.0;
4963 shove5551(shoveComponents,0,(void *)&widget.us[0]);
4964 if (myswap_bytes) {
4965 iter[0] = widget.ub[1];
4966 iter[1] = widget.ub[0];
4967 } else {
4968 *(GLushort *)iter = widget.us[0];
4970 break;
4971 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4972 for (k = 0; k < 4; k++) {
4973 shoveComponents[k]= *iter2++ / 65535.0;
4975 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
4976 if (myswap_bytes) {
4977 iter[0] = widget.ub[1];
4978 iter[1] = widget.ub[0];
4979 } else {
4980 *(GLushort *)iter = widget.us[0];
4982 break;
4983 case GL_UNSIGNED_SHORT:
4984 case GL_SHORT:
4985 if (type == GL_SHORT) {
4986 if (index_format) {
4987 widget.s[0] = *iter2++;
4988 } else {
4989 widget.s[0] = *iter2++ >> 1;
4991 } else {
4992 widget.us[0] = *iter2++;
4994 if (myswap_bytes) {
4995 iter[0] = widget.ub[1];
4996 iter[1] = widget.ub[0];
4997 } else {
4998 iter[0] = widget.ub[0];
4999 iter[1] = widget.ub[1];
5001 break;
5002 case GL_UNSIGNED_INT_8_8_8_8:
5003 for (k = 0; k < 4; k++) {
5004 shoveComponents[k]= *iter2++ / 65535.0;
5006 shove8888(shoveComponents,0,(void *)&widget.ui);
5007 if (myswap_bytes) {
5008 iter[3] = widget.ub[0];
5009 iter[2] = widget.ub[1];
5010 iter[1] = widget.ub[2];
5011 iter[0] = widget.ub[3];
5012 } else {
5013 *(GLuint *)iter= widget.ui;
5016 break;
5017 case GL_UNSIGNED_INT_8_8_8_8_REV:
5018 for (k = 0; k < 4; k++) {
5019 shoveComponents[k]= *iter2++ / 65535.0;
5021 shove8888rev(shoveComponents,0,(void *)&widget.ui);
5022 if (myswap_bytes) {
5023 iter[3] = widget.ub[0];
5024 iter[2] = widget.ub[1];
5025 iter[1] = widget.ub[2];
5026 iter[0] = widget.ub[3];
5027 } else {
5028 *(GLuint *)iter= widget.ui;
5030 break;
5031 case GL_UNSIGNED_INT_10_10_10_2:
5032 for (k = 0; k < 4; k++) {
5033 shoveComponents[k]= *iter2++ / 65535.0;
5035 shove1010102(shoveComponents,0,(void *)&widget.ui);
5036 if (myswap_bytes) {
5037 iter[3] = widget.ub[0];
5038 iter[2] = widget.ub[1];
5039 iter[1] = widget.ub[2];
5040 iter[0] = widget.ub[3];
5041 } else {
5042 *(GLuint *)iter= widget.ui;
5044 break;
5045 case GL_UNSIGNED_INT_2_10_10_10_REV:
5046 for (k = 0; k < 4; k++) {
5047 shoveComponents[k]= *iter2++ / 65535.0;
5049 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5050 if (myswap_bytes) {
5051 iter[3] = widget.ub[0];
5052 iter[2] = widget.ub[1];
5053 iter[1] = widget.ub[2];
5054 iter[0] = widget.ub[3];
5055 } else {
5056 *(GLuint *)iter= widget.ui;
5058 break;
5059 case GL_INT:
5060 case GL_UNSIGNED_INT:
5061 case GL_FLOAT:
5062 if (type == GL_FLOAT) {
5063 if (index_format) {
5064 widget.f = *iter2++;
5065 } else {
5066 widget.f = *iter2++ / (float) 65535.0;
5068 } else if (type == GL_UNSIGNED_INT) {
5069 if (index_format) {
5070 widget.ui = *iter2++;
5071 } else {
5072 widget.ui = (unsigned int) *iter2++ * 65537;
5074 } else {
5075 if (index_format) {
5076 widget.i = *iter2++;
5077 } else {
5078 widget.i = ((unsigned int) *iter2++ * 65537)/2;
5081 if (myswap_bytes) {
5082 iter[3] = widget.ub[0];
5083 iter[2] = widget.ub[1];
5084 iter[1] = widget.ub[2];
5085 iter[0] = widget.ub[3];
5086 } else {
5087 iter[0] = widget.ub[0];
5088 iter[1] = widget.ub[1];
5089 iter[2] = widget.ub[2];
5090 iter[3] = widget.ub[3];
5092 break;
5094 iter += element_size;
5095 } /* for j */
5096 start += rowsize;
5097 #if 1
5098 /* want 'iter' pointing at start, not within, row for assertion
5099 * purposes
5101 iter= start;
5102 #endif
5103 } /* for i */
5105 /* iterators should be one byte past end */
5106 if (!isTypePackedPixel(type)) {
5107 assert(iter2 == &oldimage[width*height*components]);
5109 else {
5110 assert(iter2 == &oldimage[width*height*
5111 elements_per_group(format,0)]);
5113 assert( iter == &((GLubyte *)userdata)[rowsize*height +
5114 psm->pack_skip_rows * rowsize +
5115 psm->pack_skip_pixels * group_size] );
5117 } /* else */
5118 } /* empty_image() */
5120 /*--------------------------------------------------------------------------
5121 * Decimation of packed pixel types
5122 *--------------------------------------------------------------------------
5124 static void extract332(int isSwap,
5125 const void *packedPixel, GLfloat extractComponents[])
5127 GLubyte ubyte= *(const GLubyte *)packedPixel;
5129 /* 11100000 == 0xe0 */
5130 /* 00011100 == 0x1c */
5131 /* 00000011 == 0x03 */
5133 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0;
5134 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5135 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */
5136 } /* extract332() */
5138 static void shove332(const GLfloat shoveComponents[],
5139 int index, void *packedPixel)
5141 /* 11100000 == 0xe0 */
5142 /* 00011100 == 0x1c */
5143 /* 00000011 == 0x03 */
5145 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5146 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5147 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5149 /* due to limited precision, need to round before shoving */
5150 ((GLubyte *)packedPixel)[index] =
5151 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0;
5152 ((GLubyte *)packedPixel)[index] |=
5153 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c;
5154 ((GLubyte *)packedPixel)[index] |=
5155 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03;
5156 } /* shove332() */
5158 static void extract233rev(int isSwap,
5159 const void *packedPixel, GLfloat extractComponents[])
5161 GLubyte ubyte= *(const GLubyte *)packedPixel;
5163 /* 0000,0111 == 0x07 */
5164 /* 0011,1000 == 0x38 */
5165 /* 1100,0000 == 0xC0 */
5167 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0;
5168 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5169 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5170 } /* extract233rev() */
5172 static void shove233rev(const GLfloat shoveComponents[],
5173 int index, void *packedPixel)
5175 /* 0000,0111 == 0x07 */
5176 /* 0011,1000 == 0x38 */
5177 /* 1100,0000 == 0xC0 */
5179 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5180 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5181 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5183 /* due to limited precision, need to round before shoving */
5184 ((GLubyte *)packedPixel)[index] =
5185 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07;
5186 ((GLubyte *)packedPixel)[index]|=
5187 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5188 ((GLubyte *)packedPixel)[index]|=
5189 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5190 } /* shove233rev() */
5192 static void extract565(int isSwap,
5193 const void *packedPixel, GLfloat extractComponents[])
5195 GLushort ushort;
5197 if (isSwap) {
5198 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5200 else {
5201 ushort= *(const GLushort *)packedPixel;
5204 /* 11111000,00000000 == 0xf800 */
5205 /* 00000111,11100000 == 0x07e0 */
5206 /* 00000000,00011111 == 0x001f */
5208 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5209 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5210 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0;
5211 } /* extract565() */
5213 static void shove565(const GLfloat shoveComponents[],
5214 int index,void *packedPixel)
5216 /* 11111000,00000000 == 0xf800 */
5217 /* 00000111,11100000 == 0x07e0 */
5218 /* 00000000,00011111 == 0x001f */
5220 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5221 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5222 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5224 /* due to limited precision, need to round before shoving */
5225 ((GLushort *)packedPixel)[index] =
5226 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5227 ((GLushort *)packedPixel)[index]|=
5228 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0;
5229 ((GLushort *)packedPixel)[index]|=
5230 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f;
5231 } /* shove565() */
5233 static void extract565rev(int isSwap,
5234 const void *packedPixel, GLfloat extractComponents[])
5236 GLushort ushort;
5238 if (isSwap) {
5239 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5241 else {
5242 ushort= *(const GLushort *)packedPixel;
5245 /* 00000000,00011111 == 0x001f */
5246 /* 00000111,11100000 == 0x07e0 */
5247 /* 11111000,00000000 == 0xf800 */
5249 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5250 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0;
5251 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5252 } /* extract565rev() */
5254 static void shove565rev(const GLfloat shoveComponents[],
5255 int index,void *packedPixel)
5257 /* 00000000,00011111 == 0x001f */
5258 /* 00000111,11100000 == 0x07e0 */
5259 /* 11111000,00000000 == 0xf800 */
5261 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5262 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5263 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5265 /* due to limited precision, need to round before shoving */
5266 ((GLushort *)packedPixel)[index] =
5267 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F;
5268 ((GLushort *)packedPixel)[index]|=
5269 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0;
5270 ((GLushort *)packedPixel)[index]|=
5271 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5272 } /* shove565rev() */
5274 static void extract4444(int isSwap,const void *packedPixel,
5275 GLfloat extractComponents[])
5277 GLushort ushort;
5279 if (isSwap) {
5280 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5282 else {
5283 ushort= *(const GLushort *)packedPixel;
5286 /* 11110000,00000000 == 0xf000 */
5287 /* 00001111,00000000 == 0x0f00 */
5288 /* 00000000,11110000 == 0x00f0 */
5289 /* 00000000,00001111 == 0x000f */
5291 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5292 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0;
5293 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0;
5294 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0;
5295 } /* extract4444() */
5297 static void shove4444(const GLfloat shoveComponents[],
5298 int index,void *packedPixel)
5300 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5301 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5302 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5303 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5305 /* due to limited precision, need to round before shoving */
5306 ((GLushort *)packedPixel)[index] =
5307 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5308 ((GLushort *)packedPixel)[index]|=
5309 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00;
5310 ((GLushort *)packedPixel)[index]|=
5311 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0;
5312 ((GLushort *)packedPixel)[index]|=
5313 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f;
5314 } /* shove4444() */
5316 static void extract4444rev(int isSwap,const void *packedPixel,
5317 GLfloat extractComponents[])
5319 GLushort ushort;
5321 if (isSwap) {
5322 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5324 else {
5325 ushort= *(const GLushort *)packedPixel;
5328 /* 00000000,00001111 == 0x000f */
5329 /* 00000000,11110000 == 0x00f0 */
5330 /* 00001111,00000000 == 0x0f00 */
5331 /* 11110000,00000000 == 0xf000 */
5333 /* 15 = 2^4-1 */
5334 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0;
5335 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0;
5336 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0;
5337 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5338 } /* extract4444rev() */
5340 static void shove4444rev(const GLfloat shoveComponents[],
5341 int index,void *packedPixel)
5343 /* 00000000,00001111 == 0x000f */
5344 /* 00000000,11110000 == 0x00f0 */
5345 /* 00001111,00000000 == 0x0f00 */
5346 /* 11110000,00000000 == 0xf000 */
5348 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5349 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5350 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5351 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5353 /* due to limited precision, need to round before shoving */
5354 ((GLushort *)packedPixel)[index] =
5355 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F;
5356 ((GLushort *)packedPixel)[index]|=
5357 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0;
5358 ((GLushort *)packedPixel)[index]|=
5359 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00;
5360 ((GLushort *)packedPixel)[index]|=
5361 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5362 } /* shove4444rev() */
5364 static void extract5551(int isSwap,const void *packedPixel,
5365 GLfloat extractComponents[])
5367 GLushort ushort;
5369 if (isSwap) {
5370 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5372 else {
5373 ushort= *(const GLushort *)packedPixel;
5376 /* 11111000,00000000 == 0xf800 */
5377 /* 00000111,11000000 == 0x07c0 */
5378 /* 00000000,00111110 == 0x003e */
5379 /* 00000000,00000001 == 0x0001 */
5381 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5382 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0;
5383 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0;
5384 extractComponents[3]=(float)((ushort & 0x0001) );
5385 } /* extract5551() */
5387 static void shove5551(const GLfloat shoveComponents[],
5388 int index,void *packedPixel)
5390 /* 11111000,00000000 == 0xf800 */
5391 /* 00000111,11000000 == 0x07c0 */
5392 /* 00000000,00111110 == 0x003e */
5393 /* 00000000,00000001 == 0x0001 */
5395 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5396 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5397 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5398 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5400 /* due to limited precision, need to round before shoving */
5401 ((GLushort *)packedPixel)[index] =
5402 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5403 ((GLushort *)packedPixel)[index]|=
5404 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0;
5405 ((GLushort *)packedPixel)[index]|=
5406 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e;
5407 ((GLushort *)packedPixel)[index]|=
5408 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001;
5409 } /* shove5551() */
5411 static void extract1555rev(int isSwap,const void *packedPixel,
5412 GLfloat extractComponents[])
5414 GLushort ushort;
5416 if (isSwap) {
5417 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5419 else {
5420 ushort= *(const GLushort *)packedPixel;
5423 /* 00000000,00011111 == 0x001F */
5424 /* 00000011,11100000 == 0x03E0 */
5425 /* 01111100,00000000 == 0x7C00 */
5426 /* 10000000,00000000 == 0x8000 */
5428 /* 31 = 2^5-1 */
5429 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5430 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0;
5431 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5432 extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5433 } /* extract1555rev() */
5435 static void shove1555rev(const GLfloat shoveComponents[],
5436 int index,void *packedPixel)
5438 /* 00000000,00011111 == 0x001F */
5439 /* 00000011,11100000 == 0x03E0 */
5440 /* 01111100,00000000 == 0x7C00 */
5441 /* 10000000,00000000 == 0x8000 */
5443 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5444 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5445 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5446 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5448 /* due to limited precision, need to round before shoving */
5449 ((GLushort *)packedPixel)[index] =
5450 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F;
5451 ((GLushort *)packedPixel)[index]|=
5452 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0;
5453 ((GLushort *)packedPixel)[index]|=
5454 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5455 ((GLushort *)packedPixel)[index]|=
5456 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000;
5457 } /* shove1555rev() */
5459 static void extract8888(int isSwap,
5460 const void *packedPixel, GLfloat extractComponents[])
5462 GLuint uint;
5464 if (isSwap) {
5465 uint= __GLU_SWAP_4_BYTES(packedPixel);
5467 else {
5468 uint= *(const GLuint *)packedPixel;
5471 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5472 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5473 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5474 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5476 /* 255 = 2^8-1 */
5477 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5478 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5479 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0;
5480 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0;
5481 } /* extract8888() */
5483 static void shove8888(const GLfloat shoveComponents[],
5484 int index,void *packedPixel)
5486 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5487 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5488 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5489 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5491 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5492 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5493 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5494 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5496 /* due to limited precision, need to round before shoving */
5497 ((GLuint *)packedPixel)[index] =
5498 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5499 ((GLuint *)packedPixel)[index]|=
5500 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5501 ((GLuint *)packedPixel)[index]|=
5502 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00;
5503 ((GLuint *)packedPixel)[index]|=
5504 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff;
5505 } /* shove8888() */
5507 static void extract8888rev(int isSwap,
5508 const void *packedPixel,GLfloat extractComponents[])
5510 GLuint uint;
5512 if (isSwap) {
5513 uint= __GLU_SWAP_4_BYTES(packedPixel);
5515 else {
5516 uint= *(const GLuint *)packedPixel;
5519 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5520 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5521 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5522 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5524 /* 255 = 2^8-1 */
5525 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0;
5526 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0;
5527 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5528 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5529 } /* extract8888rev() */
5531 static void shove8888rev(const GLfloat shoveComponents[],
5532 int index,void *packedPixel)
5534 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5535 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5536 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5537 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5539 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5540 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5541 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5542 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5544 /* due to limited precision, need to round before shoving */
5545 ((GLuint *)packedPixel)[index] =
5546 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF;
5547 ((GLuint *)packedPixel)[index]|=
5548 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00;
5549 ((GLuint *)packedPixel)[index]|=
5550 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5551 ((GLuint *)packedPixel)[index]|=
5552 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5553 } /* shove8888rev() */
5555 static void extract1010102(int isSwap,
5556 const void *packedPixel,GLfloat extractComponents[])
5558 GLuint uint;
5560 if (isSwap) {
5561 uint= __GLU_SWAP_4_BYTES(packedPixel);
5563 else {
5564 uint= *(const GLuint *)packedPixel;
5567 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5568 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5569 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5570 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5572 /* 1023 = 2^10-1 */
5573 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5574 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5575 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0;
5576 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0;
5577 } /* extract1010102() */
5579 static void shove1010102(const GLfloat shoveComponents[],
5580 int index,void *packedPixel)
5582 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5583 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5584 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5585 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5587 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5588 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5589 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5590 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5592 /* due to limited precision, need to round before shoving */
5593 ((GLuint *)packedPixel)[index] =
5594 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5595 ((GLuint *)packedPixel)[index]|=
5596 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5597 ((GLuint *)packedPixel)[index]|=
5598 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc;
5599 ((GLuint *)packedPixel)[index]|=
5600 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003;
5601 } /* shove1010102() */
5603 static void extract2101010rev(int isSwap,
5604 const void *packedPixel,
5605 GLfloat extractComponents[])
5607 GLuint uint;
5609 if (isSwap) {
5610 uint= __GLU_SWAP_4_BYTES(packedPixel);
5612 else {
5613 uint= *(const GLuint *)packedPixel;
5616 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5617 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5618 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5619 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5621 /* 1023 = 2^10-1 */
5622 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0;
5623 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5624 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5625 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5626 /* 3 = 2^2-1 */
5627 } /* extract2101010rev() */
5629 static void shove2101010rev(const GLfloat shoveComponents[],
5630 int index,void *packedPixel)
5632 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5633 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5634 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5635 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5637 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5638 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5639 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5640 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5642 /* due to limited precision, need to round before shoving */
5643 ((GLuint *)packedPixel)[index] =
5644 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF;
5645 ((GLuint *)packedPixel)[index]|=
5646 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
5647 ((GLuint *)packedPixel)[index]|=
5648 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
5649 ((GLuint *)packedPixel)[index]|=
5650 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000;
5651 } /* shove2101010rev() */
5653 static void scaleInternalPackedPixel(int components,
5654 void (*extractPackedPixel)
5655 (int, const void *,GLfloat []),
5656 void (*shovePackedPixel)
5657 (const GLfloat [], int, void *),
5658 GLint widthIn,GLint heightIn,
5659 const void *dataIn,
5660 GLint widthOut,GLint heightOut,
5661 void *dataOut,
5662 GLint pixelSizeInBytes,
5663 GLint rowSizeInBytes,GLint isSwap)
5665 float convx;
5666 float convy;
5667 float percent;
5669 /* Max components in a format is 4, so... */
5670 float totals[4];
5671 float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
5673 float area;
5674 int i,j,k,xindex;
5676 const char *temp, *temp0;
5677 int outindex;
5679 int lowx_int, highx_int, lowy_int, highy_int;
5680 float x_percent, y_percent;
5681 float lowx_float, highx_float, lowy_float, highy_float;
5682 float convy_float, convx_float;
5683 int convy_int, convx_int;
5684 int l, m;
5685 const char *left, *right;
5687 if (widthIn == widthOut*2 && heightIn == heightOut*2) {
5688 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
5689 widthIn, heightIn, dataIn, dataOut,
5690 pixelSizeInBytes,rowSizeInBytes,isSwap);
5691 return;
5693 convy = (float) heightIn/heightOut;
5694 convx = (float) widthIn/widthOut;
5695 convy_int = floor(convy);
5696 convy_float = convy - convy_int;
5697 convx_int = floor(convx);
5698 convx_float = convx - convx_int;
5700 area = convx * convy;
5702 lowy_int = 0;
5703 lowy_float = 0;
5704 highy_int = convy_int;
5705 highy_float = convy_float;
5707 for (i = 0; i < heightOut; i++) {
5708 lowx_int = 0;
5709 lowx_float = 0;
5710 highx_int = convx_int;
5711 highx_float = convx_float;
5713 for (j = 0; j < widthOut; j++) {
5715 ** Ok, now apply box filter to box that goes from (lowx, lowy)
5716 ** to (highx, highy) on input data into this pixel on output
5717 ** data.
5719 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
5721 /* calculate the value for pixels in the 1st row */
5722 xindex = lowx_int*pixelSizeInBytes;
5723 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
5725 y_percent = 1-lowy_float;
5726 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
5727 percent = y_percent * (1-lowx_float);
5728 #if 0
5729 for (k = 0, temp_index = temp; k < components;
5730 k++, temp_index += element_size) {
5731 if (myswap_bytes) {
5732 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5733 } else {
5734 totals[k] += *(const GLushort*)temp_index * percent;
5737 #else
5738 (*extractPackedPixel)(isSwap,temp,extractTotals);
5739 for (k = 0; k < components; k++) {
5740 totals[k]+= extractTotals[k] * percent;
5742 #endif
5743 left = temp;
5744 for(l = lowx_int+1; l < highx_int; l++) {
5745 temp += pixelSizeInBytes;
5746 #if 0
5747 for (k = 0, temp_index = temp; k < components;
5748 k++, temp_index += element_size) {
5749 if (myswap_bytes) {
5750 totals[k] +=
5751 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5752 } else {
5753 totals[k] += *(const GLushort*)temp_index * y_percent;
5756 #else
5757 (*extractPackedPixel)(isSwap,temp,extractTotals);
5758 for (k = 0; k < components; k++) {
5759 totals[k]+= extractTotals[k] * y_percent;
5761 #endif
5763 temp += pixelSizeInBytes;
5764 right = temp;
5765 percent = y_percent * highx_float;
5766 #if 0
5767 for (k = 0, temp_index = temp; k < components;
5768 k++, temp_index += element_size) {
5769 if (myswap_bytes) {
5770 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5771 } else {
5772 totals[k] += *(const GLushort*)temp_index * percent;
5775 #else
5776 (*extractPackedPixel)(isSwap,temp,extractTotals);
5777 for (k = 0; k < components; k++) {
5778 totals[k]+= extractTotals[k] * percent;
5780 #endif
5782 /* calculate the value for pixels in the last row */
5784 y_percent = highy_float;
5785 percent = y_percent * (1-lowx_float);
5786 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
5787 #if 0
5788 for (k = 0, temp_index = temp; k < components;
5789 k++, temp_index += element_size) {
5790 if (myswap_bytes) {
5791 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5792 } else {
5793 totals[k] += *(const GLushort*)temp_index * percent;
5796 #else
5797 (*extractPackedPixel)(isSwap,temp,extractTotals);
5798 for (k = 0; k < components; k++) {
5799 totals[k]+= extractTotals[k] * percent;
5801 #endif
5802 for(l = lowx_int+1; l < highx_int; l++) {
5803 temp += pixelSizeInBytes;
5804 #if 0
5805 for (k = 0, temp_index = temp; k < components;
5806 k++, temp_index += element_size) {
5807 if (myswap_bytes) {
5808 totals[k] +=
5809 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5810 } else {
5811 totals[k] += *(const GLushort*)temp_index * y_percent;
5814 #else
5815 (*extractPackedPixel)(isSwap,temp,extractTotals);
5816 for (k = 0; k < components; k++) {
5817 totals[k]+= extractTotals[k] * y_percent;
5819 #endif
5822 temp += pixelSizeInBytes;
5823 percent = y_percent * highx_float;
5824 #if 0
5825 for (k = 0, temp_index = temp; k < components;
5826 k++, temp_index += element_size) {
5827 if (myswap_bytes) {
5828 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5829 } else {
5830 totals[k] += *(const GLushort*)temp_index * percent;
5833 #else
5834 (*extractPackedPixel)(isSwap,temp,extractTotals);
5835 for (k = 0; k < components; k++) {
5836 totals[k]+= extractTotals[k] * percent;
5838 #endif
5840 /* calculate the value for pixels in the 1st and last column */
5841 for(m = lowy_int+1; m < highy_int; m++) {
5842 left += rowSizeInBytes;
5843 right += rowSizeInBytes;
5844 #if 0
5845 for (k = 0; k < components;
5846 k++, left += element_size, right += element_size) {
5847 if (myswap_bytes) {
5848 totals[k] +=
5849 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
5850 __GLU_SWAP_2_BYTES(right) * highx_float;
5851 } else {
5852 totals[k] += *(const GLushort*)left * (1-lowx_float)
5853 + *(const GLushort*)right * highx_float;
5856 #else
5857 (*extractPackedPixel)(isSwap,left,extractTotals);
5858 (*extractPackedPixel)(isSwap,right,extractMoreTotals);
5859 for (k = 0; k < components; k++) {
5860 totals[k]+= (extractTotals[k]*(1-lowx_float) +
5861 extractMoreTotals[k]*highx_float);
5863 #endif
5865 } else if (highy_int > lowy_int) {
5866 x_percent = highx_float - lowx_float;
5867 percent = (1-lowy_float)*x_percent;
5868 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
5869 #if 0
5870 for (k = 0, temp_index = temp; k < components;
5871 k++, temp_index += element_size) {
5872 if (myswap_bytes) {
5873 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5874 } else {
5875 totals[k] += *(const GLushort*)temp_index * percent;
5878 #else
5879 (*extractPackedPixel)(isSwap,temp,extractTotals);
5880 for (k = 0; k < components; k++) {
5881 totals[k]+= extractTotals[k] * percent;
5883 #endif
5884 for(m = lowy_int+1; m < highy_int; m++) {
5885 temp += rowSizeInBytes;
5886 #if 0
5887 for (k = 0, temp_index = temp; k < components;
5888 k++, temp_index += element_size) {
5889 if (myswap_bytes) {
5890 totals[k] +=
5891 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
5892 } else {
5893 totals[k] += *(const GLushort*)temp_index * x_percent;
5896 #else
5897 (*extractPackedPixel)(isSwap,temp,extractTotals);
5898 for (k = 0; k < components; k++) {
5899 totals[k]+= extractTotals[k] * x_percent;
5901 #endif
5903 percent = x_percent * highy_float;
5904 temp += rowSizeInBytes;
5905 #if 0
5906 for (k = 0, temp_index = temp; k < components;
5907 k++, temp_index += element_size) {
5908 if (myswap_bytes) {
5909 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5910 } else {
5911 totals[k] += *(const GLushort*)temp_index * percent;
5914 #else
5915 (*extractPackedPixel)(isSwap,temp,extractTotals);
5916 for (k = 0; k < components; k++) {
5917 totals[k]+= extractTotals[k] * percent;
5919 #endif
5920 } else if (highx_int > lowx_int) {
5921 y_percent = highy_float - lowy_float;
5922 percent = (1-lowx_float)*y_percent;
5923 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
5924 #if 0
5925 for (k = 0, temp_index = temp; k < components;
5926 k++, temp_index += element_size) {
5927 if (myswap_bytes) {
5928 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5929 } else {
5930 totals[k] += *(const GLushort*)temp_index * percent;
5933 #else
5934 (*extractPackedPixel)(isSwap,temp,extractTotals);
5935 for (k = 0; k < components; k++) {
5936 totals[k]+= extractTotals[k] * percent;
5938 #endif
5939 for (l = lowx_int+1; l < highx_int; l++) {
5940 temp += pixelSizeInBytes;
5941 #if 0
5942 for (k = 0, temp_index = temp; k < components;
5943 k++, temp_index += element_size) {
5944 if (myswap_bytes) {
5945 totals[k] +=
5946 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5947 } else {
5948 totals[k] += *(const GLushort*)temp_index * y_percent;
5951 #else
5952 (*extractPackedPixel)(isSwap,temp,extractTotals);
5953 for (k = 0; k < components; k++) {
5954 totals[k]+= extractTotals[k] * y_percent;
5956 #endif
5958 temp += pixelSizeInBytes;
5959 percent = y_percent * highx_float;
5960 #if 0
5961 for (k = 0, temp_index = temp; k < components;
5962 k++, temp_index += element_size) {
5963 if (myswap_bytes) {
5964 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5965 } else {
5966 totals[k] += *(const GLushort*)temp_index * percent;
5969 #else
5970 (*extractPackedPixel)(isSwap,temp,extractTotals);
5971 for (k = 0; k < components; k++) {
5972 totals[k]+= extractTotals[k] * percent;
5974 #endif
5975 } else {
5976 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
5977 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
5978 #if 0
5979 for (k = 0, temp_index = temp; k < components;
5980 k++, temp_index += element_size) {
5981 if (myswap_bytes) {
5982 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5983 } else {
5984 totals[k] += *(const GLushort*)temp_index * percent;
5987 #else
5988 (*extractPackedPixel)(isSwap,temp,extractTotals);
5989 for (k = 0; k < components; k++) {
5990 totals[k]+= extractTotals[k] * percent;
5992 #endif
5995 /* this is for the pixels in the body */
5996 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
5997 for (m = lowy_int+1; m < highy_int; m++) {
5998 temp = temp0;
5999 for(l = lowx_int+1; l < highx_int; l++) {
6000 #if 0
6001 for (k = 0, temp_index = temp; k < components;
6002 k++, temp_index += element_size) {
6003 if (myswap_bytes) {
6004 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6005 } else {
6006 totals[k] += *(const GLushort*)temp_index;
6009 #else
6010 (*extractPackedPixel)(isSwap,temp,extractTotals);
6011 for (k = 0; k < components; k++) {
6012 totals[k]+= extractTotals[k];
6014 #endif
6015 temp += pixelSizeInBytes;
6017 temp0 += rowSizeInBytes;
6020 outindex = (j + (i * widthOut)); /* * (components == 1) */
6021 #if 0
6022 for (k = 0; k < components; k++) {
6023 dataout[outindex + k] = totals[k]/area;
6024 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6026 #else
6027 for (k = 0; k < components; k++) {
6028 shoveTotals[k]= totals[k]/area;
6030 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6031 #endif
6032 lowx_int = highx_int;
6033 lowx_float = highx_float;
6034 highx_int += convx_int;
6035 highx_float += convx_float;
6036 if(highx_float > 1) {
6037 highx_float -= 1.0;
6038 highx_int++;
6041 lowy_int = highy_int;
6042 lowy_float = highy_float;
6043 highy_int += convy_int;
6044 highy_float += convy_float;
6045 if(highy_float > 1) {
6046 highy_float -= 1.0;
6047 highy_int++;
6050 } /* scaleInternalPackedPixel() */
6052 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6053 * inputs; not always equal. Output NEVER has row padding.
6055 static void halveImagePackedPixel(int components,
6056 void (*extractPackedPixel)
6057 (int, const void *,GLfloat []),
6058 void (*shovePackedPixel)
6059 (const GLfloat [],int, void *),
6060 GLint width, GLint height,
6061 const void *dataIn, void *dataOut,
6062 GLint pixelSizeInBytes,
6063 GLint rowSizeInBytes, GLint isSwap)
6065 /* handle case where there is only 1 column/row */
6066 if (width == 1 || height == 1) {
6067 assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6068 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6069 width,height,dataIn,dataOut,pixelSizeInBytes,
6070 rowSizeInBytes,isSwap);
6071 return;
6075 int ii, jj;
6077 int halfWidth= width / 2;
6078 int halfHeight= height / 2;
6079 const char *src= (const char *) dataIn;
6080 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6081 int outIndex= 0;
6083 for (ii= 0; ii< halfHeight; ii++) {
6084 for (jj= 0; jj< halfWidth; jj++) {
6085 #define BOX4 4
6086 float totals[4]; /* 4 is maximum components */
6087 float extractTotals[BOX4][4]; /* 4 is maximum components */
6088 int cc;
6090 (*extractPackedPixel)(isSwap,src,
6091 &extractTotals[0][0]);
6092 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6093 &extractTotals[1][0]);
6094 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6095 &extractTotals[2][0]);
6096 (*extractPackedPixel)(isSwap,
6097 (src+rowSizeInBytes+pixelSizeInBytes),
6098 &extractTotals[3][0]);
6099 for (cc = 0; cc < components; cc++) {
6100 int kk;
6102 /* grab 4 pixels to average */
6103 totals[cc]= 0.0;
6104 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6105 * extractTotals[2][RED]+extractTotals[3][RED];
6106 * totals[RED]/= 4.0;
6108 for (kk = 0; kk < BOX4; kk++) {
6109 totals[cc]+= extractTotals[kk][cc];
6111 totals[cc]/= (float)BOX4;
6113 (*shovePackedPixel)(totals,outIndex,dataOut);
6115 outIndex++;
6116 /* skip over to next square of 4 */
6117 src+= pixelSizeInBytes + pixelSizeInBytes;
6119 /* skip past pad bytes, if any, to get to next row */
6120 src+= padBytes;
6122 /* src is at beginning of a row here, but it's the second row of
6123 * the square block of 4 pixels that we just worked on so we
6124 * need to go one more row.
6125 * i.e.,
6126 * OO...
6127 * here -->OO...
6128 * but want -->OO...
6129 * OO...
6130 * ...
6132 src+= rowSizeInBytes;
6135 /* both pointers must reach one byte after the end */
6136 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6137 assert(outIndex == halfWidth * halfHeight);
6139 } /* halveImagePackedPixel() */
6141 static void halve1DimagePackedPixel(int components,
6142 void (*extractPackedPixel)
6143 (int, const void *,GLfloat []),
6144 void (*shovePackedPixel)
6145 (const GLfloat [],int, void *),
6146 GLint width, GLint height,
6147 const void *dataIn, void *dataOut,
6148 GLint pixelSizeInBytes,
6149 GLint rowSizeInBytes, GLint isSwap)
6151 int halfWidth= width / 2;
6152 int halfHeight= height / 2;
6153 const char *src= (const char *) dataIn;
6154 int jj;
6156 assert(width == 1 || height == 1); /* must be 1D */
6157 assert(width != height); /* can't be square */
6159 if (height == 1) { /* 1 row */
6160 int outIndex= 0;
6162 assert(width != 1); /* widthxheight can't be 1x1 */
6163 halfHeight= 1;
6165 /* one horizontal row with possible pad bytes */
6167 for (jj= 0; jj< halfWidth; jj++) {
6168 #define BOX2 2
6169 float totals[4]; /* 4 is maximum components */
6170 float extractTotals[BOX2][4]; /* 4 is maximum components */
6171 int cc;
6173 /* average two at a time, instead of four */
6174 (*extractPackedPixel)(isSwap,src,
6175 &extractTotals[0][0]);
6176 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6177 &extractTotals[1][0]);
6178 for (cc = 0; cc < components; cc++) {
6179 int kk;
6181 /* grab 2 pixels to average */
6182 totals[cc]= 0.0;
6183 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6184 * totals[RED]/= 2.0;
6186 for (kk = 0; kk < BOX2; kk++) {
6187 totals[cc]+= extractTotals[kk][cc];
6189 totals[cc]/= (float)BOX2;
6191 (*shovePackedPixel)(totals,outIndex,dataOut);
6193 outIndex++;
6194 /* skip over to next group of 2 */
6195 src+= pixelSizeInBytes + pixelSizeInBytes;
6199 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6200 src+= padBytes; /* for assertion only */
6202 assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6203 assert(outIndex == halfWidth * halfHeight);
6205 else if (width == 1) { /* 1 column */
6206 int outIndex= 0;
6208 assert(height != 1); /* widthxheight can't be 1x1 */
6209 halfWidth= 1;
6210 /* one vertical column with possible pad bytes per row */
6211 /* average two at a time */
6213 for (jj= 0; jj< halfHeight; jj++) {
6214 #define BOX2 2
6215 float totals[4]; /* 4 is maximum components */
6216 float extractTotals[BOX2][4]; /* 4 is maximum components */
6217 int cc;
6219 /* average two at a time, instead of four */
6220 (*extractPackedPixel)(isSwap,src,
6221 &extractTotals[0][0]);
6222 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6223 &extractTotals[1][0]);
6224 for (cc = 0; cc < components; cc++) {
6225 int kk;
6227 /* grab 2 pixels to average */
6228 totals[cc]= 0.0;
6229 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6230 * totals[RED]/= 2.0;
6232 for (kk = 0; kk < BOX2; kk++) {
6233 totals[cc]+= extractTotals[kk][cc];
6235 totals[cc]/= (float)BOX2;
6237 (*shovePackedPixel)(totals,outIndex,dataOut);
6239 outIndex++;
6240 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6243 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6244 assert(outIndex == halfWidth * halfHeight);
6246 } /* halve1DimagePackedPixel() */