include: Use the hard-float calling convention for Windows APIs on ARM
[wine.git] / dlls / glu32 / mipmap.c
blob87d4770d59689735ce3d799cbaeb95b22ebc17e0
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 "config.h"
32 #include "wine/port.h"
34 #include <assert.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <limits.h>
39 #include <math.h>
41 #include "windef.h"
42 #include "winbase.h"
43 #include "wine/wgl.h"
44 #include "wine/glu.h"
46 #define GLU_INVALID_OPERATION GLU_INVALID_VALUE /* GLU_INVALID_OPERATION is missing on Windows */
48 typedef union {
49 unsigned char ub[4];
50 unsigned short us[2];
51 unsigned int ui;
52 char b[4];
53 short s[2];
54 int i;
55 float f;
56 } Type_Widget;
58 /* Pixel storage modes */
59 typedef struct {
60 GLint pack_alignment;
61 GLint pack_row_length;
62 GLint pack_skip_rows;
63 GLint pack_skip_pixels;
64 GLint pack_lsb_first;
65 GLint pack_swap_bytes;
66 GLint pack_skip_images;
67 GLint pack_image_height;
69 GLint unpack_alignment;
70 GLint unpack_row_length;
71 GLint unpack_skip_rows;
72 GLint unpack_skip_pixels;
73 GLint unpack_lsb_first;
74 GLint unpack_swap_bytes;
75 GLint unpack_skip_images;
76 GLint unpack_image_height;
77 } PixelStorageModes;
79 static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
80 GLsizei,
81 GLsizei,
82 GLenum, GLenum, GLint, GLint, GLint,
83 const void *);
84 static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
85 GLsizei, GLsizei,
86 GLsizei, GLsizei,
87 GLenum, GLenum, GLint, GLint, GLint,
88 const void *);
91 * internal function declarations
93 static GLfloat bytes_per_element(GLenum type);
94 static GLint elements_per_group(GLenum format, GLenum type);
95 static GLint is_index(GLenum format);
96 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
97 static void fill_image(const PixelStorageModes *,
98 GLint width, GLint height, GLenum format,
99 GLenum type, GLboolean index_format,
100 const void *userdata, GLushort *newimage);
101 static void empty_image(const PixelStorageModes *,
102 GLint width, GLint height, GLenum format,
103 GLenum type, GLboolean index_format,
104 const GLushort *oldimage, void *userdata);
105 static void scale_internal(GLint components, GLint widthin, GLint heightin,
106 const GLushort *datain,
107 GLint widthout, GLint heightout,
108 GLushort *dataout);
110 static void scale_internal_ubyte(GLint components, GLint widthin,
111 GLint heightin, const GLubyte *datain,
112 GLint widthout, GLint heightout,
113 GLubyte *dataout, GLint element_size,
114 GLint ysize, GLint group_size);
115 static void scale_internal_byte(GLint components, GLint widthin,
116 GLint heightin, const GLbyte *datain,
117 GLint widthout, GLint heightout,
118 GLbyte *dataout, GLint element_size,
119 GLint ysize, GLint group_size);
120 static void scale_internal_ushort(GLint components, GLint widthin,
121 GLint heightin, const GLushort *datain,
122 GLint widthout, GLint heightout,
123 GLushort *dataout, GLint element_size,
124 GLint ysize, GLint group_size,
125 GLint myswap_bytes);
126 static void scale_internal_short(GLint components, GLint widthin,
127 GLint heightin, const GLshort *datain,
128 GLint widthout, GLint heightout,
129 GLshort *dataout, GLint element_size,
130 GLint ysize, GLint group_size,
131 GLint myswap_bytes);
132 static void scale_internal_uint(GLint components, GLint widthin,
133 GLint heightin, const GLuint *datain,
134 GLint widthout, GLint heightout,
135 GLuint *dataout, GLint element_size,
136 GLint ysize, GLint group_size,
137 GLint myswap_bytes);
138 static void scale_internal_int(GLint components, GLint widthin,
139 GLint heightin, const GLint *datain,
140 GLint widthout, GLint heightout,
141 GLint *dataout, GLint element_size,
142 GLint ysize, GLint group_size,
143 GLint myswap_bytes);
144 static void scale_internal_float(GLint components, GLint widthin,
145 GLint heightin, const GLfloat *datain,
146 GLint widthout, GLint heightout,
147 GLfloat *dataout, GLint element_size,
148 GLint ysize, GLint group_size,
149 GLint myswap_bytes);
151 static int checkMipmapArgs(GLenum, GLenum, GLenum);
152 static GLboolean legalFormat(GLenum);
153 static GLboolean legalType(GLenum);
154 static GLboolean isTypePackedPixel(GLenum);
155 static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
156 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
157 GLint *, GLint *);
159 /* packedpixel type scale routines */
160 static void extract332(int,const void *, GLfloat []);
161 static void shove332(const GLfloat [],int ,void *);
162 static void extract233rev(int,const void *, GLfloat []);
163 static void shove233rev(const GLfloat [],int ,void *);
164 static void extract565(int,const void *, GLfloat []);
165 static void shove565(const GLfloat [],int ,void *);
166 static void extract565rev(int,const void *, GLfloat []);
167 static void shove565rev(const GLfloat [],int ,void *);
168 static void extract4444(int,const void *, GLfloat []);
169 static void shove4444(const GLfloat [],int ,void *);
170 static void extract4444rev(int,const void *, GLfloat []);
171 static void shove4444rev(const GLfloat [],int ,void *);
172 static void extract5551(int,const void *, GLfloat []);
173 static void shove5551(const GLfloat [],int ,void *);
174 static void extract1555rev(int,const void *, GLfloat []);
175 static void shove1555rev(const GLfloat [],int ,void *);
176 static void extract8888(int,const void *, GLfloat []);
177 static void shove8888(const GLfloat [],int ,void *);
178 static void extract8888rev(int,const void *, GLfloat []);
179 static void shove8888rev(const GLfloat [],int ,void *);
180 static void extract1010102(int,const void *, GLfloat []);
181 static void shove1010102(const GLfloat [],int ,void *);
182 static void extract2101010rev(int,const void *, GLfloat []);
183 static void shove2101010rev(const GLfloat [],int ,void *);
184 static void scaleInternalPackedPixel(int,
185 void (*)(int, const void *,GLfloat []),
186 void (*)(const GLfloat [],int, void *),
187 GLint,GLint, const void *,
188 GLint,GLint,void *,GLint,GLint,GLint);
189 static void halveImagePackedPixel(int,
190 void (*)(int, const void *,GLfloat []),
191 void (*)(const GLfloat [],int, void *),
192 GLint, GLint, const void *,
193 void *, GLint, GLint, GLint);
194 static void halve1DimagePackedPixel(int,
195 void (*)(int, const void *,GLfloat []),
196 void (*)(const GLfloat [],int, void *),
197 GLint, GLint, const void *,
198 void *, GLint, GLint, GLint);
200 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
201 GLubyte *, GLint, GLint, GLint);
202 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
203 GLint, GLint, GLint);
204 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
205 GLushort *, GLint, GLint, GLint, GLint);
206 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
207 GLint, GLint, GLint, GLint);
208 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
209 GLint, GLint, GLint, GLint);
210 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
211 GLint, GLint, GLint, GLint);
212 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
213 GLint, GLint, GLint, GLint);
215 static void retrieveStoreModes(PixelStorageModes *psm)
217 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
218 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
219 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
220 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
221 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
222 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
224 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
225 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
226 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
227 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
228 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
229 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
232 static int computeLog(GLuint value)
234 int i;
236 i = 0;
238 /* Error! */
239 if (value == 0) return -1;
241 for (;;) {
242 if (value & 1) {
243 /* Error ! */
244 if (value != 1) return -1;
245 return i;
247 value = value >> 1;
248 i++;
253 ** Compute the nearest power of 2 number. This algorithm is a little
254 ** strange, but it works quite well.
256 static int nearestPower(GLuint value)
258 int i;
260 i = 1;
262 /* Error! */
263 if (value == 0) return -1;
265 for (;;) {
266 if (value == 1) {
267 return i;
268 } else if (value == 3) {
269 return i*4;
271 value = value >> 1;
272 i *= 2;
276 #define __GLU_SWAP_2_BYTES(s)\
277 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
279 #define __GLU_SWAP_4_BYTES(s)\
280 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
281 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
282 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
284 static void halveImage(GLint components, GLuint width, GLuint height,
285 const GLushort *datain, GLushort *dataout)
287 int i, j, k;
288 int newwidth, newheight;
289 int delta;
290 GLushort *s;
291 const GLushort *t;
293 newwidth = width / 2;
294 newheight = height / 2;
295 delta = width * components;
296 s = dataout;
297 t = datain;
299 /* Piece o' cake! */
300 for (i = 0; i < newheight; i++) {
301 for (j = 0; j < newwidth; j++) {
302 for (k = 0; k < components; k++) {
303 s[0] = (t[0] + t[components] + t[delta] +
304 t[delta+components] + 2) / 4;
305 s++; t++;
307 t += components;
309 t += delta;
313 static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
314 const GLubyte *datain, GLubyte *dataout,
315 GLint element_size, GLint ysize, GLint group_size)
317 int i, j, k;
318 int newwidth, newheight;
319 int padBytes;
320 GLubyte *s;
321 const char *t;
323 /* handle case where there is only 1 column/row */
324 if (width == 1 || height == 1) {
325 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
326 halve1Dimage_ubyte(components,width,height,datain,dataout,
327 element_size,ysize,group_size);
328 return;
331 newwidth = width / 2;
332 newheight = height / 2;
333 padBytes = ysize - (width*group_size);
334 s = dataout;
335 t = (const char *)datain;
337 /* Piece o' cake! */
338 for (i = 0; i < newheight; i++) {
339 for (j = 0; j < newwidth; j++) {
340 for (k = 0; k < components; k++) {
341 s[0] = (*(const GLubyte*)t +
342 *(const GLubyte*)(t+group_size) +
343 *(const GLubyte*)(t+ysize) +
344 *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
345 s++; t += element_size;
347 t += group_size;
349 t += padBytes;
350 t += ysize;
354 /* */
355 static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
356 const GLubyte *dataIn, GLubyte *dataOut,
357 GLint element_size, GLint ysize,
358 GLint group_size)
360 GLint halfWidth= width / 2;
361 GLint halfHeight= height / 2;
362 const char *src= (const char *) dataIn;
363 GLubyte *dest= dataOut;
364 int jj;
366 assert(width == 1 || height == 1); /* must be 1D */
367 assert(width != height); /* can't be square */
369 if (height == 1) { /* 1 row */
370 assert(width != 1); /* widthxheight can't be 1x1 */
371 halfHeight= 1;
373 for (jj= 0; jj< halfWidth; jj++) {
374 int kk;
375 for (kk= 0; kk< components; kk++) {
376 *dest= (*(const GLubyte*)src +
377 *(const GLubyte*)(src+group_size)) / 2;
379 src+= element_size;
380 dest++;
382 src+= group_size; /* skip to next 2 */
385 int padBytes= ysize - (width*group_size);
386 src+= padBytes; /* for assertion only */
389 else if (width == 1) { /* 1 column */
390 int padBytes= ysize - (width * group_size);
391 assert(height != 1); /* widthxheight can't be 1x1 */
392 halfWidth= 1;
393 /* one vertical column with possible pad bytes per row */
394 /* average two at a time */
396 for (jj= 0; jj< halfHeight; jj++) {
397 int kk;
398 for (kk= 0; kk< components; kk++) {
399 *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
401 src+= element_size;
402 dest++;
404 src+= padBytes; /* add pad bytes, if any, to get to end to row */
405 src+= ysize;
409 assert(src == &((const char *)dataIn)[ysize*height]);
410 assert((char *)dest == &((char *)dataOut)
411 [components * element_size * halfWidth * halfHeight]);
412 } /* halve1Dimage_ubyte() */
414 static void halveImage_byte(GLint components, GLuint width, GLuint height,
415 const GLbyte *datain, GLbyte *dataout,
416 GLint element_size,
417 GLint ysize, GLint group_size)
419 int i, j, k;
420 int newwidth, newheight;
421 int padBytes;
422 GLbyte *s;
423 const char *t;
425 /* handle case where there is only 1 column/row */
426 if (width == 1 || height == 1) {
427 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
428 halve1Dimage_byte(components,width,height,datain,dataout,
429 element_size,ysize,group_size);
430 return;
433 newwidth = width / 2;
434 newheight = height / 2;
435 padBytes = ysize - (width*group_size);
436 s = dataout;
437 t = (const char *)datain;
439 /* Piece o' cake! */
440 for (i = 0; i < newheight; i++) {
441 for (j = 0; j < newwidth; j++) {
442 for (k = 0; k < components; k++) {
443 s[0] = (*(const GLbyte*)t +
444 *(const GLbyte*)(t+group_size) +
445 *(const GLbyte*)(t+ysize) +
446 *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
447 s++; t += element_size;
449 t += group_size;
451 t += padBytes;
452 t += ysize;
456 static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
457 const GLbyte *dataIn, GLbyte *dataOut,
458 GLint element_size,GLint ysize, GLint group_size)
460 GLint halfWidth= width / 2;
461 GLint halfHeight= height / 2;
462 const char *src= (const char *) dataIn;
463 GLbyte *dest= dataOut;
464 int jj;
466 assert(width == 1 || height == 1); /* must be 1D */
467 assert(width != height); /* can't be square */
469 if (height == 1) { /* 1 row */
470 assert(width != 1); /* widthxheight can't be 1x1 */
471 halfHeight= 1;
473 for (jj= 0; jj< halfWidth; jj++) {
474 int kk;
475 for (kk= 0; kk< components; kk++) {
476 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
478 src+= element_size;
479 dest++;
481 src+= group_size; /* skip to next 2 */
484 int padBytes= ysize - (width*group_size);
485 src+= padBytes; /* for assertion only */
488 else if (width == 1) { /* 1 column */
489 int padBytes= ysize - (width * group_size);
490 assert(height != 1); /* widthxheight can't be 1x1 */
491 halfWidth= 1;
492 /* one vertical column with possible pad bytes per row */
493 /* average two at a time */
495 for (jj= 0; jj< halfHeight; jj++) {
496 int kk;
497 for (kk= 0; kk< components; kk++) {
498 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
500 src+= element_size;
501 dest++;
503 src+= padBytes; /* add pad bytes, if any, to get to end to row */
504 src+= ysize;
507 assert(src == &((const char *)dataIn)[ysize*height]);
510 assert((char *)dest == &((char *)dataOut)
511 [components * element_size * halfWidth * halfHeight]);
512 } /* halve1Dimage_byte() */
514 static void halveImage_ushort(GLint components, GLuint width, GLuint height,
515 const GLushort *datain, GLushort *dataout,
516 GLint element_size, GLint ysize, GLint group_size,
517 GLint myswap_bytes)
519 int i, j, k;
520 int newwidth, newheight;
521 int padBytes;
522 GLushort *s;
523 const char *t;
525 /* handle case where there is only 1 column/row */
526 if (width == 1 || height == 1) {
527 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
528 halve1Dimage_ushort(components,width,height,datain,dataout,
529 element_size,ysize,group_size, myswap_bytes);
530 return;
533 newwidth = width / 2;
534 newheight = height / 2;
535 padBytes = ysize - (width*group_size);
536 s = dataout;
537 t = (const char *)datain;
539 /* Piece o' cake! */
540 if (!myswap_bytes)
541 for (i = 0; i < newheight; i++) {
542 for (j = 0; j < newwidth; j++) {
543 for (k = 0; k < components; k++) {
544 s[0] = (*(const GLushort*)t +
545 *(const GLushort*)(t+group_size) +
546 *(const GLushort*)(t+ysize) +
547 *(const GLushort*)(t+ysize+group_size) + 2) / 4;
548 s++; t += element_size;
550 t += group_size;
552 t += padBytes;
553 t += ysize;
555 else
556 for (i = 0; i < newheight; i++) {
557 for (j = 0; j < newwidth; j++) {
558 for (k = 0; k < components; k++) {
559 s[0] = (__GLU_SWAP_2_BYTES(t) +
560 __GLU_SWAP_2_BYTES(t+group_size) +
561 __GLU_SWAP_2_BYTES(t+ysize) +
562 __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
563 s++; t += element_size;
565 t += group_size;
567 t += padBytes;
568 t += ysize;
572 static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
573 const GLushort *dataIn, GLushort *dataOut,
574 GLint element_size, GLint ysize,
575 GLint group_size, GLint myswap_bytes)
577 GLint halfWidth= width / 2;
578 GLint halfHeight= height / 2;
579 const char *src= (const char *) dataIn;
580 GLushort *dest= dataOut;
581 int jj;
583 assert(width == 1 || height == 1); /* must be 1D */
584 assert(width != height); /* can't be square */
586 if (height == 1) { /* 1 row */
587 assert(width != 1); /* widthxheight can't be 1x1 */
588 halfHeight= 1;
590 for (jj= 0; jj< halfWidth; jj++) {
591 int kk;
592 for (kk= 0; kk< components; kk++) {
593 #define BOX2 2
594 GLushort ushort[BOX2];
595 if (myswap_bytes) {
596 ushort[0]= __GLU_SWAP_2_BYTES(src);
597 ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
599 else {
600 ushort[0]= *(const GLushort*)src;
601 ushort[1]= *(const GLushort*)(src+group_size);
604 *dest= (ushort[0] + ushort[1]) / 2;
605 src+= element_size;
606 dest++;
608 src+= group_size; /* skip to next 2 */
611 int padBytes= ysize - (width*group_size);
612 src+= padBytes; /* for assertion only */
615 else if (width == 1) { /* 1 column */
616 int padBytes= ysize - (width * group_size);
617 assert(height != 1); /* widthxheight can't be 1x1 */
618 halfWidth= 1;
619 /* one vertical column with possible pad bytes per row */
620 /* average two at a time */
622 for (jj= 0; jj< halfHeight; jj++) {
623 int kk;
624 for (kk= 0; kk< components; kk++) {
625 #define BOX2 2
626 GLushort ushort[BOX2];
627 if (myswap_bytes) {
628 ushort[0]= __GLU_SWAP_2_BYTES(src);
629 ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
631 else {
632 ushort[0]= *(const GLushort*)src;
633 ushort[1]= *(const GLushort*)(src+ysize);
635 *dest= (ushort[0] + ushort[1]) / 2;
637 src+= element_size;
638 dest++;
640 src+= padBytes; /* add pad bytes, if any, to get to end to row */
641 src+= ysize;
644 assert(src == &((const char *)dataIn)[ysize*height]);
647 assert((char *)dest == &((char *)dataOut)
648 [components * element_size * halfWidth * halfHeight]);
650 } /* halve1Dimage_ushort() */
653 static void halveImage_short(GLint components, GLuint width, GLuint height,
654 const GLshort *datain, GLshort *dataout,
655 GLint element_size, GLint ysize, GLint group_size,
656 GLint myswap_bytes)
658 int i, j, k;
659 int newwidth, newheight;
660 int padBytes;
661 GLshort *s;
662 const char *t;
664 /* handle case where there is only 1 column/row */
665 if (width == 1 || height == 1) {
666 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
667 halve1Dimage_short(components,width,height,datain,dataout,
668 element_size,ysize,group_size, myswap_bytes);
669 return;
672 newwidth = width / 2;
673 newheight = height / 2;
674 padBytes = ysize - (width*group_size);
675 s = dataout;
676 t = (const char *)datain;
678 /* Piece o' cake! */
679 if (!myswap_bytes)
680 for (i = 0; i < newheight; i++) {
681 for (j = 0; j < newwidth; j++) {
682 for (k = 0; k < components; k++) {
683 s[0] = (*(const GLshort*)t +
684 *(const GLshort*)(t+group_size) +
685 *(const GLshort*)(t+ysize) +
686 *(const GLshort*)(t+ysize+group_size) + 2) / 4;
687 s++; t += element_size;
689 t += group_size;
691 t += padBytes;
692 t += ysize;
694 else
695 for (i = 0; i < newheight; i++) {
696 for (j = 0; j < newwidth; j++) {
697 for (k = 0; k < components; k++) {
698 GLushort b;
699 GLint buf;
700 b = __GLU_SWAP_2_BYTES(t);
701 buf = *(const GLshort*)&b;
702 b = __GLU_SWAP_2_BYTES(t+group_size);
703 buf += *(const GLshort*)&b;
704 b = __GLU_SWAP_2_BYTES(t+ysize);
705 buf += *(const GLshort*)&b;
706 b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
707 buf += *(const GLshort*)&b;
708 s[0] = (GLshort)((buf+2)/4);
709 s++; t += element_size;
711 t += group_size;
713 t += padBytes;
714 t += ysize;
718 static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
719 const GLshort *dataIn, GLshort *dataOut,
720 GLint element_size, GLint ysize,
721 GLint group_size, GLint myswap_bytes)
723 GLint halfWidth= width / 2;
724 GLint halfHeight= height / 2;
725 const char *src= (const char *) dataIn;
726 GLshort *dest= dataOut;
727 int jj;
729 assert(width == 1 || height == 1); /* must be 1D */
730 assert(width != height); /* can't be square */
732 if (height == 1) { /* 1 row */
733 assert(width != 1); /* widthxheight can't be 1x1 */
734 halfHeight= 1;
736 for (jj= 0; jj< halfWidth; jj++) {
737 int kk;
738 for (kk= 0; kk< components; kk++) {
739 #define BOX2 2
740 GLshort sshort[BOX2];
741 if (myswap_bytes) {
742 sshort[0]= __GLU_SWAP_2_BYTES(src);
743 sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
745 else {
746 sshort[0]= *(const GLshort*)src;
747 sshort[1]= *(const GLshort*)(src+group_size);
750 *dest= (sshort[0] + sshort[1]) / 2;
751 src+= element_size;
752 dest++;
754 src+= group_size; /* skip to next 2 */
757 int padBytes= ysize - (width*group_size);
758 src+= padBytes; /* for assertion only */
761 else if (width == 1) { /* 1 column */
762 int padBytes= ysize - (width * group_size);
763 assert(height != 1); /* widthxheight can't be 1x1 */
764 halfWidth= 1;
765 /* one vertical column with possible pad bytes per row */
766 /* average two at a time */
768 for (jj= 0; jj< halfHeight; jj++) {
769 int kk;
770 for (kk= 0; kk< components; kk++) {
771 #define BOX2 2
772 GLshort sshort[BOX2];
773 if (myswap_bytes) {
774 sshort[0]= __GLU_SWAP_2_BYTES(src);
775 sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
777 else {
778 sshort[0]= *(const GLshort*)src;
779 sshort[1]= *(const GLshort*)(src+ysize);
781 *dest= (sshort[0] + sshort[1]) / 2;
783 src+= element_size;
784 dest++;
786 src+= padBytes; /* add pad bytes, if any, to get to end to row */
787 src+= ysize;
790 assert(src == &((const char *)dataIn)[ysize*height]);
793 assert((char *)dest == &((char *)dataOut)
794 [components * element_size * halfWidth * halfHeight]);
796 } /* halve1Dimage_short() */
799 static void halveImage_uint(GLint components, GLuint width, GLuint height,
800 const GLuint *datain, GLuint *dataout,
801 GLint element_size, GLint ysize, GLint group_size,
802 GLint myswap_bytes)
804 int i, j, k;
805 int newwidth, newheight;
806 int padBytes;
807 GLuint *s;
808 const char *t;
810 /* handle case where there is only 1 column/row */
811 if (width == 1 || height == 1) {
812 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
813 halve1Dimage_uint(components,width,height,datain,dataout,
814 element_size,ysize,group_size, myswap_bytes);
815 return;
818 newwidth = width / 2;
819 newheight = height / 2;
820 padBytes = ysize - (width*group_size);
821 s = dataout;
822 t = (const char *)datain;
824 /* Piece o' cake! */
825 if (!myswap_bytes)
826 for (i = 0; i < newheight; i++) {
827 for (j = 0; j < newwidth; j++) {
828 for (k = 0; k < components; k++) {
829 /* need to cast to double to hold large unsigned ints */
830 s[0] = ((double)*(const GLuint*)t +
831 (double)*(const GLuint*)(t+group_size) +
832 (double)*(const GLuint*)(t+ysize) +
833 (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
834 s++; t += element_size;
837 t += group_size;
839 t += padBytes;
840 t += ysize;
842 else
843 for (i = 0; i < newheight; i++) {
844 for (j = 0; j < newwidth; j++) {
845 for (k = 0; k < components; k++) {
846 /* need to cast to double to hold large unsigned ints */
847 GLdouble buf;
848 buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
849 (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
850 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
851 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
852 s[0] = (GLuint)(buf/4 + 0.5);
854 s++; t += element_size;
856 t += group_size;
858 t += padBytes;
859 t += ysize;
863 /* */
864 static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
865 const GLuint *dataIn, GLuint *dataOut,
866 GLint element_size, GLint ysize,
867 GLint group_size, GLint myswap_bytes)
869 GLint halfWidth= width / 2;
870 GLint halfHeight= height / 2;
871 const char *src= (const char *) dataIn;
872 GLuint *dest= dataOut;
873 int jj;
875 assert(width == 1 || height == 1); /* must be 1D */
876 assert(width != height); /* can't be square */
878 if (height == 1) { /* 1 row */
879 assert(width != 1); /* widthxheight can't be 1x1 */
880 halfHeight= 1;
882 for (jj= 0; jj< halfWidth; jj++) {
883 int kk;
884 for (kk= 0; kk< components; kk++) {
885 #define BOX2 2
886 GLuint uint[BOX2];
887 if (myswap_bytes) {
888 uint[0]= __GLU_SWAP_4_BYTES(src);
889 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
891 else {
892 uint[0]= *(const GLuint*)src;
893 uint[1]= *(const GLuint*)(src+group_size);
895 *dest= ((double)uint[0]+(double)uint[1])/2.0;
897 src+= element_size;
898 dest++;
900 src+= group_size; /* skip to next 2 */
903 int padBytes= ysize - (width*group_size);
904 src+= padBytes; /* for assertion only */
907 else if (width == 1) { /* 1 column */
908 int padBytes= ysize - (width * group_size);
909 assert(height != 1); /* widthxheight can't be 1x1 */
910 halfWidth= 1;
911 /* one vertical column with possible pad bytes per row */
912 /* average two at a time */
914 for (jj= 0; jj< halfHeight; jj++) {
915 int kk;
916 for (kk= 0; kk< components; kk++) {
917 #define BOX2 2
918 GLuint uint[BOX2];
919 if (myswap_bytes) {
920 uint[0]= __GLU_SWAP_4_BYTES(src);
921 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
923 else {
924 uint[0]= *(const GLuint*)src;
925 uint[1]= *(const GLuint*)(src+ysize);
927 *dest= ((double)uint[0]+(double)uint[1])/2.0;
929 src+= element_size;
930 dest++;
932 src+= padBytes; /* add pad bytes, if any, to get to end to row */
933 src+= ysize;
936 assert(src == &((const char *)dataIn)[ysize*height]);
939 assert((char *)dest == &((char *)dataOut)
940 [components * element_size * halfWidth * halfHeight]);
942 } /* halve1Dimage_uint() */
944 static void halveImage_int(GLint components, GLuint width, GLuint height,
945 const GLint *datain, GLint *dataout, GLint element_size,
946 GLint ysize, GLint group_size, GLint myswap_bytes)
948 int i, j, k;
949 int newwidth, newheight;
950 int padBytes;
951 GLint *s;
952 const char *t;
954 /* handle case where there is only 1 column/row */
955 if (width == 1 || height == 1) {
956 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
957 halve1Dimage_int(components,width,height,datain,dataout,
958 element_size,ysize,group_size, myswap_bytes);
959 return;
962 newwidth = width / 2;
963 newheight = height / 2;
964 padBytes = ysize - (width*group_size);
965 s = dataout;
966 t = (const char *)datain;
968 /* Piece o' cake! */
969 if (!myswap_bytes)
970 for (i = 0; i < newheight; i++) {
971 for (j = 0; j < newwidth; j++) {
972 for (k = 0; k < components; k++) {
973 s[0] = ((float)*(const GLint*)t +
974 (float)*(const GLint*)(t+group_size) +
975 (float)*(const GLint*)(t+ysize) +
976 (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
977 s++; t += element_size;
979 t += group_size;
981 t += padBytes;
982 t += ysize;
984 else
985 for (i = 0; i < newheight; i++) {
986 for (j = 0; j < newwidth; j++) {
987 for (k = 0; k < components; k++) {
988 GLuint b;
989 GLfloat buf;
990 b = __GLU_SWAP_4_BYTES(t);
991 buf = *(GLint*)&b;
992 b = __GLU_SWAP_4_BYTES(t+group_size);
993 buf += *(GLint*)&b;
994 b = __GLU_SWAP_4_BYTES(t+ysize);
995 buf += *(GLint*)&b;
996 b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
997 buf += *(GLint*)&b;
998 s[0] = (GLint)(buf/4 + 0.5);
1000 s++; t += element_size;
1002 t += group_size;
1004 t += padBytes;
1005 t += ysize;
1009 /* */
1010 static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
1011 const GLint *dataIn, GLint *dataOut,
1012 GLint element_size, GLint ysize,
1013 GLint group_size, GLint myswap_bytes)
1015 GLint halfWidth= width / 2;
1016 GLint halfHeight= height / 2;
1017 const char *src= (const char *) dataIn;
1018 GLint *dest= dataOut;
1019 int jj;
1021 assert(width == 1 || height == 1); /* must be 1D */
1022 assert(width != height); /* can't be square */
1024 if (height == 1) { /* 1 row */
1025 assert(width != 1); /* widthxheight can't be 1x1 */
1026 halfHeight= 1;
1028 for (jj= 0; jj< halfWidth; jj++) {
1029 int kk;
1030 for (kk= 0; kk< components; kk++) {
1031 #define BOX2 2
1032 GLuint uint[BOX2];
1033 if (myswap_bytes) {
1034 uint[0]= __GLU_SWAP_4_BYTES(src);
1035 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
1037 else {
1038 uint[0]= *(const GLuint*)src;
1039 uint[1]= *(const GLuint*)(src+group_size);
1041 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1043 src+= element_size;
1044 dest++;
1046 src+= group_size; /* skip to next 2 */
1049 int padBytes= ysize - (width*group_size);
1050 src+= padBytes; /* for assertion only */
1053 else if (width == 1) { /* 1 column */
1054 int padBytes= ysize - (width * group_size);
1055 assert(height != 1); /* widthxheight can't be 1x1 */
1056 halfWidth= 1;
1057 /* one vertical column with possible pad bytes per row */
1058 /* average two at a time */
1060 for (jj= 0; jj< halfHeight; jj++) {
1061 int kk;
1062 for (kk= 0; kk< components; kk++) {
1063 #define BOX2 2
1064 GLuint uint[BOX2];
1065 if (myswap_bytes) {
1066 uint[0]= __GLU_SWAP_4_BYTES(src);
1067 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
1069 else {
1070 uint[0]= *(const GLuint*)src;
1071 uint[1]= *(const GLuint*)(src+ysize);
1073 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1075 src+= element_size;
1076 dest++;
1078 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1079 src+= ysize;
1082 assert(src == &((const char *)dataIn)[ysize*height]);
1085 assert((char *)dest == &((char *)dataOut)
1086 [components * element_size * halfWidth * halfHeight]);
1088 } /* halve1Dimage_int() */
1091 static void halveImage_float(GLint components, GLuint width, GLuint height,
1092 const GLfloat *datain, GLfloat *dataout,
1093 GLint element_size, GLint ysize, GLint group_size,
1094 GLint myswap_bytes)
1096 int i, j, k;
1097 int newwidth, newheight;
1098 int padBytes;
1099 GLfloat *s;
1100 const char *t;
1102 /* handle case where there is only 1 column/row */
1103 if (width == 1 || height == 1) {
1104 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1105 halve1Dimage_float(components,width,height,datain,dataout,
1106 element_size,ysize,group_size, myswap_bytes);
1107 return;
1110 newwidth = width / 2;
1111 newheight = height / 2;
1112 padBytes = ysize - (width*group_size);
1113 s = dataout;
1114 t = (const char *)datain;
1116 /* Piece o' cake! */
1117 if (!myswap_bytes)
1118 for (i = 0; i < newheight; i++) {
1119 for (j = 0; j < newwidth; j++) {
1120 for (k = 0; k < components; k++) {
1121 s[0] = (*(const GLfloat*)t +
1122 *(const GLfloat*)(t+group_size) +
1123 *(const GLfloat*)(t+ysize) +
1124 *(const GLfloat*)(t+ysize+group_size)) / 4;
1125 s++; t += element_size;
1127 t += group_size;
1129 t += padBytes;
1130 t += ysize;
1132 else
1133 for (i = 0; i < newheight; i++) {
1134 for (j = 0; j < newwidth; j++) {
1135 for (k = 0; k < components; k++) {
1136 union { GLuint b; GLfloat f; } swapbuf;
1137 swapbuf.b = __GLU_SWAP_4_BYTES(t);
1138 s[0] = swapbuf.f;
1139 swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
1140 s[0] += swapbuf.f;
1141 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
1142 s[0] += swapbuf.f;
1143 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1144 s[0] += swapbuf.f;
1145 s[0] /= 4;
1146 s++; t += element_size;
1148 t += group_size;
1150 t += padBytes;
1151 t += ysize;
1155 /* */
1156 static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
1157 const GLfloat *dataIn, GLfloat *dataOut,
1158 GLint element_size, GLint ysize,
1159 GLint group_size, GLint myswap_bytes)
1161 GLint halfWidth= width / 2;
1162 GLint halfHeight= height / 2;
1163 const char *src= (const char *) dataIn;
1164 GLfloat *dest= dataOut;
1165 int jj;
1167 assert(width == 1 || height == 1); /* must be 1D */
1168 assert(width != height); /* can't be square */
1170 if (height == 1) { /* 1 row */
1171 assert(width != 1); /* widthxheight can't be 1x1 */
1172 halfHeight= 1;
1174 for (jj= 0; jj< halfWidth; jj++) {
1175 int kk;
1176 for (kk= 0; kk< components; kk++) {
1177 #define BOX2 2
1178 GLfloat sfloat[BOX2];
1179 if (myswap_bytes) {
1180 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1181 sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
1183 else {
1184 sfloat[0]= *(const GLfloat*)src;
1185 sfloat[1]= *(const GLfloat*)(src+group_size);
1188 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1189 src+= element_size;
1190 dest++;
1192 src+= group_size; /* skip to next 2 */
1195 int padBytes= ysize - (width*group_size);
1196 src+= padBytes; /* for assertion only */
1199 else if (width == 1) { /* 1 column */
1200 int padBytes= ysize - (width * group_size);
1201 assert(height != 1); /* widthxheight can't be 1x1 */
1202 halfWidth= 1;
1203 /* one vertical column with possible pad bytes per row */
1204 /* average two at a time */
1206 for (jj= 0; jj< halfHeight; jj++) {
1207 int kk;
1208 for (kk= 0; kk< components; kk++) {
1209 #define BOX2 2
1210 GLfloat sfloat[BOX2];
1211 if (myswap_bytes) {
1212 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1213 sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
1215 else {
1216 sfloat[0]= *(const GLfloat*)src;
1217 sfloat[1]= *(const GLfloat*)(src+ysize);
1219 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1221 src+= element_size;
1222 dest++;
1224 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1225 src+= ysize; /* skip to odd row */
1229 assert(src == &((const char *)dataIn)[ysize*height]);
1230 assert((char *)dest == &((char *)dataOut)
1231 [components * element_size * halfWidth * halfHeight]);
1232 } /* halve1Dimage_float() */
1234 static void scale_internal(GLint components, GLint widthin, GLint heightin,
1235 const GLushort *datain,
1236 GLint widthout, GLint heightout,
1237 GLushort *dataout)
1239 float x, lowx, highx, convx, halfconvx;
1240 float y, lowy, highy, convy, halfconvy;
1241 float xpercent,ypercent;
1242 float percent;
1243 /* Max components in a format is 4, so... */
1244 float totals[4];
1245 float area;
1246 int i,j,k,yint,xint,xindex,yindex;
1247 int temp;
1249 if (widthin == widthout*2 && heightin == heightout*2) {
1250 halveImage(components, widthin, heightin, datain, dataout);
1251 return;
1253 convy = (float) heightin/heightout;
1254 convx = (float) widthin/widthout;
1255 halfconvx = convx/2;
1256 halfconvy = convy/2;
1257 for (i = 0; i < heightout; i++) {
1258 y = convy * (i+0.5);
1259 if (heightin > heightout) {
1260 highy = y + halfconvy;
1261 lowy = y - halfconvy;
1262 } else {
1263 highy = y + 0.5;
1264 lowy = y - 0.5;
1266 for (j = 0; j < widthout; j++) {
1267 x = convx * (j+0.5);
1268 if (widthin > widthout) {
1269 highx = x + halfconvx;
1270 lowx = x - halfconvx;
1271 } else {
1272 highx = x + 0.5;
1273 lowx = x - 0.5;
1277 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1278 ** to (highx, highy) on input data into this pixel on output
1279 ** data.
1281 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1282 area = 0.0;
1284 y = lowy;
1285 yint = floor(y);
1286 while (y < highy) {
1287 yindex = (yint + heightin) % heightin;
1288 if (highy < yint+1) {
1289 ypercent = highy - y;
1290 } else {
1291 ypercent = yint+1 - y;
1294 x = lowx;
1295 xint = floor(x);
1297 while (x < highx) {
1298 xindex = (xint + widthin) % widthin;
1299 if (highx < xint+1) {
1300 xpercent = highx - x;
1301 } else {
1302 xpercent = xint+1 - x;
1305 percent = xpercent * ypercent;
1306 area += percent;
1307 temp = (xindex + (yindex * widthin)) * components;
1308 for (k = 0; k < components; k++) {
1309 totals[k] += datain[temp + k] * percent;
1312 xint++;
1313 x = xint;
1315 yint++;
1316 y = yint;
1319 temp = (j + (i * widthout)) * components;
1320 for (k = 0; k < components; k++) {
1321 /* totals[] should be rounded in the case of enlarging an RGB
1322 * ramp when the type is 332 or 4444
1324 dataout[temp + k] = (totals[k]+0.5)/area;
1330 static void scale_internal_ubyte(GLint components, GLint widthin,
1331 GLint heightin, const GLubyte *datain,
1332 GLint widthout, GLint heightout,
1333 GLubyte *dataout, GLint element_size,
1334 GLint ysize, GLint group_size)
1336 float convx;
1337 float convy;
1338 float percent;
1339 /* Max components in a format is 4, so... */
1340 float totals[4];
1341 float area;
1342 int i,j,k,xindex;
1344 const char *temp, *temp0;
1345 const char *temp_index;
1346 int outindex;
1348 int lowx_int, highx_int, lowy_int, highy_int;
1349 float x_percent, y_percent;
1350 float lowx_float, highx_float, lowy_float, highy_float;
1351 float convy_float, convx_float;
1352 int convy_int, convx_int;
1353 int l, m;
1354 const char *left, *right;
1356 if (widthin == widthout*2 && heightin == heightout*2) {
1357 halveImage_ubyte(components, widthin, heightin,
1358 (const GLubyte *)datain, (GLubyte *)dataout,
1359 element_size, ysize, group_size);
1360 return;
1362 convy = (float) heightin/heightout;
1363 convx = (float) widthin/widthout;
1364 convy_int = floor(convy);
1365 convy_float = convy - convy_int;
1366 convx_int = floor(convx);
1367 convx_float = convx - convx_int;
1369 area = convx * convy;
1371 lowy_int = 0;
1372 lowy_float = 0;
1373 highy_int = convy_int;
1374 highy_float = convy_float;
1376 for (i = 0; i < heightout; i++) {
1377 /* Clamp here to be sure we don't read beyond input buffer. */
1378 if (highy_int >= heightin)
1379 highy_int = heightin - 1;
1380 lowx_int = 0;
1381 lowx_float = 0;
1382 highx_int = convx_int;
1383 highx_float = convx_float;
1385 for (j = 0; j < widthout; j++) {
1388 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1389 ** to (highx, highy) on input data into this pixel on output
1390 ** data.
1392 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1394 /* calculate the value for pixels in the 1st row */
1395 xindex = lowx_int*group_size;
1396 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1398 y_percent = 1-lowy_float;
1399 temp = (const char *)datain + xindex + lowy_int * ysize;
1400 percent = y_percent * (1-lowx_float);
1401 for (k = 0, temp_index = temp; k < components;
1402 k++, temp_index += element_size) {
1403 totals[k] += (GLubyte)(*(temp_index)) * percent;
1405 left = temp;
1406 for(l = lowx_int+1; l < highx_int; l++) {
1407 temp += group_size;
1408 for (k = 0, temp_index = temp; k < components;
1409 k++, temp_index += element_size) {
1410 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1413 temp += group_size;
1414 right = temp;
1415 percent = y_percent * highx_float;
1416 for (k = 0, temp_index = temp; k < components;
1417 k++, temp_index += element_size) {
1418 totals[k] += (GLubyte)(*(temp_index)) * percent;
1421 /* calculate the value for pixels in the last row */
1422 y_percent = highy_float;
1423 percent = y_percent * (1-lowx_float);
1424 temp = (const char *)datain + xindex + highy_int * ysize;
1425 for (k = 0, temp_index = temp; k < components;
1426 k++, temp_index += element_size) {
1427 totals[k] += (GLubyte)(*(temp_index)) * percent;
1429 for(l = lowx_int+1; l < highx_int; l++) {
1430 temp += group_size;
1431 for (k = 0, temp_index = temp; k < components;
1432 k++, temp_index += element_size) {
1433 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1436 temp += group_size;
1437 percent = y_percent * highx_float;
1438 for (k = 0, temp_index = temp; k < components;
1439 k++, temp_index += element_size) {
1440 totals[k] += (GLubyte)(*(temp_index)) * percent;
1444 /* calculate the value for pixels in the 1st and last column */
1445 for(m = lowy_int+1; m < highy_int; m++) {
1446 left += ysize;
1447 right += ysize;
1448 for (k = 0; k < components;
1449 k++, left += element_size, right += element_size) {
1450 totals[k] += (GLubyte)(*(left))*(1-lowx_float)
1451 +(GLubyte)(*(right))*highx_float;
1454 } else if (highy_int > lowy_int) {
1455 x_percent = highx_float - lowx_float;
1456 percent = (1-lowy_float)*x_percent;
1457 temp = (const char *)datain + xindex + lowy_int*ysize;
1458 for (k = 0, temp_index = temp; k < components;
1459 k++, temp_index += element_size) {
1460 totals[k] += (GLubyte)(*(temp_index)) * percent;
1462 for(m = lowy_int+1; m < highy_int; m++) {
1463 temp += ysize;
1464 for (k = 0, temp_index = temp; k < components;
1465 k++, temp_index += element_size) {
1466 totals[k] += (GLubyte)(*(temp_index)) * x_percent;
1469 percent = x_percent * highy_float;
1470 temp += ysize;
1471 for (k = 0, temp_index = temp; k < components;
1472 k++, temp_index += element_size) {
1473 totals[k] += (GLubyte)(*(temp_index)) * percent;
1475 } else if (highx_int > lowx_int) {
1476 y_percent = highy_float - lowy_float;
1477 percent = (1-lowx_float)*y_percent;
1478 temp = (const char *)datain + xindex + lowy_int*ysize;
1479 for (k = 0, temp_index = temp; k < components;
1480 k++, temp_index += element_size) {
1481 totals[k] += (GLubyte)(*(temp_index)) * percent;
1483 for (l = lowx_int+1; l < highx_int; l++) {
1484 temp += group_size;
1485 for (k = 0, temp_index = temp; k < components;
1486 k++, temp_index += element_size) {
1487 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1490 temp += group_size;
1491 percent = y_percent * highx_float;
1492 for (k = 0, temp_index = temp; k < components;
1493 k++, temp_index += element_size) {
1494 totals[k] += (GLubyte)(*(temp_index)) * percent;
1496 } else {
1497 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1498 temp = (const char *)datain + xindex + lowy_int * ysize;
1499 for (k = 0, temp_index = temp; k < components;
1500 k++, temp_index += element_size) {
1501 totals[k] += (GLubyte)(*(temp_index)) * percent;
1507 /* this is for the pixels in the body */
1508 temp0 = (const char *)datain + xindex + group_size +
1509 (lowy_int+1)*ysize;
1510 for (m = lowy_int+1; m < highy_int; m++) {
1511 temp = temp0;
1512 for(l = lowx_int+1; l < highx_int; l++) {
1513 for (k = 0, temp_index = temp; k < components;
1514 k++, temp_index += element_size) {
1515 totals[k] += (GLubyte)(*(temp_index));
1517 temp += group_size;
1519 temp0 += ysize;
1522 outindex = (j + (i * widthout)) * components;
1523 for (k = 0; k < components; k++) {
1524 dataout[outindex + k] = totals[k]/area;
1525 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1527 lowx_int = highx_int;
1528 lowx_float = highx_float;
1529 highx_int += convx_int;
1530 highx_float += convx_float;
1531 if(highx_float > 1) {
1532 highx_float -= 1.0;
1533 highx_int++;
1536 lowy_int = highy_int;
1537 lowy_float = highy_float;
1538 highy_int += convy_int;
1539 highy_float += convy_float;
1540 if(highy_float > 1) {
1541 highy_float -= 1.0;
1542 highy_int++;
1547 static void scale_internal_byte(GLint components, GLint widthin,
1548 GLint heightin, const GLbyte *datain,
1549 GLint widthout, GLint heightout,
1550 GLbyte *dataout, GLint element_size,
1551 GLint ysize, GLint group_size)
1553 float convx;
1554 float convy;
1555 float percent;
1556 /* Max components in a format is 4, so... */
1557 float totals[4];
1558 float area;
1559 int i,j,k,xindex;
1561 const char *temp, *temp0;
1562 const char *temp_index;
1563 int outindex;
1565 int lowx_int, highx_int, lowy_int, highy_int;
1566 float x_percent, y_percent;
1567 float lowx_float, highx_float, lowy_float, highy_float;
1568 float convy_float, convx_float;
1569 int convy_int, convx_int;
1570 int l, m;
1571 const char *left, *right;
1573 if (widthin == widthout*2 && heightin == heightout*2) {
1574 halveImage_byte(components, widthin, heightin,
1575 (const GLbyte *)datain, (GLbyte *)dataout,
1576 element_size, ysize, group_size);
1577 return;
1579 convy = (float) heightin/heightout;
1580 convx = (float) widthin/widthout;
1581 convy_int = floor(convy);
1582 convy_float = convy - convy_int;
1583 convx_int = floor(convx);
1584 convx_float = convx - convx_int;
1586 area = convx * convy;
1588 lowy_int = 0;
1589 lowy_float = 0;
1590 highy_int = convy_int;
1591 highy_float = convy_float;
1593 for (i = 0; i < heightout; i++) {
1594 /* Clamp here to be sure we don't read beyond input buffer. */
1595 if (highy_int >= heightin)
1596 highy_int = heightin - 1;
1597 lowx_int = 0;
1598 lowx_float = 0;
1599 highx_int = convx_int;
1600 highx_float = convx_float;
1602 for (j = 0; j < widthout; j++) {
1605 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1606 ** to (highx, highy) on input data into this pixel on output
1607 ** data.
1609 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1611 /* calculate the value for pixels in the 1st row */
1612 xindex = lowx_int*group_size;
1613 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1615 y_percent = 1-lowy_float;
1616 temp = (const char *)datain + xindex + lowy_int * ysize;
1617 percent = y_percent * (1-lowx_float);
1618 for (k = 0, temp_index = temp; k < components;
1619 k++, temp_index += element_size) {
1620 totals[k] += (GLbyte)(*(temp_index)) * percent;
1622 left = temp;
1623 for(l = lowx_int+1; l < highx_int; l++) {
1624 temp += group_size;
1625 for (k = 0, temp_index = temp; k < components;
1626 k++, temp_index += element_size) {
1627 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1630 temp += group_size;
1631 right = temp;
1632 percent = y_percent * highx_float;
1633 for (k = 0, temp_index = temp; k < components;
1634 k++, temp_index += element_size) {
1635 totals[k] += (GLbyte)(*(temp_index)) * percent;
1638 /* calculate the value for pixels in the last row */
1639 y_percent = highy_float;
1640 percent = y_percent * (1-lowx_float);
1641 temp = (const char *)datain + xindex + highy_int * ysize;
1642 for (k = 0, temp_index = temp; k < components;
1643 k++, temp_index += element_size) {
1644 totals[k] += (GLbyte)(*(temp_index)) * percent;
1646 for(l = lowx_int+1; l < highx_int; l++) {
1647 temp += group_size;
1648 for (k = 0, temp_index = temp; k < components;
1649 k++, temp_index += element_size) {
1650 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1653 temp += group_size;
1654 percent = y_percent * highx_float;
1655 for (k = 0, temp_index = temp; k < components;
1656 k++, temp_index += element_size) {
1657 totals[k] += (GLbyte)(*(temp_index)) * percent;
1661 /* calculate the value for pixels in the 1st and last column */
1662 for(m = lowy_int+1; m < highy_int; m++) {
1663 left += ysize;
1664 right += ysize;
1665 for (k = 0; k < components;
1666 k++, left += element_size, right += element_size) {
1667 totals[k] += (GLbyte)(*(left))*(1-lowx_float)
1668 +(GLbyte)(*(right))*highx_float;
1671 } else if (highy_int > lowy_int) {
1672 x_percent = highx_float - lowx_float;
1673 percent = (1-lowy_float)*x_percent;
1674 temp = (const char *)datain + xindex + lowy_int*ysize;
1675 for (k = 0, temp_index = temp; k < components;
1676 k++, temp_index += element_size) {
1677 totals[k] += (GLbyte)(*(temp_index)) * percent;
1679 for(m = lowy_int+1; m < highy_int; m++) {
1680 temp += ysize;
1681 for (k = 0, temp_index = temp; k < components;
1682 k++, temp_index += element_size) {
1683 totals[k] += (GLbyte)(*(temp_index)) * x_percent;
1686 percent = x_percent * highy_float;
1687 temp += ysize;
1688 for (k = 0, temp_index = temp; k < components;
1689 k++, temp_index += element_size) {
1690 totals[k] += (GLbyte)(*(temp_index)) * percent;
1692 } else if (highx_int > lowx_int) {
1693 y_percent = highy_float - lowy_float;
1694 percent = (1-lowx_float)*y_percent;
1695 temp = (const char *)datain + xindex + lowy_int*ysize;
1696 for (k = 0, temp_index = temp; k < components;
1697 k++, temp_index += element_size) {
1698 totals[k] += (GLbyte)(*(temp_index)) * percent;
1700 for (l = lowx_int+1; l < highx_int; l++) {
1701 temp += group_size;
1702 for (k = 0, temp_index = temp; k < components;
1703 k++, temp_index += element_size) {
1704 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1707 temp += group_size;
1708 percent = y_percent * highx_float;
1709 for (k = 0, temp_index = temp; k < components;
1710 k++, temp_index += element_size) {
1711 totals[k] += (GLbyte)(*(temp_index)) * percent;
1713 } else {
1714 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1715 temp = (const char *)datain + xindex + lowy_int * ysize;
1716 for (k = 0, temp_index = temp; k < components;
1717 k++, temp_index += element_size) {
1718 totals[k] += (GLbyte)(*(temp_index)) * percent;
1724 /* this is for the pixels in the body */
1725 temp0 = (const char *)datain + xindex + group_size +
1726 (lowy_int+1)*ysize;
1727 for (m = lowy_int+1; m < highy_int; m++) {
1728 temp = temp0;
1729 for(l = lowx_int+1; l < highx_int; l++) {
1730 for (k = 0, temp_index = temp; k < components;
1731 k++, temp_index += element_size) {
1732 totals[k] += (GLbyte)(*(temp_index));
1734 temp += group_size;
1736 temp0 += ysize;
1739 outindex = (j + (i * widthout)) * components;
1740 for (k = 0; k < components; k++) {
1741 dataout[outindex + k] = totals[k]/area;
1742 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1744 lowx_int = highx_int;
1745 lowx_float = highx_float;
1746 highx_int += convx_int;
1747 highx_float += convx_float;
1748 if(highx_float > 1) {
1749 highx_float -= 1.0;
1750 highx_int++;
1753 lowy_int = highy_int;
1754 lowy_float = highy_float;
1755 highy_int += convy_int;
1756 highy_float += convy_float;
1757 if(highy_float > 1) {
1758 highy_float -= 1.0;
1759 highy_int++;
1764 static void scale_internal_ushort(GLint components, GLint widthin,
1765 GLint heightin, const GLushort *datain,
1766 GLint widthout, GLint heightout,
1767 GLushort *dataout, GLint element_size,
1768 GLint ysize, GLint group_size,
1769 GLint myswap_bytes)
1771 float convx;
1772 float convy;
1773 float percent;
1774 /* Max components in a format is 4, so... */
1775 float totals[4];
1776 float area;
1777 int i,j,k,xindex;
1779 const char *temp, *temp0;
1780 const char *temp_index;
1781 int outindex;
1783 int lowx_int, highx_int, lowy_int, highy_int;
1784 float x_percent, y_percent;
1785 float lowx_float, highx_float, lowy_float, highy_float;
1786 float convy_float, convx_float;
1787 int convy_int, convx_int;
1788 int l, m;
1789 const char *left, *right;
1791 if (widthin == widthout*2 && heightin == heightout*2) {
1792 halveImage_ushort(components, widthin, heightin,
1793 (const GLushort *)datain, (GLushort *)dataout,
1794 element_size, ysize, group_size, myswap_bytes);
1795 return;
1797 convy = (float) heightin/heightout;
1798 convx = (float) widthin/widthout;
1799 convy_int = floor(convy);
1800 convy_float = convy - convy_int;
1801 convx_int = floor(convx);
1802 convx_float = convx - convx_int;
1804 area = convx * convy;
1806 lowy_int = 0;
1807 lowy_float = 0;
1808 highy_int = convy_int;
1809 highy_float = convy_float;
1811 for (i = 0; i < heightout; i++) {
1812 /* Clamp here to be sure we don't read beyond input buffer. */
1813 if (highy_int >= heightin)
1814 highy_int = heightin - 1;
1815 lowx_int = 0;
1816 lowx_float = 0;
1817 highx_int = convx_int;
1818 highx_float = convx_float;
1820 for (j = 0; j < widthout; j++) {
1822 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1823 ** to (highx, highy) on input data into this pixel on output
1824 ** data.
1826 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1828 /* calculate the value for pixels in the 1st row */
1829 xindex = lowx_int*group_size;
1830 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1832 y_percent = 1-lowy_float;
1833 temp = (const char *)datain + xindex + lowy_int * ysize;
1834 percent = y_percent * (1-lowx_float);
1835 for (k = 0, temp_index = temp; k < components;
1836 k++, temp_index += element_size) {
1837 if (myswap_bytes) {
1838 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1839 } else {
1840 totals[k] += *(const GLushort*)temp_index * percent;
1843 left = temp;
1844 for(l = lowx_int+1; l < highx_int; l++) {
1845 temp += group_size;
1846 for (k = 0, temp_index = temp; k < components;
1847 k++, temp_index += element_size) {
1848 if (myswap_bytes) {
1849 totals[k] +=
1850 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1851 } else {
1852 totals[k] += *(const GLushort*)temp_index * y_percent;
1856 temp += group_size;
1857 right = temp;
1858 percent = y_percent * highx_float;
1859 for (k = 0, temp_index = temp; k < components;
1860 k++, temp_index += element_size) {
1861 if (myswap_bytes) {
1862 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1863 } else {
1864 totals[k] += *(const GLushort*)temp_index * percent;
1868 /* calculate the value for pixels in the last row */
1869 y_percent = highy_float;
1870 percent = y_percent * (1-lowx_float);
1871 temp = (const char *)datain + xindex + highy_int * ysize;
1872 for (k = 0, temp_index = temp; k < components;
1873 k++, temp_index += element_size) {
1874 if (myswap_bytes) {
1875 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1876 } else {
1877 totals[k] += *(const GLushort*)temp_index * percent;
1880 for(l = lowx_int+1; l < highx_int; l++) {
1881 temp += group_size;
1882 for (k = 0, temp_index = temp; k < components;
1883 k++, temp_index += element_size) {
1884 if (myswap_bytes) {
1885 totals[k] +=
1886 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1887 } else {
1888 totals[k] += *(const GLushort*)temp_index * y_percent;
1892 temp += group_size;
1893 percent = y_percent * highx_float;
1894 for (k = 0, temp_index = temp; k < components;
1895 k++, temp_index += element_size) {
1896 if (myswap_bytes) {
1897 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1898 } else {
1899 totals[k] += *(const GLushort*)temp_index * percent;
1903 /* calculate the value for pixels in the 1st and last column */
1904 for(m = lowy_int+1; m < highy_int; m++) {
1905 left += ysize;
1906 right += ysize;
1907 for (k = 0; k < components;
1908 k++, left += element_size, right += element_size) {
1909 if (myswap_bytes) {
1910 totals[k] +=
1911 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
1912 __GLU_SWAP_2_BYTES(right) * highx_float;
1913 } else {
1914 totals[k] += *(const GLushort*)left * (1-lowx_float)
1915 + *(const GLushort*)right * highx_float;
1919 } else if (highy_int > lowy_int) {
1920 x_percent = highx_float - lowx_float;
1921 percent = (1-lowy_float)*x_percent;
1922 temp = (const char *)datain + xindex + lowy_int*ysize;
1923 for (k = 0, temp_index = temp; k < components;
1924 k++, temp_index += element_size) {
1925 if (myswap_bytes) {
1926 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1927 } else {
1928 totals[k] += *(const GLushort*)temp_index * percent;
1931 for(m = lowy_int+1; m < highy_int; m++) {
1932 temp += ysize;
1933 for (k = 0, temp_index = temp; k < components;
1934 k++, temp_index += element_size) {
1935 if (myswap_bytes) {
1936 totals[k] +=
1937 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
1938 } else {
1939 totals[k] += *(const GLushort*)temp_index * x_percent;
1943 percent = x_percent * highy_float;
1944 temp += ysize;
1945 for (k = 0, temp_index = temp; k < components;
1946 k++, temp_index += element_size) {
1947 if (myswap_bytes) {
1948 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1949 } else {
1950 totals[k] += *(const GLushort*)temp_index * percent;
1953 } else if (highx_int > lowx_int) {
1954 y_percent = highy_float - lowy_float;
1955 percent = (1-lowx_float)*y_percent;
1956 temp = (const char *)datain + xindex + lowy_int*ysize;
1957 for (k = 0, temp_index = temp; k < components;
1958 k++, temp_index += element_size) {
1959 if (myswap_bytes) {
1960 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1961 } else {
1962 totals[k] += *(const GLushort*)temp_index * percent;
1965 for (l = lowx_int+1; l < highx_int; l++) {
1966 temp += group_size;
1967 for (k = 0, temp_index = temp; k < components;
1968 k++, temp_index += element_size) {
1969 if (myswap_bytes) {
1970 totals[k] +=
1971 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1972 } else {
1973 totals[k] += *(const GLushort*)temp_index * y_percent;
1977 temp += group_size;
1978 percent = y_percent * highx_float;
1979 for (k = 0, temp_index = temp; k < components;
1980 k++, temp_index += element_size) {
1981 if (myswap_bytes) {
1982 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1983 } else {
1984 totals[k] += *(const GLushort*)temp_index * percent;
1987 } else {
1988 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1989 temp = (const char *)datain + xindex + lowy_int * ysize;
1990 for (k = 0, temp_index = temp; k < components;
1991 k++, temp_index += element_size) {
1992 if (myswap_bytes) {
1993 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1994 } else {
1995 totals[k] += *(const GLushort*)temp_index * percent;
2000 /* this is for the pixels in the body */
2001 temp0 = (const char *)datain + xindex + group_size +
2002 (lowy_int+1)*ysize;
2003 for (m = lowy_int+1; m < highy_int; m++) {
2004 temp = temp0;
2005 for(l = lowx_int+1; l < highx_int; l++) {
2006 for (k = 0, temp_index = temp; k < components;
2007 k++, temp_index += element_size) {
2008 if (myswap_bytes) {
2009 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
2010 } else {
2011 totals[k] += *(const GLushort*)temp_index;
2014 temp += group_size;
2016 temp0 += ysize;
2019 outindex = (j + (i * widthout)) * components;
2020 for (k = 0; k < components; k++) {
2021 dataout[outindex + k] = totals[k]/area;
2022 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2024 lowx_int = highx_int;
2025 lowx_float = highx_float;
2026 highx_int += convx_int;
2027 highx_float += convx_float;
2028 if(highx_float > 1) {
2029 highx_float -= 1.0;
2030 highx_int++;
2033 lowy_int = highy_int;
2034 lowy_float = highy_float;
2035 highy_int += convy_int;
2036 highy_float += convy_float;
2037 if(highy_float > 1) {
2038 highy_float -= 1.0;
2039 highy_int++;
2044 static void scale_internal_short(GLint components, GLint widthin,
2045 GLint heightin, const GLshort *datain,
2046 GLint widthout, GLint heightout,
2047 GLshort *dataout, GLint element_size,
2048 GLint ysize, GLint group_size,
2049 GLint myswap_bytes)
2051 float convx;
2052 float convy;
2053 float percent;
2054 /* Max components in a format is 4, so... */
2055 float totals[4];
2056 float area;
2057 int i,j,k,xindex;
2059 const char *temp, *temp0;
2060 const char *temp_index;
2061 int outindex;
2063 int lowx_int, highx_int, lowy_int, highy_int;
2064 float x_percent, y_percent;
2065 float lowx_float, highx_float, lowy_float, highy_float;
2066 float convy_float, convx_float;
2067 int convy_int, convx_int;
2068 int l, m;
2069 const char *left, *right;
2071 GLushort swapbuf; /* unsigned buffer */
2073 if (widthin == widthout*2 && heightin == heightout*2) {
2074 halveImage_short(components, widthin, heightin,
2075 (const GLshort *)datain, (GLshort *)dataout,
2076 element_size, ysize, group_size, myswap_bytes);
2077 return;
2079 convy = (float) heightin/heightout;
2080 convx = (float) widthin/widthout;
2081 convy_int = floor(convy);
2082 convy_float = convy - convy_int;
2083 convx_int = floor(convx);
2084 convx_float = convx - convx_int;
2086 area = convx * convy;
2088 lowy_int = 0;
2089 lowy_float = 0;
2090 highy_int = convy_int;
2091 highy_float = convy_float;
2093 for (i = 0; i < heightout; i++) {
2094 /* Clamp here to be sure we don't read beyond input buffer. */
2095 if (highy_int >= heightin)
2096 highy_int = heightin - 1;
2097 lowx_int = 0;
2098 lowx_float = 0;
2099 highx_int = convx_int;
2100 highx_float = convx_float;
2102 for (j = 0; j < widthout; j++) {
2104 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2105 ** to (highx, highy) on input data into this pixel on output
2106 ** data.
2108 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2110 /* calculate the value for pixels in the 1st row */
2111 xindex = lowx_int*group_size;
2112 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2114 y_percent = 1-lowy_float;
2115 temp = (const char *)datain + xindex + lowy_int * ysize;
2116 percent = y_percent * (1-lowx_float);
2117 for (k = 0, temp_index = temp; k < components;
2118 k++, temp_index += element_size) {
2119 if (myswap_bytes) {
2120 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2121 totals[k] += *(const GLshort*)&swapbuf * percent;
2122 } else {
2123 totals[k] += *(const GLshort*)temp_index * percent;
2126 left = temp;
2127 for(l = lowx_int+1; l < highx_int; l++) {
2128 temp += group_size;
2129 for (k = 0, temp_index = temp; k < components;
2130 k++, temp_index += element_size) {
2131 if (myswap_bytes) {
2132 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2133 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2134 } else {
2135 totals[k] += *(const GLshort*)temp_index * y_percent;
2139 temp += group_size;
2140 right = temp;
2141 percent = y_percent * highx_float;
2142 for (k = 0, temp_index = temp; k < components;
2143 k++, temp_index += element_size) {
2144 if (myswap_bytes) {
2145 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2146 totals[k] += *(const GLshort*)&swapbuf * percent;
2147 } else {
2148 totals[k] += *(const GLshort*)temp_index * percent;
2152 /* calculate the value for pixels in the last row */
2153 y_percent = highy_float;
2154 percent = y_percent * (1-lowx_float);
2155 temp = (const char *)datain + xindex + highy_int * ysize;
2156 for (k = 0, temp_index = temp; k < components;
2157 k++, temp_index += element_size) {
2158 if (myswap_bytes) {
2159 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2160 totals[k] += *(const GLshort*)&swapbuf * percent;
2161 } else {
2162 totals[k] += *(const GLshort*)temp_index * percent;
2165 for(l = lowx_int+1; l < highx_int; l++) {
2166 temp += group_size;
2167 for (k = 0, temp_index = temp; k < components;
2168 k++, temp_index += element_size) {
2169 if (myswap_bytes) {
2170 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2171 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2172 } else {
2173 totals[k] += *(const GLshort*)temp_index * y_percent;
2177 temp += group_size;
2178 percent = y_percent * highx_float;
2179 for (k = 0, temp_index = temp; k < components;
2180 k++, temp_index += element_size) {
2181 if (myswap_bytes) {
2182 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2183 totals[k] += *(const GLshort*)&swapbuf * percent;
2184 } else {
2185 totals[k] += *(const GLshort*)temp_index * percent;
2189 /* calculate the value for pixels in the 1st and last column */
2190 for(m = lowy_int+1; m < highy_int; m++) {
2191 left += ysize;
2192 right += ysize;
2193 for (k = 0; k < components;
2194 k++, left += element_size, right += element_size) {
2195 if (myswap_bytes) {
2196 swapbuf = __GLU_SWAP_2_BYTES(left);
2197 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
2198 swapbuf = __GLU_SWAP_2_BYTES(right);
2199 totals[k] += *(const GLshort*)&swapbuf * highx_float;
2200 } else {
2201 totals[k] += *(const GLshort*)left * (1-lowx_float)
2202 + *(const GLshort*)right * highx_float;
2206 } else if (highy_int > lowy_int) {
2207 x_percent = highx_float - lowx_float;
2208 percent = (1-lowy_float)*x_percent;
2209 temp = (const char *)datain + xindex + lowy_int*ysize;
2210 for (k = 0, temp_index = temp; k < components;
2211 k++, temp_index += element_size) {
2212 if (myswap_bytes) {
2213 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2214 totals[k] += *(const GLshort*)&swapbuf * percent;
2215 } else {
2216 totals[k] += *(const GLshort*)temp_index * percent;
2219 for(m = lowy_int+1; m < highy_int; m++) {
2220 temp += ysize;
2221 for (k = 0, temp_index = temp; k < components;
2222 k++, temp_index += element_size) {
2223 if (myswap_bytes) {
2224 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2225 totals[k] += *(const GLshort*)&swapbuf * x_percent;
2226 } else {
2227 totals[k] += *(const GLshort*)temp_index * x_percent;
2231 percent = x_percent * highy_float;
2232 temp += ysize;
2233 for (k = 0, temp_index = temp; k < components;
2234 k++, temp_index += element_size) {
2235 if (myswap_bytes) {
2236 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2237 totals[k] += *(const GLshort*)&swapbuf * percent;
2238 } else {
2239 totals[k] += *(const GLshort*)temp_index * percent;
2242 } else if (highx_int > lowx_int) {
2243 y_percent = highy_float - lowy_float;
2244 percent = (1-lowx_float)*y_percent;
2246 temp = (const char *)datain + xindex + lowy_int*ysize;
2247 for (k = 0, temp_index = temp; k < components;
2248 k++, temp_index += element_size) {
2249 if (myswap_bytes) {
2250 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2251 totals[k] += *(const GLshort*)&swapbuf * percent;
2252 } else {
2253 totals[k] += *(const GLshort*)temp_index * percent;
2256 for (l = lowx_int+1; l < highx_int; l++) {
2257 temp += group_size;
2258 for (k = 0, temp_index = temp; k < components;
2259 k++, temp_index += element_size) {
2260 if (myswap_bytes) {
2261 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2262 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2263 } else {
2264 totals[k] += *(const GLshort*)temp_index * y_percent;
2268 temp += group_size;
2269 percent = y_percent * highx_float;
2270 for (k = 0, temp_index = temp; k < components;
2271 k++, temp_index += element_size) {
2272 if (myswap_bytes) {
2273 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2274 totals[k] += *(const GLshort*)&swapbuf * percent;
2275 } else {
2276 totals[k] += *(const GLshort*)temp_index * percent;
2279 } else {
2280 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2281 temp = (const char *)datain + xindex + lowy_int * ysize;
2282 for (k = 0, temp_index = temp; k < components;
2283 k++, temp_index += element_size) {
2284 if (myswap_bytes) {
2285 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2286 totals[k] += *(const GLshort*)&swapbuf * percent;
2287 } else {
2288 totals[k] += *(const GLshort*)temp_index * percent;
2293 /* this is for the pixels in the body */
2294 temp0 = (const char *)datain + xindex + group_size +
2295 (lowy_int+1)*ysize;
2296 for (m = lowy_int+1; m < highy_int; m++) {
2297 temp = temp0;
2298 for(l = lowx_int+1; l < highx_int; l++) {
2299 for (k = 0, temp_index = temp; k < components;
2300 k++, temp_index += element_size) {
2301 if (myswap_bytes) {
2302 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2303 totals[k] += *(const GLshort*)&swapbuf;
2304 } else {
2305 totals[k] += *(const GLshort*)temp_index;
2308 temp += group_size;
2310 temp0 += ysize;
2313 outindex = (j + (i * widthout)) * components;
2314 for (k = 0; k < components; k++) {
2315 dataout[outindex + k] = totals[k]/area;
2316 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2318 lowx_int = highx_int;
2319 lowx_float = highx_float;
2320 highx_int += convx_int;
2321 highx_float += convx_float;
2322 if(highx_float > 1) {
2323 highx_float -= 1.0;
2324 highx_int++;
2327 lowy_int = highy_int;
2328 lowy_float = highy_float;
2329 highy_int += convy_int;
2330 highy_float += convy_float;
2331 if(highy_float > 1) {
2332 highy_float -= 1.0;
2333 highy_int++;
2338 static void scale_internal_uint(GLint components, GLint widthin,
2339 GLint heightin, const GLuint *datain,
2340 GLint widthout, GLint heightout,
2341 GLuint *dataout, GLint element_size,
2342 GLint ysize, GLint group_size,
2343 GLint myswap_bytes)
2345 float convx;
2346 float convy;
2347 float percent;
2348 /* Max components in a format is 4, so... */
2349 float totals[4];
2350 float area;
2351 int i,j,k,xindex;
2353 const char *temp, *temp0;
2354 const char *temp_index;
2355 int outindex;
2357 int lowx_int, highx_int, lowy_int, highy_int;
2358 float x_percent, y_percent;
2359 float lowx_float, highx_float, lowy_float, highy_float;
2360 float convy_float, convx_float;
2361 int convy_int, convx_int;
2362 int l, m;
2363 const char *left, *right;
2365 if (widthin == widthout*2 && heightin == heightout*2) {
2366 halveImage_uint(components, widthin, heightin,
2367 (const GLuint *)datain, (GLuint *)dataout,
2368 element_size, ysize, group_size, myswap_bytes);
2369 return;
2371 convy = (float) heightin/heightout;
2372 convx = (float) widthin/widthout;
2373 convy_int = floor(convy);
2374 convy_float = convy - convy_int;
2375 convx_int = floor(convx);
2376 convx_float = convx - convx_int;
2378 area = convx * convy;
2380 lowy_int = 0;
2381 lowy_float = 0;
2382 highy_int = convy_int;
2383 highy_float = convy_float;
2385 for (i = 0; i < heightout; i++) {
2386 /* Clamp here to be sure we don't read beyond input buffer. */
2387 if (highy_int >= heightin)
2388 highy_int = heightin - 1;
2389 lowx_int = 0;
2390 lowx_float = 0;
2391 highx_int = convx_int;
2392 highx_float = convx_float;
2394 for (j = 0; j < widthout; j++) {
2396 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2397 ** to (highx, highy) on input data into this pixel on output
2398 ** data.
2400 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2402 /* calculate the value for pixels in the 1st row */
2403 xindex = lowx_int*group_size;
2404 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2406 y_percent = 1-lowy_float;
2407 temp = (const char *)datain + xindex + lowy_int * ysize;
2408 percent = y_percent * (1-lowx_float);
2409 for (k = 0, temp_index = temp; k < components;
2410 k++, temp_index += element_size) {
2411 if (myswap_bytes) {
2412 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2413 } else {
2414 totals[k] += *(const GLuint*)temp_index * percent;
2417 left = temp;
2418 for(l = lowx_int+1; l < highx_int; l++) {
2419 temp += group_size;
2420 for (k = 0, temp_index = temp; k < components;
2421 k++, temp_index += element_size) {
2422 if (myswap_bytes) {
2423 totals[k] +=
2424 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2425 } else {
2426 totals[k] += *(const GLuint*)temp_index * y_percent;
2430 temp += group_size;
2431 right = temp;
2432 percent = y_percent * highx_float;
2433 for (k = 0, temp_index = temp; k < components;
2434 k++, temp_index += element_size) {
2435 if (myswap_bytes) {
2436 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2437 } else {
2438 totals[k] += *(const GLuint*)temp_index * percent;
2442 /* calculate the value for pixels in the last row */
2443 y_percent = highy_float;
2444 percent = y_percent * (1-lowx_float);
2445 temp = (const char *)datain + xindex + highy_int * ysize;
2446 for (k = 0, temp_index = temp; k < components;
2447 k++, temp_index += element_size) {
2448 if (myswap_bytes) {
2449 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2450 } else {
2451 totals[k] += *(const GLuint*)temp_index * percent;
2454 for(l = lowx_int+1; l < highx_int; l++) {
2455 temp += group_size;
2456 for (k = 0, temp_index = temp; k < components;
2457 k++, temp_index += element_size) {
2458 if (myswap_bytes) {
2459 totals[k] +=
2460 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2461 } else {
2462 totals[k] += *(const GLuint*)temp_index * y_percent;
2466 temp += group_size;
2467 percent = y_percent * highx_float;
2468 for (k = 0, temp_index = temp; k < components;
2469 k++, temp_index += element_size) {
2470 if (myswap_bytes) {
2471 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2472 } else {
2473 totals[k] += *(const GLuint*)temp_index * percent;
2477 /* calculate the value for pixels in the 1st and last column */
2478 for(m = lowy_int+1; m < highy_int; m++) {
2479 left += ysize;
2480 right += ysize;
2481 for (k = 0; k < components;
2482 k++, left += element_size, right += element_size) {
2483 if (myswap_bytes) {
2484 totals[k] +=
2485 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
2486 + __GLU_SWAP_4_BYTES(right) * highx_float;
2487 } else {
2488 totals[k] += *(const GLuint*)left * (1-lowx_float)
2489 + *(const GLuint*)right * highx_float;
2493 } else if (highy_int > lowy_int) {
2494 x_percent = highx_float - lowx_float;
2495 percent = (1-lowy_float)*x_percent;
2496 temp = (const char *)datain + xindex + lowy_int*ysize;
2497 for (k = 0, temp_index = temp; k < components;
2498 k++, temp_index += element_size) {
2499 if (myswap_bytes) {
2500 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2501 } else {
2502 totals[k] += *(const GLuint*)temp_index * percent;
2505 for(m = lowy_int+1; m < highy_int; m++) {
2506 temp += ysize;
2507 for (k = 0, temp_index = temp; k < components;
2508 k++, temp_index += element_size) {
2509 if (myswap_bytes) {
2510 totals[k] +=
2511 __GLU_SWAP_4_BYTES(temp_index) * x_percent;
2512 } else {
2513 totals[k] += *(const GLuint*)temp_index * x_percent;
2517 percent = x_percent * highy_float;
2518 temp += ysize;
2519 for (k = 0, temp_index = temp; k < components;
2520 k++, temp_index += element_size) {
2521 if (myswap_bytes) {
2522 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2523 } else {
2524 totals[k] += *(const GLuint*)temp_index * percent;
2527 } else if (highx_int > lowx_int) {
2528 y_percent = highy_float - lowy_float;
2529 percent = (1-lowx_float)*y_percent;
2531 temp = (const char *)datain + xindex + lowy_int*ysize;
2532 for (k = 0, temp_index = temp; k < components;
2533 k++, temp_index += element_size) {
2534 if (myswap_bytes) {
2535 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2536 } else {
2537 totals[k] += *(const GLuint*)temp_index * percent;
2540 for (l = lowx_int+1; l < highx_int; l++) {
2541 temp += group_size;
2542 for (k = 0, temp_index = temp; k < components;
2543 k++, temp_index += element_size) {
2544 if (myswap_bytes) {
2545 totals[k] +=
2546 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2547 } else {
2548 totals[k] += *(const GLuint*)temp_index * y_percent;
2552 temp += group_size;
2553 percent = y_percent * highx_float;
2554 for (k = 0, temp_index = temp; k < components;
2555 k++, temp_index += element_size) {
2556 if (myswap_bytes) {
2557 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2558 } else {
2559 totals[k] += *(const GLuint*)temp_index * percent;
2562 } else {
2563 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2564 temp = (const char *)datain + xindex + lowy_int * ysize;
2565 for (k = 0, temp_index = temp; k < components;
2566 k++, temp_index += element_size) {
2567 if (myswap_bytes) {
2568 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2569 } else {
2570 totals[k] += *(const GLuint*)temp_index * percent;
2575 /* this is for the pixels in the body */
2576 temp0 = (const char *)datain + xindex + group_size +
2577 (lowy_int+1)*ysize;
2578 for (m = lowy_int+1; m < highy_int; m++) {
2579 temp = temp0;
2580 for(l = lowx_int+1; l < highx_int; l++) {
2581 for (k = 0, temp_index = temp; k < components;
2582 k++, temp_index += element_size) {
2583 if (myswap_bytes) {
2584 totals[k] += __GLU_SWAP_4_BYTES(temp_index);
2585 } else {
2586 totals[k] += *(const GLuint*)temp_index;
2589 temp += group_size;
2591 temp0 += ysize;
2594 outindex = (j + (i * widthout)) * components;
2595 for (k = 0; k < components; k++) {
2596 /* clamp at UINT_MAX */
2597 float value= totals[k]/area;
2598 if (value >= (float) UINT_MAX) { /* need '=' */
2599 dataout[outindex + k] = UINT_MAX;
2601 else dataout[outindex + k] = value;
2603 lowx_int = highx_int;
2604 lowx_float = highx_float;
2605 highx_int += convx_int;
2606 highx_float += convx_float;
2607 if(highx_float > 1) {
2608 highx_float -= 1.0;
2609 highx_int++;
2612 lowy_int = highy_int;
2613 lowy_float = highy_float;
2614 highy_int += convy_int;
2615 highy_float += convy_float;
2616 if(highy_float > 1) {
2617 highy_float -= 1.0;
2618 highy_int++;
2625 static void scale_internal_int(GLint components, GLint widthin,
2626 GLint heightin, const GLint *datain,
2627 GLint widthout, GLint heightout,
2628 GLint *dataout, GLint element_size,
2629 GLint ysize, GLint group_size,
2630 GLint myswap_bytes)
2632 float convx;
2633 float convy;
2634 float percent;
2635 /* Max components in a format is 4, so... */
2636 float totals[4];
2637 float area;
2638 int i,j,k,xindex;
2640 const char *temp, *temp0;
2641 const char *temp_index;
2642 int outindex;
2644 int lowx_int, highx_int, lowy_int, highy_int;
2645 float x_percent, y_percent;
2646 float lowx_float, highx_float, lowy_float, highy_float;
2647 float convy_float, convx_float;
2648 int convy_int, convx_int;
2649 int l, m;
2650 const char *left, *right;
2652 GLuint swapbuf; /* unsigned buffer */
2654 if (widthin == widthout*2 && heightin == heightout*2) {
2655 halveImage_int(components, widthin, heightin,
2656 (const GLint *)datain, (GLint *)dataout,
2657 element_size, ysize, group_size, myswap_bytes);
2658 return;
2660 convy = (float) heightin/heightout;
2661 convx = (float) widthin/widthout;
2662 convy_int = floor(convy);
2663 convy_float = convy - convy_int;
2664 convx_int = floor(convx);
2665 convx_float = convx - convx_int;
2667 area = convx * convy;
2669 lowy_int = 0;
2670 lowy_float = 0;
2671 highy_int = convy_int;
2672 highy_float = convy_float;
2674 for (i = 0; i < heightout; i++) {
2675 /* Clamp here to be sure we don't read beyond input buffer. */
2676 if (highy_int >= heightin)
2677 highy_int = heightin - 1;
2678 lowx_int = 0;
2679 lowx_float = 0;
2680 highx_int = convx_int;
2681 highx_float = convx_float;
2683 for (j = 0; j < widthout; j++) {
2685 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2686 ** to (highx, highy) on input data into this pixel on output
2687 ** data.
2689 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2691 /* calculate the value for pixels in the 1st row */
2692 xindex = lowx_int*group_size;
2693 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2695 y_percent = 1-lowy_float;
2696 temp = (const char *)datain + xindex + lowy_int * ysize;
2697 percent = y_percent * (1-lowx_float);
2698 for (k = 0, temp_index = temp; k < components;
2699 k++, temp_index += element_size) {
2700 if (myswap_bytes) {
2701 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2702 totals[k] += *(const GLint*)&swapbuf * percent;
2703 } else {
2704 totals[k] += *(const GLint*)temp_index * percent;
2707 left = temp;
2708 for(l = lowx_int+1; l < highx_int; l++) {
2709 temp += group_size;
2710 for (k = 0, temp_index = temp; k < components;
2711 k++, temp_index += element_size) {
2712 if (myswap_bytes) {
2713 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2714 totals[k] += *(const GLint*)&swapbuf * y_percent;
2715 } else {
2716 totals[k] += *(const GLint*)temp_index * y_percent;
2720 temp += group_size;
2721 right = temp;
2722 percent = y_percent * highx_float;
2723 for (k = 0, temp_index = temp; k < components;
2724 k++, temp_index += element_size) {
2725 if (myswap_bytes) {
2726 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2727 totals[k] += *(const GLint*)&swapbuf * percent;
2728 } else {
2729 totals[k] += *(const GLint*)temp_index * percent;
2733 /* calculate the value for pixels in the last row */
2734 y_percent = highy_float;
2735 percent = y_percent * (1-lowx_float);
2736 temp = (const char *)datain + xindex + highy_int * ysize;
2737 for (k = 0, temp_index = temp; k < components;
2738 k++, temp_index += element_size) {
2739 if (myswap_bytes) {
2740 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2741 totals[k] += *(const GLint*)&swapbuf * percent;
2742 } else {
2743 totals[k] += *(const GLint*)temp_index * percent;
2746 for(l = lowx_int+1; l < highx_int; l++) {
2747 temp += group_size;
2748 for (k = 0, temp_index = temp; k < components;
2749 k++, temp_index += element_size) {
2750 if (myswap_bytes) {
2751 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2752 totals[k] += *(const GLint*)&swapbuf * y_percent;
2753 } else {
2754 totals[k] += *(const GLint*)temp_index * y_percent;
2758 temp += group_size;
2759 percent = y_percent * highx_float;
2760 for (k = 0, temp_index = temp; k < components;
2761 k++, temp_index += element_size) {
2762 if (myswap_bytes) {
2763 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2764 totals[k] += *(const GLint*)&swapbuf * percent;
2765 } else {
2766 totals[k] += *(const GLint*)temp_index * percent;
2770 /* calculate the value for pixels in the 1st and last column */
2771 for(m = lowy_int+1; m < highy_int; m++) {
2772 left += ysize;
2773 right += ysize;
2774 for (k = 0; k < components;
2775 k++, left += element_size, right += element_size) {
2776 if (myswap_bytes) {
2777 swapbuf = __GLU_SWAP_4_BYTES(left);
2778 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
2779 swapbuf = __GLU_SWAP_4_BYTES(right);
2780 totals[k] += *(const GLint*)&swapbuf * highx_float;
2781 } else {
2782 totals[k] += *(const GLint*)left * (1-lowx_float)
2783 + *(const GLint*)right * highx_float;
2787 } else if (highy_int > lowy_int) {
2788 x_percent = highx_float - lowx_float;
2789 percent = (1-lowy_float)*x_percent;
2790 temp = (const char *)datain + xindex + lowy_int*ysize;
2791 for (k = 0, temp_index = temp; k < components;
2792 k++, temp_index += element_size) {
2793 if (myswap_bytes) {
2794 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2795 totals[k] += *(const GLint*)&swapbuf * percent;
2796 } else {
2797 totals[k] += *(const GLint*)temp_index * percent;
2800 for(m = lowy_int+1; m < highy_int; m++) {
2801 temp += ysize;
2802 for (k = 0, temp_index = temp; k < components;
2803 k++, temp_index += element_size) {
2804 if (myswap_bytes) {
2805 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2806 totals[k] += *(const GLint*)&swapbuf * x_percent;
2807 } else {
2808 totals[k] += *(const GLint*)temp_index * x_percent;
2812 percent = x_percent * highy_float;
2813 temp += ysize;
2814 for (k = 0, temp_index = temp; k < components;
2815 k++, temp_index += element_size) {
2816 if (myswap_bytes) {
2817 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2818 totals[k] += *(const GLint*)&swapbuf * percent;
2819 } else {
2820 totals[k] += *(const GLint*)temp_index * percent;
2823 } else if (highx_int > lowx_int) {
2824 y_percent = highy_float - lowy_float;
2825 percent = (1-lowx_float)*y_percent;
2827 temp = (const char *)datain + xindex + lowy_int*ysize;
2828 for (k = 0, temp_index = temp; k < components;
2829 k++, temp_index += element_size) {
2830 if (myswap_bytes) {
2831 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2832 totals[k] += *(const GLint*)&swapbuf * percent;
2833 } else {
2834 totals[k] += *(const GLint*)temp_index * percent;
2837 for (l = lowx_int+1; l < highx_int; l++) {
2838 temp += group_size;
2839 for (k = 0, temp_index = temp; k < components;
2840 k++, temp_index += element_size) {
2841 if (myswap_bytes) {
2842 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2843 totals[k] += *(const GLint*)&swapbuf * y_percent;
2844 } else {
2845 totals[k] += *(const GLint*)temp_index * y_percent;
2849 temp += group_size;
2850 percent = y_percent * highx_float;
2851 for (k = 0, temp_index = temp; k < components;
2852 k++, temp_index += element_size) {
2853 if (myswap_bytes) {
2854 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2855 totals[k] += *(const GLint*)&swapbuf * percent;
2856 } else {
2857 totals[k] += *(const GLint*)temp_index * percent;
2860 } else {
2861 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2862 temp = (const char *)datain + xindex + lowy_int * ysize;
2863 for (k = 0, temp_index = temp; k < components;
2864 k++, temp_index += element_size) {
2865 if (myswap_bytes) {
2866 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2867 totals[k] += *(const GLint*)&swapbuf * percent;
2868 } else {
2869 totals[k] += *(const GLint*)temp_index * percent;
2874 /* this is for the pixels in the body */
2875 temp0 = (const char *)datain + xindex + group_size +
2876 (lowy_int+1)*ysize;
2877 for (m = lowy_int+1; m < highy_int; m++) {
2878 temp = temp0;
2879 for(l = lowx_int+1; l < highx_int; l++) {
2880 for (k = 0, temp_index = temp; k < components;
2881 k++, temp_index += element_size) {
2882 if (myswap_bytes) {
2883 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2884 totals[k] += *(const GLint*)&swapbuf;
2885 } else {
2886 totals[k] += *(const GLint*)temp_index;
2889 temp += group_size;
2891 temp0 += ysize;
2894 outindex = (j + (i * widthout)) * components;
2895 for (k = 0; k < components; k++) {
2896 dataout[outindex + k] = totals[k]/area;
2897 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2899 lowx_int = highx_int;
2900 lowx_float = highx_float;
2901 highx_int += convx_int;
2902 highx_float += convx_float;
2903 if(highx_float > 1) {
2904 highx_float -= 1.0;
2905 highx_int++;
2908 lowy_int = highy_int;
2909 lowy_float = highy_float;
2910 highy_int += convy_int;
2911 highy_float += convy_float;
2912 if(highy_float > 1) {
2913 highy_float -= 1.0;
2914 highy_int++;
2921 static void scale_internal_float(GLint components, GLint widthin,
2922 GLint heightin, const GLfloat *datain,
2923 GLint widthout, GLint heightout,
2924 GLfloat *dataout, GLint element_size,
2925 GLint ysize, GLint group_size,
2926 GLint myswap_bytes)
2928 float convx;
2929 float convy;
2930 float percent;
2931 /* Max components in a format is 4, so... */
2932 float totals[4];
2933 float area;
2934 int i,j,k,xindex;
2936 const char *temp, *temp0;
2937 const char *temp_index;
2938 int outindex;
2940 int lowx_int, highx_int, lowy_int, highy_int;
2941 float x_percent, y_percent;
2942 float lowx_float, highx_float, lowy_float, highy_float;
2943 float convy_float, convx_float;
2944 int convy_int, convx_int;
2945 int l, m;
2946 const char *left, *right;
2948 union { GLuint b; GLfloat f; } swapbuf;
2950 if (widthin == widthout*2 && heightin == heightout*2) {
2951 halveImage_float(components, widthin, heightin,
2952 (const GLfloat *)datain, (GLfloat *)dataout,
2953 element_size, ysize, group_size, myswap_bytes);
2954 return;
2956 convy = (float) heightin/heightout;
2957 convx = (float) widthin/widthout;
2958 convy_int = floor(convy);
2959 convy_float = convy - convy_int;
2960 convx_int = floor(convx);
2961 convx_float = convx - convx_int;
2963 area = convx * convy;
2965 lowy_int = 0;
2966 lowy_float = 0;
2967 highy_int = convy_int;
2968 highy_float = convy_float;
2970 for (i = 0; i < heightout; i++) {
2971 /* Clamp here to be sure we don't read beyond input buffer. */
2972 if (highy_int >= heightin)
2973 highy_int = heightin - 1;
2974 lowx_int = 0;
2975 lowx_float = 0;
2976 highx_int = convx_int;
2977 highx_float = convx_float;
2979 for (j = 0; j < widthout; j++) {
2981 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2982 ** to (highx, highy) on input data into this pixel on output
2983 ** data.
2985 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2987 /* calculate the value for pixels in the 1st row */
2988 xindex = lowx_int*group_size;
2989 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2991 y_percent = 1-lowy_float;
2992 temp = (const char *)datain + xindex + lowy_int * ysize;
2993 percent = y_percent * (1-lowx_float);
2994 for (k = 0, temp_index = temp; k < components;
2995 k++, temp_index += element_size) {
2996 if (myswap_bytes) {
2997 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
2998 totals[k] += swapbuf.f * percent;
2999 } else {
3000 totals[k] += *(const GLfloat*)temp_index * percent;
3003 left = temp;
3004 for(l = lowx_int+1; l < highx_int; l++) {
3005 temp += group_size;
3006 for (k = 0, temp_index = temp; k < components;
3007 k++, temp_index += element_size) {
3008 if (myswap_bytes) {
3009 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3010 totals[k] += swapbuf.f * y_percent;
3011 } else {
3012 totals[k] += *(const GLfloat*)temp_index * y_percent;
3016 temp += group_size;
3017 right = temp;
3018 percent = y_percent * highx_float;
3019 for (k = 0, temp_index = temp; k < components;
3020 k++, temp_index += element_size) {
3021 if (myswap_bytes) {
3022 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3023 totals[k] += swapbuf.f * percent;
3024 } else {
3025 totals[k] += *(const GLfloat*)temp_index * percent;
3029 /* calculate the value for pixels in the last row */
3030 y_percent = highy_float;
3031 percent = y_percent * (1-lowx_float);
3032 temp = (const char *)datain + xindex + highy_int * ysize;
3033 for (k = 0, temp_index = temp; k < components;
3034 k++, temp_index += element_size) {
3035 if (myswap_bytes) {
3036 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3037 totals[k] += swapbuf.f * percent;
3038 } else {
3039 totals[k] += *(const GLfloat*)temp_index * percent;
3042 for(l = lowx_int+1; l < highx_int; l++) {
3043 temp += group_size;
3044 for (k = 0, temp_index = temp; k < components;
3045 k++, temp_index += element_size) {
3046 if (myswap_bytes) {
3047 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3048 totals[k] += swapbuf.f * y_percent;
3049 } else {
3050 totals[k] += *(const GLfloat*)temp_index * y_percent;
3054 temp += group_size;
3055 percent = y_percent * highx_float;
3056 for (k = 0, temp_index = temp; k < components;
3057 k++, temp_index += element_size) {
3058 if (myswap_bytes) {
3059 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3060 totals[k] += swapbuf.f * percent;
3061 } else {
3062 totals[k] += *(const GLfloat*)temp_index * percent;
3066 /* calculate the value for pixels in the 1st and last column */
3067 for(m = lowy_int+1; m < highy_int; m++) {
3068 left += ysize;
3069 right += ysize;
3070 for (k = 0; k < components;
3071 k++, left += element_size, right += element_size) {
3072 if (myswap_bytes) {
3073 swapbuf.b = __GLU_SWAP_4_BYTES(left);
3074 totals[k] += swapbuf.f * (1-lowx_float);
3075 swapbuf.b = __GLU_SWAP_4_BYTES(right);
3076 totals[k] += swapbuf.f * highx_float;
3077 } else {
3078 totals[k] += *(const GLfloat*)left * (1-lowx_float)
3079 + *(const GLfloat*)right * highx_float;
3083 } else if (highy_int > lowy_int) {
3084 x_percent = highx_float - lowx_float;
3085 percent = (1-lowy_float)*x_percent;
3086 temp = (const char *)datain + xindex + lowy_int*ysize;
3087 for (k = 0, temp_index = temp; k < components;
3088 k++, temp_index += element_size) {
3089 if (myswap_bytes) {
3090 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3091 totals[k] += swapbuf.f * percent;
3092 } else {
3093 totals[k] += *(const GLfloat*)temp_index * percent;
3096 for(m = lowy_int+1; m < highy_int; m++) {
3097 temp += ysize;
3098 for (k = 0, temp_index = temp; k < components;
3099 k++, temp_index += element_size) {
3100 if (myswap_bytes) {
3101 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3102 totals[k] += swapbuf.f * x_percent;
3103 } else {
3104 totals[k] += *(const GLfloat*)temp_index * x_percent;
3108 percent = x_percent * highy_float;
3109 temp += ysize;
3110 for (k = 0, temp_index = temp; k < components;
3111 k++, temp_index += element_size) {
3112 if (myswap_bytes) {
3113 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3114 totals[k] += swapbuf.f * percent;
3115 } else {
3116 totals[k] += *(const GLfloat*)temp_index * percent;
3119 } else if (highx_int > lowx_int) {
3120 y_percent = highy_float - lowy_float;
3121 percent = (1-lowx_float)*y_percent;
3123 temp = (const char *)datain + xindex + lowy_int*ysize;
3124 for (k = 0, temp_index = temp; k < components;
3125 k++, temp_index += element_size) {
3126 if (myswap_bytes) {
3127 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3128 totals[k] += swapbuf.f * percent;
3129 } else {
3130 totals[k] += *(const GLfloat*)temp_index * percent;
3133 for (l = lowx_int+1; l < highx_int; l++) {
3134 temp += group_size;
3135 for (k = 0, temp_index = temp; k < components;
3136 k++, temp_index += element_size) {
3137 if (myswap_bytes) {
3138 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3139 totals[k] += swapbuf.f * y_percent;
3140 } else {
3141 totals[k] += *(const GLfloat*)temp_index * y_percent;
3145 temp += group_size;
3146 percent = y_percent * highx_float;
3147 for (k = 0, temp_index = temp; k < components;
3148 k++, temp_index += element_size) {
3149 if (myswap_bytes) {
3150 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3151 totals[k] += swapbuf.f * percent;
3152 } else {
3153 totals[k] += *(const GLfloat*)temp_index * percent;
3156 } else {
3157 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
3158 temp = (const char *)datain + xindex + lowy_int * ysize;
3159 for (k = 0, temp_index = temp; k < components;
3160 k++, temp_index += element_size) {
3161 if (myswap_bytes) {
3162 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3163 totals[k] += swapbuf.f * percent;
3164 } else {
3165 totals[k] += *(const GLfloat*)temp_index * percent;
3170 /* this is for the pixels in the body */
3171 temp0 = (const char *)datain + xindex + group_size +
3172 (lowy_int+1)*ysize;
3173 for (m = lowy_int+1; m < highy_int; m++) {
3174 temp = temp0;
3175 for(l = lowx_int+1; l < highx_int; l++) {
3176 for (k = 0, temp_index = temp; k < components;
3177 k++, temp_index += element_size) {
3178 if (myswap_bytes) {
3179 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3180 totals[k] += swapbuf.f;
3181 } else {
3182 totals[k] += *(const GLfloat*)temp_index;
3185 temp += group_size;
3187 temp0 += ysize;
3190 outindex = (j + (i * widthout)) * components;
3191 for (k = 0; k < components; k++) {
3192 dataout[outindex + k] = totals[k]/area;
3193 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3195 lowx_int = highx_int;
3196 lowx_float = highx_float;
3197 highx_int += convx_int;
3198 highx_float += convx_float;
3199 if(highx_float > 1) {
3200 highx_float -= 1.0;
3201 highx_int++;
3204 lowy_int = highy_int;
3205 lowy_float = highy_float;
3206 highy_int += convy_int;
3207 highy_float += convy_float;
3208 if(highy_float > 1) {
3209 highy_float -= 1.0;
3210 highy_int++;
3215 static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
3217 if (!legalFormat(format) || !legalType(type)) {
3218 return GLU_INVALID_ENUM;
3220 if (format == GL_STENCIL_INDEX) {
3221 return GLU_INVALID_ENUM;
3224 if (!isLegalFormatForPackedPixelType(format, type)) {
3225 return GLU_INVALID_OPERATION;
3228 return 0;
3229 } /* checkMipmapArgs() */
3231 static GLboolean legalFormat(GLenum format)
3233 switch(format) {
3234 case GL_COLOR_INDEX:
3235 case GL_STENCIL_INDEX:
3236 case GL_DEPTH_COMPONENT:
3237 case GL_RED:
3238 case GL_GREEN:
3239 case GL_BLUE:
3240 case GL_ALPHA:
3241 case GL_RGB:
3242 case GL_RGBA:
3243 case GL_LUMINANCE:
3244 case GL_LUMINANCE_ALPHA:
3245 case GL_BGR:
3246 case GL_BGRA:
3247 return GL_TRUE;
3248 default:
3249 return GL_FALSE;
3254 static GLboolean legalType(GLenum type)
3256 switch(type) {
3257 case GL_BITMAP:
3258 case GL_BYTE:
3259 case GL_UNSIGNED_BYTE:
3260 case GL_SHORT:
3261 case GL_UNSIGNED_SHORT:
3262 case GL_INT:
3263 case GL_UNSIGNED_INT:
3264 case GL_FLOAT:
3265 case GL_UNSIGNED_BYTE_3_3_2:
3266 case GL_UNSIGNED_BYTE_2_3_3_REV:
3267 case GL_UNSIGNED_SHORT_5_6_5:
3268 case GL_UNSIGNED_SHORT_5_6_5_REV:
3269 case GL_UNSIGNED_SHORT_4_4_4_4:
3270 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3271 case GL_UNSIGNED_SHORT_5_5_5_1:
3272 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3273 case GL_UNSIGNED_INT_8_8_8_8:
3274 case GL_UNSIGNED_INT_8_8_8_8_REV:
3275 case GL_UNSIGNED_INT_10_10_10_2:
3276 case GL_UNSIGNED_INT_2_10_10_10_REV:
3277 return GL_TRUE;
3278 default:
3279 return GL_FALSE;
3283 /* */
3284 static GLboolean isTypePackedPixel(GLenum type)
3286 assert(legalType(type));
3288 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
3289 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
3290 type == GL_UNSIGNED_SHORT_5_6_5 ||
3291 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
3292 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3293 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3294 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3295 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3296 type == GL_UNSIGNED_INT_8_8_8_8 ||
3297 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3298 type == GL_UNSIGNED_INT_10_10_10_2 ||
3299 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
3300 return 1;
3302 else return 0;
3303 } /* isTypePackedPixel() */
3305 /* Determines if the packed pixel type is compatible with the format */
3306 static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
3308 /* if not a packed pixel type then return true */
3309 if (!isTypePackedPixel(type)) {
3310 return GL_TRUE;
3313 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3314 if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
3315 type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
3316 && format != GL_RGB)
3317 return GL_FALSE;
3319 /* 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 &
3320 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3322 if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3323 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3324 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3325 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3326 type == GL_UNSIGNED_INT_8_8_8_8 ||
3327 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3328 type == GL_UNSIGNED_INT_10_10_10_2 ||
3329 type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
3330 (format != GL_RGBA &&
3331 format != GL_BGRA)) {
3332 return GL_FALSE;
3335 return GL_TRUE;
3336 } /* isLegalFormatForPackedPixelType() */
3338 /* Given user requested texture size, determine if it fits. If it
3339 * doesn't then halve both sides and make the determination again
3340 * until it does fit (for IR only).
3341 * Note that proxy textures are not implemented in RE* even though
3342 * they advertise the texture extension.
3343 * Note that proxy textures are implemented but not according to spec in
3344 * IMPACT*.
3346 static void closestFit(GLenum target, GLint width, GLint height,
3347 GLint internalFormat, GLenum format, GLenum type,
3348 GLint *newWidth, GLint *newHeight)
3350 /* Use proxy textures if OpenGL version is >= 1.1 */
3351 if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
3353 GLint widthPowerOf2= nearestPower(width);
3354 GLint heightPowerOf2= nearestPower(height);
3355 GLint proxyWidth;
3357 do {
3358 /* compute level 1 width & height, clamping each at 1 */
3359 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
3360 widthPowerOf2 >> 1 :
3361 widthPowerOf2;
3362 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
3363 heightPowerOf2 >> 1 :
3364 heightPowerOf2;
3365 GLenum proxyTarget;
3366 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
3368 /* does width x height at level 1 & all their mipmaps fit? */
3369 if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
3370 proxyTarget = GL_PROXY_TEXTURE_2D;
3371 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3372 internalFormat,
3373 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3374 } else
3375 if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
3376 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
3377 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
3378 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
3379 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
3380 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
3381 proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3382 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3383 internalFormat,
3384 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3385 } else
3387 assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
3388 proxyTarget = GL_PROXY_TEXTURE_1D;
3389 glTexImage1D(proxyTarget, 1, /* must be non-zero */
3390 internalFormat,widthAtLevelOne,0,format,type,NULL);
3392 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
3393 /* does it fit??? */
3394 if (proxyWidth == 0) { /* nope, so try again with these sizes */
3395 if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
3396 /* An 1x1 texture couldn't fit for some reason, so
3397 * break out. This should never happen. But things
3398 * happen. The disadvantage with this if-statement is
3399 * that we will never be aware of when this happens
3400 * since it will silently branch out.
3402 goto noProxyTextures;
3404 widthPowerOf2= widthAtLevelOne;
3405 heightPowerOf2= heightAtLevelOne;
3407 /* else it does fit */
3408 } while (proxyWidth == 0);
3409 /* loop must terminate! */
3411 /* return the width & height at level 0 that fits */
3412 *newWidth= widthPowerOf2;
3413 *newHeight= heightPowerOf2;
3414 /*printf("Proxy Textures\n");*/
3415 } /* if gluCheckExtension() */
3416 else { /* no texture extension, so do this instead */
3417 GLint maxsize;
3419 noProxyTextures:
3421 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3422 /* clamp user's texture sizes to maximum sizes, if necessary */
3423 *newWidth = nearestPower(width);
3424 if (*newWidth > maxsize) *newWidth = maxsize;
3425 *newHeight = nearestPower(height);
3426 if (*newHeight > maxsize) *newHeight = maxsize;
3427 /*printf("NO proxy textures\n");*/
3429 } /* closestFit() */
3432 /***********************************************************************
3433 * gluScaleImage (GLU32.@)
3435 GLint WINAPI gluScaleImage( GLenum format, GLint widthin, GLint heightin, GLenum typein, const void *datain,
3436 GLint widthout, GLint heightout, GLenum typeout, void *dataout )
3438 int components;
3439 GLushort *beforeImage;
3440 GLushort *afterImage;
3441 PixelStorageModes psm;
3443 if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
3444 return 0;
3446 if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
3447 return GLU_INVALID_VALUE;
3449 if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
3450 return GLU_INVALID_ENUM;
3452 if (!isLegalFormatForPackedPixelType(format, typein)) {
3453 return GLU_INVALID_OPERATION;
3455 if (!isLegalFormatForPackedPixelType(format, typeout)) {
3456 return GLU_INVALID_OPERATION;
3458 beforeImage =
3459 HeapAlloc(GetProcessHeap(), 0, image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
3460 afterImage =
3461 HeapAlloc(GetProcessHeap(), 0, image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
3462 if (beforeImage == NULL || afterImage == NULL) {
3463 HeapFree(GetProcessHeap(), 0, beforeImage);
3464 HeapFree(GetProcessHeap(), 0, afterImage);
3465 return GLU_OUT_OF_MEMORY;
3468 retrieveStoreModes(&psm);
3469 fill_image(&psm,widthin, heightin, format, typein, is_index(format),
3470 datain, beforeImage);
3471 components = elements_per_group(format, 0);
3472 scale_internal(components, widthin, heightin, beforeImage,
3473 widthout, heightout, afterImage);
3474 empty_image(&psm,widthout, heightout, format, typeout,
3475 is_index(format), afterImage, dataout);
3476 HeapFree(GetProcessHeap(), 0, beforeImage);
3477 HeapFree(GetProcessHeap(), 0, afterImage);
3479 return 0;
3482 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
3483 GLsizei width,
3484 GLsizei widthPowerOf2,
3485 GLenum format, GLenum type,
3486 GLint userLevel, GLint baseLevel,GLint maxLevel,
3487 const void *data)
3489 GLint newwidth;
3490 GLint level, levels;
3491 GLushort *newImage;
3492 GLint newImage_width;
3493 GLushort *otherImage;
3494 GLushort *imageTemp;
3495 GLint memreq;
3496 GLint cmpts;
3497 PixelStorageModes psm;
3499 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3500 assert(width >= 1);
3502 otherImage = NULL;
3504 newwidth= widthPowerOf2;
3505 levels = computeLog(newwidth);
3507 levels+= userLevel;
3509 retrieveStoreModes(&psm);
3510 newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, 1, format, GL_UNSIGNED_SHORT));
3511 newImage_width = width;
3512 if (newImage == NULL) {
3513 return GLU_OUT_OF_MEMORY;
3515 fill_image(&psm,width, 1, format, type, is_index(format),
3516 data, newImage);
3517 cmpts = elements_per_group(format,type);
3518 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3519 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3520 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3521 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3523 ** If swap_bytes was set, swapping occurred in fill_image.
3525 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3527 for (level = userLevel; level <= levels; level++) {
3528 if (newImage_width == newwidth) {
3529 /* Use newImage for this level */
3530 if (baseLevel <= level && level <= maxLevel) {
3531 glTexImage1D(target, level, internalFormat, newImage_width,
3532 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3534 } else {
3535 if (otherImage == NULL) {
3536 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
3537 otherImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3538 if (otherImage == NULL) {
3539 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3540 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3541 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3542 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3543 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3544 HeapFree(GetProcessHeap(), 0, newImage);
3545 return GLU_OUT_OF_MEMORY;
3548 scale_internal(cmpts, newImage_width, 1, newImage,
3549 newwidth, 1, otherImage);
3550 /* Swap newImage and otherImage */
3551 imageTemp = otherImage;
3552 otherImage = newImage;
3553 newImage = imageTemp;
3555 newImage_width = newwidth;
3556 if (baseLevel <= level && level <= maxLevel) {
3557 glTexImage1D(target, level, internalFormat, newImage_width,
3558 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3561 if (newwidth > 1) newwidth /= 2;
3563 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3564 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3565 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3566 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3567 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3569 HeapFree(GetProcessHeap(), 0, newImage);
3570 HeapFree(GetProcessHeap(), 0, otherImage);
3571 return 0;
3575 /***********************************************************************
3576 * gluBuild1DMipmaps (GLU32.@)
3578 GLint WINAPI gluBuild1DMipmaps( GLenum target, GLint internalFormat, GLsizei width,
3579 GLenum format, GLenum type, const void *data )
3581 GLint widthPowerOf2;
3582 int levels;
3583 GLint dummy;
3585 int rc= checkMipmapArgs(internalFormat,format,type);
3586 if (rc != 0) return rc;
3588 if (width < 1) {
3589 return GLU_INVALID_VALUE;
3592 closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
3593 levels = computeLog(widthPowerOf2);
3595 return gluBuild1DMipmapLevelsCore(target,internalFormat,
3596 width,
3597 widthPowerOf2,
3598 format,type,0,0,levels,data);
3601 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
3602 GLint width, GLint height, GLenum format,
3603 GLenum type, const void *data)
3605 GLint newwidth, newheight;
3606 GLint level, levels;
3607 GLushort *newImage;
3608 GLint newImage_width;
3609 GLint newImage_height;
3610 GLushort *otherImage;
3611 GLushort *imageTemp;
3612 GLint memreq;
3613 GLint cmpts;
3614 PixelStorageModes psm;
3616 retrieveStoreModes(&psm);
3618 #if 0
3619 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3620 newwidth = nearestPower(width);
3621 if (newwidth > maxsize) newwidth = maxsize;
3622 newheight = nearestPower(height);
3623 if (newheight > maxsize) newheight = maxsize;
3624 #else
3625 closestFit(target,width,height,internalFormat,format,type,
3626 &newwidth,&newheight);
3627 #endif
3628 levels = computeLog(newwidth);
3629 level = computeLog(newheight);
3630 if (level > levels) levels=level;
3632 otherImage = NULL;
3633 newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, height, format, GL_UNSIGNED_SHORT));
3634 newImage_width = width;
3635 newImage_height = height;
3636 if (newImage == NULL) {
3637 return GLU_OUT_OF_MEMORY;
3640 fill_image(&psm,width, height, format, type, is_index(format),
3641 data, newImage);
3643 cmpts = elements_per_group(format,type);
3644 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3645 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3646 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3647 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3649 ** If swap_bytes was set, swapping occurred in fill_image.
3651 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3653 for (level = 0; level <= levels; level++) {
3654 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
3655 glTexImage2D(target, level, internalFormat, newImage_width,
3656 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3657 (void *) newImage);
3658 } else {
3659 if (otherImage == NULL) {
3660 memreq =
3661 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
3662 otherImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3663 if (otherImage == NULL) {
3664 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3665 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3666 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3667 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3668 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3669 HeapFree(GetProcessHeap(), 0, newImage);
3670 return GLU_OUT_OF_MEMORY;
3673 scale_internal(cmpts, newImage_width, newImage_height, newImage,
3674 newwidth, newheight, otherImage);
3675 /* Swap newImage and otherImage */
3676 imageTemp = otherImage;
3677 otherImage = newImage;
3678 newImage = imageTemp;
3680 newImage_width = newwidth;
3681 newImage_height = newheight;
3682 glTexImage2D(target, level, internalFormat, newImage_width,
3683 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3684 (void *) newImage);
3686 if (newwidth > 1) newwidth /= 2;
3687 if (newheight > 1) newheight /= 2;
3689 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3690 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3691 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3692 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3693 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3695 HeapFree(GetProcessHeap(), 0, newImage);
3696 HeapFree(GetProcessHeap(), 0, otherImage);
3697 return 0;
3700 /* To make swapping images less error prone */
3701 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3702 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3704 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3705 GLsizei width, GLsizei height,
3706 GLsizei widthPowerOf2,
3707 GLsizei heightPowerOf2,
3708 GLenum format, GLenum type,
3709 GLint userLevel,
3710 GLint baseLevel,GLint maxLevel,
3711 const void *data)
3713 GLint newwidth, newheight;
3714 GLint level, levels;
3715 const void *usersImage; /* passed from user. Don't touch! */
3716 void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3717 __GLU_INIT_SWAP_IMAGE;
3718 GLint memreq;
3719 GLint cmpts;
3721 GLint myswap_bytes, groups_per_line, element_size, group_size;
3722 GLint rowsize, padding;
3723 PixelStorageModes psm;
3725 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3726 assert(width >= 1 && height >= 1);
3728 if(type == GL_BITMAP) {
3729 return bitmapBuild2DMipmaps(target, internalFormat, width, height,
3730 format, type, data);
3733 srcImage = dstImage = NULL;
3735 newwidth= widthPowerOf2;
3736 newheight= heightPowerOf2;
3737 levels = computeLog(newwidth);
3738 level = computeLog(newheight);
3739 if (level > levels) levels=level;
3741 levels+= userLevel;
3743 retrieveStoreModes(&psm);
3744 myswap_bytes = psm.unpack_swap_bytes;
3745 cmpts = elements_per_group(format,type);
3746 if (psm.unpack_row_length > 0) {
3747 groups_per_line = psm.unpack_row_length;
3748 } else {
3749 groups_per_line = width;
3752 element_size = bytes_per_element(type);
3753 group_size = element_size * cmpts;
3754 if (element_size == 1) myswap_bytes = 0;
3756 rowsize = groups_per_line * group_size;
3757 padding = (rowsize % psm.unpack_alignment);
3758 if (padding) {
3759 rowsize += psm.unpack_alignment - padding;
3761 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3762 psm.unpack_skip_pixels * group_size;
3764 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3765 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3766 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3768 level = userLevel;
3770 /* already power-of-two square */
3771 if (width == newwidth && height == newheight) {
3772 /* Use usersImage for level userLevel */
3773 if (baseLevel <= level && level <= maxLevel) {
3774 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3775 glTexImage2D(target, level, internalFormat, width,
3776 height, 0, format, type,
3777 usersImage);
3779 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3780 if(levels == 0) { /* we're done. clean up and return */
3781 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3782 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3783 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3784 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3785 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3786 return 0;
3789 int nextWidth= newwidth/2;
3790 int nextHeight= newheight/2;
3792 /* clamp to 1 */
3793 if (nextWidth < 1) nextWidth= 1;
3794 if (nextHeight < 1) nextHeight= 1;
3795 memreq = image_size(nextWidth, nextHeight, format, type);
3798 switch(type) {
3799 case GL_UNSIGNED_BYTE:
3800 case GL_BYTE:
3801 case GL_UNSIGNED_SHORT:
3802 case GL_SHORT:
3803 case GL_UNSIGNED_INT:
3804 case GL_INT:
3805 case GL_FLOAT:
3806 case GL_UNSIGNED_BYTE_3_3_2:
3807 case GL_UNSIGNED_BYTE_2_3_3_REV:
3808 case GL_UNSIGNED_SHORT_5_6_5:
3809 case GL_UNSIGNED_SHORT_5_6_5_REV:
3810 case GL_UNSIGNED_SHORT_4_4_4_4:
3811 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3812 case GL_UNSIGNED_SHORT_5_5_5_1:
3813 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3814 case GL_UNSIGNED_INT_8_8_8_8:
3815 case GL_UNSIGNED_INT_8_8_8_8_REV:
3816 case GL_UNSIGNED_INT_10_10_10_2:
3817 case GL_UNSIGNED_INT_2_10_10_10_REV:
3818 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3819 break;
3820 default:
3821 return GLU_INVALID_ENUM;
3823 if (dstImage == NULL) {
3824 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3825 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3826 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3827 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3828 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3829 return GLU_OUT_OF_MEMORY;
3831 else
3832 switch(type) {
3833 case GL_UNSIGNED_BYTE:
3834 halveImage_ubyte(cmpts, width, height,
3835 (const GLubyte *)usersImage, (GLubyte *)dstImage,
3836 element_size, rowsize, group_size);
3837 break;
3838 case GL_BYTE:
3839 halveImage_byte(cmpts, width, height,
3840 (const GLbyte *)usersImage, (GLbyte *)dstImage,
3841 element_size, rowsize, group_size);
3842 break;
3843 case GL_UNSIGNED_SHORT:
3844 halveImage_ushort(cmpts, width, height,
3845 (const GLushort *)usersImage, (GLushort *)dstImage,
3846 element_size, rowsize, group_size, myswap_bytes);
3847 break;
3848 case GL_SHORT:
3849 halveImage_short(cmpts, width, height,
3850 (const GLshort *)usersImage, (GLshort *)dstImage,
3851 element_size, rowsize, group_size, myswap_bytes);
3852 break;
3853 case GL_UNSIGNED_INT:
3854 halveImage_uint(cmpts, width, height,
3855 (const GLuint *)usersImage, (GLuint *)dstImage,
3856 element_size, rowsize, group_size, myswap_bytes);
3857 break;
3858 case GL_INT:
3859 halveImage_int(cmpts, width, height,
3860 (const GLint *)usersImage, (GLint *)dstImage,
3861 element_size, rowsize, group_size, myswap_bytes);
3862 break;
3863 case GL_FLOAT:
3864 halveImage_float(cmpts, width, height,
3865 (const GLfloat *)usersImage, (GLfloat *)dstImage,
3866 element_size, rowsize, group_size, myswap_bytes);
3867 break;
3868 case GL_UNSIGNED_BYTE_3_3_2:
3869 assert(format == GL_RGB);
3870 halveImagePackedPixel(3,extract332,shove332,
3871 width,height,usersImage,dstImage,
3872 element_size,rowsize,myswap_bytes);
3873 break;
3874 case GL_UNSIGNED_BYTE_2_3_3_REV:
3875 assert(format == GL_RGB);
3876 halveImagePackedPixel(3,extract233rev,shove233rev,
3877 width,height,usersImage,dstImage,
3878 element_size,rowsize,myswap_bytes);
3879 break;
3880 case GL_UNSIGNED_SHORT_5_6_5:
3881 halveImagePackedPixel(3,extract565,shove565,
3882 width,height,usersImage,dstImage,
3883 element_size,rowsize,myswap_bytes);
3884 break;
3885 case GL_UNSIGNED_SHORT_5_6_5_REV:
3886 halveImagePackedPixel(3,extract565rev,shove565rev,
3887 width,height,usersImage,dstImage,
3888 element_size,rowsize,myswap_bytes);
3889 break;
3890 case GL_UNSIGNED_SHORT_4_4_4_4:
3891 halveImagePackedPixel(4,extract4444,shove4444,
3892 width,height,usersImage,dstImage,
3893 element_size,rowsize,myswap_bytes);
3894 break;
3895 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3896 halveImagePackedPixel(4,extract4444rev,shove4444rev,
3897 width,height,usersImage,dstImage,
3898 element_size,rowsize,myswap_bytes);
3899 break;
3900 case GL_UNSIGNED_SHORT_5_5_5_1:
3901 halveImagePackedPixel(4,extract5551,shove5551,
3902 width,height,usersImage,dstImage,
3903 element_size,rowsize,myswap_bytes);
3904 break;
3905 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3906 halveImagePackedPixel(4,extract1555rev,shove1555rev,
3907 width,height,usersImage,dstImage,
3908 element_size,rowsize,myswap_bytes);
3909 break;
3910 case GL_UNSIGNED_INT_8_8_8_8:
3911 halveImagePackedPixel(4,extract8888,shove8888,
3912 width,height,usersImage,dstImage,
3913 element_size,rowsize,myswap_bytes);
3914 break;
3915 case GL_UNSIGNED_INT_8_8_8_8_REV:
3916 halveImagePackedPixel(4,extract8888rev,shove8888rev,
3917 width,height,usersImage,dstImage,
3918 element_size,rowsize,myswap_bytes);
3919 break;
3920 case GL_UNSIGNED_INT_10_10_10_2:
3921 halveImagePackedPixel(4,extract1010102,shove1010102,
3922 width,height,usersImage,dstImage,
3923 element_size,rowsize,myswap_bytes);
3924 break;
3925 case GL_UNSIGNED_INT_2_10_10_10_REV:
3926 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
3927 width,height,usersImage,dstImage,
3928 element_size,rowsize,myswap_bytes);
3929 break;
3930 default:
3931 assert(0);
3932 break;
3934 newwidth = width/2;
3935 newheight = height/2;
3936 /* clamp to 1 */
3937 if (newwidth < 1) newwidth= 1;
3938 if (newheight < 1) newheight= 1;
3940 myswap_bytes = 0;
3941 rowsize = newwidth * group_size;
3942 memreq = image_size(newwidth, newheight, format, type);
3943 /* Swap srcImage and dstImage */
3944 __GLU_SWAP_IMAGE(srcImage,dstImage);
3945 switch(type) {
3946 case GL_UNSIGNED_BYTE:
3947 case GL_BYTE:
3948 case GL_UNSIGNED_SHORT:
3949 case GL_SHORT:
3950 case GL_UNSIGNED_INT:
3951 case GL_INT:
3952 case GL_FLOAT:
3953 case GL_UNSIGNED_BYTE_3_3_2:
3954 case GL_UNSIGNED_BYTE_2_3_3_REV:
3955 case GL_UNSIGNED_SHORT_5_6_5:
3956 case GL_UNSIGNED_SHORT_5_6_5_REV:
3957 case GL_UNSIGNED_SHORT_4_4_4_4:
3958 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3959 case GL_UNSIGNED_SHORT_5_5_5_1:
3960 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3961 case GL_UNSIGNED_INT_8_8_8_8:
3962 case GL_UNSIGNED_INT_8_8_8_8_REV:
3963 case GL_UNSIGNED_INT_10_10_10_2:
3964 case GL_UNSIGNED_INT_2_10_10_10_REV:
3965 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
3966 break;
3967 default:
3968 return GLU_INVALID_ENUM;
3970 if (dstImage == NULL) {
3971 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3972 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3973 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3974 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3975 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3976 HeapFree(GetProcessHeap(), 0, srcImage);
3977 return GLU_OUT_OF_MEMORY;
3979 /* level userLevel+1 is in srcImage; level userLevel already saved */
3980 level = userLevel+1;
3981 } else { /* user's image is *not* nice power-of-2 sized square */
3982 memreq = image_size(newwidth, newheight, format, type);
3983 switch(type) {
3984 case GL_UNSIGNED_BYTE:
3985 case GL_BYTE:
3986 case GL_UNSIGNED_SHORT:
3987 case GL_SHORT:
3988 case GL_UNSIGNED_INT:
3989 case GL_INT:
3990 case GL_FLOAT:
3991 case GL_UNSIGNED_BYTE_3_3_2:
3992 case GL_UNSIGNED_BYTE_2_3_3_REV:
3993 case GL_UNSIGNED_SHORT_5_6_5:
3994 case GL_UNSIGNED_SHORT_5_6_5_REV:
3995 case GL_UNSIGNED_SHORT_4_4_4_4:
3996 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3997 case GL_UNSIGNED_SHORT_5_5_5_1:
3998 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3999 case GL_UNSIGNED_INT_8_8_8_8:
4000 case GL_UNSIGNED_INT_8_8_8_8_REV:
4001 case GL_UNSIGNED_INT_10_10_10_2:
4002 case GL_UNSIGNED_INT_2_10_10_10_REV:
4003 dstImage = HeapAlloc(GetProcessHeap(), 0, memreq);
4004 break;
4005 default:
4006 return GLU_INVALID_ENUM;
4009 if (dstImage == NULL) {
4010 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4011 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4012 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4013 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4014 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4015 return GLU_OUT_OF_MEMORY;
4018 switch(type) {
4019 case GL_UNSIGNED_BYTE:
4020 scale_internal_ubyte(cmpts, width, height,
4021 (const GLubyte *)usersImage, newwidth, newheight,
4022 (GLubyte *)dstImage, element_size,
4023 rowsize, group_size);
4024 break;
4025 case GL_BYTE:
4026 scale_internal_byte(cmpts, width, height,
4027 (const GLbyte *)usersImage, newwidth, newheight,
4028 (GLbyte *)dstImage, element_size,
4029 rowsize, group_size);
4030 break;
4031 case GL_UNSIGNED_SHORT:
4032 scale_internal_ushort(cmpts, width, height,
4033 (const GLushort *)usersImage, newwidth, newheight,
4034 (GLushort *)dstImage, element_size,
4035 rowsize, group_size, myswap_bytes);
4036 break;
4037 case GL_SHORT:
4038 scale_internal_short(cmpts, width, height,
4039 (const GLshort *)usersImage, newwidth, newheight,
4040 (GLshort *)dstImage, element_size,
4041 rowsize, group_size, myswap_bytes);
4042 break;
4043 case GL_UNSIGNED_INT:
4044 scale_internal_uint(cmpts, width, height,
4045 (const GLuint *)usersImage, newwidth, newheight,
4046 (GLuint *)dstImage, element_size,
4047 rowsize, group_size, myswap_bytes);
4048 break;
4049 case GL_INT:
4050 scale_internal_int(cmpts, width, height,
4051 (const GLint *)usersImage, newwidth, newheight,
4052 (GLint *)dstImage, element_size,
4053 rowsize, group_size, myswap_bytes);
4054 break;
4055 case GL_FLOAT:
4056 scale_internal_float(cmpts, width, height,
4057 (const GLfloat *)usersImage, newwidth, newheight,
4058 (GLfloat *)dstImage, element_size,
4059 rowsize, group_size, myswap_bytes);
4060 break;
4061 case GL_UNSIGNED_BYTE_3_3_2:
4062 scaleInternalPackedPixel(3,extract332,shove332,
4063 width, height,usersImage,
4064 newwidth,newheight,(void *)dstImage,
4065 element_size,rowsize,myswap_bytes);
4066 break;
4067 case GL_UNSIGNED_BYTE_2_3_3_REV:
4068 scaleInternalPackedPixel(3,extract233rev,shove233rev,
4069 width, height,usersImage,
4070 newwidth,newheight,(void *)dstImage,
4071 element_size,rowsize,myswap_bytes);
4072 break;
4073 case GL_UNSIGNED_SHORT_5_6_5:
4074 scaleInternalPackedPixel(3,extract565,shove565,
4075 width, height,usersImage,
4076 newwidth,newheight,(void *)dstImage,
4077 element_size,rowsize,myswap_bytes);
4078 break;
4079 case GL_UNSIGNED_SHORT_5_6_5_REV:
4080 scaleInternalPackedPixel(3,extract565rev,shove565rev,
4081 width, height,usersImage,
4082 newwidth,newheight,(void *)dstImage,
4083 element_size,rowsize,myswap_bytes);
4084 break;
4085 case GL_UNSIGNED_SHORT_4_4_4_4:
4086 scaleInternalPackedPixel(4,extract4444,shove4444,
4087 width, height,usersImage,
4088 newwidth,newheight,(void *)dstImage,
4089 element_size,rowsize,myswap_bytes);
4090 break;
4091 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4092 scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4093 width, height,usersImage,
4094 newwidth,newheight,(void *)dstImage,
4095 element_size,rowsize,myswap_bytes);
4096 break;
4097 case GL_UNSIGNED_SHORT_5_5_5_1:
4098 scaleInternalPackedPixel(4,extract5551,shove5551,
4099 width, height,usersImage,
4100 newwidth,newheight,(void *)dstImage,
4101 element_size,rowsize,myswap_bytes);
4102 break;
4103 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4104 scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4105 width, height,usersImage,
4106 newwidth,newheight,(void *)dstImage,
4107 element_size,rowsize,myswap_bytes);
4108 break;
4109 case GL_UNSIGNED_INT_8_8_8_8:
4110 scaleInternalPackedPixel(4,extract8888,shove8888,
4111 width, height,usersImage,
4112 newwidth,newheight,(void *)dstImage,
4113 element_size,rowsize,myswap_bytes);
4114 break;
4115 case GL_UNSIGNED_INT_8_8_8_8_REV:
4116 scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4117 width, height,usersImage,
4118 newwidth,newheight,(void *)dstImage,
4119 element_size,rowsize,myswap_bytes);
4120 break;
4121 case GL_UNSIGNED_INT_10_10_10_2:
4122 scaleInternalPackedPixel(4,extract1010102,shove1010102,
4123 width, height,usersImage,
4124 newwidth,newheight,(void *)dstImage,
4125 element_size,rowsize,myswap_bytes);
4126 break;
4127 case GL_UNSIGNED_INT_2_10_10_10_REV:
4128 scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
4129 width, height,usersImage,
4130 newwidth,newheight,(void *)dstImage,
4131 element_size,rowsize,myswap_bytes);
4132 break;
4133 default:
4134 assert(0);
4135 break;
4137 myswap_bytes = 0;
4138 rowsize = newwidth * group_size;
4139 /* Swap dstImage and srcImage */
4140 __GLU_SWAP_IMAGE(srcImage,dstImage);
4142 if(levels != 0) { /* use as little memory as possible */
4144 int nextWidth= newwidth/2;
4145 int nextHeight= newheight/2;
4146 if (nextWidth < 1) nextWidth= 1;
4147 if (nextHeight < 1) nextHeight= 1;
4149 memreq = image_size(nextWidth, nextHeight, format, type);
4152 switch(type) {
4153 case GL_UNSIGNED_BYTE:
4154 case GL_BYTE:
4155 case GL_UNSIGNED_SHORT:
4156 case GL_SHORT:
4157 case GL_UNSIGNED_INT:
4158 case GL_INT:
4159 case GL_FLOAT:
4160 case GL_UNSIGNED_BYTE_3_3_2:
4161 case GL_UNSIGNED_BYTE_2_3_3_REV:
4162 case GL_UNSIGNED_SHORT_5_6_5:
4163 case GL_UNSIGNED_SHORT_5_6_5_REV:
4164 case GL_UNSIGNED_SHORT_4_4_4_4:
4165 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4166 case GL_UNSIGNED_SHORT_5_5_5_1:
4167 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4168 case GL_UNSIGNED_INT_8_8_8_8:
4169 case GL_UNSIGNED_INT_8_8_8_8_REV:
4170 case GL_UNSIGNED_INT_10_10_10_2:
4171 case GL_UNSIGNED_INT_2_10_10_10_REV:
4172 dstImage = (GLuint *)HeapAlloc(GetProcessHeap(), 0, memreq);
4173 break;
4174 default:
4175 return GLU_INVALID_ENUM;
4177 if (dstImage == NULL) {
4178 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4179 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4180 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4181 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4182 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4183 HeapFree(GetProcessHeap(), 0, srcImage);
4184 return GLU_OUT_OF_MEMORY;
4187 /* level userLevel is in srcImage; nothing saved yet */
4188 level = userLevel;
4191 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4192 if (baseLevel <= level && level <= maxLevel) {
4193 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4194 format, type, (void *)srcImage);
4197 level++; /* update current level for the loop */
4198 for (; level <= levels; level++) {
4199 switch(type) {
4200 case GL_UNSIGNED_BYTE:
4201 halveImage_ubyte(cmpts, newwidth, newheight,
4202 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4203 rowsize, group_size);
4204 break;
4205 case GL_BYTE:
4206 halveImage_byte(cmpts, newwidth, newheight,
4207 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4208 rowsize, group_size);
4209 break;
4210 case GL_UNSIGNED_SHORT:
4211 halveImage_ushort(cmpts, newwidth, newheight,
4212 (GLushort *)srcImage, (GLushort *)dstImage, element_size,
4213 rowsize, group_size, myswap_bytes);
4214 break;
4215 case GL_SHORT:
4216 halveImage_short(cmpts, newwidth, newheight,
4217 (GLshort *)srcImage, (GLshort *)dstImage, element_size,
4218 rowsize, group_size, myswap_bytes);
4219 break;
4220 case GL_UNSIGNED_INT:
4221 halveImage_uint(cmpts, newwidth, newheight,
4222 (GLuint *)srcImage, (GLuint *)dstImage, element_size,
4223 rowsize, group_size, myswap_bytes);
4224 break;
4225 case GL_INT:
4226 halveImage_int(cmpts, newwidth, newheight,
4227 (GLint *)srcImage, (GLint *)dstImage, element_size,
4228 rowsize, group_size, myswap_bytes);
4229 break;
4230 case GL_FLOAT:
4231 halveImage_float(cmpts, newwidth, newheight,
4232 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4233 rowsize, group_size, myswap_bytes);
4234 break;
4235 case GL_UNSIGNED_BYTE_3_3_2:
4236 halveImagePackedPixel(3,extract332,shove332,
4237 newwidth,newheight,
4238 srcImage,dstImage,element_size,rowsize,
4239 myswap_bytes);
4240 break;
4241 case GL_UNSIGNED_BYTE_2_3_3_REV:
4242 halveImagePackedPixel(3,extract233rev,shove233rev,
4243 newwidth,newheight,
4244 srcImage,dstImage,element_size,rowsize,
4245 myswap_bytes);
4246 break;
4247 case GL_UNSIGNED_SHORT_5_6_5:
4248 halveImagePackedPixel(3,extract565,shove565,
4249 newwidth,newheight,
4250 srcImage,dstImage,element_size,rowsize,
4251 myswap_bytes);
4252 break;
4253 case GL_UNSIGNED_SHORT_5_6_5_REV:
4254 halveImagePackedPixel(3,extract565rev,shove565rev,
4255 newwidth,newheight,
4256 srcImage,dstImage,element_size,rowsize,
4257 myswap_bytes);
4258 break;
4259 case GL_UNSIGNED_SHORT_4_4_4_4:
4260 halveImagePackedPixel(4,extract4444,shove4444,
4261 newwidth,newheight,
4262 srcImage,dstImage,element_size,rowsize,
4263 myswap_bytes);
4264 break;
4265 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4266 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4267 newwidth,newheight,
4268 srcImage,dstImage,element_size,rowsize,
4269 myswap_bytes);
4270 break;
4271 case GL_UNSIGNED_SHORT_5_5_5_1:
4272 halveImagePackedPixel(4,extract5551,shove5551,
4273 newwidth,newheight,
4274 srcImage,dstImage,element_size,rowsize,
4275 myswap_bytes);
4276 break;
4277 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4278 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4279 newwidth,newheight,
4280 srcImage,dstImage,element_size,rowsize,
4281 myswap_bytes);
4282 break;
4283 case GL_UNSIGNED_INT_8_8_8_8:
4284 halveImagePackedPixel(4,extract8888,shove8888,
4285 newwidth,newheight,
4286 srcImage,dstImage,element_size,rowsize,
4287 myswap_bytes);
4288 break;
4289 case GL_UNSIGNED_INT_8_8_8_8_REV:
4290 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4291 newwidth,newheight,
4292 srcImage,dstImage,element_size,rowsize,
4293 myswap_bytes);
4294 break;
4295 case GL_UNSIGNED_INT_10_10_10_2:
4296 halveImagePackedPixel(4,extract1010102,shove1010102,
4297 newwidth,newheight,
4298 srcImage,dstImage,element_size,rowsize,
4299 myswap_bytes);
4300 break;
4301 case GL_UNSIGNED_INT_2_10_10_10_REV:
4302 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4303 newwidth,newheight,
4304 srcImage,dstImage,element_size,rowsize,
4305 myswap_bytes);
4306 break;
4307 default:
4308 assert(0);
4309 break;
4312 __GLU_SWAP_IMAGE(srcImage,dstImage);
4314 if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4315 if (newheight > 1) newheight /= 2;
4317 /* compute amount to pad per row, if any */
4318 int rowPad= rowsize % psm.unpack_alignment;
4320 /* should row be padded? */
4321 if (rowPad == 0) { /* nope, row should not be padded */
4322 /* call tex image with srcImage untouched since it's not padded */
4323 if (baseLevel <= level && level <= maxLevel) {
4324 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4325 format, type, (void *) srcImage);
4328 else { /* yes, row should be padded */
4329 /* compute length of new row in bytes, including padding */
4330 int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4331 int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4333 /* allocate new image for mipmap of size newRowLength x newheight */
4334 void *newMipmapImage= HeapAlloc(GetProcessHeap(), 0, (size_t) (newRowLength*newheight));
4335 if (newMipmapImage == NULL) {
4336 /* out of memory so return */
4337 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4338 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4339 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4340 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4341 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4342 return GLU_OUT_OF_MEMORY;
4345 /* copy image from srcImage into newMipmapImage by rows */
4346 for (ii= 0,
4347 dstTrav= (unsigned char *) newMipmapImage,
4348 srcTrav= (unsigned char *) srcImage;
4349 ii< newheight;
4350 ii++,
4351 dstTrav+= newRowLength, /* make sure the correct distance... */
4352 srcTrav+= rowsize) { /* ...is skipped */
4353 memcpy(dstTrav,srcTrav,rowsize);
4354 /* note that the pad bytes are not visited and will contain
4355 * garbage, which is ok.
4359 /* ...and use this new image for mipmapping instead */
4360 if (baseLevel <= level && level <= maxLevel) {
4361 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4362 format, type, newMipmapImage);
4364 HeapFree(GetProcessHeap(), 0, newMipmapImage); /* don't forget to free it! */
4365 } /* else */
4367 } /* for level */
4368 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4369 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4370 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4371 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4372 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4374 HeapFree(GetProcessHeap(), 0, srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4375 HeapFree(GetProcessHeap(), 0, dstImage);
4376 return 0;
4377 } /* gluBuild2DMipmapLevelsCore() */
4380 /***********************************************************************
4381 * gluBuild2DMipmaps (GLU32.@)
4383 GLint WINAPI gluBuild2DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height,
4384 GLenum format, GLenum type, const void *data )
4386 GLint widthPowerOf2, heightPowerOf2;
4387 int level, levels;
4389 int rc= checkMipmapArgs(internalFormat,format,type);
4390 if (rc != 0) return rc;
4392 if (width < 1 || height < 1) {
4393 return GLU_INVALID_VALUE;
4396 closestFit(target,width,height,internalFormat,format,type,
4397 &widthPowerOf2,&heightPowerOf2);
4399 levels = computeLog(widthPowerOf2);
4400 level = computeLog(heightPowerOf2);
4401 if (level > levels) levels=level;
4403 return gluBuild2DMipmapLevelsCore(target,internalFormat,
4404 width, height,
4405 widthPowerOf2,heightPowerOf2,
4406 format,type,
4407 0,0,levels,data);
4408 } /* gluBuild2DMipmaps() */
4412 * Utility Routines
4414 static GLint elements_per_group(GLenum format, GLenum type)
4417 * Return the number of elements per group of a specified format
4420 /* If the type is packedpixels then answer is 1 (ignore format) */
4421 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4422 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4423 type == GL_UNSIGNED_SHORT_5_6_5 ||
4424 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4425 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4426 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4427 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
4428 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
4429 type == GL_UNSIGNED_INT_8_8_8_8 ||
4430 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4431 type == GL_UNSIGNED_INT_10_10_10_2 ||
4432 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
4433 return 1;
4436 /* Types are not packed pixels, so get elements per group */
4437 switch(format) {
4438 case GL_RGB:
4439 case GL_BGR:
4440 return 3;
4441 case GL_LUMINANCE_ALPHA:
4442 return 2;
4443 case GL_RGBA:
4444 case GL_BGRA:
4445 return 4;
4446 default:
4447 return 1;
4451 static GLfloat bytes_per_element(GLenum type)
4454 * Return the number of bytes per element, based on the element type
4456 switch(type) {
4457 case GL_BITMAP:
4458 return 1.0 / 8.0;
4459 case GL_UNSIGNED_SHORT:
4460 return(sizeof(GLushort));
4461 case GL_SHORT:
4462 return(sizeof(GLshort));
4463 case GL_UNSIGNED_BYTE:
4464 return(sizeof(GLubyte));
4465 case GL_BYTE:
4466 return(sizeof(GLbyte));
4467 case GL_INT:
4468 return(sizeof(GLint));
4469 case GL_UNSIGNED_INT:
4470 return(sizeof(GLuint));
4471 case GL_FLOAT:
4472 return(sizeof(GLfloat));
4473 case GL_UNSIGNED_BYTE_3_3_2:
4474 case GL_UNSIGNED_BYTE_2_3_3_REV:
4475 return(sizeof(GLubyte));
4476 case GL_UNSIGNED_SHORT_5_6_5:
4477 case GL_UNSIGNED_SHORT_5_6_5_REV:
4478 case GL_UNSIGNED_SHORT_4_4_4_4:
4479 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4480 case GL_UNSIGNED_SHORT_5_5_5_1:
4481 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4482 return(sizeof(GLushort));
4483 case GL_UNSIGNED_INT_8_8_8_8:
4484 case GL_UNSIGNED_INT_8_8_8_8_REV:
4485 case GL_UNSIGNED_INT_10_10_10_2:
4486 case GL_UNSIGNED_INT_2_10_10_10_REV:
4487 return(sizeof(GLuint));
4488 default:
4489 return 4;
4493 static GLint is_index(GLenum format)
4495 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4499 ** Compute memory required for internal packed array of data of given type
4500 ** and format.
4502 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4504 int bytes_per_row;
4505 int components;
4507 assert(width > 0);
4508 assert(height > 0);
4509 components = elements_per_group(format,type);
4510 if (type == GL_BITMAP) {
4511 bytes_per_row = (width + 7) / 8;
4512 } else {
4513 bytes_per_row = bytes_per_element(type) * width;
4515 return bytes_per_row * height * components;
4519 ** Extract array from user's data applying all pixel store modes.
4520 ** The internal format used is an array of unsigned shorts.
4522 static void fill_image(const PixelStorageModes *psm,
4523 GLint width, GLint height, GLenum format,
4524 GLenum type, GLboolean index_format,
4525 const void *userdata, GLushort *newimage)
4527 GLint components;
4528 GLint element_size;
4529 GLint rowsize;
4530 GLint padding;
4531 GLint groups_per_line;
4532 GLint group_size;
4533 GLint elements_per_line;
4534 const GLubyte *start;
4535 const GLubyte *iter;
4536 GLushort *iter2;
4537 GLint i, j, k;
4538 GLint myswap_bytes;
4540 myswap_bytes = psm->unpack_swap_bytes;
4541 components = elements_per_group(format,type);
4542 if (psm->unpack_row_length > 0) {
4543 groups_per_line = psm->unpack_row_length;
4544 } else {
4545 groups_per_line = width;
4548 /* All formats except GL_BITMAP fall out trivially */
4549 if (type == GL_BITMAP) {
4550 GLint bit_offset;
4551 GLint current_bit;
4553 rowsize = (groups_per_line * components + 7) / 8;
4554 padding = (rowsize % psm->unpack_alignment);
4555 if (padding) {
4556 rowsize += psm->unpack_alignment - padding;
4558 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4559 (psm->unpack_skip_pixels * components / 8);
4560 elements_per_line = width * components;
4561 iter2 = newimage;
4562 for (i = 0; i < height; i++) {
4563 iter = start;
4564 bit_offset = (psm->unpack_skip_pixels * components) % 8;
4565 for (j = 0; j < elements_per_line; j++) {
4566 /* Retrieve bit */
4567 if (psm->unpack_lsb_first) {
4568 current_bit = iter[0] & (1 << bit_offset);
4569 } else {
4570 current_bit = iter[0] & (1 << (7 - bit_offset));
4572 if (current_bit) {
4573 if (index_format) {
4574 *iter2 = 1;
4575 } else {
4576 *iter2 = 65535;
4578 } else {
4579 *iter2 = 0;
4581 bit_offset++;
4582 if (bit_offset == 8) {
4583 bit_offset = 0;
4584 iter++;
4586 iter2++;
4588 start += rowsize;
4590 } else {
4591 element_size = bytes_per_element(type);
4592 group_size = element_size * components;
4593 if (element_size == 1) myswap_bytes = 0;
4595 rowsize = groups_per_line * group_size;
4596 padding = (rowsize % psm->unpack_alignment);
4597 if (padding) {
4598 rowsize += psm->unpack_alignment - padding;
4600 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4601 psm->unpack_skip_pixels * group_size;
4602 elements_per_line = width * components;
4604 iter2 = newimage;
4605 for (i = 0; i < height; i++) {
4606 iter = start;
4607 for (j = 0; j < elements_per_line; j++) {
4608 Type_Widget widget;
4609 float extractComponents[4];
4611 switch(type) {
4612 case GL_UNSIGNED_BYTE_3_3_2:
4613 extract332(0,iter,extractComponents);
4614 for (k = 0; k < 3; k++) {
4615 *iter2++ = (GLushort)(extractComponents[k]*65535);
4617 break;
4618 case GL_UNSIGNED_BYTE_2_3_3_REV:
4619 extract233rev(0,iter,extractComponents);
4620 for (k = 0; k < 3; k++) {
4621 *iter2++ = (GLushort)(extractComponents[k]*65535);
4623 break;
4624 case GL_UNSIGNED_BYTE:
4625 if (index_format) {
4626 *iter2++ = *iter;
4627 } else {
4628 *iter2++ = (*iter) * 257;
4630 break;
4631 case GL_BYTE:
4632 if (index_format) {
4633 *iter2++ = *((const GLbyte *) iter);
4634 } else {
4635 /* rough approx */
4636 *iter2++ = (*((const GLbyte *) iter)) * 516;
4638 break;
4639 case GL_UNSIGNED_SHORT_5_6_5:
4640 extract565(myswap_bytes,iter,extractComponents);
4641 for (k = 0; k < 3; k++) {
4642 *iter2++ = (GLushort)(extractComponents[k]*65535);
4644 break;
4645 case GL_UNSIGNED_SHORT_5_6_5_REV:
4646 extract565rev(myswap_bytes,iter,extractComponents);
4647 for (k = 0; k < 3; k++) {
4648 *iter2++ = (GLushort)(extractComponents[k]*65535);
4650 break;
4651 case GL_UNSIGNED_SHORT_4_4_4_4:
4652 extract4444(myswap_bytes,iter,extractComponents);
4653 for (k = 0; k < 4; k++) {
4654 *iter2++ = (GLushort)(extractComponents[k]*65535);
4656 break;
4657 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4658 extract4444rev(myswap_bytes,iter,extractComponents);
4659 for (k = 0; k < 4; k++) {
4660 *iter2++ = (GLushort)(extractComponents[k]*65535);
4662 break;
4663 case GL_UNSIGNED_SHORT_5_5_5_1:
4664 extract5551(myswap_bytes,iter,extractComponents);
4665 for (k = 0; k < 4; k++) {
4666 *iter2++ = (GLushort)(extractComponents[k]*65535);
4668 break;
4669 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4670 extract1555rev(myswap_bytes,iter,extractComponents);
4671 for (k = 0; k < 4; k++) {
4672 *iter2++ = (GLushort)(extractComponents[k]*65535);
4674 break;
4675 case GL_UNSIGNED_SHORT:
4676 case GL_SHORT:
4677 if (myswap_bytes) {
4678 widget.ub[0] = iter[1];
4679 widget.ub[1] = iter[0];
4680 } else {
4681 widget.ub[0] = iter[0];
4682 widget.ub[1] = iter[1];
4684 if (type == GL_SHORT) {
4685 if (index_format) {
4686 *iter2++ = widget.s[0];
4687 } else {
4688 /* rough approx */
4689 *iter2++ = widget.s[0]*2;
4691 } else {
4692 *iter2++ = widget.us[0];
4694 break;
4695 case GL_UNSIGNED_INT_8_8_8_8:
4696 extract8888(myswap_bytes,iter,extractComponents);
4697 for (k = 0; k < 4; k++) {
4698 *iter2++ = (GLushort)(extractComponents[k]*65535);
4700 break;
4701 case GL_UNSIGNED_INT_8_8_8_8_REV:
4702 extract8888rev(myswap_bytes,iter,extractComponents);
4703 for (k = 0; k < 4; k++) {
4704 *iter2++ = (GLushort)(extractComponents[k]*65535);
4706 break;
4707 case GL_UNSIGNED_INT_10_10_10_2:
4708 extract1010102(myswap_bytes,iter,extractComponents);
4709 for (k = 0; k < 4; k++) {
4710 *iter2++ = (GLushort)(extractComponents[k]*65535);
4712 break;
4713 case GL_UNSIGNED_INT_2_10_10_10_REV:
4714 extract2101010rev(myswap_bytes,iter,extractComponents);
4715 for (k = 0; k < 4; k++) {
4716 *iter2++ = (GLushort)(extractComponents[k]*65535);
4718 break;
4719 case GL_INT:
4720 case GL_UNSIGNED_INT:
4721 case GL_FLOAT:
4722 if (myswap_bytes) {
4723 widget.ub[0] = iter[3];
4724 widget.ub[1] = iter[2];
4725 widget.ub[2] = iter[1];
4726 widget.ub[3] = iter[0];
4727 } else {
4728 widget.ub[0] = iter[0];
4729 widget.ub[1] = iter[1];
4730 widget.ub[2] = iter[2];
4731 widget.ub[3] = iter[3];
4733 if (type == GL_FLOAT) {
4734 if (index_format) {
4735 *iter2++ = widget.f;
4736 } else {
4737 *iter2++ = 65535 * widget.f;
4739 } else if (type == GL_UNSIGNED_INT) {
4740 if (index_format) {
4741 *iter2++ = widget.ui;
4742 } else {
4743 *iter2++ = widget.ui >> 16;
4745 } else {
4746 if (index_format) {
4747 *iter2++ = widget.i;
4748 } else {
4749 *iter2++ = widget.i >> 15;
4752 break;
4754 iter += element_size;
4755 } /* for j */
4756 start += rowsize;
4757 #if 1
4758 /* want 'iter' pointing at start, not within, row for assertion
4759 * purposes
4761 iter= start;
4762 #endif
4763 } /* for i */
4765 /* iterators should be one byte past end */
4766 if (!isTypePackedPixel(type)) {
4767 assert(iter2 == &newimage[width*height*components]);
4769 else {
4770 assert(iter2 == &newimage[width*height*
4771 elements_per_group(format,0)]);
4773 assert( iter == &((const GLubyte *)userdata)[rowsize*height +
4774 psm->unpack_skip_rows * rowsize +
4775 psm->unpack_skip_pixels * group_size] );
4777 } /* else */
4778 } /* fill_image() */
4781 ** Insert array into user's data applying all pixel store modes.
4782 ** The internal format is an array of unsigned shorts.
4783 ** empty_image() because it is the opposite of fill_image().
4785 static void empty_image(const PixelStorageModes *psm,
4786 GLint width, GLint height, GLenum format,
4787 GLenum type, GLboolean index_format,
4788 const GLushort *oldimage, void *userdata)
4790 GLint components;
4791 GLint element_size;
4792 GLint rowsize;
4793 GLint padding;
4794 GLint groups_per_line;
4795 GLint group_size;
4796 GLint elements_per_line;
4797 GLubyte *start;
4798 GLubyte *iter;
4799 const GLushort *iter2;
4800 GLint i, j, k;
4801 GLint myswap_bytes;
4803 myswap_bytes = psm->pack_swap_bytes;
4804 components = elements_per_group(format,type);
4805 if (psm->pack_row_length > 0) {
4806 groups_per_line = psm->pack_row_length;
4807 } else {
4808 groups_per_line = width;
4811 /* All formats except GL_BITMAP fall out trivially */
4812 if (type == GL_BITMAP) {
4813 GLint bit_offset;
4814 GLint current_bit;
4816 rowsize = (groups_per_line * components + 7) / 8;
4817 padding = (rowsize % psm->pack_alignment);
4818 if (padding) {
4819 rowsize += psm->pack_alignment - padding;
4821 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
4822 (psm->pack_skip_pixels * components / 8);
4823 elements_per_line = width * components;
4824 iter2 = oldimage;
4825 for (i = 0; i < height; i++) {
4826 iter = start;
4827 bit_offset = (psm->pack_skip_pixels * components) % 8;
4828 for (j = 0; j < elements_per_line; j++) {
4829 if (index_format) {
4830 current_bit = iter2[0] & 1;
4831 } else {
4832 if (iter2[0] > 32767) {
4833 current_bit = 1;
4834 } else {
4835 current_bit = 0;
4839 if (current_bit) {
4840 if (psm->pack_lsb_first) {
4841 *iter |= (1 << bit_offset);
4842 } else {
4843 *iter |= (1 << (7 - bit_offset));
4845 } else {
4846 if (psm->pack_lsb_first) {
4847 *iter &= ~(1 << bit_offset);
4848 } else {
4849 *iter &= ~(1 << (7 - bit_offset));
4853 bit_offset++;
4854 if (bit_offset == 8) {
4855 bit_offset = 0;
4856 iter++;
4858 iter2++;
4860 start += rowsize;
4862 } else {
4863 float shoveComponents[4];
4865 element_size = bytes_per_element(type);
4866 group_size = element_size * components;
4867 if (element_size == 1) myswap_bytes = 0;
4869 rowsize = groups_per_line * group_size;
4870 padding = (rowsize % psm->pack_alignment);
4871 if (padding) {
4872 rowsize += psm->pack_alignment - padding;
4874 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
4875 psm->pack_skip_pixels * group_size;
4876 elements_per_line = width * components;
4878 iter2 = oldimage;
4879 for (i = 0; i < height; i++) {
4880 iter = start;
4881 for (j = 0; j < elements_per_line; j++) {
4882 Type_Widget widget;
4884 switch(type) {
4885 case GL_UNSIGNED_BYTE_3_3_2:
4886 for (k = 0; k < 3; k++) {
4887 shoveComponents[k]= *iter2++ / 65535.0;
4889 shove332(shoveComponents,0,(void *)iter);
4890 break;
4891 case GL_UNSIGNED_BYTE_2_3_3_REV:
4892 for (k = 0; k < 3; k++) {
4893 shoveComponents[k]= *iter2++ / 65535.0;
4895 shove233rev(shoveComponents,0,(void *)iter);
4896 break;
4897 case GL_UNSIGNED_BYTE:
4898 if (index_format) {
4899 *iter = *iter2++;
4900 } else {
4901 *iter = *iter2++ >> 8;
4903 break;
4904 case GL_BYTE:
4905 if (index_format) {
4906 *((GLbyte *) iter) = *iter2++;
4907 } else {
4908 *((GLbyte *) iter) = *iter2++ >> 9;
4910 break;
4911 case GL_UNSIGNED_SHORT_5_6_5:
4912 for (k = 0; k < 3; k++) {
4913 shoveComponents[k]= *iter2++ / 65535.0;
4915 shove565(shoveComponents,0,(void *)&widget.us[0]);
4916 if (myswap_bytes) {
4917 iter[0] = widget.ub[1];
4918 iter[1] = widget.ub[0];
4920 else {
4921 *(GLushort *)iter = widget.us[0];
4923 break;
4924 case GL_UNSIGNED_SHORT_5_6_5_REV:
4925 for (k = 0; k < 3; k++) {
4926 shoveComponents[k]= *iter2++ / 65535.0;
4928 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
4929 if (myswap_bytes) {
4930 iter[0] = widget.ub[1];
4931 iter[1] = widget.ub[0];
4933 else {
4934 *(GLushort *)iter = widget.us[0];
4936 break;
4937 case GL_UNSIGNED_SHORT_4_4_4_4:
4938 for (k = 0; k < 4; k++) {
4939 shoveComponents[k]= *iter2++ / 65535.0;
4941 shove4444(shoveComponents,0,(void *)&widget.us[0]);
4942 if (myswap_bytes) {
4943 iter[0] = widget.ub[1];
4944 iter[1] = widget.ub[0];
4945 } else {
4946 *(GLushort *)iter = widget.us[0];
4948 break;
4949 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4950 for (k = 0; k < 4; k++) {
4951 shoveComponents[k]= *iter2++ / 65535.0;
4953 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
4954 if (myswap_bytes) {
4955 iter[0] = widget.ub[1];
4956 iter[1] = widget.ub[0];
4957 } else {
4958 *(GLushort *)iter = widget.us[0];
4960 break;
4961 case GL_UNSIGNED_SHORT_5_5_5_1:
4962 for (k = 0; k < 4; k++) {
4963 shoveComponents[k]= *iter2++ / 65535.0;
4965 shove5551(shoveComponents,0,(void *)&widget.us[0]);
4966 if (myswap_bytes) {
4967 iter[0] = widget.ub[1];
4968 iter[1] = widget.ub[0];
4969 } else {
4970 *(GLushort *)iter = widget.us[0];
4972 break;
4973 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4974 for (k = 0; k < 4; k++) {
4975 shoveComponents[k]= *iter2++ / 65535.0;
4977 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
4978 if (myswap_bytes) {
4979 iter[0] = widget.ub[1];
4980 iter[1] = widget.ub[0];
4981 } else {
4982 *(GLushort *)iter = widget.us[0];
4984 break;
4985 case GL_UNSIGNED_SHORT:
4986 case GL_SHORT:
4987 if (type == GL_SHORT) {
4988 if (index_format) {
4989 widget.s[0] = *iter2++;
4990 } else {
4991 widget.s[0] = *iter2++ >> 1;
4993 } else {
4994 widget.us[0] = *iter2++;
4996 if (myswap_bytes) {
4997 iter[0] = widget.ub[1];
4998 iter[1] = widget.ub[0];
4999 } else {
5000 iter[0] = widget.ub[0];
5001 iter[1] = widget.ub[1];
5003 break;
5004 case GL_UNSIGNED_INT_8_8_8_8:
5005 for (k = 0; k < 4; k++) {
5006 shoveComponents[k]= *iter2++ / 65535.0;
5008 shove8888(shoveComponents,0,(void *)&widget.ui);
5009 if (myswap_bytes) {
5010 iter[3] = widget.ub[0];
5011 iter[2] = widget.ub[1];
5012 iter[1] = widget.ub[2];
5013 iter[0] = widget.ub[3];
5014 } else {
5015 *(GLuint *)iter= widget.ui;
5018 break;
5019 case GL_UNSIGNED_INT_8_8_8_8_REV:
5020 for (k = 0; k < 4; k++) {
5021 shoveComponents[k]= *iter2++ / 65535.0;
5023 shove8888rev(shoveComponents,0,(void *)&widget.ui);
5024 if (myswap_bytes) {
5025 iter[3] = widget.ub[0];
5026 iter[2] = widget.ub[1];
5027 iter[1] = widget.ub[2];
5028 iter[0] = widget.ub[3];
5029 } else {
5030 *(GLuint *)iter= widget.ui;
5032 break;
5033 case GL_UNSIGNED_INT_10_10_10_2:
5034 for (k = 0; k < 4; k++) {
5035 shoveComponents[k]= *iter2++ / 65535.0;
5037 shove1010102(shoveComponents,0,(void *)&widget.ui);
5038 if (myswap_bytes) {
5039 iter[3] = widget.ub[0];
5040 iter[2] = widget.ub[1];
5041 iter[1] = widget.ub[2];
5042 iter[0] = widget.ub[3];
5043 } else {
5044 *(GLuint *)iter= widget.ui;
5046 break;
5047 case GL_UNSIGNED_INT_2_10_10_10_REV:
5048 for (k = 0; k < 4; k++) {
5049 shoveComponents[k]= *iter2++ / 65535.0;
5051 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5052 if (myswap_bytes) {
5053 iter[3] = widget.ub[0];
5054 iter[2] = widget.ub[1];
5055 iter[1] = widget.ub[2];
5056 iter[0] = widget.ub[3];
5057 } else {
5058 *(GLuint *)iter= widget.ui;
5060 break;
5061 case GL_INT:
5062 case GL_UNSIGNED_INT:
5063 case GL_FLOAT:
5064 if (type == GL_FLOAT) {
5065 if (index_format) {
5066 widget.f = *iter2++;
5067 } else {
5068 widget.f = *iter2++ / (float) 65535.0;
5070 } else if (type == GL_UNSIGNED_INT) {
5071 if (index_format) {
5072 widget.ui = *iter2++;
5073 } else {
5074 widget.ui = (unsigned int) *iter2++ * 65537;
5076 } else {
5077 if (index_format) {
5078 widget.i = *iter2++;
5079 } else {
5080 widget.i = ((unsigned int) *iter2++ * 65537)/2;
5083 if (myswap_bytes) {
5084 iter[3] = widget.ub[0];
5085 iter[2] = widget.ub[1];
5086 iter[1] = widget.ub[2];
5087 iter[0] = widget.ub[3];
5088 } else {
5089 iter[0] = widget.ub[0];
5090 iter[1] = widget.ub[1];
5091 iter[2] = widget.ub[2];
5092 iter[3] = widget.ub[3];
5094 break;
5096 iter += element_size;
5097 } /* for j */
5098 start += rowsize;
5099 #if 1
5100 /* want 'iter' pointing at start, not within, row for assertion
5101 * purposes
5103 iter= start;
5104 #endif
5105 } /* for i */
5107 /* iterators should be one byte past end */
5108 if (!isTypePackedPixel(type)) {
5109 assert(iter2 == &oldimage[width*height*components]);
5111 else {
5112 assert(iter2 == &oldimage[width*height*
5113 elements_per_group(format,0)]);
5115 assert( iter == &((GLubyte *)userdata)[rowsize*height +
5116 psm->pack_skip_rows * rowsize +
5117 psm->pack_skip_pixels * group_size] );
5119 } /* else */
5120 } /* empty_image() */
5122 /*--------------------------------------------------------------------------
5123 * Decimation of packed pixel types
5124 *--------------------------------------------------------------------------
5126 static void extract332(int isSwap,
5127 const void *packedPixel, GLfloat extractComponents[])
5129 GLubyte ubyte= *(const GLubyte *)packedPixel;
5131 /* 11100000 == 0xe0 */
5132 /* 00011100 == 0x1c */
5133 /* 00000011 == 0x03 */
5135 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0;
5136 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5137 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */
5138 } /* extract332() */
5140 static void shove332(const GLfloat shoveComponents[],
5141 int index, void *packedPixel)
5143 /* 11100000 == 0xe0 */
5144 /* 00011100 == 0x1c */
5145 /* 00000011 == 0x03 */
5147 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5148 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5149 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5151 /* due to limited precision, need to round before shoving */
5152 ((GLubyte *)packedPixel)[index] =
5153 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0;
5154 ((GLubyte *)packedPixel)[index] |=
5155 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c;
5156 ((GLubyte *)packedPixel)[index] |=
5157 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03;
5158 } /* shove332() */
5160 static void extract233rev(int isSwap,
5161 const void *packedPixel, GLfloat extractComponents[])
5163 GLubyte ubyte= *(const GLubyte *)packedPixel;
5165 /* 0000,0111 == 0x07 */
5166 /* 0011,1000 == 0x38 */
5167 /* 1100,0000 == 0xC0 */
5169 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0;
5170 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5171 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5172 } /* extract233rev() */
5174 static void shove233rev(const GLfloat shoveComponents[],
5175 int index, void *packedPixel)
5177 /* 0000,0111 == 0x07 */
5178 /* 0011,1000 == 0x38 */
5179 /* 1100,0000 == 0xC0 */
5181 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5182 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5183 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5185 /* due to limited precision, need to round before shoving */
5186 ((GLubyte *)packedPixel)[index] =
5187 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07;
5188 ((GLubyte *)packedPixel)[index]|=
5189 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5190 ((GLubyte *)packedPixel)[index]|=
5191 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5192 } /* shove233rev() */
5194 static void extract565(int isSwap,
5195 const void *packedPixel, GLfloat extractComponents[])
5197 GLushort ushort;
5199 if (isSwap) {
5200 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5202 else {
5203 ushort= *(const GLushort *)packedPixel;
5206 /* 11111000,00000000 == 0xf800 */
5207 /* 00000111,11100000 == 0x07e0 */
5208 /* 00000000,00011111 == 0x001f */
5210 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5211 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5212 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0;
5213 } /* extract565() */
5215 static void shove565(const GLfloat shoveComponents[],
5216 int index,void *packedPixel)
5218 /* 11111000,00000000 == 0xf800 */
5219 /* 00000111,11100000 == 0x07e0 */
5220 /* 00000000,00011111 == 0x001f */
5222 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5223 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5224 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5226 /* due to limited precision, need to round before shoving */
5227 ((GLushort *)packedPixel)[index] =
5228 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5229 ((GLushort *)packedPixel)[index]|=
5230 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0;
5231 ((GLushort *)packedPixel)[index]|=
5232 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f;
5233 } /* shove565() */
5235 static void extract565rev(int isSwap,
5236 const void *packedPixel, GLfloat extractComponents[])
5238 GLushort ushort;
5240 if (isSwap) {
5241 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5243 else {
5244 ushort= *(const GLushort *)packedPixel;
5247 /* 00000000,00011111 == 0x001f */
5248 /* 00000111,11100000 == 0x07e0 */
5249 /* 11111000,00000000 == 0xf800 */
5251 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5252 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0;
5253 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5254 } /* extract565rev() */
5256 static void shove565rev(const GLfloat shoveComponents[],
5257 int index,void *packedPixel)
5259 /* 00000000,00011111 == 0x001f */
5260 /* 00000111,11100000 == 0x07e0 */
5261 /* 11111000,00000000 == 0xf800 */
5263 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5264 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5265 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5267 /* due to limited precision, need to round before shoving */
5268 ((GLushort *)packedPixel)[index] =
5269 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F;
5270 ((GLushort *)packedPixel)[index]|=
5271 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0;
5272 ((GLushort *)packedPixel)[index]|=
5273 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5274 } /* shove565rev() */
5276 static void extract4444(int isSwap,const void *packedPixel,
5277 GLfloat extractComponents[])
5279 GLushort ushort;
5281 if (isSwap) {
5282 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5284 else {
5285 ushort= *(const GLushort *)packedPixel;
5288 /* 11110000,00000000 == 0xf000 */
5289 /* 00001111,00000000 == 0x0f00 */
5290 /* 00000000,11110000 == 0x00f0 */
5291 /* 00000000,00001111 == 0x000f */
5293 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5294 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0;
5295 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0;
5296 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0;
5297 } /* extract4444() */
5299 static void shove4444(const GLfloat shoveComponents[],
5300 int index,void *packedPixel)
5302 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5303 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5304 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5305 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5307 /* due to limited precision, need to round before shoving */
5308 ((GLushort *)packedPixel)[index] =
5309 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5310 ((GLushort *)packedPixel)[index]|=
5311 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00;
5312 ((GLushort *)packedPixel)[index]|=
5313 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0;
5314 ((GLushort *)packedPixel)[index]|=
5315 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f;
5316 } /* shove4444() */
5318 static void extract4444rev(int isSwap,const void *packedPixel,
5319 GLfloat extractComponents[])
5321 GLushort ushort;
5323 if (isSwap) {
5324 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5326 else {
5327 ushort= *(const GLushort *)packedPixel;
5330 /* 00000000,00001111 == 0x000f */
5331 /* 00000000,11110000 == 0x00f0 */
5332 /* 00001111,00000000 == 0x0f00 */
5333 /* 11110000,00000000 == 0xf000 */
5335 /* 15 = 2^4-1 */
5336 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0;
5337 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0;
5338 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0;
5339 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5340 } /* extract4444rev() */
5342 static void shove4444rev(const GLfloat shoveComponents[],
5343 int index,void *packedPixel)
5345 /* 00000000,00001111 == 0x000f */
5346 /* 00000000,11110000 == 0x00f0 */
5347 /* 00001111,00000000 == 0x0f00 */
5348 /* 11110000,00000000 == 0xf000 */
5350 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5351 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5352 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5353 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5355 /* due to limited precision, need to round before shoving */
5356 ((GLushort *)packedPixel)[index] =
5357 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F;
5358 ((GLushort *)packedPixel)[index]|=
5359 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0;
5360 ((GLushort *)packedPixel)[index]|=
5361 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00;
5362 ((GLushort *)packedPixel)[index]|=
5363 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5364 } /* shove4444rev() */
5366 static void extract5551(int isSwap,const void *packedPixel,
5367 GLfloat extractComponents[])
5369 GLushort ushort;
5371 if (isSwap) {
5372 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5374 else {
5375 ushort= *(const GLushort *)packedPixel;
5378 /* 11111000,00000000 == 0xf800 */
5379 /* 00000111,11000000 == 0x07c0 */
5380 /* 00000000,00111110 == 0x003e */
5381 /* 00000000,00000001 == 0x0001 */
5383 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5384 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0;
5385 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0;
5386 extractComponents[3]=(float)((ushort & 0x0001) );
5387 } /* extract5551() */
5389 static void shove5551(const GLfloat shoveComponents[],
5390 int index,void *packedPixel)
5392 /* 11111000,00000000 == 0xf800 */
5393 /* 00000111,11000000 == 0x07c0 */
5394 /* 00000000,00111110 == 0x003e */
5395 /* 00000000,00000001 == 0x0001 */
5397 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5398 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5399 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5400 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5402 /* due to limited precision, need to round before shoving */
5403 ((GLushort *)packedPixel)[index] =
5404 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5405 ((GLushort *)packedPixel)[index]|=
5406 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0;
5407 ((GLushort *)packedPixel)[index]|=
5408 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e;
5409 ((GLushort *)packedPixel)[index]|=
5410 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001;
5411 } /* shove5551() */
5413 static void extract1555rev(int isSwap,const void *packedPixel,
5414 GLfloat extractComponents[])
5416 GLushort ushort;
5418 if (isSwap) {
5419 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5421 else {
5422 ushort= *(const GLushort *)packedPixel;
5425 /* 00000000,00011111 == 0x001F */
5426 /* 00000011,11100000 == 0x03E0 */
5427 /* 01111100,00000000 == 0x7C00 */
5428 /* 10000000,00000000 == 0x8000 */
5430 /* 31 = 2^5-1 */
5431 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5432 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0;
5433 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5434 extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5435 } /* extract1555rev() */
5437 static void shove1555rev(const GLfloat shoveComponents[],
5438 int index,void *packedPixel)
5440 /* 00000000,00011111 == 0x001F */
5441 /* 00000011,11100000 == 0x03E0 */
5442 /* 01111100,00000000 == 0x7C00 */
5443 /* 10000000,00000000 == 0x8000 */
5445 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5446 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5447 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5448 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5450 /* due to limited precision, need to round before shoving */
5451 ((GLushort *)packedPixel)[index] =
5452 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F;
5453 ((GLushort *)packedPixel)[index]|=
5454 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0;
5455 ((GLushort *)packedPixel)[index]|=
5456 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5457 ((GLushort *)packedPixel)[index]|=
5458 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000;
5459 } /* shove1555rev() */
5461 static void extract8888(int isSwap,
5462 const void *packedPixel, GLfloat extractComponents[])
5464 GLuint uint;
5466 if (isSwap) {
5467 uint= __GLU_SWAP_4_BYTES(packedPixel);
5469 else {
5470 uint= *(const GLuint *)packedPixel;
5473 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5474 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5475 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5476 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5478 /* 255 = 2^8-1 */
5479 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5480 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5481 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0;
5482 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0;
5483 } /* extract8888() */
5485 static void shove8888(const GLfloat shoveComponents[],
5486 int index,void *packedPixel)
5488 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5489 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5490 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5491 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5493 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5494 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5495 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5496 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5498 /* due to limited precision, need to round before shoving */
5499 ((GLuint *)packedPixel)[index] =
5500 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5501 ((GLuint *)packedPixel)[index]|=
5502 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5503 ((GLuint *)packedPixel)[index]|=
5504 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00;
5505 ((GLuint *)packedPixel)[index]|=
5506 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff;
5507 } /* shove8888() */
5509 static void extract8888rev(int isSwap,
5510 const void *packedPixel,GLfloat extractComponents[])
5512 GLuint uint;
5514 if (isSwap) {
5515 uint= __GLU_SWAP_4_BYTES(packedPixel);
5517 else {
5518 uint= *(const GLuint *)packedPixel;
5521 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5522 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5523 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5524 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5526 /* 255 = 2^8-1 */
5527 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0;
5528 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0;
5529 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5530 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5531 } /* extract8888rev() */
5533 static void shove8888rev(const GLfloat shoveComponents[],
5534 int index,void *packedPixel)
5536 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5537 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5538 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5539 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5541 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5542 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5543 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5544 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5546 /* due to limited precision, need to round before shoving */
5547 ((GLuint *)packedPixel)[index] =
5548 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF;
5549 ((GLuint *)packedPixel)[index]|=
5550 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00;
5551 ((GLuint *)packedPixel)[index]|=
5552 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5553 ((GLuint *)packedPixel)[index]|=
5554 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5555 } /* shove8888rev() */
5557 static void extract1010102(int isSwap,
5558 const void *packedPixel,GLfloat extractComponents[])
5560 GLuint uint;
5562 if (isSwap) {
5563 uint= __GLU_SWAP_4_BYTES(packedPixel);
5565 else {
5566 uint= *(const GLuint *)packedPixel;
5569 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5570 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5571 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5572 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5574 /* 1023 = 2^10-1 */
5575 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5576 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5577 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0;
5578 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0;
5579 } /* extract1010102() */
5581 static void shove1010102(const GLfloat shoveComponents[],
5582 int index,void *packedPixel)
5584 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5585 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5586 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5587 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5589 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5590 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5591 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5592 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5594 /* due to limited precision, need to round before shoving */
5595 ((GLuint *)packedPixel)[index] =
5596 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5597 ((GLuint *)packedPixel)[index]|=
5598 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5599 ((GLuint *)packedPixel)[index]|=
5600 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc;
5601 ((GLuint *)packedPixel)[index]|=
5602 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003;
5603 } /* shove1010102() */
5605 static void extract2101010rev(int isSwap,
5606 const void *packedPixel,
5607 GLfloat extractComponents[])
5609 GLuint uint;
5611 if (isSwap) {
5612 uint= __GLU_SWAP_4_BYTES(packedPixel);
5614 else {
5615 uint= *(const GLuint *)packedPixel;
5618 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5619 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5620 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5621 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5623 /* 1023 = 2^10-1 */
5624 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0;
5625 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5626 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5627 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5628 /* 3 = 2^2-1 */
5629 } /* extract2101010rev() */
5631 static void shove2101010rev(const GLfloat shoveComponents[],
5632 int index,void *packedPixel)
5634 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5635 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5636 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5637 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5639 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5640 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5641 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5642 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5644 /* due to limited precision, need to round before shoving */
5645 ((GLuint *)packedPixel)[index] =
5646 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF;
5647 ((GLuint *)packedPixel)[index]|=
5648 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
5649 ((GLuint *)packedPixel)[index]|=
5650 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
5651 ((GLuint *)packedPixel)[index]|=
5652 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000;
5653 } /* shove2101010rev() */
5655 static void scaleInternalPackedPixel(int components,
5656 void (*extractPackedPixel)
5657 (int, const void *,GLfloat []),
5658 void (*shovePackedPixel)
5659 (const GLfloat [], int, void *),
5660 GLint widthIn,GLint heightIn,
5661 const void *dataIn,
5662 GLint widthOut,GLint heightOut,
5663 void *dataOut,
5664 GLint pixelSizeInBytes,
5665 GLint rowSizeInBytes,GLint isSwap)
5667 float convx;
5668 float convy;
5669 float percent;
5671 /* Max components in a format is 4, so... */
5672 float totals[4];
5673 float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
5675 float area;
5676 int i,j,k,xindex;
5678 const char *temp, *temp0;
5679 int outindex;
5681 int lowx_int, highx_int, lowy_int, highy_int;
5682 float x_percent, y_percent;
5683 float lowx_float, highx_float, lowy_float, highy_float;
5684 float convy_float, convx_float;
5685 int convy_int, convx_int;
5686 int l, m;
5687 const char *left, *right;
5689 if (widthIn == widthOut*2 && heightIn == heightOut*2) {
5690 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
5691 widthIn, heightIn, dataIn, dataOut,
5692 pixelSizeInBytes,rowSizeInBytes,isSwap);
5693 return;
5695 convy = (float) heightIn/heightOut;
5696 convx = (float) widthIn/widthOut;
5697 convy_int = floor(convy);
5698 convy_float = convy - convy_int;
5699 convx_int = floor(convx);
5700 convx_float = convx - convx_int;
5702 area = convx * convy;
5704 lowy_int = 0;
5705 lowy_float = 0;
5706 highy_int = convy_int;
5707 highy_float = convy_float;
5709 for (i = 0; i < heightOut; i++) {
5710 lowx_int = 0;
5711 lowx_float = 0;
5712 highx_int = convx_int;
5713 highx_float = convx_float;
5715 for (j = 0; j < widthOut; j++) {
5717 ** Ok, now apply box filter to box that goes from (lowx, lowy)
5718 ** to (highx, highy) on input data into this pixel on output
5719 ** data.
5721 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
5723 /* calculate the value for pixels in the 1st row */
5724 xindex = lowx_int*pixelSizeInBytes;
5725 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
5727 y_percent = 1-lowy_float;
5728 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
5729 percent = y_percent * (1-lowx_float);
5730 #if 0
5731 for (k = 0, temp_index = temp; k < components;
5732 k++, temp_index += element_size) {
5733 if (myswap_bytes) {
5734 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5735 } else {
5736 totals[k] += *(const GLushort*)temp_index * percent;
5739 #else
5740 (*extractPackedPixel)(isSwap,temp,extractTotals);
5741 for (k = 0; k < components; k++) {
5742 totals[k]+= extractTotals[k] * percent;
5744 #endif
5745 left = temp;
5746 for(l = lowx_int+1; l < highx_int; l++) {
5747 temp += pixelSizeInBytes;
5748 #if 0
5749 for (k = 0, temp_index = temp; k < components;
5750 k++, temp_index += element_size) {
5751 if (myswap_bytes) {
5752 totals[k] +=
5753 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5754 } else {
5755 totals[k] += *(const GLushort*)temp_index * y_percent;
5758 #else
5759 (*extractPackedPixel)(isSwap,temp,extractTotals);
5760 for (k = 0; k < components; k++) {
5761 totals[k]+= extractTotals[k] * y_percent;
5763 #endif
5765 temp += pixelSizeInBytes;
5766 right = temp;
5767 percent = y_percent * highx_float;
5768 #if 0
5769 for (k = 0, temp_index = temp; k < components;
5770 k++, temp_index += element_size) {
5771 if (myswap_bytes) {
5772 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5773 } else {
5774 totals[k] += *(const GLushort*)temp_index * percent;
5777 #else
5778 (*extractPackedPixel)(isSwap,temp,extractTotals);
5779 for (k = 0; k < components; k++) {
5780 totals[k]+= extractTotals[k] * percent;
5782 #endif
5784 /* calculate the value for pixels in the last row */
5786 y_percent = highy_float;
5787 percent = y_percent * (1-lowx_float);
5788 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
5789 #if 0
5790 for (k = 0, temp_index = temp; k < components;
5791 k++, temp_index += element_size) {
5792 if (myswap_bytes) {
5793 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5794 } else {
5795 totals[k] += *(const GLushort*)temp_index * percent;
5798 #else
5799 (*extractPackedPixel)(isSwap,temp,extractTotals);
5800 for (k = 0; k < components; k++) {
5801 totals[k]+= extractTotals[k] * percent;
5803 #endif
5804 for(l = lowx_int+1; l < highx_int; l++) {
5805 temp += pixelSizeInBytes;
5806 #if 0
5807 for (k = 0, temp_index = temp; k < components;
5808 k++, temp_index += element_size) {
5809 if (myswap_bytes) {
5810 totals[k] +=
5811 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5812 } else {
5813 totals[k] += *(const GLushort*)temp_index * y_percent;
5816 #else
5817 (*extractPackedPixel)(isSwap,temp,extractTotals);
5818 for (k = 0; k < components; k++) {
5819 totals[k]+= extractTotals[k] * y_percent;
5821 #endif
5824 temp += pixelSizeInBytes;
5825 percent = y_percent * highx_float;
5826 #if 0
5827 for (k = 0, temp_index = temp; k < components;
5828 k++, temp_index += element_size) {
5829 if (myswap_bytes) {
5830 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5831 } else {
5832 totals[k] += *(const GLushort*)temp_index * percent;
5835 #else
5836 (*extractPackedPixel)(isSwap,temp,extractTotals);
5837 for (k = 0; k < components; k++) {
5838 totals[k]+= extractTotals[k] * percent;
5840 #endif
5842 /* calculate the value for pixels in the 1st and last column */
5843 for(m = lowy_int+1; m < highy_int; m++) {
5844 left += rowSizeInBytes;
5845 right += rowSizeInBytes;
5846 #if 0
5847 for (k = 0; k < components;
5848 k++, left += element_size, right += element_size) {
5849 if (myswap_bytes) {
5850 totals[k] +=
5851 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
5852 __GLU_SWAP_2_BYTES(right) * highx_float;
5853 } else {
5854 totals[k] += *(const GLushort*)left * (1-lowx_float)
5855 + *(const GLushort*)right * highx_float;
5858 #else
5859 (*extractPackedPixel)(isSwap,left,extractTotals);
5860 (*extractPackedPixel)(isSwap,right,extractMoreTotals);
5861 for (k = 0; k < components; k++) {
5862 totals[k]+= (extractTotals[k]*(1-lowx_float) +
5863 extractMoreTotals[k]*highx_float);
5865 #endif
5867 } else if (highy_int > lowy_int) {
5868 x_percent = highx_float - lowx_float;
5869 percent = (1-lowy_float)*x_percent;
5870 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
5871 #if 0
5872 for (k = 0, temp_index = temp; k < components;
5873 k++, temp_index += element_size) {
5874 if (myswap_bytes) {
5875 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5876 } else {
5877 totals[k] += *(const GLushort*)temp_index * percent;
5880 #else
5881 (*extractPackedPixel)(isSwap,temp,extractTotals);
5882 for (k = 0; k < components; k++) {
5883 totals[k]+= extractTotals[k] * percent;
5885 #endif
5886 for(m = lowy_int+1; m < highy_int; m++) {
5887 temp += rowSizeInBytes;
5888 #if 0
5889 for (k = 0, temp_index = temp; k < components;
5890 k++, temp_index += element_size) {
5891 if (myswap_bytes) {
5892 totals[k] +=
5893 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
5894 } else {
5895 totals[k] += *(const GLushort*)temp_index * x_percent;
5898 #else
5899 (*extractPackedPixel)(isSwap,temp,extractTotals);
5900 for (k = 0; k < components; k++) {
5901 totals[k]+= extractTotals[k] * x_percent;
5903 #endif
5905 percent = x_percent * highy_float;
5906 temp += rowSizeInBytes;
5907 #if 0
5908 for (k = 0, temp_index = temp; k < components;
5909 k++, temp_index += element_size) {
5910 if (myswap_bytes) {
5911 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5912 } else {
5913 totals[k] += *(const GLushort*)temp_index * percent;
5916 #else
5917 (*extractPackedPixel)(isSwap,temp,extractTotals);
5918 for (k = 0; k < components; k++) {
5919 totals[k]+= extractTotals[k] * percent;
5921 #endif
5922 } else if (highx_int > lowx_int) {
5923 y_percent = highy_float - lowy_float;
5924 percent = (1-lowx_float)*y_percent;
5925 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
5926 #if 0
5927 for (k = 0, temp_index = temp; k < components;
5928 k++, temp_index += element_size) {
5929 if (myswap_bytes) {
5930 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5931 } else {
5932 totals[k] += *(const GLushort*)temp_index * percent;
5935 #else
5936 (*extractPackedPixel)(isSwap,temp,extractTotals);
5937 for (k = 0; k < components; k++) {
5938 totals[k]+= extractTotals[k] * percent;
5940 #endif
5941 for (l = lowx_int+1; l < highx_int; l++) {
5942 temp += pixelSizeInBytes;
5943 #if 0
5944 for (k = 0, temp_index = temp; k < components;
5945 k++, temp_index += element_size) {
5946 if (myswap_bytes) {
5947 totals[k] +=
5948 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
5949 } else {
5950 totals[k] += *(const GLushort*)temp_index * y_percent;
5953 #else
5954 (*extractPackedPixel)(isSwap,temp,extractTotals);
5955 for (k = 0; k < components; k++) {
5956 totals[k]+= extractTotals[k] * y_percent;
5958 #endif
5960 temp += pixelSizeInBytes;
5961 percent = y_percent * highx_float;
5962 #if 0
5963 for (k = 0, temp_index = temp; k < components;
5964 k++, temp_index += element_size) {
5965 if (myswap_bytes) {
5966 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5967 } else {
5968 totals[k] += *(const GLushort*)temp_index * percent;
5971 #else
5972 (*extractPackedPixel)(isSwap,temp,extractTotals);
5973 for (k = 0; k < components; k++) {
5974 totals[k]+= extractTotals[k] * percent;
5976 #endif
5977 } else {
5978 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
5979 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
5980 #if 0
5981 for (k = 0, temp_index = temp; k < components;
5982 k++, temp_index += element_size) {
5983 if (myswap_bytes) {
5984 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
5985 } else {
5986 totals[k] += *(const GLushort*)temp_index * percent;
5989 #else
5990 (*extractPackedPixel)(isSwap,temp,extractTotals);
5991 for (k = 0; k < components; k++) {
5992 totals[k]+= extractTotals[k] * percent;
5994 #endif
5997 /* this is for the pixels in the body */
5998 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
5999 for (m = lowy_int+1; m < highy_int; m++) {
6000 temp = temp0;
6001 for(l = lowx_int+1; l < highx_int; l++) {
6002 #if 0
6003 for (k = 0, temp_index = temp; k < components;
6004 k++, temp_index += element_size) {
6005 if (myswap_bytes) {
6006 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6007 } else {
6008 totals[k] += *(const GLushort*)temp_index;
6011 #else
6012 (*extractPackedPixel)(isSwap,temp,extractTotals);
6013 for (k = 0; k < components; k++) {
6014 totals[k]+= extractTotals[k];
6016 #endif
6017 temp += pixelSizeInBytes;
6019 temp0 += rowSizeInBytes;
6022 outindex = (j + (i * widthOut)); /* * (components == 1) */
6023 #if 0
6024 for (k = 0; k < components; k++) {
6025 dataout[outindex + k] = totals[k]/area;
6026 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6028 #else
6029 for (k = 0; k < components; k++) {
6030 shoveTotals[k]= totals[k]/area;
6032 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6033 #endif
6034 lowx_int = highx_int;
6035 lowx_float = highx_float;
6036 highx_int += convx_int;
6037 highx_float += convx_float;
6038 if(highx_float > 1) {
6039 highx_float -= 1.0;
6040 highx_int++;
6043 lowy_int = highy_int;
6044 lowy_float = highy_float;
6045 highy_int += convy_int;
6046 highy_float += convy_float;
6047 if(highy_float > 1) {
6048 highy_float -= 1.0;
6049 highy_int++;
6053 assert(outindex == (widthOut*heightOut - 1));
6054 } /* scaleInternalPackedPixel() */
6056 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6057 * inputs; not always equal. Output NEVER has row padding.
6059 static void halveImagePackedPixel(int components,
6060 void (*extractPackedPixel)
6061 (int, const void *,GLfloat []),
6062 void (*shovePackedPixel)
6063 (const GLfloat [],int, void *),
6064 GLint width, GLint height,
6065 const void *dataIn, void *dataOut,
6066 GLint pixelSizeInBytes,
6067 GLint rowSizeInBytes, GLint isSwap)
6069 /* handle case where there is only 1 column/row */
6070 if (width == 1 || height == 1) {
6071 assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6072 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6073 width,height,dataIn,dataOut,pixelSizeInBytes,
6074 rowSizeInBytes,isSwap);
6075 return;
6079 int ii, jj;
6081 int halfWidth= width / 2;
6082 int halfHeight= height / 2;
6083 const char *src= (const char *) dataIn;
6084 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6085 int outIndex= 0;
6087 for (ii= 0; ii< halfHeight; ii++) {
6088 for (jj= 0; jj< halfWidth; jj++) {
6089 #define BOX4 4
6090 float totals[4]; /* 4 is maximum components */
6091 float extractTotals[BOX4][4]; /* 4 is maximum components */
6092 int cc;
6094 (*extractPackedPixel)(isSwap,src,
6095 &extractTotals[0][0]);
6096 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6097 &extractTotals[1][0]);
6098 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6099 &extractTotals[2][0]);
6100 (*extractPackedPixel)(isSwap,
6101 (src+rowSizeInBytes+pixelSizeInBytes),
6102 &extractTotals[3][0]);
6103 for (cc = 0; cc < components; cc++) {
6104 int kk;
6106 /* grab 4 pixels to average */
6107 totals[cc]= 0.0;
6108 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6109 * extractTotals[2][RED]+extractTotals[3][RED];
6110 * totals[RED]/= 4.0;
6112 for (kk = 0; kk < BOX4; kk++) {
6113 totals[cc]+= extractTotals[kk][cc];
6115 totals[cc]/= (float)BOX4;
6117 (*shovePackedPixel)(totals,outIndex,dataOut);
6119 outIndex++;
6120 /* skip over to next square of 4 */
6121 src+= pixelSizeInBytes + pixelSizeInBytes;
6123 /* skip past pad bytes, if any, to get to next row */
6124 src+= padBytes;
6126 /* src is at beginning of a row here, but it's the second row of
6127 * the square block of 4 pixels that we just worked on so we
6128 * need to go one more row.
6129 * i.e.,
6130 * OO...
6131 * here -->OO...
6132 * but want -->OO...
6133 * OO...
6134 * ...
6136 src+= rowSizeInBytes;
6139 /* both pointers must reach one byte after the end */
6140 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6141 assert(outIndex == halfWidth * halfHeight);
6143 } /* halveImagePackedPixel() */
6145 static void halve1DimagePackedPixel(int components,
6146 void (*extractPackedPixel)
6147 (int, const void *,GLfloat []),
6148 void (*shovePackedPixel)
6149 (const GLfloat [],int, void *),
6150 GLint width, GLint height,
6151 const void *dataIn, void *dataOut,
6152 GLint pixelSizeInBytes,
6153 GLint rowSizeInBytes, GLint isSwap)
6155 int halfWidth= width / 2;
6156 int halfHeight= height / 2;
6157 const char *src= (const char *) dataIn;
6158 int jj;
6160 assert(width == 1 || height == 1); /* must be 1D */
6161 assert(width != height); /* can't be square */
6163 if (height == 1) { /* 1 row */
6164 int outIndex= 0;
6166 assert(width != 1); /* widthxheight can't be 1x1 */
6167 halfHeight= 1;
6169 /* one horizontal row with possible pad bytes */
6171 for (jj= 0; jj< halfWidth; jj++) {
6172 #define BOX2 2
6173 float totals[4]; /* 4 is maximum components */
6174 float extractTotals[BOX2][4]; /* 4 is maximum components */
6175 int cc;
6177 /* average two at a time, instead of four */
6178 (*extractPackedPixel)(isSwap,src,
6179 &extractTotals[0][0]);
6180 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6181 &extractTotals[1][0]);
6182 for (cc = 0; cc < components; cc++) {
6183 int kk;
6185 /* grab 2 pixels to average */
6186 totals[cc]= 0.0;
6187 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6188 * totals[RED]/= 2.0;
6190 for (kk = 0; kk < BOX2; kk++) {
6191 totals[cc]+= extractTotals[kk][cc];
6193 totals[cc]/= (float)BOX2;
6195 (*shovePackedPixel)(totals,outIndex,dataOut);
6197 outIndex++;
6198 /* skip over to next group of 2 */
6199 src+= pixelSizeInBytes + pixelSizeInBytes;
6203 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6204 src+= padBytes; /* for assertion only */
6206 assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6207 assert(outIndex == halfWidth * halfHeight);
6209 else if (width == 1) { /* 1 column */
6210 int outIndex= 0;
6212 assert(height != 1); /* widthxheight can't be 1x1 */
6213 halfWidth= 1;
6214 /* one vertical column with possible pad bytes per row */
6215 /* average two at a time */
6217 for (jj= 0; jj< halfHeight; jj++) {
6218 #define BOX2 2
6219 float totals[4]; /* 4 is maximum components */
6220 float extractTotals[BOX2][4]; /* 4 is maximum components */
6221 int cc;
6223 /* average two at a time, instead of four */
6224 (*extractPackedPixel)(isSwap,src,
6225 &extractTotals[0][0]);
6226 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6227 &extractTotals[1][0]);
6228 for (cc = 0; cc < components; cc++) {
6229 int kk;
6231 /* grab 2 pixels to average */
6232 totals[cc]= 0.0;
6233 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6234 * totals[RED]/= 2.0;
6236 for (kk = 0; kk < BOX2; kk++) {
6237 totals[cc]+= extractTotals[kk][cc];
6239 totals[cc]/= (float)BOX2;
6241 (*shovePackedPixel)(totals,outIndex,dataOut);
6243 outIndex++;
6244 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6247 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6248 assert(outIndex == halfWidth * halfHeight);
6250 } /* halve1DimagePackedPixel() */