ReactOS 0.4.15-dev-6052-g2626c72
mipmap.c
Go to the documentation of this file.
1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
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:
11 *
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.
16 *
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.
24 *
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.
29 */
30
31#include "gluos.h"
32#include <assert.h>
33#include <GL/glu.h>
34//#include <stdio.h>
35//#include <stdlib.h>
36//#include <string.h>
37//#include <limits.h> /* UINT_MAX */
38#include <math.h>
39
40typedef union {
41 unsigned char ub[4];
42 unsigned short us[2];
43 unsigned int ui;
44 char b[4];
45 short s[2];
46 int i;
47 float f;
49
50/* Pixel storage modes */
51typedef struct {
60
70
72 GLsizei,
73 GLsizei,
75 const void *);
80 const void *);
85 const void *);
86
87/*
88 * internal function declarations
89 */
94static void fill_image(const PixelStorageModes *,
96 GLenum type, GLboolean index_format,
97 const void *userdata, GLushort *newimage);
98static void empty_image(const PixelStorageModes *,
100 GLenum type, GLboolean index_format,
101 const GLushort *oldimage, void *userdata);
102static void scale_internal(GLint components, GLint widthin, GLint heightin,
103 const GLushort *datain,
104 GLint widthout, GLint heightout,
105 GLushort *dataout);
106
107static void scale_internal_ubyte(GLint components, GLint widthin,
108 GLint heightin, const GLubyte *datain,
109 GLint widthout, GLint heightout,
110 GLubyte *dataout, GLint element_size,
111 GLint ysize, GLint group_size);
112static void scale_internal_byte(GLint components, GLint widthin,
113 GLint heightin, const GLbyte *datain,
114 GLint widthout, GLint heightout,
115 GLbyte *dataout, GLint element_size,
116 GLint ysize, GLint group_size);
117static void scale_internal_ushort(GLint components, GLint widthin,
118 GLint heightin, const GLushort *datain,
119 GLint widthout, GLint heightout,
120 GLushort *dataout, GLint element_size,
121 GLint ysize, GLint group_size,
122 GLint myswap_bytes);
123static void scale_internal_short(GLint components, GLint widthin,
124 GLint heightin, const GLshort *datain,
125 GLint widthout, GLint heightout,
126 GLshort *dataout, GLint element_size,
127 GLint ysize, GLint group_size,
128 GLint myswap_bytes);
129static void scale_internal_uint(GLint components, GLint widthin,
130 GLint heightin, const GLuint *datain,
131 GLint widthout, GLint heightout,
132 GLuint *dataout, GLint element_size,
133 GLint ysize, GLint group_size,
134 GLint myswap_bytes);
135static void scale_internal_int(GLint components, GLint widthin,
136 GLint heightin, const GLint *datain,
137 GLint widthout, GLint heightout,
138 GLint *dataout, GLint element_size,
139 GLint ysize, GLint group_size,
140 GLint myswap_bytes);
141static void scale_internal_float(GLint components, GLint widthin,
142 GLint heightin, const GLfloat *datain,
143 GLint widthout, GLint heightout,
144 GLfloat *dataout, GLint element_size,
145 GLint ysize, GLint group_size,
146 GLint myswap_bytes);
147
148static int checkMipmapArgs(GLenum, GLenum, GLenum);
155 GLint *, GLint *);
156
157/* all extract/shove routines must return double to handle unsigned ints */
158static GLdouble extractUbyte(int, const void *);
159static void shoveUbyte(GLdouble, int, void *);
160static GLdouble extractSbyte(int, const void *);
161static void shoveSbyte(GLdouble, int, void *);
162static GLdouble extractUshort(int, const void *);
163static void shoveUshort(GLdouble, int, void *);
164static GLdouble extractSshort(int, const void *);
165static void shoveSshort(GLdouble, int, void *);
166static GLdouble extractUint(int, const void *);
167static void shoveUint(GLdouble, int, void *);
168static GLdouble extractSint(int, const void *);
169static void shoveSint(GLdouble, int, void *);
170static GLdouble extractFloat(int, const void *);
171static void shoveFloat(GLdouble, int, void *);
172static void halveImageSlice(int, GLdouble (*)(int, const void *),
173 void (*)(GLdouble, int, void *),
174 GLint, GLint, GLint,
175 const void *, void *,
177static void halveImage3D(int, GLdouble (*)(int, const void *),
178 void (*)(GLdouble, int, void *),
179 GLint, GLint, GLint,
180 const void *, void *,
182
183/* packedpixel type scale routines */
184static void extract332(int,const void *, GLfloat []);
185static void shove332(const GLfloat [],int ,void *);
186static void extract233rev(int,const void *, GLfloat []);
187static void shove233rev(const GLfloat [],int ,void *);
188static void extract565(int,const void *, GLfloat []);
189static void shove565(const GLfloat [],int ,void *);
190static void extract565rev(int,const void *, GLfloat []);
191static void shove565rev(const GLfloat [],int ,void *);
192static void extract4444(int,const void *, GLfloat []);
193static void shove4444(const GLfloat [],int ,void *);
194static void extract4444rev(int,const void *, GLfloat []);
195static void shove4444rev(const GLfloat [],int ,void *);
196static void extract5551(int,const void *, GLfloat []);
197static void shove5551(const GLfloat [],int ,void *);
198static void extract1555rev(int,const void *, GLfloat []);
199static void shove1555rev(const GLfloat [],int ,void *);
200static void extract8888(int,const void *, GLfloat []);
201static void shove8888(const GLfloat [],int ,void *);
202static void extract8888rev(int,const void *, GLfloat []);
203static void shove8888rev(const GLfloat [],int ,void *);
204static void extract1010102(int,const void *, GLfloat []);
205static void shove1010102(const GLfloat [],int ,void *);
206static void extract2101010rev(int,const void *, GLfloat []);
207static void shove2101010rev(const GLfloat [],int ,void *);
208static void scaleInternalPackedPixel(int,
209 void (*)(int, const void *,GLfloat []),
210 void (*)(const GLfloat [],int, void *),
211 GLint,GLint, const void *,
212 GLint,GLint,void *,GLint,GLint,GLint);
213static void halveImagePackedPixel(int,
214 void (*)(int, const void *,GLfloat []),
215 void (*)(const GLfloat [],int, void *),
216 GLint, GLint, const void *,
217 void *, GLint, GLint, GLint);
218static void halve1DimagePackedPixel(int,
219 void (*)(int, const void *,GLfloat []),
220 void (*)(const GLfloat [],int, void *),
221 GLint, GLint, const void *,
222 void *, GLint, GLint, GLint);
223
224static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
225 GLubyte *, GLint, GLint, GLint);
226static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
227 GLint, GLint, GLint);
228static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
230static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
232static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
234static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
236static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
238
240static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
241 GLenum, GLboolean, const void *, GLushort *);
242static void emptyImage3D(const PixelStorageModes *,
245 const GLushort *, void *);
246static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
248
250{
257
264}
265
267{
276
285}
286
288{
289 int i;
290
291 i = 0;
292
293 /* Error! */
294 if (value == 0) return -1;
295
296 for (;;) {
297 if (value & 1) {
298 /* Error ! */
299 if (value != 1) return -1;
300 return i;
301 }
302 value = value >> 1;
303 i++;
304 }
305}
306
307/*
308** Compute the nearest power of 2 number. This algorithm is a little
309** strange, but it works quite well.
310*/
312{
313 int i;
314
315 i = 1;
316
317 /* Error! */
318 if (value == 0) return -1;
319
320 for (;;) {
321 if (value == 1) {
322 return i;
323 } else if (value == 3) {
324 return i*4;
325 }
326 value = value >> 1;
327 i *= 2;
328 }
329}
330
331#define __GLU_SWAP_2_BYTES(s)\
332(GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
333
334#define __GLU_SWAP_4_BYTES(s)\
335(GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
336 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
337 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
338
340 const GLushort *datain, GLushort *dataout)
341{
342 int i, j, k;
343 int newwidth, newheight;
344 int delta;
345 GLushort *s;
346 const GLushort *t;
347
348 newwidth = width / 2;
349 newheight = height / 2;
350 delta = width * components;
351 s = dataout;
352 t = datain;
353
354 /* Piece o' cake! */
355 for (i = 0; i < newheight; i++) {
356 for (j = 0; j < newwidth; j++) {
357 for (k = 0; k < components; k++) {
358 s[0] = (t[0] + t[components] + t[delta] +
359 t[delta+components] + 2) / 4;
360 s++; t++;
361 }
362 t += components;
363 }
364 t += delta;
365 }
366}
367
369 const GLubyte *datain, GLubyte *dataout,
370 GLint element_size, GLint ysize, GLint group_size)
371{
372 int i, j, k;
373 int newwidth, newheight;
374 int padBytes;
375 GLubyte *s;
376 const char *t;
377
378 /* handle case where there is only 1 column/row */
379 if (width == 1 || height == 1) {
380 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
382 element_size,ysize,group_size);
383 return;
384 }
385
386 newwidth = width / 2;
387 newheight = height / 2;
388 padBytes = ysize - (width*group_size);
389 s = dataout;
390 t = (const char *)datain;
391
392 /* Piece o' cake! */
393 for (i = 0; i < newheight; i++) {
394 for (j = 0; j < newwidth; j++) {
395 for (k = 0; k < components; k++) {
396 s[0] = (*(const GLubyte*)t +
397 *(const GLubyte*)(t+group_size) +
398 *(const GLubyte*)(t+ysize) +
399 *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
400 s++; t += element_size;
401 }
402 t += group_size;
403 }
404 t += padBytes;
405 t += ysize;
406 }
407}
408
409/* */
411 const GLubyte *dataIn, GLubyte *dataOut,
412 GLint element_size, GLint ysize,
413 GLint group_size)
414{
415 GLint halfWidth= width / 2;
416 GLint halfHeight= height / 2;
417 const char *src= (const char *) dataIn;
418 GLubyte *dest= dataOut;
419 int jj;
420
421 assert(width == 1 || height == 1); /* must be 1D */
422 assert(width != height); /* can't be square */
423
424 if (height == 1) { /* 1 row */
425 assert(width != 1); /* widthxheight can't be 1x1 */
426 halfHeight= 1;
427
428 for (jj= 0; jj< halfWidth; jj++) {
429 int kk;
430 for (kk= 0; kk< components; kk++) {
431 *dest= (*(const GLubyte*)src +
432 *(const GLubyte*)(src+group_size)) / 2;
433
434 src+= element_size;
435 dest++;
436 }
437 src+= group_size; /* skip to next 2 */
438 }
439 {
440 int padBytes= ysize - (width*group_size);
441 src+= padBytes; /* for assertion only */
442 }
443 }
444 else if (width == 1) { /* 1 column */
445 int padBytes= ysize - (width * group_size);
446 assert(height != 1); /* widthxheight can't be 1x1 */
447 halfWidth= 1;
448 /* one vertical column with possible pad bytes per row */
449 /* average two at a time */
450
451 for (jj= 0; jj< halfHeight; jj++) {
452 int kk;
453 for (kk= 0; kk< components; kk++) {
454 *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
455
456 src+= element_size;
457 dest++;
458 }
459 src+= padBytes; /* add pad bytes, if any, to get to end to row */
460 src+= ysize;
461 }
462 }
463
464 assert(src == &((const char *)dataIn)[ysize*height]);
465 assert((char *)dest == &((char *)dataOut)
466 [components * element_size * halfWidth * halfHeight]);
467} /* halve1Dimage_ubyte() */
468
470 const GLbyte *datain, GLbyte *dataout,
471 GLint element_size,
472 GLint ysize, GLint group_size)
473{
474 int i, j, k;
475 int newwidth, newheight;
476 int padBytes;
477 GLbyte *s;
478 const char *t;
479
480 /* handle case where there is only 1 column/row */
481 if (width == 1 || height == 1) {
482 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
484 element_size,ysize,group_size);
485 return;
486 }
487
488 newwidth = width / 2;
489 newheight = height / 2;
490 padBytes = ysize - (width*group_size);
491 s = dataout;
492 t = (const char *)datain;
493
494 /* Piece o' cake! */
495 for (i = 0; i < newheight; i++) {
496 for (j = 0; j < newwidth; j++) {
497 for (k = 0; k < components; k++) {
498 s[0] = (*(const GLbyte*)t +
499 *(const GLbyte*)(t+group_size) +
500 *(const GLbyte*)(t+ysize) +
501 *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
502 s++; t += element_size;
503 }
504 t += group_size;
505 }
506 t += padBytes;
507 t += ysize;
508 }
509}
510
512 const GLbyte *dataIn, GLbyte *dataOut,
513 GLint element_size,GLint ysize, GLint group_size)
514{
515 GLint halfWidth= width / 2;
516 GLint halfHeight= height / 2;
517 const char *src= (const char *) dataIn;
518 GLbyte *dest= dataOut;
519 int jj;
520
521 assert(width == 1 || height == 1); /* must be 1D */
522 assert(width != height); /* can't be square */
523
524 if (height == 1) { /* 1 row */
525 assert(width != 1); /* widthxheight can't be 1x1 */
526 halfHeight= 1;
527
528 for (jj= 0; jj< halfWidth; jj++) {
529 int kk;
530 for (kk= 0; kk< components; kk++) {
531 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
532
533 src+= element_size;
534 dest++;
535 }
536 src+= group_size; /* skip to next 2 */
537 }
538 {
539 int padBytes= ysize - (width*group_size);
540 src+= padBytes; /* for assertion only */
541 }
542 }
543 else if (width == 1) { /* 1 column */
544 int padBytes= ysize - (width * group_size);
545 assert(height != 1); /* widthxheight can't be 1x1 */
546 halfWidth= 1;
547 /* one vertical column with possible pad bytes per row */
548 /* average two at a time */
549
550 for (jj= 0; jj< halfHeight; jj++) {
551 int kk;
552 for (kk= 0; kk< components; kk++) {
553 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
554
555 src+= element_size;
556 dest++;
557 }
558 src+= padBytes; /* add pad bytes, if any, to get to end to row */
559 src+= ysize;
560 }
561
562 assert(src == &((const char *)dataIn)[ysize*height]);
563 }
564
565 assert((char *)dest == &((char *)dataOut)
566 [components * element_size * halfWidth * halfHeight]);
567} /* halve1Dimage_byte() */
568
570 const GLushort *datain, GLushort *dataout,
571 GLint element_size, GLint ysize, GLint group_size,
572 GLint myswap_bytes)
573{
574 int i, j, k;
575 int newwidth, newheight;
576 int padBytes;
577 GLushort *s;
578 const char *t;
579
580 /* handle case where there is only 1 column/row */
581 if (width == 1 || height == 1) {
582 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
584 element_size,ysize,group_size, myswap_bytes);
585 return;
586 }
587
588 newwidth = width / 2;
589 newheight = height / 2;
590 padBytes = ysize - (width*group_size);
591 s = dataout;
592 t = (const char *)datain;
593
594 /* Piece o' cake! */
595 if (!myswap_bytes)
596 for (i = 0; i < newheight; i++) {
597 for (j = 0; j < newwidth; j++) {
598 for (k = 0; k < components; k++) {
599 s[0] = (*(const GLushort*)t +
600 *(const GLushort*)(t+group_size) +
601 *(const GLushort*)(t+ysize) +
602 *(const GLushort*)(t+ysize+group_size) + 2) / 4;
603 s++; t += element_size;
604 }
605 t += group_size;
606 }
607 t += padBytes;
608 t += ysize;
609 }
610 else
611 for (i = 0; i < newheight; i++) {
612 for (j = 0; j < newwidth; j++) {
613 for (k = 0; k < components; k++) {
614 s[0] = (__GLU_SWAP_2_BYTES(t) +
615 __GLU_SWAP_2_BYTES(t+group_size) +
616 __GLU_SWAP_2_BYTES(t+ysize) +
617 __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
618 s++; t += element_size;
619 }
620 t += group_size;
621 }
622 t += padBytes;
623 t += ysize;
624 }
625}
626
628 const GLushort *dataIn, GLushort *dataOut,
629 GLint element_size, GLint ysize,
630 GLint group_size, GLint myswap_bytes)
631{
632 GLint halfWidth= width / 2;
633 GLint halfHeight= height / 2;
634 const char *src= (const char *) dataIn;
635 GLushort *dest= dataOut;
636 int jj;
637
638 assert(width == 1 || height == 1); /* must be 1D */
639 assert(width != height); /* can't be square */
640
641 if (height == 1) { /* 1 row */
642 assert(width != 1); /* widthxheight can't be 1x1 */
643 halfHeight= 1;
644
645 for (jj= 0; jj< halfWidth; jj++) {
646 int kk;
647 for (kk= 0; kk< components; kk++) {
648#define BOX2 2
650 if (myswap_bytes) {
652 ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
653 }
654 else {
655 ushort[0]= *(const GLushort*)src;
656 ushort[1]= *(const GLushort*)(src+group_size);
657 }
658
659 *dest= (ushort[0] + ushort[1]) / 2;
660 src+= element_size;
661 dest++;
662 }
663 src+= group_size; /* skip to next 2 */
664 }
665 {
666 int padBytes= ysize - (width*group_size);
667 src+= padBytes; /* for assertion only */
668 }
669 }
670 else if (width == 1) { /* 1 column */
671 int padBytes= ysize - (width * group_size);
672 assert(height != 1); /* widthxheight can't be 1x1 */
673 halfWidth= 1;
674 /* one vertical column with possible pad bytes per row */
675 /* average two at a time */
676
677 for (jj= 0; jj< halfHeight; jj++) {
678 int kk;
679 for (kk= 0; kk< components; kk++) {
680#define BOX2 2
682 if (myswap_bytes) {
684 ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
685 }
686 else {
687 ushort[0]= *(const GLushort*)src;
688 ushort[1]= *(const GLushort*)(src+ysize);
689 }
690 *dest= (ushort[0] + ushort[1]) / 2;
691
692 src+= element_size;
693 dest++;
694 }
695 src+= padBytes; /* add pad bytes, if any, to get to end to row */
696 src+= ysize;
697 }
698
699 assert(src == &((const char *)dataIn)[ysize*height]);
700 }
701
702 assert((char *)dest == &((char *)dataOut)
703 [components * element_size * halfWidth * halfHeight]);
704
705} /* halve1Dimage_ushort() */
706
707
709 const GLshort *datain, GLshort *dataout,
710 GLint element_size, GLint ysize, GLint group_size,
711 GLint myswap_bytes)
712{
713 int i, j, k;
714 int newwidth, newheight;
715 int padBytes;
716 GLshort *s;
717 const char *t;
718
719 /* handle case where there is only 1 column/row */
720 if (width == 1 || height == 1) {
721 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
723 element_size,ysize,group_size, myswap_bytes);
724 return;
725 }
726
727 newwidth = width / 2;
728 newheight = height / 2;
729 padBytes = ysize - (width*group_size);
730 s = dataout;
731 t = (const char *)datain;
732
733 /* Piece o' cake! */
734 if (!myswap_bytes)
735 for (i = 0; i < newheight; i++) {
736 for (j = 0; j < newwidth; j++) {
737 for (k = 0; k < components; k++) {
738 s[0] = (*(const GLshort*)t +
739 *(const GLshort*)(t+group_size) +
740 *(const GLshort*)(t+ysize) +
741 *(const GLshort*)(t+ysize+group_size) + 2) / 4;
742 s++; t += element_size;
743 }
744 t += group_size;
745 }
746 t += padBytes;
747 t += ysize;
748 }
749 else
750 for (i = 0; i < newheight; i++) {
751 for (j = 0; j < newwidth; j++) {
752 for (k = 0; k < components; k++) {
753 GLushort b;
754 GLint buf;
756 buf = *(const GLshort*)&b;
757 b = __GLU_SWAP_2_BYTES(t+group_size);
758 buf += *(const GLshort*)&b;
759 b = __GLU_SWAP_2_BYTES(t+ysize);
760 buf += *(const GLshort*)&b;
761 b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
762 buf += *(const GLshort*)&b;
763 s[0] = (GLshort)((buf+2)/4);
764 s++; t += element_size;
765 }
766 t += group_size;
767 }
768 t += padBytes;
769 t += ysize;
770 }
771}
772
774 const GLshort *dataIn, GLshort *dataOut,
775 GLint element_size, GLint ysize,
776 GLint group_size, GLint myswap_bytes)
777{
778 GLint halfWidth= width / 2;
779 GLint halfHeight= height / 2;
780 const char *src= (const char *) dataIn;
781 GLshort *dest= dataOut;
782 int jj;
783
784 assert(width == 1 || height == 1); /* must be 1D */
785 assert(width != height); /* can't be square */
786
787 if (height == 1) { /* 1 row */
788 assert(width != 1); /* widthxheight can't be 1x1 */
789 halfHeight= 1;
790
791 for (jj= 0; jj< halfWidth; jj++) {
792 int kk;
793 for (kk= 0; kk< components; kk++) {
794#define BOX2 2
795 GLshort sshort[BOX2];
796 if (myswap_bytes) {
797 sshort[0]= __GLU_SWAP_2_BYTES(src);
798 sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
799 }
800 else {
801 sshort[0]= *(const GLshort*)src;
802 sshort[1]= *(const GLshort*)(src+group_size);
803 }
804
805 *dest= (sshort[0] + sshort[1]) / 2;
806 src+= element_size;
807 dest++;
808 }
809 src+= group_size; /* skip to next 2 */
810 }
811 {
812 int padBytes= ysize - (width*group_size);
813 src+= padBytes; /* for assertion only */
814 }
815 }
816 else if (width == 1) { /* 1 column */
817 int padBytes= ysize - (width * group_size);
818 assert(height != 1); /* widthxheight can't be 1x1 */
819 halfWidth= 1;
820 /* one vertical column with possible pad bytes per row */
821 /* average two at a time */
822
823 for (jj= 0; jj< halfHeight; jj++) {
824 int kk;
825 for (kk= 0; kk< components; kk++) {
826#define BOX2 2
827 GLshort sshort[BOX2];
828 if (myswap_bytes) {
829 sshort[0]= __GLU_SWAP_2_BYTES(src);
830 sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
831 }
832 else {
833 sshort[0]= *(const GLshort*)src;
834 sshort[1]= *(const GLshort*)(src+ysize);
835 }
836 *dest= (sshort[0] + sshort[1]) / 2;
837
838 src+= element_size;
839 dest++;
840 }
841 src+= padBytes; /* add pad bytes, if any, to get to end to row */
842 src+= ysize;
843 }
844
845 assert(src == &((const char *)dataIn)[ysize*height]);
846 }
847
848 assert((char *)dest == &((char *)dataOut)
849 [components * element_size * halfWidth * halfHeight]);
850
851} /* halve1Dimage_short() */
852
853
855 const GLuint *datain, GLuint *dataout,
856 GLint element_size, GLint ysize, GLint group_size,
857 GLint myswap_bytes)
858{
859 int i, j, k;
860 int newwidth, newheight;
861 int padBytes;
862 GLuint *s;
863 const char *t;
864
865 /* handle case where there is only 1 column/row */
866 if (width == 1 || height == 1) {
867 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
869 element_size,ysize,group_size, myswap_bytes);
870 return;
871 }
872
873 newwidth = width / 2;
874 newheight = height / 2;
875 padBytes = ysize - (width*group_size);
876 s = dataout;
877 t = (const char *)datain;
878
879 /* Piece o' cake! */
880 if (!myswap_bytes)
881 for (i = 0; i < newheight; i++) {
882 for (j = 0; j < newwidth; j++) {
883 for (k = 0; k < components; k++) {
884 /* need to cast to double to hold large unsigned ints */
885 s[0] = ((double)*(const GLuint*)t +
886 (double)*(const GLuint*)(t+group_size) +
887 (double)*(const GLuint*)(t+ysize) +
888 (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
889 s++; t += element_size;
890
891 }
892 t += group_size;
893 }
894 t += padBytes;
895 t += ysize;
896 }
897 else
898 for (i = 0; i < newheight; i++) {
899 for (j = 0; j < newwidth; j++) {
900 for (k = 0; k < components; k++) {
901 /* need to cast to double to hold large unsigned ints */
904 (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
906 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
907 s[0] = (GLuint)(buf/4 + 0.5);
908
909 s++; t += element_size;
910 }
911 t += group_size;
912 }
913 t += padBytes;
914 t += ysize;
915 }
916}
917
918/* */
920 const GLuint *dataIn, GLuint *dataOut,
921 GLint element_size, GLint ysize,
922 GLint group_size, GLint myswap_bytes)
923{
924 GLint halfWidth= width / 2;
925 GLint halfHeight= height / 2;
926 const char *src= (const char *) dataIn;
927 GLuint *dest= dataOut;
928 int jj;
929
930 assert(width == 1 || height == 1); /* must be 1D */
931 assert(width != height); /* can't be square */
932
933 if (height == 1) { /* 1 row */
934 assert(width != 1); /* widthxheight can't be 1x1 */
935 halfHeight= 1;
936
937 for (jj= 0; jj< halfWidth; jj++) {
938 int kk;
939 for (kk= 0; kk< components; kk++) {
940#define BOX2 2
942 if (myswap_bytes) {
944 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
945 }
946 else {
947 uint[0]= *(const GLuint*)src;
948 uint[1]= *(const GLuint*)(src+group_size);
949 }
950 *dest= ((double)uint[0]+(double)uint[1])/2.0;
951
952 src+= element_size;
953 dest++;
954 }
955 src+= group_size; /* skip to next 2 */
956 }
957 {
958 int padBytes= ysize - (width*group_size);
959 src+= padBytes; /* for assertion only */
960 }
961 }
962 else if (width == 1) { /* 1 column */
963 int padBytes= ysize - (width * group_size);
964 assert(height != 1); /* widthxheight can't be 1x1 */
965 halfWidth= 1;
966 /* one vertical column with possible pad bytes per row */
967 /* average two at a time */
968
969 for (jj= 0; jj< halfHeight; jj++) {
970 int kk;
971 for (kk= 0; kk< components; kk++) {
972#define BOX2 2
974 if (myswap_bytes) {
976 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
977 }
978 else {
979 uint[0]= *(const GLuint*)src;
980 uint[1]= *(const GLuint*)(src+ysize);
981 }
982 *dest= ((double)uint[0]+(double)uint[1])/2.0;
983
984 src+= element_size;
985 dest++;
986 }
987 src+= padBytes; /* add pad bytes, if any, to get to end to row */
988 src+= ysize;
989 }
990
991 assert(src == &((const char *)dataIn)[ysize*height]);
992 }
993
994 assert((char *)dest == &((char *)dataOut)
995 [components * element_size * halfWidth * halfHeight]);
996
997} /* halve1Dimage_uint() */
998
1000 const GLint *datain, GLint *dataout, GLint element_size,
1001 GLint ysize, GLint group_size, GLint myswap_bytes)
1002{
1003 int i, j, k;
1004 int newwidth, newheight;
1005 int padBytes;
1006 GLint *s;
1007 const char *t;
1008
1009 /* handle case where there is only 1 column/row */
1010 if (width == 1 || height == 1) {
1011 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1012 halve1Dimage_int(components,width,height,datain,dataout,
1013 element_size,ysize,group_size, myswap_bytes);
1014 return;
1015 }
1016
1017 newwidth = width / 2;
1018 newheight = height / 2;
1019 padBytes = ysize - (width*group_size);
1020 s = dataout;
1021 t = (const char *)datain;
1022
1023 /* Piece o' cake! */
1024 if (!myswap_bytes)
1025 for (i = 0; i < newheight; i++) {
1026 for (j = 0; j < newwidth; j++) {
1027 for (k = 0; k < components; k++) {
1028 s[0] = ((float)*(const GLint*)t +
1029 (float)*(const GLint*)(t+group_size) +
1030 (float)*(const GLint*)(t+ysize) +
1031 (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
1032 s++; t += element_size;
1033 }
1034 t += group_size;
1035 }
1036 t += padBytes;
1037 t += ysize;
1038 }
1039 else
1040 for (i = 0; i < newheight; i++) {
1041 for (j = 0; j < newwidth; j++) {
1042 for (k = 0; k < components; k++) {
1043 GLuint b;
1044 GLfloat buf;
1046 buf = *(GLint*)&b;
1047 b = __GLU_SWAP_4_BYTES(t+group_size);
1048 buf += *(GLint*)&b;
1049 b = __GLU_SWAP_4_BYTES(t+ysize);
1050 buf += *(GLint*)&b;
1051 b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1052 buf += *(GLint*)&b;
1053 s[0] = (GLint)(buf/4 + 0.5);
1054
1055 s++; t += element_size;
1056 }
1057 t += group_size;
1058 }
1059 t += padBytes;
1060 t += ysize;
1061 }
1062}
1063
1064/* */
1066 const GLint *dataIn, GLint *dataOut,
1067 GLint element_size, GLint ysize,
1068 GLint group_size, GLint myswap_bytes)
1069{
1070 GLint halfWidth= width / 2;
1071 GLint halfHeight= height / 2;
1072 const char *src= (const char *) dataIn;
1073 GLint *dest= dataOut;
1074 int jj;
1075
1076 assert(width == 1 || height == 1); /* must be 1D */
1077 assert(width != height); /* can't be square */
1078
1079 if (height == 1) { /* 1 row */
1080 assert(width != 1); /* widthxheight can't be 1x1 */
1081 halfHeight= 1;
1082
1083 for (jj= 0; jj< halfWidth; jj++) {
1084 int kk;
1085 for (kk= 0; kk< components; kk++) {
1086#define BOX2 2
1087 GLuint uint[BOX2];
1088 if (myswap_bytes) {
1090 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
1091 }
1092 else {
1093 uint[0]= *(const GLuint*)src;
1094 uint[1]= *(const GLuint*)(src+group_size);
1095 }
1096 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1097
1098 src+= element_size;
1099 dest++;
1100 }
1101 src+= group_size; /* skip to next 2 */
1102 }
1103 {
1104 int padBytes= ysize - (width*group_size);
1105 src+= padBytes; /* for assertion only */
1106 }
1107 }
1108 else if (width == 1) { /* 1 column */
1109 int padBytes= ysize - (width * group_size);
1110 assert(height != 1); /* widthxheight can't be 1x1 */
1111 halfWidth= 1;
1112 /* one vertical column with possible pad bytes per row */
1113 /* average two at a time */
1114
1115 for (jj= 0; jj< halfHeight; jj++) {
1116 int kk;
1117 for (kk= 0; kk< components; kk++) {
1118#define BOX2 2
1119 GLuint uint[BOX2];
1120 if (myswap_bytes) {
1122 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
1123 }
1124 else {
1125 uint[0]= *(const GLuint*)src;
1126 uint[1]= *(const GLuint*)(src+ysize);
1127 }
1128 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1129
1130 src+= element_size;
1131 dest++;
1132 }
1133 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1134 src+= ysize;
1135 }
1136
1137 assert(src == &((const char *)dataIn)[ysize*height]);
1138 }
1139
1140 assert((char *)dest == &((char *)dataOut)
1141 [components * element_size * halfWidth * halfHeight]);
1142
1143} /* halve1Dimage_int() */
1144
1145
1147 const GLfloat *datain, GLfloat *dataout,
1148 GLint element_size, GLint ysize, GLint group_size,
1149 GLint myswap_bytes)
1150{
1151 int i, j, k;
1152 int newwidth, newheight;
1153 int padBytes;
1154 GLfloat *s;
1155 const char *t;
1156
1157 /* handle case where there is only 1 column/row */
1158 if (width == 1 || height == 1) {
1159 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1161 element_size,ysize,group_size, myswap_bytes);
1162 return;
1163 }
1164
1165 newwidth = width / 2;
1166 newheight = height / 2;
1167 padBytes = ysize - (width*group_size);
1168 s = dataout;
1169 t = (const char *)datain;
1170
1171 /* Piece o' cake! */
1172 if (!myswap_bytes)
1173 for (i = 0; i < newheight; i++) {
1174 for (j = 0; j < newwidth; j++) {
1175 for (k = 0; k < components; k++) {
1176 s[0] = (*(const GLfloat*)t +
1177 *(const GLfloat*)(t+group_size) +
1178 *(const GLfloat*)(t+ysize) +
1179 *(const GLfloat*)(t+ysize+group_size)) / 4;
1180 s++; t += element_size;
1181 }
1182 t += group_size;
1183 }
1184 t += padBytes;
1185 t += ysize;
1186 }
1187 else
1188 for (i = 0; i < newheight; i++) {
1189 for (j = 0; j < newwidth; j++) {
1190 for (k = 0; k < components; k++) {
1191 union { GLuint b; GLfloat f; } swapbuf;
1192 swapbuf.b = __GLU_SWAP_4_BYTES(t);
1193 s[0] = swapbuf.f;
1194 swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
1195 s[0] += swapbuf.f;
1196 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
1197 s[0] += swapbuf.f;
1198 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1199 s[0] += swapbuf.f;
1200 s[0] /= 4;
1201 s++; t += element_size;
1202 }
1203 t += group_size;
1204 }
1205 t += padBytes;
1206 t += ysize;
1207 }
1208}
1209
1210/* */
1212 const GLfloat *dataIn, GLfloat *dataOut,
1213 GLint element_size, GLint ysize,
1214 GLint group_size, GLint myswap_bytes)
1215{
1216 GLint halfWidth= width / 2;
1217 GLint halfHeight= height / 2;
1218 const char *src= (const char *) dataIn;
1219 GLfloat *dest= dataOut;
1220 int jj;
1221
1222 assert(width == 1 || height == 1); /* must be 1D */
1223 assert(width != height); /* can't be square */
1224
1225 if (height == 1) { /* 1 row */
1226 assert(width != 1); /* widthxheight can't be 1x1 */
1227 halfHeight= 1;
1228
1229 for (jj= 0; jj< halfWidth; jj++) {
1230 int kk;
1231 for (kk= 0; kk< components; kk++) {
1232#define BOX2 2
1233 GLfloat sfloat[BOX2];
1234 if (myswap_bytes) {
1235 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1236 sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
1237 }
1238 else {
1239 sfloat[0]= *(const GLfloat*)src;
1240 sfloat[1]= *(const GLfloat*)(src+group_size);
1241 }
1242
1243 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1244 src+= element_size;
1245 dest++;
1246 }
1247 src+= group_size; /* skip to next 2 */
1248 }
1249 {
1250 int padBytes= ysize - (width*group_size);
1251 src+= padBytes; /* for assertion only */
1252 }
1253 }
1254 else if (width == 1) { /* 1 column */
1255 int padBytes= ysize - (width * group_size);
1256 assert(height != 1); /* widthxheight can't be 1x1 */
1257 halfWidth= 1;
1258 /* one vertical column with possible pad bytes per row */
1259 /* average two at a time */
1260
1261 for (jj= 0; jj< halfHeight; jj++) {
1262 int kk;
1263 for (kk= 0; kk< components; kk++) {
1264#define BOX2 2
1265 GLfloat sfloat[BOX2];
1266 if (myswap_bytes) {
1267 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1268 sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
1269 }
1270 else {
1271 sfloat[0]= *(const GLfloat*)src;
1272 sfloat[1]= *(const GLfloat*)(src+ysize);
1273 }
1274 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1275
1276 src+= element_size;
1277 dest++;
1278 }
1279 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1280 src+= ysize; /* skip to odd row */
1281 }
1282 }
1283
1284 assert(src == &((const char *)dataIn)[ysize*height]);
1285 assert((char *)dest == &((char *)dataOut)
1286 [components * element_size * halfWidth * halfHeight]);
1287} /* halve1Dimage_float() */
1288
1289static void scale_internal(GLint components, GLint widthin, GLint heightin,
1290 const GLushort *datain,
1291 GLint widthout, GLint heightout,
1292 GLushort *dataout)
1293{
1294 float x, lowx, highx, convx, halfconvx;
1295 float y, lowy, highy, convy, halfconvy;
1296 float xpercent,ypercent;
1297 float percent;
1298 /* Max components in a format is 4, so... */
1299 float totals[4];
1300 float area;
1301 int i,j,k,yint,xint,xindex,yindex;
1302 int temp;
1303
1304 if (widthin == widthout*2 && heightin == heightout*2) {
1305 halveImage(components, widthin, heightin, datain, dataout);
1306 return;
1307 }
1308 convy = (float) heightin/heightout;
1309 convx = (float) widthin/widthout;
1310 halfconvx = convx/2;
1311 halfconvy = convy/2;
1312 for (i = 0; i < heightout; i++) {
1313 y = convy * (i+0.5);
1314 if (heightin > heightout) {
1315 highy = y + halfconvy;
1316 lowy = y - halfconvy;
1317 } else {
1318 highy = y + 0.5;
1319 lowy = y - 0.5;
1320 }
1321 for (j = 0; j < widthout; j++) {
1322 x = convx * (j+0.5);
1323 if (widthin > widthout) {
1324 highx = x + halfconvx;
1325 lowx = x - halfconvx;
1326 } else {
1327 highx = x + 0.5;
1328 lowx = x - 0.5;
1329 }
1330
1331 /*
1332 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1333 ** to (highx, highy) on input data into this pixel on output
1334 ** data.
1335 */
1336 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1337 area = 0.0;
1338
1339 y = lowy;
1340 yint = floor(y);
1341 while (y < highy) {
1342 yindex = (yint + heightin) % heightin;
1343 if (highy < yint+1) {
1344 ypercent = highy - y;
1345 } else {
1346 ypercent = yint+1 - y;
1347 }
1348
1349 x = lowx;
1350 xint = floor(x);
1351
1352 while (x < highx) {
1353 xindex = (xint + widthin) % widthin;
1354 if (highx < xint+1) {
1355 xpercent = highx - x;
1356 } else {
1357 xpercent = xint+1 - x;
1358 }
1359
1360 percent = xpercent * ypercent;
1361 area += percent;
1362 temp = (xindex + (yindex * widthin)) * components;
1363 for (k = 0; k < components; k++) {
1364 totals[k] += datain[temp + k] * percent;
1365 }
1366
1367 xint++;
1368 x = xint;
1369 }
1370 yint++;
1371 y = yint;
1372 }
1373
1374 temp = (j + (i * widthout)) * components;
1375 for (k = 0; k < components; k++) {
1376 /* totals[] should be rounded in the case of enlarging an RGB
1377 * ramp when the type is 332 or 4444
1378 */
1379 dataout[temp + k] = (totals[k]+0.5)/area;
1380 }
1381 }
1382 }
1383}
1384
1386 GLint heightin, const GLubyte *datain,
1387 GLint widthout, GLint heightout,
1388 GLubyte *dataout, GLint element_size,
1389 GLint ysize, GLint group_size)
1390{
1391 float convx;
1392 float convy;
1393 float percent;
1394 /* Max components in a format is 4, so... */
1395 float totals[4];
1396 float area;
1397 int i,j,k,xindex;
1398
1399 const char *temp, *temp0;
1400 const char *temp_index;
1401 int outindex;
1402
1403 int lowx_int, highx_int, lowy_int, highy_int;
1404 float x_percent, y_percent;
1405 float lowx_float, highx_float, lowy_float, highy_float;
1406 float convy_float, convx_float;
1407 int convy_int, convx_int;
1408 int l, m;
1409 const char *left, *right;
1410
1411 if (widthin == widthout*2 && heightin == heightout*2) {
1412 halveImage_ubyte(components, widthin, heightin,
1413 (const GLubyte *)datain, (GLubyte *)dataout,
1414 element_size, ysize, group_size);
1415 return;
1416 }
1417 convy = (float) heightin/heightout;
1418 convx = (float) widthin/widthout;
1419 convy_int = floor(convy);
1420 convy_float = convy - convy_int;
1421 convx_int = floor(convx);
1422 convx_float = convx - convx_int;
1423
1424 area = convx * convy;
1425
1426 lowy_int = 0;
1427 lowy_float = 0;
1428 highy_int = convy_int;
1429 highy_float = convy_float;
1430
1431 for (i = 0; i < heightout; i++) {
1432 /* Clamp here to be sure we don't read beyond input buffer. */
1433 if (highy_int >= heightin)
1434 highy_int = heightin - 1;
1435 lowx_int = 0;
1436 lowx_float = 0;
1437 highx_int = convx_int;
1438 highx_float = convx_float;
1439
1440 for (j = 0; j < widthout; j++) {
1441
1442 /*
1443 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1444 ** to (highx, highy) on input data into this pixel on output
1445 ** data.
1446 */
1447 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1448
1449 /* calculate the value for pixels in the 1st row */
1450 xindex = lowx_int*group_size;
1451 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1452
1453 y_percent = 1-lowy_float;
1454 temp = (const char *)datain + xindex + lowy_int * ysize;
1455 percent = y_percent * (1-lowx_float);
1456 for (k = 0, temp_index = temp; k < components;
1457 k++, temp_index += element_size) {
1458 totals[k] += (GLubyte)(*(temp_index)) * percent;
1459 }
1460 left = temp;
1461 for(l = lowx_int+1; l < highx_int; l++) {
1462 temp += group_size;
1463 for (k = 0, temp_index = temp; k < components;
1464 k++, temp_index += element_size) {
1465 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1466 }
1467 }
1468 temp += group_size;
1469 right = temp;
1470 percent = y_percent * highx_float;
1471 for (k = 0, temp_index = temp; k < components;
1472 k++, temp_index += element_size) {
1473 totals[k] += (GLubyte)(*(temp_index)) * percent;
1474 }
1475
1476 /* calculate the value for pixels in the last row */
1477 y_percent = highy_float;
1478 percent = y_percent * (1-lowx_float);
1479 temp = (const char *)datain + xindex + highy_int * ysize;
1480 for (k = 0, temp_index = temp; k < components;
1481 k++, temp_index += element_size) {
1482 totals[k] += (GLubyte)(*(temp_index)) * percent;
1483 }
1484 for(l = lowx_int+1; l < highx_int; l++) {
1485 temp += group_size;
1486 for (k = 0, temp_index = temp; k < components;
1487 k++, temp_index += element_size) {
1488 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1489 }
1490 }
1491 temp += group_size;
1492 percent = y_percent * highx_float;
1493 for (k = 0, temp_index = temp; k < components;
1494 k++, temp_index += element_size) {
1495 totals[k] += (GLubyte)(*(temp_index)) * percent;
1496 }
1497
1498
1499 /* calculate the value for pixels in the 1st and last column */
1500 for(m = lowy_int+1; m < highy_int; m++) {
1501 left += ysize;
1502 right += ysize;
1503 for (k = 0; k < components;
1504 k++, left += element_size, right += element_size) {
1505 totals[k] += (GLubyte)(*(left))*(1-lowx_float)
1506 +(GLubyte)(*(right))*highx_float;
1507 }
1508 }
1509 } else if (highy_int > lowy_int) {
1510 x_percent = highx_float - lowx_float;
1511 percent = (1-lowy_float)*x_percent;
1512 temp = (const char *)datain + xindex + lowy_int*ysize;
1513 for (k = 0, temp_index = temp; k < components;
1514 k++, temp_index += element_size) {
1515 totals[k] += (GLubyte)(*(temp_index)) * percent;
1516 }
1517 for(m = lowy_int+1; m < highy_int; m++) {
1518 temp += ysize;
1519 for (k = 0, temp_index = temp; k < components;
1520 k++, temp_index += element_size) {
1521 totals[k] += (GLubyte)(*(temp_index)) * x_percent;
1522 }
1523 }
1524 percent = x_percent * highy_float;
1525 temp += ysize;
1526 for (k = 0, temp_index = temp; k < components;
1527 k++, temp_index += element_size) {
1528 totals[k] += (GLubyte)(*(temp_index)) * percent;
1529 }
1530 } else if (highx_int > lowx_int) {
1531 y_percent = highy_float - lowy_float;
1532 percent = (1-lowx_float)*y_percent;
1533 temp = (const char *)datain + xindex + lowy_int*ysize;
1534 for (k = 0, temp_index = temp; k < components;
1535 k++, temp_index += element_size) {
1536 totals[k] += (GLubyte)(*(temp_index)) * percent;
1537 }
1538 for (l = lowx_int+1; l < highx_int; l++) {
1539 temp += group_size;
1540 for (k = 0, temp_index = temp; k < components;
1541 k++, temp_index += element_size) {
1542 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1543 }
1544 }
1545 temp += group_size;
1546 percent = y_percent * highx_float;
1547 for (k = 0, temp_index = temp; k < components;
1548 k++, temp_index += element_size) {
1549 totals[k] += (GLubyte)(*(temp_index)) * percent;
1550 }
1551 } else {
1552 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1553 temp = (const char *)datain + xindex + lowy_int * ysize;
1554 for (k = 0, temp_index = temp; k < components;
1555 k++, temp_index += element_size) {
1556 totals[k] += (GLubyte)(*(temp_index)) * percent;
1557 }
1558 }
1559
1560
1561
1562 /* this is for the pixels in the body */
1563 temp0 = (const char *)datain + xindex + group_size +
1564 (lowy_int+1)*ysize;
1565 for (m = lowy_int+1; m < highy_int; m++) {
1566 temp = temp0;
1567 for(l = lowx_int+1; l < highx_int; l++) {
1568 for (k = 0, temp_index = temp; k < components;
1569 k++, temp_index += element_size) {
1570 totals[k] += (GLubyte)(*(temp_index));
1571 }
1572 temp += group_size;
1573 }
1574 temp0 += ysize;
1575 }
1576
1577 outindex = (j + (i * widthout)) * components;
1578 for (k = 0; k < components; k++) {
1579 dataout[outindex + k] = totals[k]/area;
1580 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1581 }
1582 lowx_int = highx_int;
1583 lowx_float = highx_float;
1584 highx_int += convx_int;
1585 highx_float += convx_float;
1586 if(highx_float > 1) {
1587 highx_float -= 1.0;
1588 highx_int++;
1589 }
1590 }
1591 lowy_int = highy_int;
1592 lowy_float = highy_float;
1593 highy_int += convy_int;
1594 highy_float += convy_float;
1595 if(highy_float > 1) {
1596 highy_float -= 1.0;
1597 highy_int++;
1598 }
1599 }
1600}
1601
1603 GLint heightin, const GLbyte *datain,
1604 GLint widthout, GLint heightout,
1605 GLbyte *dataout, GLint element_size,
1606 GLint ysize, GLint group_size)
1607{
1608 float convx;
1609 float convy;
1610 float percent;
1611 /* Max components in a format is 4, so... */
1612 float totals[4];
1613 float area;
1614 int i,j,k,xindex;
1615
1616 const char *temp, *temp0;
1617 const char *temp_index;
1618 int outindex;
1619
1620 int lowx_int, highx_int, lowy_int, highy_int;
1621 float x_percent, y_percent;
1622 float lowx_float, highx_float, lowy_float, highy_float;
1623 float convy_float, convx_float;
1624 int convy_int, convx_int;
1625 int l, m;
1626 const char *left, *right;
1627
1628 if (widthin == widthout*2 && heightin == heightout*2) {
1629 halveImage_byte(components, widthin, heightin,
1630 (const GLbyte *)datain, (GLbyte *)dataout,
1631 element_size, ysize, group_size);
1632 return;
1633 }
1634 convy = (float) heightin/heightout;
1635 convx = (float) widthin/widthout;
1636 convy_int = floor(convy);
1637 convy_float = convy - convy_int;
1638 convx_int = floor(convx);
1639 convx_float = convx - convx_int;
1640
1641 area = convx * convy;
1642
1643 lowy_int = 0;
1644 lowy_float = 0;
1645 highy_int = convy_int;
1646 highy_float = convy_float;
1647
1648 for (i = 0; i < heightout; i++) {
1649 /* Clamp here to be sure we don't read beyond input buffer. */
1650 if (highy_int >= heightin)
1651 highy_int = heightin - 1;
1652 lowx_int = 0;
1653 lowx_float = 0;
1654 highx_int = convx_int;
1655 highx_float = convx_float;
1656
1657 for (j = 0; j < widthout; j++) {
1658
1659 /*
1660 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1661 ** to (highx, highy) on input data into this pixel on output
1662 ** data.
1663 */
1664 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1665
1666 /* calculate the value for pixels in the 1st row */
1667 xindex = lowx_int*group_size;
1668 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1669
1670 y_percent = 1-lowy_float;
1671 temp = (const char *)datain + xindex + lowy_int * ysize;
1672 percent = y_percent * (1-lowx_float);
1673 for (k = 0, temp_index = temp; k < components;
1674 k++, temp_index += element_size) {
1675 totals[k] += (GLbyte)(*(temp_index)) * percent;
1676 }
1677 left = temp;
1678 for(l = lowx_int+1; l < highx_int; l++) {
1679 temp += group_size;
1680 for (k = 0, temp_index = temp; k < components;
1681 k++, temp_index += element_size) {
1682 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1683 }
1684 }
1685 temp += group_size;
1686 right = temp;
1687 percent = y_percent * highx_float;
1688 for (k = 0, temp_index = temp; k < components;
1689 k++, temp_index += element_size) {
1690 totals[k] += (GLbyte)(*(temp_index)) * percent;
1691 }
1692
1693 /* calculate the value for pixels in the last row */
1694 y_percent = highy_float;
1695 percent = y_percent * (1-lowx_float);
1696 temp = (const char *)datain + xindex + highy_int * ysize;
1697 for (k = 0, temp_index = temp; k < components;
1698 k++, temp_index += element_size) {
1699 totals[k] += (GLbyte)(*(temp_index)) * percent;
1700 }
1701 for(l = lowx_int+1; l < highx_int; l++) {
1702 temp += group_size;
1703 for (k = 0, temp_index = temp; k < components;
1704 k++, temp_index += element_size) {
1705 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1706 }
1707 }
1708 temp += group_size;
1709 percent = y_percent * highx_float;
1710 for (k = 0, temp_index = temp; k < components;
1711 k++, temp_index += element_size) {
1712 totals[k] += (GLbyte)(*(temp_index)) * percent;
1713 }
1714
1715
1716 /* calculate the value for pixels in the 1st and last column */
1717 for(m = lowy_int+1; m < highy_int; m++) {
1718 left += ysize;
1719 right += ysize;
1720 for (k = 0; k < components;
1721 k++, left += element_size, right += element_size) {
1722 totals[k] += (GLbyte)(*(left))*(1-lowx_float)
1723 +(GLbyte)(*(right))*highx_float;
1724 }
1725 }
1726 } else if (highy_int > lowy_int) {
1727 x_percent = highx_float - lowx_float;
1728 percent = (1-lowy_float)*x_percent;
1729 temp = (const char *)datain + xindex + lowy_int*ysize;
1730 for (k = 0, temp_index = temp; k < components;
1731 k++, temp_index += element_size) {
1732 totals[k] += (GLbyte)(*(temp_index)) * percent;
1733 }
1734 for(m = lowy_int+1; m < highy_int; m++) {
1735 temp += ysize;
1736 for (k = 0, temp_index = temp; k < components;
1737 k++, temp_index += element_size) {
1738 totals[k] += (GLbyte)(*(temp_index)) * x_percent;
1739 }
1740 }
1741 percent = x_percent * highy_float;
1742 temp += ysize;
1743 for (k = 0, temp_index = temp; k < components;
1744 k++, temp_index += element_size) {
1745 totals[k] += (GLbyte)(*(temp_index)) * percent;
1746 }
1747 } else if (highx_int > lowx_int) {
1748 y_percent = highy_float - lowy_float;
1749 percent = (1-lowx_float)*y_percent;
1750 temp = (const char *)datain + xindex + lowy_int*ysize;
1751 for (k = 0, temp_index = temp; k < components;
1752 k++, temp_index += element_size) {
1753 totals[k] += (GLbyte)(*(temp_index)) * percent;
1754 }
1755 for (l = lowx_int+1; l < highx_int; l++) {
1756 temp += group_size;
1757 for (k = 0, temp_index = temp; k < components;
1758 k++, temp_index += element_size) {
1759 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1760 }
1761 }
1762 temp += group_size;
1763 percent = y_percent * highx_float;
1764 for (k = 0, temp_index = temp; k < components;
1765 k++, temp_index += element_size) {
1766 totals[k] += (GLbyte)(*(temp_index)) * percent;
1767 }
1768 } else {
1769 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1770 temp = (const char *)datain + xindex + lowy_int * ysize;
1771 for (k = 0, temp_index = temp; k < components;
1772 k++, temp_index += element_size) {
1773 totals[k] += (GLbyte)(*(temp_index)) * percent;
1774 }
1775 }
1776
1777
1778
1779 /* this is for the pixels in the body */
1780 temp0 = (const char *)datain + xindex + group_size +
1781 (lowy_int+1)*ysize;
1782 for (m = lowy_int+1; m < highy_int; m++) {
1783 temp = temp0;
1784 for(l = lowx_int+1; l < highx_int; l++) {
1785 for (k = 0, temp_index = temp; k < components;
1786 k++, temp_index += element_size) {
1787 totals[k] += (GLbyte)(*(temp_index));
1788 }
1789 temp += group_size;
1790 }
1791 temp0 += ysize;
1792 }
1793
1794 outindex = (j + (i * widthout)) * components;
1795 for (k = 0; k < components; k++) {
1796 dataout[outindex + k] = totals[k]/area;
1797 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1798 }
1799 lowx_int = highx_int;
1800 lowx_float = highx_float;
1801 highx_int += convx_int;
1802 highx_float += convx_float;
1803 if(highx_float > 1) {
1804 highx_float -= 1.0;
1805 highx_int++;
1806 }
1807 }
1808 lowy_int = highy_int;
1809 lowy_float = highy_float;
1810 highy_int += convy_int;
1811 highy_float += convy_float;
1812 if(highy_float > 1) {
1813 highy_float -= 1.0;
1814 highy_int++;
1815 }
1816 }
1817}
1818
1820 GLint heightin, const GLushort *datain,
1821 GLint widthout, GLint heightout,
1822 GLushort *dataout, GLint element_size,
1823 GLint ysize, GLint group_size,
1824 GLint myswap_bytes)
1825{
1826 float convx;
1827 float convy;
1828 float percent;
1829 /* Max components in a format is 4, so... */
1830 float totals[4];
1831 float area;
1832 int i,j,k,xindex;
1833
1834 const char *temp, *temp0;
1835 const char *temp_index;
1836 int outindex;
1837
1838 int lowx_int, highx_int, lowy_int, highy_int;
1839 float x_percent, y_percent;
1840 float lowx_float, highx_float, lowy_float, highy_float;
1841 float convy_float, convx_float;
1842 int convy_int, convx_int;
1843 int l, m;
1844 const char *left, *right;
1845
1846 if (widthin == widthout*2 && heightin == heightout*2) {
1847 halveImage_ushort(components, widthin, heightin,
1848 (const GLushort *)datain, (GLushort *)dataout,
1849 element_size, ysize, group_size, myswap_bytes);
1850 return;
1851 }
1852 convy = (float) heightin/heightout;
1853 convx = (float) widthin/widthout;
1854 convy_int = floor(convy);
1855 convy_float = convy - convy_int;
1856 convx_int = floor(convx);
1857 convx_float = convx - convx_int;
1858
1859 area = convx * convy;
1860
1861 lowy_int = 0;
1862 lowy_float = 0;
1863 highy_int = convy_int;
1864 highy_float = convy_float;
1865
1866 for (i = 0; i < heightout; i++) {
1867 /* Clamp here to be sure we don't read beyond input buffer. */
1868 if (highy_int >= heightin)
1869 highy_int = heightin - 1;
1870 lowx_int = 0;
1871 lowx_float = 0;
1872 highx_int = convx_int;
1873 highx_float = convx_float;
1874
1875 for (j = 0; j < widthout; j++) {
1876 /*
1877 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1878 ** to (highx, highy) on input data into this pixel on output
1879 ** data.
1880 */
1881 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1882
1883 /* calculate the value for pixels in the 1st row */
1884 xindex = lowx_int*group_size;
1885 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1886
1887 y_percent = 1-lowy_float;
1888 temp = (const char *)datain + xindex + lowy_int * ysize;
1889 percent = y_percent * (1-lowx_float);
1890 for (k = 0, temp_index = temp; k < components;
1891 k++, temp_index += element_size) {
1892 if (myswap_bytes) {
1893 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1894 } else {
1895 totals[k] += *(const GLushort*)temp_index * percent;
1896 }
1897 }
1898 left = temp;
1899 for(l = lowx_int+1; l < highx_int; l++) {
1900 temp += group_size;
1901 for (k = 0, temp_index = temp; k < components;
1902 k++, temp_index += element_size) {
1903 if (myswap_bytes) {
1904 totals[k] +=
1905 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1906 } else {
1907 totals[k] += *(const GLushort*)temp_index * y_percent;
1908 }
1909 }
1910 }
1911 temp += group_size;
1912 right = temp;
1913 percent = y_percent * highx_float;
1914 for (k = 0, temp_index = temp; k < components;
1915 k++, temp_index += element_size) {
1916 if (myswap_bytes) {
1917 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1918 } else {
1919 totals[k] += *(const GLushort*)temp_index * percent;
1920 }
1921 }
1922
1923 /* calculate the value for pixels in the last row */
1924 y_percent = highy_float;
1925 percent = y_percent * (1-lowx_float);
1926 temp = (const char *)datain + xindex + highy_int * ysize;
1927 for (k = 0, temp_index = temp; k < components;
1928 k++, temp_index += element_size) {
1929 if (myswap_bytes) {
1930 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1931 } else {
1932 totals[k] += *(const GLushort*)temp_index * percent;
1933 }
1934 }
1935 for(l = lowx_int+1; l < highx_int; l++) {
1936 temp += group_size;
1937 for (k = 0, temp_index = temp; k < components;
1938 k++, temp_index += element_size) {
1939 if (myswap_bytes) {
1940 totals[k] +=
1941 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1942 } else {
1943 totals[k] += *(const GLushort*)temp_index * y_percent;
1944 }
1945 }
1946 }
1947 temp += group_size;
1948 percent = y_percent * highx_float;
1949 for (k = 0, temp_index = temp; k < components;
1950 k++, temp_index += element_size) {
1951 if (myswap_bytes) {
1952 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1953 } else {
1954 totals[k] += *(const GLushort*)temp_index * percent;
1955 }
1956 }
1957
1958 /* calculate the value for pixels in the 1st and last column */
1959 for(m = lowy_int+1; m < highy_int; m++) {
1960 left += ysize;
1961 right += ysize;
1962 for (k = 0; k < components;
1963 k++, left += element_size, right += element_size) {
1964 if (myswap_bytes) {
1965 totals[k] +=
1966 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
1967 __GLU_SWAP_2_BYTES(right) * highx_float;
1968 } else {
1969 totals[k] += *(const GLushort*)left * (1-lowx_float)
1970 + *(const GLushort*)right * highx_float;
1971 }
1972 }
1973 }
1974 } else if (highy_int > lowy_int) {
1975 x_percent = highx_float - lowx_float;
1976 percent = (1-lowy_float)*x_percent;
1977 temp = (const char *)datain + xindex + lowy_int*ysize;
1978 for (k = 0, temp_index = temp; k < components;
1979 k++, temp_index += element_size) {
1980 if (myswap_bytes) {
1981 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1982 } else {
1983 totals[k] += *(const GLushort*)temp_index * percent;
1984 }
1985 }
1986 for(m = lowy_int+1; m < highy_int; m++) {
1987 temp += ysize;
1988 for (k = 0, temp_index = temp; k < components;
1989 k++, temp_index += element_size) {
1990 if (myswap_bytes) {
1991 totals[k] +=
1992 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
1993 } else {
1994 totals[k] += *(const GLushort*)temp_index * x_percent;
1995 }
1996 }
1997 }
1998 percent = x_percent * highy_float;
1999 temp += ysize;
2000 for (k = 0, temp_index = temp; k < components;
2001 k++, temp_index += element_size) {
2002 if (myswap_bytes) {
2003 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2004 } else {
2005 totals[k] += *(const GLushort*)temp_index * percent;
2006 }
2007 }
2008 } else if (highx_int > lowx_int) {
2009 y_percent = highy_float - lowy_float;
2010 percent = (1-lowx_float)*y_percent;
2011 temp = (const char *)datain + xindex + lowy_int*ysize;
2012 for (k = 0, temp_index = temp; k < components;
2013 k++, temp_index += element_size) {
2014 if (myswap_bytes) {
2015 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2016 } else {
2017 totals[k] += *(const GLushort*)temp_index * percent;
2018 }
2019 }
2020 for (l = lowx_int+1; l < highx_int; l++) {
2021 temp += group_size;
2022 for (k = 0, temp_index = temp; k < components;
2023 k++, temp_index += element_size) {
2024 if (myswap_bytes) {
2025 totals[k] +=
2026 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
2027 } else {
2028 totals[k] += *(const GLushort*)temp_index * y_percent;
2029 }
2030 }
2031 }
2032 temp += group_size;
2033 percent = y_percent * highx_float;
2034 for (k = 0, temp_index = temp; k < components;
2035 k++, temp_index += element_size) {
2036 if (myswap_bytes) {
2037 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2038 } else {
2039 totals[k] += *(const GLushort*)temp_index * percent;
2040 }
2041 }
2042 } else {
2043 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2044 temp = (const char *)datain + xindex + lowy_int * ysize;
2045 for (k = 0, temp_index = temp; k < components;
2046 k++, temp_index += element_size) {
2047 if (myswap_bytes) {
2048 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2049 } else {
2050 totals[k] += *(const GLushort*)temp_index * percent;
2051 }
2052 }
2053 }
2054
2055 /* this is for the pixels in the body */
2056 temp0 = (const char *)datain + xindex + group_size +
2057 (lowy_int+1)*ysize;
2058 for (m = lowy_int+1; m < highy_int; m++) {
2059 temp = temp0;
2060 for(l = lowx_int+1; l < highx_int; l++) {
2061 for (k = 0, temp_index = temp; k < components;
2062 k++, temp_index += element_size) {
2063 if (myswap_bytes) {
2064 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
2065 } else {
2066 totals[k] += *(const GLushort*)temp_index;
2067 }
2068 }
2069 temp += group_size;
2070 }
2071 temp0 += ysize;
2072 }
2073
2074 outindex = (j + (i * widthout)) * components;
2075 for (k = 0; k < components; k++) {
2076 dataout[outindex + k] = totals[k]/area;
2077 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2078 }
2079 lowx_int = highx_int;
2080 lowx_float = highx_float;
2081 highx_int += convx_int;
2082 highx_float += convx_float;
2083 if(highx_float > 1) {
2084 highx_float -= 1.0;
2085 highx_int++;
2086 }
2087 }
2088 lowy_int = highy_int;
2089 lowy_float = highy_float;
2090 highy_int += convy_int;
2091 highy_float += convy_float;
2092 if(highy_float > 1) {
2093 highy_float -= 1.0;
2094 highy_int++;
2095 }
2096 }
2097}
2098
2100 GLint heightin, const GLshort *datain,
2101 GLint widthout, GLint heightout,
2102 GLshort *dataout, GLint element_size,
2103 GLint ysize, GLint group_size,
2104 GLint myswap_bytes)
2105{
2106 float convx;
2107 float convy;
2108 float percent;
2109 /* Max components in a format is 4, so... */
2110 float totals[4];
2111 float area;
2112 int i,j,k,xindex;
2113
2114 const char *temp, *temp0;
2115 const char *temp_index;
2116 int outindex;
2117
2118 int lowx_int, highx_int, lowy_int, highy_int;
2119 float x_percent, y_percent;
2120 float lowx_float, highx_float, lowy_float, highy_float;
2121 float convy_float, convx_float;
2122 int convy_int, convx_int;
2123 int l, m;
2124 const char *left, *right;
2125
2126 GLushort swapbuf; /* unsigned buffer */
2127
2128 if (widthin == widthout*2 && heightin == heightout*2) {
2129 halveImage_short(components, widthin, heightin,
2130 (const GLshort *)datain, (GLshort *)dataout,
2131 element_size, ysize, group_size, myswap_bytes);
2132 return;
2133 }
2134 convy = (float) heightin/heightout;
2135 convx = (float) widthin/widthout;
2136 convy_int = floor(convy);
2137 convy_float = convy - convy_int;
2138 convx_int = floor(convx);
2139 convx_float = convx - convx_int;
2140
2141 area = convx * convy;
2142
2143 lowy_int = 0;
2144 lowy_float = 0;
2145 highy_int = convy_int;
2146 highy_float = convy_float;
2147
2148 for (i = 0; i < heightout; i++) {
2149 /* Clamp here to be sure we don't read beyond input buffer. */
2150 if (highy_int >= heightin)
2151 highy_int = heightin - 1;
2152 lowx_int = 0;
2153 lowx_float = 0;
2154 highx_int = convx_int;
2155 highx_float = convx_float;
2156
2157 for (j = 0; j < widthout; j++) {
2158 /*
2159 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2160 ** to (highx, highy) on input data into this pixel on output
2161 ** data.
2162 */
2163 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2164
2165 /* calculate the value for pixels in the 1st row */
2166 xindex = lowx_int*group_size;
2167 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2168
2169 y_percent = 1-lowy_float;
2170 temp = (const char *)datain + xindex + lowy_int * ysize;
2171 percent = y_percent * (1-lowx_float);
2172 for (k = 0, temp_index = temp; k < components;
2173 k++, temp_index += element_size) {
2174 if (myswap_bytes) {
2175 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2176 totals[k] += *(const GLshort*)&swapbuf * percent;
2177 } else {
2178 totals[k] += *(const GLshort*)temp_index * percent;
2179 }
2180 }
2181 left = temp;
2182 for(l = lowx_int+1; l < highx_int; l++) {
2183 temp += group_size;
2184 for (k = 0, temp_index = temp; k < components;
2185 k++, temp_index += element_size) {
2186 if (myswap_bytes) {
2187 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2188 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2189 } else {
2190 totals[k] += *(const GLshort*)temp_index * y_percent;
2191 }
2192 }
2193 }
2194 temp += group_size;
2195 right = temp;
2196 percent = y_percent * highx_float;
2197 for (k = 0, temp_index = temp; k < components;
2198 k++, temp_index += element_size) {
2199 if (myswap_bytes) {
2200 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2201 totals[k] += *(const GLshort*)&swapbuf * percent;
2202 } else {
2203 totals[k] += *(const GLshort*)temp_index * percent;
2204 }
2205 }
2206
2207 /* calculate the value for pixels in the last row */
2208 y_percent = highy_float;
2209 percent = y_percent * (1-lowx_float);
2210 temp = (const char *)datain + xindex + highy_int * ysize;
2211 for (k = 0, temp_index = temp; k < components;
2212 k++, temp_index += element_size) {
2213 if (myswap_bytes) {
2214 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2215 totals[k] += *(const GLshort*)&swapbuf * percent;
2216 } else {
2217 totals[k] += *(const GLshort*)temp_index * percent;
2218 }
2219 }
2220 for(l = lowx_int+1; l < highx_int; l++) {
2221 temp += group_size;
2222 for (k = 0, temp_index = temp; k < components;
2223 k++, temp_index += element_size) {
2224 if (myswap_bytes) {
2225 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2226 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2227 } else {
2228 totals[k] += *(const GLshort*)temp_index * y_percent;
2229 }
2230 }
2231 }
2232 temp += group_size;
2233 percent = y_percent * highx_float;
2234 for (k = 0, temp_index = temp; k < components;
2235 k++, temp_index += element_size) {
2236 if (myswap_bytes) {
2237 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2238 totals[k] += *(const GLshort*)&swapbuf * percent;
2239 } else {
2240 totals[k] += *(const GLshort*)temp_index * percent;
2241 }
2242 }
2243
2244 /* calculate the value for pixels in the 1st and last column */
2245 for(m = lowy_int+1; m < highy_int; m++) {
2246 left += ysize;
2247 right += ysize;
2248 for (k = 0; k < components;
2249 k++, left += element_size, right += element_size) {
2250 if (myswap_bytes) {
2251 swapbuf = __GLU_SWAP_2_BYTES(left);
2252 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
2253 swapbuf = __GLU_SWAP_2_BYTES(right);
2254 totals[k] += *(const GLshort*)&swapbuf * highx_float;
2255 } else {
2256 totals[k] += *(const GLshort*)left * (1-lowx_float)
2257 + *(const GLshort*)right * highx_float;
2258 }
2259 }
2260 }
2261 } else if (highy_int > lowy_int) {
2262 x_percent = highx_float - lowx_float;
2263 percent = (1-lowy_float)*x_percent;
2264 temp = (const char *)datain + xindex + lowy_int*ysize;
2265 for (k = 0, temp_index = temp; k < components;
2266 k++, temp_index += element_size) {
2267 if (myswap_bytes) {
2268 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2269 totals[k] += *(const GLshort*)&swapbuf * percent;
2270 } else {
2271 totals[k] += *(const GLshort*)temp_index * percent;
2272 }
2273 }
2274 for(m = lowy_int+1; m < highy_int; m++) {
2275 temp += ysize;
2276 for (k = 0, temp_index = temp; k < components;
2277 k++, temp_index += element_size) {
2278 if (myswap_bytes) {
2279 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2280 totals[k] += *(const GLshort*)&swapbuf * x_percent;
2281 } else {
2282 totals[k] += *(const GLshort*)temp_index * x_percent;
2283 }
2284 }
2285 }
2286 percent = x_percent * highy_float;
2287 temp += ysize;
2288 for (k = 0, temp_index = temp; k < components;
2289 k++, temp_index += element_size) {
2290 if (myswap_bytes) {
2291 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2292 totals[k] += *(const GLshort*)&swapbuf * percent;
2293 } else {
2294 totals[k] += *(const GLshort*)temp_index * percent;
2295 }
2296 }
2297 } else if (highx_int > lowx_int) {
2298 y_percent = highy_float - lowy_float;
2299 percent = (1-lowx_float)*y_percent;
2300
2301 temp = (const char *)datain + xindex + lowy_int*ysize;
2302 for (k = 0, temp_index = temp; k < components;
2303 k++, temp_index += element_size) {
2304 if (myswap_bytes) {
2305 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2306 totals[k] += *(const GLshort*)&swapbuf * percent;
2307 } else {
2308 totals[k] += *(const GLshort*)temp_index * percent;
2309 }
2310 }
2311 for (l = lowx_int+1; l < highx_int; l++) {
2312 temp += group_size;
2313 for (k = 0, temp_index = temp; k < components;
2314 k++, temp_index += element_size) {
2315 if (myswap_bytes) {
2316 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2317 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2318 } else {
2319 totals[k] += *(const GLshort*)temp_index * y_percent;
2320 }
2321 }
2322 }
2323 temp += group_size;
2324 percent = y_percent * highx_float;
2325 for (k = 0, temp_index = temp; k < components;
2326 k++, temp_index += element_size) {
2327 if (myswap_bytes) {
2328 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2329 totals[k] += *(const GLshort*)&swapbuf * percent;
2330 } else {
2331 totals[k] += *(const GLshort*)temp_index * percent;
2332 }
2333 }
2334 } else {
2335 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2336 temp = (const char *)datain + xindex + lowy_int * ysize;
2337 for (k = 0, temp_index = temp; k < components;
2338 k++, temp_index += element_size) {
2339 if (myswap_bytes) {
2340 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2341 totals[k] += *(const GLshort*)&swapbuf * percent;
2342 } else {
2343 totals[k] += *(const GLshort*)temp_index * percent;
2344 }
2345 }
2346 }
2347
2348 /* this is for the pixels in the body */
2349 temp0 = (const char *)datain + xindex + group_size +
2350 (lowy_int+1)*ysize;
2351 for (m = lowy_int+1; m < highy_int; m++) {
2352 temp = temp0;
2353 for(l = lowx_int+1; l < highx_int; l++) {
2354 for (k = 0, temp_index = temp; k < components;
2355 k++, temp_index += element_size) {
2356 if (myswap_bytes) {
2357 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2358 totals[k] += *(const GLshort*)&swapbuf;
2359 } else {
2360 totals[k] += *(const GLshort*)temp_index;
2361 }
2362 }
2363 temp += group_size;
2364 }
2365 temp0 += ysize;
2366 }
2367
2368 outindex = (j + (i * widthout)) * components;
2369 for (k = 0; k < components; k++) {
2370 dataout[outindex + k] = totals[k]/area;
2371 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2372 }
2373 lowx_int = highx_int;
2374 lowx_float = highx_float;
2375 highx_int += convx_int;
2376 highx_float += convx_float;
2377 if(highx_float > 1) {
2378 highx_float -= 1.0;
2379 highx_int++;
2380 }
2381 }
2382 lowy_int = highy_int;
2383 lowy_float = highy_float;
2384 highy_int += convy_int;
2385 highy_float += convy_float;
2386 if(highy_float > 1) {
2387 highy_float -= 1.0;
2388 highy_int++;
2389 }
2390 }
2391}
2392
2394 GLint heightin, const GLuint *datain,
2395 GLint widthout, GLint heightout,
2396 GLuint *dataout, GLint element_size,
2397 GLint ysize, GLint group_size,
2398 GLint myswap_bytes)
2399{
2400 float convx;
2401 float convy;
2402 float percent;
2403 /* Max components in a format is 4, so... */
2404 float totals[4];
2405 float area;
2406 int i,j,k,xindex;
2407
2408 const char *temp, *temp0;
2409 const char *temp_index;
2410 int outindex;
2411
2412 int lowx_int, highx_int, lowy_int, highy_int;
2413 float x_percent, y_percent;
2414 float lowx_float, highx_float, lowy_float, highy_float;
2415 float convy_float, convx_float;
2416 int convy_int, convx_int;
2417 int l, m;
2418 const char *left, *right;
2419
2420 if (widthin == widthout*2 && heightin == heightout*2) {
2421 halveImage_uint(components, widthin, heightin,
2422 (const GLuint *)datain, (GLuint *)dataout,
2423 element_size, ysize, group_size, myswap_bytes);
2424 return;
2425 }
2426 convy = (float) heightin/heightout;
2427 convx = (float) widthin/widthout;
2428 convy_int = floor(convy);
2429 convy_float = convy - convy_int;
2430 convx_int = floor(convx);
2431 convx_float = convx - convx_int;
2432
2433 area = convx * convy;
2434
2435 lowy_int = 0;
2436 lowy_float = 0;
2437 highy_int = convy_int;
2438 highy_float = convy_float;
2439
2440 for (i = 0; i < heightout; i++) {
2441 /* Clamp here to be sure we don't read beyond input buffer. */
2442 if (highy_int >= heightin)
2443 highy_int = heightin - 1;
2444 lowx_int = 0;
2445 lowx_float = 0;
2446 highx_int = convx_int;
2447 highx_float = convx_float;
2448
2449 for (j = 0; j < widthout; j++) {
2450 /*
2451 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2452 ** to (highx, highy) on input data into this pixel on output
2453 ** data.
2454 */
2455 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2456
2457 /* calculate the value for pixels in the 1st row */
2458 xindex = lowx_int*group_size;
2459 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2460
2461 y_percent = 1-lowy_float;
2462 temp = (const char *)datain + xindex + lowy_int * ysize;
2463 percent = y_percent * (1-lowx_float);
2464 for (k = 0, temp_index = temp; k < components;
2465 k++, temp_index += element_size) {
2466 if (myswap_bytes) {
2467 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2468 } else {
2469 totals[k] += *(const GLuint*)temp_index * percent;
2470 }
2471 }
2472 left = temp;
2473 for(l = lowx_int+1; l < highx_int; l++) {
2474 temp += group_size;
2475 for (k = 0, temp_index = temp; k < components;
2476 k++, temp_index += element_size) {
2477 if (myswap_bytes) {
2478 totals[k] +=
2479 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2480 } else {
2481 totals[k] += *(const GLuint*)temp_index * y_percent;
2482 }
2483 }
2484 }
2485 temp += group_size;
2486 right = temp;
2487 percent = y_percent * highx_float;
2488 for (k = 0, temp_index = temp; k < components;
2489 k++, temp_index += element_size) {
2490 if (myswap_bytes) {
2491 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2492 } else {
2493 totals[k] += *(const GLuint*)temp_index * percent;
2494 }
2495 }
2496
2497 /* calculate the value for pixels in the last row */
2498 y_percent = highy_float;
2499 percent = y_percent * (1-lowx_float);
2500 temp = (const char *)datain + xindex + highy_int * ysize;
2501 for (k = 0, temp_index = temp; k < components;
2502 k++, temp_index += element_size) {
2503 if (myswap_bytes) {
2504 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2505 } else {
2506 totals[k] += *(const GLuint*)temp_index * percent;
2507 }
2508 }
2509 for(l = lowx_int+1; l < highx_int; l++) {
2510 temp += group_size;
2511 for (k = 0, temp_index = temp; k < components;
2512 k++, temp_index += element_size) {
2513 if (myswap_bytes) {
2514 totals[k] +=
2515 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2516 } else {
2517 totals[k] += *(const GLuint*)temp_index * y_percent;
2518 }
2519 }
2520 }
2521 temp += group_size;
2522 percent = y_percent * highx_float;
2523 for (k = 0, temp_index = temp; k < components;
2524 k++, temp_index += element_size) {
2525 if (myswap_bytes) {
2526 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2527 } else {
2528 totals[k] += *(const GLuint*)temp_index * percent;
2529 }
2530 }
2531
2532 /* calculate the value for pixels in the 1st and last column */
2533 for(m = lowy_int+1; m < highy_int; m++) {
2534 left += ysize;
2535 right += ysize;
2536 for (k = 0; k < components;
2537 k++, left += element_size, right += element_size) {
2538 if (myswap_bytes) {
2539 totals[k] +=
2540 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
2541 + __GLU_SWAP_4_BYTES(right) * highx_float;
2542 } else {
2543 totals[k] += *(const GLuint*)left * (1-lowx_float)
2544 + *(const GLuint*)right * highx_float;
2545 }
2546 }
2547 }
2548 } else if (highy_int > lowy_int) {
2549 x_percent = highx_float - lowx_float;
2550 percent = (1-lowy_float)*x_percent;
2551 temp = (const char *)datain + xindex + lowy_int*ysize;
2552 for (k = 0, temp_index = temp; k < components;
2553 k++, temp_index += element_size) {
2554 if (myswap_bytes) {
2555 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2556 } else {
2557 totals[k] += *(const GLuint*)temp_index * percent;
2558 }
2559 }
2560 for(m = lowy_int+1; m < highy_int; m++) {
2561 temp += ysize;
2562 for (k = 0, temp_index = temp; k < components;
2563 k++, temp_index += element_size) {
2564 if (myswap_bytes) {
2565 totals[k] +=
2566 __GLU_SWAP_4_BYTES(temp_index) * x_percent;
2567 } else {
2568 totals[k] += *(const GLuint*)temp_index * x_percent;
2569 }
2570 }
2571 }
2572 percent = x_percent * highy_float;
2573 temp += ysize;
2574 for (k = 0, temp_index = temp; k < components;
2575 k++, temp_index += element_size) {
2576 if (myswap_bytes) {
2577 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2578 } else {
2579 totals[k] += *(const GLuint*)temp_index * percent;
2580 }
2581 }
2582 } else if (highx_int > lowx_int) {
2583 y_percent = highy_float - lowy_float;
2584 percent = (1-lowx_float)*y_percent;
2585
2586 temp = (const char *)datain + xindex + lowy_int*ysize;
2587 for (k = 0, temp_index = temp; k < components;
2588 k++, temp_index += element_size) {
2589 if (myswap_bytes) {
2590 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2591 } else {
2592 totals[k] += *(const GLuint*)temp_index * percent;
2593 }
2594 }
2595 for (l = lowx_int+1; l < highx_int; l++) {
2596 temp += group_size;
2597 for (k = 0, temp_index = temp; k < components;
2598 k++, temp_index += element_size) {
2599 if (myswap_bytes) {
2600 totals[k] +=
2601 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2602 } else {
2603 totals[k] += *(const GLuint*)temp_index * y_percent;
2604 }
2605 }
2606 }
2607 temp += group_size;
2608 percent = y_percent * highx_float;
2609 for (k = 0, temp_index = temp; k < components;
2610 k++, temp_index += element_size) {
2611 if (myswap_bytes) {
2612 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2613 } else {
2614 totals[k] += *(const GLuint*)temp_index * percent;
2615 }
2616 }
2617 } else {
2618 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2619 temp = (const char *)datain + xindex + lowy_int * ysize;
2620 for (k = 0, temp_index = temp; k < components;
2621 k++, temp_index += element_size) {
2622 if (myswap_bytes) {
2623 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2624 } else {
2625 totals[k] += *(const GLuint*)temp_index * percent;
2626 }
2627 }
2628 }
2629
2630 /* this is for the pixels in the body */
2631 temp0 = (const char *)datain + xindex + group_size +
2632 (lowy_int+1)*ysize;
2633 for (m = lowy_int+1; m < highy_int; m++) {
2634 temp = temp0;
2635 for(l = lowx_int+1; l < highx_int; l++) {
2636 for (k = 0, temp_index = temp; k < components;
2637 k++, temp_index += element_size) {
2638 if (myswap_bytes) {
2639 totals[k] += __GLU_SWAP_4_BYTES(temp_index);
2640 } else {
2641 totals[k] += *(const GLuint*)temp_index;
2642 }
2643 }
2644 temp += group_size;
2645 }
2646 temp0 += ysize;
2647 }
2648
2649 outindex = (j + (i * widthout)) * components;
2650 for (k = 0; k < components; k++) {
2651 /* clamp at UINT_MAX */
2652 float value= totals[k]/area;
2653 if (value >= (float) UINT_MAX) { /* need '=' */
2654 dataout[outindex + k] = UINT_MAX;
2655 }
2656 else dataout[outindex + k] = value;
2657 }
2658 lowx_int = highx_int;
2659 lowx_float = highx_float;
2660 highx_int += convx_int;
2661 highx_float += convx_float;
2662 if(highx_float > 1) {
2663 highx_float -= 1.0;
2664 highx_int++;
2665 }
2666 }
2667 lowy_int = highy_int;
2668 lowy_float = highy_float;
2669 highy_int += convy_int;
2670 highy_float += convy_float;
2671 if(highy_float > 1) {
2672 highy_float -= 1.0;
2673 highy_int++;
2674 }
2675 }
2676}
2677
2678
2679
2681 GLint heightin, const GLint *datain,
2682 GLint widthout, GLint heightout,
2683 GLint *dataout, GLint element_size,
2684 GLint ysize, GLint group_size,
2685 GLint myswap_bytes)
2686{
2687 float convx;
2688 float convy;
2689 float percent;
2690 /* Max components in a format is 4, so... */
2691 float totals[4];
2692 float area;
2693 int i,j,k,xindex;
2694
2695 const char *temp, *temp0;
2696 const char *temp_index;
2697 int outindex;
2698
2699 int lowx_int, highx_int, lowy_int, highy_int;
2700 float x_percent, y_percent;
2701 float lowx_float, highx_float, lowy_float, highy_float;
2702 float convy_float, convx_float;
2703 int convy_int, convx_int;
2704 int l, m;
2705 const char *left, *right;
2706
2707 GLuint swapbuf; /* unsigned buffer */
2708
2709 if (widthin == widthout*2 && heightin == heightout*2) {
2710 halveImage_int(components, widthin, heightin,
2711 (const GLint *)datain, (GLint *)dataout,
2712 element_size, ysize, group_size, myswap_bytes);
2713 return;
2714 }
2715 convy = (float) heightin/heightout;
2716 convx = (float) widthin/widthout;
2717 convy_int = floor(convy);
2718 convy_float = convy - convy_int;
2719 convx_int = floor(convx);
2720 convx_float = convx - convx_int;
2721
2722 area = convx * convy;
2723
2724 lowy_int = 0;
2725 lowy_float = 0;
2726 highy_int = convy_int;
2727 highy_float = convy_float;
2728
2729 for (i = 0; i < heightout; i++) {
2730 /* Clamp here to be sure we don't read beyond input buffer. */
2731 if (highy_int >= heightin)
2732 highy_int = heightin - 1;
2733 lowx_int = 0;
2734 lowx_float = 0;
2735 highx_int = convx_int;
2736 highx_float = convx_float;
2737
2738 for (j = 0; j < widthout; j++) {
2739 /*
2740 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2741 ** to (highx, highy) on input data into this pixel on output
2742 ** data.
2743 */
2744 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2745
2746 /* calculate the value for pixels in the 1st row */
2747 xindex = lowx_int*group_size;
2748 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2749
2750 y_percent = 1-lowy_float;
2751 temp = (const char *)datain + xindex + lowy_int * ysize;
2752 percent = y_percent * (1-lowx_float);
2753 for (k = 0, temp_index = temp; k < components;
2754 k++, temp_index += element_size) {
2755 if (myswap_bytes) {
2756 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2757 totals[k] += *(const GLint*)&swapbuf * percent;
2758 } else {
2759 totals[k] += *(const GLint*)temp_index * percent;
2760 }
2761 }
2762 left = temp;
2763 for(l = lowx_int+1; l < highx_int; l++) {
2764 temp += group_size;
2765 for (k = 0, temp_index = temp; k < components;
2766 k++, temp_index += element_size) {
2767 if (myswap_bytes) {
2768 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2769 totals[k] += *(const GLint*)&swapbuf * y_percent;
2770 } else {
2771 totals[k] += *(const GLint*)temp_index * y_percent;
2772 }
2773 }
2774 }
2775 temp += group_size;
2776 right = temp;
2777 percent = y_percent * highx_float;
2778 for (k = 0, temp_index = temp; k < components;
2779 k++, temp_index += element_size) {
2780 if (myswap_bytes) {
2781 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2782 totals[k] += *(const GLint*)&swapbuf * percent;
2783 } else {
2784 totals[k] += *(const GLint*)temp_index * percent;
2785 }
2786 }
2787
2788 /* calculate the value for pixels in the last row */
2789 y_percent = highy_float;
2790 percent = y_percent * (1-lowx_float);
2791 temp = (const char *)datain + xindex + highy_int * ysize;
2792 for (k = 0, temp_index = temp; k < components;
2793 k++, temp_index += element_size) {
2794 if (myswap_bytes) {
2795 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2796 totals[k] += *(const GLint*)&swapbuf * percent;
2797 } else {
2798 totals[k] += *(const GLint*)temp_index * percent;
2799 }
2800 }
2801 for(l = lowx_int+1; l < highx_int; l++) {
2802 temp += group_size;
2803 for (k = 0, temp_index = temp; k < components;
2804 k++, temp_index += element_size) {
2805 if (myswap_bytes) {
2806 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2807 totals[k] += *(const GLint*)&swapbuf * y_percent;
2808 } else {
2809 totals[k] += *(const GLint*)temp_index * y_percent;
2810 }
2811 }
2812 }
2813 temp += group_size;
2814 percent = y_percent * highx_float;
2815 for (k = 0, temp_index = temp; k < components;
2816 k++, temp_index += element_size) {
2817 if (myswap_bytes) {
2818 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2819 totals[k] += *(const GLint*)&swapbuf * percent;
2820 } else {
2821 totals[k] += *(const GLint*)temp_index * percent;
2822 }
2823 }
2824
2825 /* calculate the value for pixels in the 1st and last column */
2826 for(m = lowy_int+1; m < highy_int; m++) {
2827 left += ysize;
2828 right += ysize;
2829 for (k = 0; k < components;
2830 k++, left += element_size, right += element_size) {
2831 if (myswap_bytes) {
2832 swapbuf = __GLU_SWAP_4_BYTES(left);
2833 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
2834 swapbuf = __GLU_SWAP_4_BYTES(right);
2835 totals[k] += *(const GLint*)&swapbuf * highx_float;
2836 } else {
2837 totals[k] += *(const GLint*)left * (1-lowx_float)
2838 + *(const GLint*)right * highx_float;
2839 }
2840 }
2841 }
2842 } else if (highy_int > lowy_int) {
2843 x_percent = highx_float - lowx_float;
2844 percent = (1-lowy_float)*x_percent;
2845 temp = (const char *)datain + xindex + lowy_int*ysize;
2846 for (k = 0, temp_index = temp; k < components;
2847 k++, temp_index += element_size) {
2848 if (myswap_bytes) {
2849 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2850 totals[k] += *(const GLint*)&swapbuf * percent;
2851 } else {
2852 totals[k] += *(const GLint*)temp_index * percent;
2853 }
2854 }
2855 for(m = lowy_int+1; m < highy_int; m++) {
2856 temp += ysize;
2857 for (k = 0, temp_index = temp; k < components;
2858 k++, temp_index += element_size) {
2859 if (myswap_bytes) {
2860 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2861 totals[k] += *(const GLint*)&swapbuf * x_percent;
2862 } else {
2863 totals[k] += *(const GLint*)temp_index * x_percent;
2864 }
2865 }
2866 }
2867 percent = x_percent * highy_float;
2868 temp += ysize;
2869 for (k = 0, temp_index = temp; k < components;
2870 k++, temp_index += element_size) {
2871 if (myswap_bytes) {
2872 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2873 totals[k] += *(const GLint*)&swapbuf * percent;
2874 } else {
2875 totals[k] += *(const GLint*)temp_index * percent;
2876 }
2877 }
2878 } else if (highx_int > lowx_int) {
2879 y_percent = highy_float - lowy_float;
2880 percent = (1-lowx_float)*y_percent;
2881
2882 temp = (const char *)datain + xindex + lowy_int*ysize;
2883 for (k = 0, temp_index = temp; k < components;
2884 k++, temp_index += element_size) {
2885 if (myswap_bytes) {
2886 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2887 totals[k] += *(const GLint*)&swapbuf * percent;
2888 } else {
2889 totals[k] += *(const GLint*)temp_index * percent;
2890 }
2891 }
2892 for (l = lowx_int+1; l < highx_int; l++) {
2893 temp += group_size;
2894 for (k = 0, temp_index = temp; k < components;
2895 k++, temp_index += element_size) {
2896 if (myswap_bytes) {
2897 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2898 totals[k] += *(const GLint*)&swapbuf * y_percent;
2899 } else {
2900 totals[k] += *(const GLint*)temp_index * y_percent;
2901 }
2902 }
2903 }
2904 temp += group_size;
2905 percent = y_percent * highx_float;
2906 for (k = 0, temp_index = temp; k < components;
2907 k++, temp_index += element_size) {
2908 if (myswap_bytes) {
2909 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2910 totals[k] += *(const GLint*)&swapbuf * percent;
2911 } else {
2912 totals[k] += *(const GLint*)temp_index * percent;
2913 }
2914 }
2915 } else {
2916 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2917 temp = (const char *)datain + xindex + lowy_int * ysize;
2918 for (k = 0, temp_index = temp; k < components;
2919 k++, temp_index += element_size) {
2920 if (myswap_bytes) {
2921 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2922 totals[k] += *(const GLint*)&swapbuf * percent;
2923 } else {
2924 totals[k] += *(const GLint*)temp_index * percent;
2925 }
2926 }
2927 }
2928
2929 /* this is for the pixels in the body */
2930 temp0 = (const char *)datain + xindex + group_size +
2931 (lowy_int+1)*ysize;
2932 for (m = lowy_int+1; m < highy_int; m++) {
2933 temp = temp0;
2934 for(l = lowx_int+1; l < highx_int; l++) {
2935 for (k = 0, temp_index = temp; k < components;
2936 k++, temp_index += element_size) {
2937 if (myswap_bytes) {
2938 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2939 totals[k] += *(const GLint*)&swapbuf;
2940 } else {
2941 totals[k] += *(const GLint*)temp_index;
2942 }
2943 }
2944 temp += group_size;
2945 }
2946 temp0 += ysize;
2947 }
2948
2949 outindex = (j + (i * widthout)) * components;
2950 for (k = 0; k < components; k++) {
2951 dataout[outindex + k] = totals[k]/area;
2952 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2953 }
2954 lowx_int = highx_int;
2955 lowx_float = highx_float;
2956 highx_int += convx_int;
2957 highx_float += convx_float;
2958 if(highx_float > 1) {
2959 highx_float -= 1.0;
2960 highx_int++;
2961 }
2962 }
2963 lowy_int = highy_int;
2964 lowy_float = highy_float;
2965 highy_int += convy_int;
2966 highy_float += convy_float;
2967 if(highy_float > 1) {
2968 highy_float -= 1.0;
2969 highy_int++;
2970 }
2971 }
2972}
2973
2974
2975
2977 GLint heightin, const GLfloat *datain,
2978 GLint widthout, GLint heightout,
2979 GLfloat *dataout, GLint element_size,
2980 GLint ysize, GLint group_size,
2981 GLint myswap_bytes)
2982{
2983 float convx;
2984 float convy;
2985 float percent;
2986 /* Max components in a format is 4, so... */
2987 float totals[4];
2988 float area;
2989 int i,j,k,xindex;
2990
2991 const char *temp, *temp0;
2992 const char *temp_index;
2993 int outindex;
2994
2995 int lowx_int, highx_int, lowy_int, highy_int;
2996 float x_percent, y_percent;
2997 float lowx_float, highx_float, lowy_float, highy_float;
2998 float convy_float, convx_float;
2999 int convy_int, convx_int;
3000 int l, m;
3001 const char *left, *right;
3002
3003 union { GLuint b; GLfloat f; } swapbuf;
3004
3005 if (widthin == widthout*2 && heightin == heightout*2) {
3006 halveImage_float(components, widthin, heightin,
3007 (const GLfloat *)datain, (GLfloat *)dataout,
3008 element_size, ysize, group_size, myswap_bytes);
3009 return;
3010 }
3011 convy = (float) heightin/heightout;
3012 convx = (float) widthin/widthout;
3013 convy_int = floor(convy);
3014 convy_float = convy - convy_int;
3015 convx_int = floor(convx);
3016 convx_float = convx - convx_int;
3017
3018 area = convx * convy;
3019
3020 lowy_int = 0;
3021 lowy_float = 0;
3022 highy_int = convy_int;
3023 highy_float = convy_float;
3024
3025 for (i = 0; i < heightout; i++) {
3026 /* Clamp here to be sure we don't read beyond input buffer. */
3027 if (highy_int >= heightin)
3028 highy_int = heightin - 1;
3029 lowx_int = 0;
3030 lowx_float = 0;
3031 highx_int = convx_int;
3032 highx_float = convx_float;
3033
3034 for (j = 0; j < widthout; j++) {
3035 /*
3036 ** Ok, now apply box filter to box that goes from (lowx, lowy)
3037 ** to (highx, highy) on input data into this pixel on output
3038 ** data.
3039 */
3040 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
3041
3042 /* calculate the value for pixels in the 1st row */
3043 xindex = lowx_int*group_size;
3044 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
3045
3046 y_percent = 1-lowy_float;
3047 temp = (const char *)datain + xindex + lowy_int * ysize;
3048 percent = y_percent * (1-lowx_float);
3049 for (k = 0, temp_index = temp; k < components;
3050 k++, temp_index += element_size) {
3051 if (myswap_bytes) {
3052 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3053 totals[k] += swapbuf.f * percent;
3054 } else {
3055 totals[k] += *(const GLfloat*)temp_index * percent;
3056 }
3057 }
3058 left = temp;
3059 for(l = lowx_int+1; l < highx_int; l++) {
3060 temp += group_size;
3061 for (k = 0, temp_index = temp; k < components;
3062 k++, temp_index += element_size) {
3063 if (myswap_bytes) {
3064 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3065 totals[k] += swapbuf.f * y_percent;
3066 } else {
3067 totals[k] += *(const GLfloat*)temp_index * y_percent;
3068 }
3069 }
3070 }
3071 temp += group_size;
3072 right = temp;
3073 percent = y_percent * highx_float;
3074 for (k = 0, temp_index = temp; k < components;
3075 k++, temp_index += element_size) {
3076 if (myswap_bytes) {
3077 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3078 totals[k] += swapbuf.f * percent;
3079 } else {
3080 totals[k] += *(const GLfloat*)temp_index * percent;
3081 }
3082 }
3083
3084 /* calculate the value for pixels in the last row */
3085 y_percent = highy_float;
3086 percent = y_percent * (1-lowx_float);
3087 temp = (const char *)datain + xindex + highy_int * ysize;
3088 for (k = 0, temp_index = temp; k < components;
3089 k++, temp_index += element_size) {
3090 if (myswap_bytes) {
3091 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3092 totals[k] += swapbuf.f * percent;
3093 } else {
3094 totals[k] += *(const GLfloat*)temp_index * percent;
3095 }
3096 }
3097 for(l = lowx_int+1; l < highx_int; l++) {
3098 temp += group_size;
3099 for (k = 0, temp_index = temp; k < components;
3100 k++, temp_index += element_size) {
3101 if (myswap_bytes) {
3102 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3103 totals[k] += swapbuf.f * y_percent;
3104 } else {
3105 totals[k] += *(const GLfloat*)temp_index * y_percent;
3106 }
3107 }
3108 }
3109 temp += group_size;
3110 percent = y_percent * highx_float;
3111 for (k = 0, temp_index = temp; k < components;
3112 k++, temp_index += element_size) {
3113 if (myswap_bytes) {
3114 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3115 totals[k] += swapbuf.f * percent;
3116 } else {
3117 totals[k] += *(const GLfloat*)temp_index * percent;
3118 }
3119 }
3120
3121 /* calculate the value for pixels in the 1st and last column */
3122 for(m = lowy_int+1; m < highy_int; m++) {
3123 left += ysize;
3124 right += ysize;
3125 for (k = 0; k < components;
3126 k++, left += element_size, right += element_size) {
3127 if (myswap_bytes) {
3128 swapbuf.b = __GLU_SWAP_4_BYTES(left);
3129 totals[k] += swapbuf.f * (1-lowx_float);
3130 swapbuf.b = __GLU_SWAP_4_BYTES(right);
3131 totals[k] += swapbuf.f * highx_float;
3132 } else {
3133 totals[k] += *(const GLfloat*)left * (1-lowx_float)
3134 + *(const GLfloat*)right * highx_float;
3135 }
3136 }
3137 }
3138 } else if (highy_int > lowy_int) {
3139 x_percent = highx_float - lowx_float;
3140 percent = (1-lowy_float)*x_percent;
3141 temp = (const char *)datain + xindex + lowy_int*ysize;
3142 for (k = 0, temp_index = temp; k < components;
3143 k++, temp_index += element_size) {
3144 if (myswap_bytes) {
3145 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3146 totals[k] += swapbuf.f * percent;
3147 } else {
3148 totals[k] += *(const GLfloat*)temp_index * percent;
3149 }
3150 }
3151 for(m = lowy_int+1; m < highy_int; m++) {
3152 temp += ysize;
3153 for (k = 0, temp_index = temp; k < components;
3154 k++, temp_index += element_size) {
3155 if (myswap_bytes) {
3156 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3157 totals[k] += swapbuf.f * x_percent;
3158 } else {
3159 totals[k] += *(const GLfloat*)temp_index * x_percent;
3160 }
3161 }
3162 }
3163 percent = x_percent * highy_float;
3164 temp += ysize;
3165 for (k = 0, temp_index = temp; k < components;
3166 k++, temp_index += element_size) {
3167 if (myswap_bytes) {
3168 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3169 totals[k] += swapbuf.f * percent;
3170 } else {
3171 totals[k] += *(const GLfloat*)temp_index * percent;
3172 }
3173 }
3174 } else if (highx_int > lowx_int) {
3175 y_percent = highy_float - lowy_float;
3176 percent = (1-lowx_float)*y_percent;
3177
3178 temp = (const char *)datain + xindex + lowy_int*ysize;
3179 for (k = 0, temp_index = temp; k < components;
3180 k++, temp_index += element_size) {
3181 if (myswap_bytes) {
3182 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3183 totals[k] += swapbuf.f * percent;
3184 } else {
3185 totals[k] += *(const GLfloat*)temp_index * percent;
3186 }
3187 }
3188 for (l = lowx_int+1; l < highx_int; l++) {
3189 temp += group_size;
3190 for (k = 0, temp_index = temp; k < components;
3191 k++, temp_index += element_size) {
3192 if (myswap_bytes) {
3193 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3194 totals[k] += swapbuf.f * y_percent;
3195 } else {
3196 totals[k] += *(const GLfloat*)temp_index * y_percent;
3197 }
3198 }
3199 }
3200 temp += group_size;
3201 percent = y_percent * highx_float;
3202 for (k = 0, temp_index = temp; k < components;
3203 k++, temp_index += element_size) {
3204 if (myswap_bytes) {
3205 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3206 totals[k] += swapbuf.f * percent;
3207 } else {
3208 totals[k] += *(const GLfloat*)temp_index * percent;
3209 }
3210 }
3211 } else {
3212 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
3213 temp = (const char *)datain + xindex + lowy_int * ysize;
3214 for (k = 0, temp_index = temp; k < components;
3215 k++, temp_index += element_size) {
3216 if (myswap_bytes) {
3217 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3218 totals[k] += swapbuf.f * percent;
3219 } else {
3220 totals[k] += *(const GLfloat*)temp_index * percent;
3221 }
3222 }
3223 }
3224
3225 /* this is for the pixels in the body */
3226 temp0 = (const char *)datain + xindex + group_size +
3227 (lowy_int+1)*ysize;
3228 for (m = lowy_int+1; m < highy_int; m++) {
3229 temp = temp0;
3230 for(l = lowx_int+1; l < highx_int; l++) {
3231 for (k = 0, temp_index = temp; k < components;
3232 k++, temp_index += element_size) {
3233 if (myswap_bytes) {
3234 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3235 totals[k] += swapbuf.f;
3236 } else {
3237 totals[k] += *(const GLfloat*)temp_index;
3238 }
3239 }
3240 temp += group_size;
3241 }
3242 temp0 += ysize;
3243 }
3244
3245 outindex = (j + (i * widthout)) * components;
3246 for (k = 0; k < components; k++) {
3247 dataout[outindex + k] = totals[k]/area;
3248 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3249 }
3250 lowx_int = highx_int;
3251 lowx_float = highx_float;
3252 highx_int += convx_int;
3253 highx_float += convx_float;
3254 if(highx_float > 1) {
3255 highx_float -= 1.0;
3256 highx_int++;
3257 }
3258 }
3259 lowy_int = highy_int;
3260 lowy_float = highy_float;
3261 highy_int += convy_int;
3262 highy_float += convy_float;
3263 if(highy_float > 1) {
3264 highy_float -= 1.0;
3265 highy_int++;
3266 }
3267 }
3268}
3269
3271{
3272 if (!legalFormat(format) || !legalType(type)) {
3273 return GLU_INVALID_ENUM;
3274 }
3275 if (format == GL_STENCIL_INDEX) {
3276 return GLU_INVALID_ENUM;
3277 }
3278
3280 return GLU_INVALID_OPERATION;
3281 }
3282
3283 return 0;
3284} /* checkMipmapArgs() */
3285
3287{
3288 switch(format) {
3289 case GL_COLOR_INDEX:
3290 case GL_STENCIL_INDEX:
3291 case GL_DEPTH_COMPONENT:
3292 case GL_RED:
3293 case GL_GREEN:
3294 case GL_BLUE:
3295 case GL_ALPHA:
3296 case GL_RGB:
3297 case GL_RGBA:
3298 case GL_LUMINANCE:
3299 case GL_LUMINANCE_ALPHA:
3300 case GL_BGR:
3301 case GL_BGRA:
3302 return GL_TRUE;
3303 default:
3304 return GL_FALSE;
3305 }
3306}
3307
3308
3310{
3311 switch(type) {
3312 case GL_BITMAP:
3313 case GL_BYTE:
3314 case GL_UNSIGNED_BYTE:
3315 case GL_SHORT:
3316 case GL_UNSIGNED_SHORT:
3317 case GL_INT:
3318 case GL_UNSIGNED_INT:
3319 case GL_FLOAT:
3332 return GL_TRUE;
3333 default:
3334 return GL_FALSE;
3335 }
3336}
3337
3338/* */
3340{
3342
3355 return 1;
3356 }
3357 else return 0;
3358} /* isTypePackedPixel() */
3359
3360/* Determines if the packed pixel type is compatible with the format */
3362{
3363 /* if not a packed pixel type then return true */
3364 if (!isTypePackedPixel(type)) {
3365 return GL_TRUE;
3366 }
3367
3368 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3371 && format != GL_RGB)
3372 return GL_FALSE;
3373
3374 /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
3375 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3376 */
3385 (format != GL_RGBA &&
3386 format != GL_BGRA)) {
3387 return GL_FALSE;
3388 }
3389
3390 return GL_TRUE;
3391} /* isLegalFormatForPackedPixelType() */
3392
3393static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel,
3394 GLint totalLevels)
3395{
3396 if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel ||
3397 totalLevels < maxLevel)
3398 return GL_FALSE;
3399 else return GL_TRUE;
3400} /* isLegalLevels() */
3401
3402/* Given user requested texture size, determine if it fits. If it
3403 * doesn't then halve both sides and make the determination again
3404 * until it does fit (for IR only).
3405 * Note that proxy textures are not implemented in RE* even though
3406 * they advertise the texture extension.
3407 * Note that proxy textures are implemented but not according to spec in
3408 * IMPACT*.
3409 */
3412 GLint *newWidth, GLint *newHeight)
3413{
3414 /* Use proxy textures if OpenGL version is >= 1.1 */
3415 if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
3416 ) {
3417 GLint widthPowerOf2= nearestPower(width);
3418 GLint heightPowerOf2= nearestPower(height);
3419 GLint proxyWidth;
3420
3421 do {
3422 /* compute level 1 width & height, clamping each at 1 */
3423 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
3424 widthPowerOf2 >> 1 :
3425 widthPowerOf2;
3426 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
3427 heightPowerOf2 >> 1 :
3428 heightPowerOf2;
3429 GLenum proxyTarget;
3430 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
3431
3432 /* does width x height at level 1 & all their mipmaps fit? */
3434 proxyTarget = GL_PROXY_TEXTURE_2D;
3435 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3437 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3438 } else
3439#if defined(GL_ARB_texture_cube_map)
3446 proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3447 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3449 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3450 } else
3451#endif /* GL_ARB_texture_cube_map */
3452 {
3454 proxyTarget = GL_PROXY_TEXTURE_1D;
3455 glTexImage1D(proxyTarget, 1, /* must be non-zero */
3456 internalFormat,widthAtLevelOne,0,format,type,NULL);
3457 }
3458 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
3459 /* does it fit??? */
3460 if (proxyWidth == 0) { /* nope, so try again with these sizes */
3461 if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
3462 /* An 1x1 texture couldn't fit for some reason, so
3463 * break out. This should never happen. But things
3464 * happen. The disadvantage with this if-statement is
3465 * that we will never be aware of when this happens
3466 * since it will silently branch out.
3467 */
3468 goto noProxyTextures;
3469 }
3470 widthPowerOf2= widthAtLevelOne;
3471 heightPowerOf2= heightAtLevelOne;
3472 }
3473 /* else it does fit */
3474 } while (proxyWidth == 0);
3475 /* loop must terminate! */
3476
3477 /* return the width & height at level 0 that fits */
3478 *newWidth= widthPowerOf2;
3479 *newHeight= heightPowerOf2;
3480/*printf("Proxy Textures\n");*/
3481 } /* if gluCheckExtension() */
3482 else { /* no texture extension, so do this instead */
3483 GLint maxsize;
3484
3485noProxyTextures:
3486
3488 /* clamp user's texture sizes to maximum sizes, if necessary */
3489 *newWidth = nearestPower(width);
3490 if (*newWidth > maxsize) *newWidth = maxsize;
3491 *newHeight = nearestPower(height);
3492 if (*newHeight > maxsize) *newHeight = maxsize;
3493/*printf("NO proxy textures\n");*/
3494 }
3495} /* closestFit() */
3496
3499 GLenum typein, const void *datain,
3500 GLsizei widthout, GLsizei heightout, GLenum typeout,
3501 void *dataout)
3502{
3503 int components;
3504 GLushort *beforeImage;
3505 GLushort *afterImage;
3507
3508 if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
3509 return 0;
3510 }
3511 if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
3512 return GLU_INVALID_VALUE;
3513 }
3514 if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
3515 return GLU_INVALID_ENUM;
3516 }
3518 return GLU_INVALID_OPERATION;
3519 }
3520 if (!isLegalFormatForPackedPixelType(format, typeout)) {
3521 return GLU_INVALID_OPERATION;
3522 }
3523 beforeImage =
3524 malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
3525 afterImage =
3526 malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
3527 if (beforeImage == NULL || afterImage == NULL) {
3528 free(beforeImage);
3529 free(afterImage);
3530 return GLU_OUT_OF_MEMORY;
3531 }
3532
3533 retrieveStoreModes(&psm);
3534 fill_image(&psm,widthin, heightin, format, typein, is_index(format),
3535 datain, beforeImage);
3537 scale_internal(components, widthin, heightin, beforeImage,
3538 widthout, heightout, afterImage);
3539 empty_image(&psm,widthout, heightout, format, typeout,
3540 is_index(format), afterImage, dataout);
3541 free((GLbyte *) beforeImage);
3542 free((GLbyte *) afterImage);
3543
3544 return 0;
3545}
3546
3548 GLsizei width,
3549 GLsizei widthPowerOf2,
3551 GLint userLevel, GLint baseLevel,GLint maxLevel,
3552 const void *data)
3553{
3554 GLint newwidth;
3556 GLushort *newImage;
3557 GLint newImage_width;
3558 GLushort *otherImage;
3559 GLushort *imageTemp;
3560 GLint memreq;
3561 GLint cmpts;
3563
3565 assert(width >= 1);
3566
3567 otherImage = NULL;
3568
3569 newwidth= widthPowerOf2;
3570 levels = computeLog(newwidth);
3571
3572 levels+= userLevel;
3573
3574 retrieveStoreModes(&psm);
3575 newImage = (GLushort *)
3577 newImage_width = width;
3578 if (newImage == NULL) {
3579 return GLU_OUT_OF_MEMORY;
3580 }
3582 data, newImage);
3588 /*
3589 ** If swap_bytes was set, swapping occurred in fill_image.
3590 */
3592
3593 for (level = userLevel; level <= levels; level++) {
3594 if (newImage_width == newwidth) {
3595 /* Use newImage for this level */
3596 if (baseLevel <= level && level <= maxLevel) {
3597 glTexImage1D(target, level, internalFormat, newImage_width,
3598 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3599 }
3600 } else {
3601 if (otherImage == NULL) {
3602 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
3603 otherImage = (GLushort *) malloc(memreq);
3604 if (otherImage == NULL) {
3610 free(newImage);
3611 return GLU_OUT_OF_MEMORY;
3612 }
3613 }
3614 scale_internal(cmpts, newImage_width, 1, newImage,
3615 newwidth, 1, otherImage);
3616 /* Swap newImage and otherImage */
3617 imageTemp = otherImage;
3618 otherImage = newImage;
3619 newImage = imageTemp;
3620
3621 newImage_width = newwidth;
3622 if (baseLevel <= level && level <= maxLevel) {
3623 glTexImage1D(target, level, internalFormat, newImage_width,
3624 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3625 }
3626 }
3627 if (newwidth > 1) newwidth /= 2;
3628 }
3634
3635 free((GLbyte *) newImage);
3636 if (otherImage) {
3637 free((GLbyte *) otherImage);
3638 }
3639 return 0;
3640}
3641
3644 GLsizei width,
3646 GLint userLevel, GLint baseLevel, GLint maxLevel,
3647 const void *data)
3648{
3649 int levels;
3650
3652 if (rc != 0) return rc;
3653
3654 if (width < 1) {
3655 return GLU_INVALID_VALUE;
3656 }
3657
3659
3660 levels+= userLevel;
3661 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
3662 return GLU_INVALID_VALUE;
3663
3665 width,
3666 width,format, type,
3667 userLevel, baseLevel, maxLevel,
3668 data);
3669} /* gluBuild1DMipmapLevels() */
3670
3674 const void *data)
3675{
3676 GLint widthPowerOf2;
3677 int levels;
3678 GLint dummy;
3679
3681 if (rc != 0) return rc;
3682
3683 if (width < 1) {
3684 return GLU_INVALID_VALUE;
3685 }
3686
3688 levels = computeLog(widthPowerOf2);
3689
3691 width,
3692 widthPowerOf2,
3693 format,type,0,0,levels,data);
3694}
3695
3698 GLenum type, const void *data)
3699{
3700 GLint newwidth, newheight;
3702 GLushort *newImage;
3703 GLint newImage_width;
3704 GLint newImage_height;
3705 GLushort *otherImage;
3706 GLushort *imageTemp;
3707 GLint memreq;
3708 GLint cmpts;
3710
3711 retrieveStoreModes(&psm);
3712
3713#if 0
3715 newwidth = nearestPower(width);
3716 if (newwidth > maxsize) newwidth = maxsize;
3717 newheight = nearestPower(height);
3718 if (newheight > maxsize) newheight = maxsize;
3719#else
3721 &newwidth,&newheight);
3722#endif
3723 levels = computeLog(newwidth);
3724 level = computeLog(newheight);
3725 if (level > levels) levels=level;
3726
3727 otherImage = NULL;
3728 newImage = (GLushort *)
3730 newImage_width = width;
3731 newImage_height = height;
3732 if (newImage == NULL) {
3733 return GLU_OUT_OF_MEMORY;
3734 }
3735
3737 data, newImage);
3738
3744 /*
3745 ** If swap_bytes was set, swapping occurred in fill_image.
3746 */
3748
3749 for (level = 0; level <= levels; level++) {
3750 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
3751 glTexImage2D(target, level, internalFormat, newImage_width,
3752 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3753 (void *) newImage);
3754 } else {
3755 if (otherImage == NULL) {
3756 memreq =
3757 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
3758 otherImage = (GLushort *) malloc(memreq);
3759 if (otherImage == NULL) {
3765 free(newImage);
3766 return GLU_OUT_OF_MEMORY;
3767 }
3768 }
3769 scale_internal(cmpts, newImage_width, newImage_height, newImage,
3770 newwidth, newheight, otherImage);
3771 /* Swap newImage and otherImage */
3772 imageTemp = otherImage;
3773 otherImage = newImage;
3774 newImage = imageTemp;
3775
3776 newImage_width = newwidth;
3777 newImage_height = newheight;
3778 glTexImage2D(target, level, internalFormat, newImage_width,
3779 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3780 (void *) newImage);
3781 }
3782 if (newwidth > 1) newwidth /= 2;
3783 if (newheight > 1) newheight /= 2;
3784 }
3790
3791 free((GLbyte *) newImage);
3792 if (otherImage) {
3793 free((GLbyte *) otherImage);
3794 }
3795 return 0;
3796}
3797
3798/* To make swapping images less error prone */
3799#define __GLU_INIT_SWAP_IMAGE void *tmpImage
3800#define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3801
3804 GLsizei widthPowerOf2,
3805 GLsizei heightPowerOf2,
3807 GLint userLevel,
3808 GLint baseLevel,GLint maxLevel,
3809 const void *data)
3810{
3811 GLint newwidth, newheight;
3813 const void *usersImage; /* passed from user. Don't touch! */
3814 void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3816 GLint memreq;
3817 GLint cmpts;
3818
3819 GLint myswap_bytes, groups_per_line, element_size, group_size;
3820 GLint rowsize, padding;
3822
3824 assert(width >= 1 && height >= 1);
3825
3826 if(type == GL_BITMAP) {
3828 format, type, data);
3829 }
3830
3831 srcImage = dstImage = NULL;
3832
3833 newwidth= widthPowerOf2;
3834 newheight= heightPowerOf2;
3835 levels = computeLog(newwidth);
3836 level = computeLog(newheight);
3837 if (level > levels) levels=level;
3838
3839 levels+= userLevel;
3840
3841 retrieveStoreModes(&psm);
3842 myswap_bytes = psm.unpack_swap_bytes;
3844 if (psm.unpack_row_length > 0) {
3845 groups_per_line = psm.unpack_row_length;
3846 } else {
3847 groups_per_line = width;
3848 }
3849
3850 element_size = bytes_per_element(type);
3851 group_size = element_size * cmpts;
3852 if (element_size == 1) myswap_bytes = 0;
3853
3854 rowsize = groups_per_line * group_size;
3855 padding = (rowsize % psm.unpack_alignment);
3856 if (padding) {
3857 rowsize += psm.unpack_alignment - padding;
3858 }
3859 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3860 psm.unpack_skip_pixels * group_size;
3861
3865
3866 level = userLevel;
3867
3868 /* already power-of-two square */
3869 if (width == newwidth && height == newheight) {
3870 /* Use usersImage for level userLevel */
3871 if (baseLevel <= level && level <= maxLevel) {
3874 height, 0, format, type,
3875 usersImage);
3876 }
3878 if(levels == 0) { /* we're done. clean up and return */
3884 return 0;
3885 }
3886 {
3887 int nextWidth= newwidth/2;
3888 int nextHeight= newheight/2;
3889
3890 /* clamp to 1 */
3891 if (nextWidth < 1) nextWidth= 1;
3892 if (nextHeight < 1) nextHeight= 1;
3893 memreq = image_size(nextWidth, nextHeight, format, type);
3894 }
3895
3896 switch(type) {
3897 case GL_UNSIGNED_BYTE:
3898 dstImage = (GLubyte *)malloc(memreq);
3899 break;
3900 case GL_BYTE:
3901 dstImage = (GLbyte *)malloc(memreq);
3902 break;
3903 case GL_UNSIGNED_SHORT:
3904 dstImage = (GLushort *)malloc(memreq);
3905 break;
3906 case GL_SHORT:
3907 dstImage = (GLshort *)malloc(memreq);
3908 break;
3909 case GL_UNSIGNED_INT:
3910 dstImage = (GLuint *)malloc(memreq);
3911 break;
3912 case GL_INT:
3913 dstImage = (GLint *)malloc(memreq);
3914 break;
3915 case GL_FLOAT:
3916 dstImage = (GLfloat *)malloc(memreq);
3917 break;
3920 dstImage = (GLubyte *)malloc(memreq);
3921 break;
3928 dstImage = (GLushort *)malloc(memreq);
3929 break;
3934 dstImage = (GLuint *)malloc(memreq);
3935 break;
3936 default:
3937 return GLU_INVALID_ENUM;
3938 }
3939 if (dstImage == NULL) {
3945 return GLU_OUT_OF_MEMORY;
3946 }
3947 else
3948 switch(type) {
3949 case GL_UNSIGNED_BYTE:
3951 (const GLubyte *)usersImage, (GLubyte *)dstImage,
3952 element_size, rowsize, group_size);
3953 break;
3954 case GL_BYTE:
3956 (const GLbyte *)usersImage, (GLbyte *)dstImage,
3957 element_size, rowsize, group_size);
3958 break;
3959 case GL_UNSIGNED_SHORT:
3961 (const GLushort *)usersImage, (GLushort *)dstImage,
3962 element_size, rowsize, group_size, myswap_bytes);
3963 break;
3964 case GL_SHORT:
3966 (const GLshort *)usersImage, (GLshort *)dstImage,
3967 element_size, rowsize, group_size, myswap_bytes);
3968 break;
3969 case GL_UNSIGNED_INT:
3971 (const GLuint *)usersImage, (GLuint *)dstImage,
3972 element_size, rowsize, group_size, myswap_bytes);
3973 break;
3974 case GL_INT:
3975 halveImage_int(cmpts, width, height,
3976 (const GLint *)usersImage, (GLint *)dstImage,
3977 element_size, rowsize, group_size, myswap_bytes);
3978 break;
3979 case GL_FLOAT:
3981 (const GLfloat *)usersImage, (GLfloat *)dstImage,
3982 element_size, rowsize, group_size, myswap_bytes);
3983 break;
3985 assert(format == GL_RGB);
3987 width,height,usersImage,dstImage,
3988 element_size,rowsize,myswap_bytes);
3989 break;
3991 assert(format == GL_RGB);
3993 width,height,usersImage,dstImage,
3994 element_size,rowsize,myswap_bytes);
3995 break;
3998 width,height,usersImage,dstImage,
3999 element_size,rowsize,myswap_bytes);
4000 break;
4003 width,height,usersImage,dstImage,
4004 element_size,rowsize,myswap_bytes);
4005 break;
4008 width,height,usersImage,dstImage,
4009 element_size,rowsize,myswap_bytes);
4010 break;
4013 width,height,usersImage,dstImage,
4014 element_size,rowsize,myswap_bytes);
4015 break;
4018 width,height,usersImage,dstImage,
4019 element_size,rowsize,myswap_bytes);
4020 break;
4023 width,height,usersImage,dstImage,
4024 element_size,rowsize,myswap_bytes);
4025 break;
4028 width,height,usersImage,dstImage,
4029 element_size,rowsize,myswap_bytes);
4030 break;
4033 width,height,usersImage,dstImage,
4034 element_size,rowsize,myswap_bytes);
4035 break;
4038 width,height,usersImage,dstImage,
4039 element_size,rowsize,myswap_bytes);
4040 break;
4043 width,height,usersImage,dstImage,
4044 element_size,rowsize,myswap_bytes);
4045 break;
4046 default:
4047 assert(0);
4048 break;
4049 }
4050 newwidth = width/2;
4051 newheight = height/2;
4052 /* clamp to 1 */
4053 if (newwidth < 1) newwidth= 1;
4054 if (newheight < 1) newheight= 1;
4055
4056 myswap_bytes = 0;
4057 rowsize = newwidth * group_size;
4058 memreq = image_size(newwidth, newheight, format, type);
4059 /* Swap srcImage and dstImage */
4060 __GLU_SWAP_IMAGE(srcImage,dstImage);
4061 switch(type) {
4062 case GL_UNSIGNED_BYTE:
4063 dstImage = (GLubyte *)malloc(memreq);
4064 break;
4065 case GL_BYTE:
4066 dstImage = (GLbyte *)malloc(memreq);
4067 break;
4068 case GL_UNSIGNED_SHORT:
4069 dstImage = (GLushort *)malloc(memreq);
4070 break;
4071 case GL_SHORT:
4072 dstImage = (GLshort *)malloc(memreq);
4073 break;
4074 case GL_UNSIGNED_INT:
4075 dstImage = (GLuint *)malloc(memreq);
4076 break;
4077 case GL_INT:
4078 dstImage = (GLint *)malloc(memreq);
4079 break;
4080 case GL_FLOAT:
4081 dstImage = (GLfloat *)malloc(memreq);
4082 break;
4085 dstImage = (GLubyte *)malloc(memreq);
4086 break;
4093 dstImage = (GLushort *)malloc(memreq);
4094 break;
4099 dstImage = (GLuint *)malloc(memreq);
4100 break;
4101 default:
4102 return GLU_INVALID_ENUM;
4103 }
4104 if (dstImage == NULL) {
4110 free(srcImage);
4111 return GLU_OUT_OF_MEMORY;
4112 }
4113 /* level userLevel+1 is in srcImage; level userLevel already saved */
4114 level = userLevel+1;
4115 } else { /* user's image is *not* nice power-of-2 sized square */
4116 memreq = image_size(newwidth, newheight, format, type);
4117 switch(type) {
4118 case GL_UNSIGNED_BYTE:
4119 dstImage = (GLubyte *)malloc(memreq);
4120 break;
4121 case GL_BYTE:
4122 dstImage = (GLbyte *)malloc(memreq);
4123 break;
4124 case GL_UNSIGNED_SHORT:
4125 dstImage = (GLushort *)malloc(memreq);
4126 break;
4127 case GL_SHORT:
4128 dstImage = (GLshort *)malloc(memreq);
4129 break;
4130 case GL_UNSIGNED_INT:
4131 dstImage = (GLuint *)malloc(memreq);
4132 break;
4133 case GL_INT:
4134 dstImage = (GLint *)malloc(memreq);
4135 break;
4136 case GL_FLOAT:
4137 dstImage = (GLfloat *)malloc(memreq);
4138 break;
4141 dstImage = (GLubyte *)malloc(memreq);
4142 break;
4149 dstImage = (GLushort *)malloc(memreq);
4150 break;
4155 dstImage = (GLuint *)malloc(memreq);
4156 break;
4157 default:
4158 return GLU_INVALID_ENUM;
4159 }
4160
4161 if (dstImage == NULL) {
4167 return GLU_OUT_OF_MEMORY;
4168 }
4169
4170 switch(type) {
4171 case GL_UNSIGNED_BYTE: