ReactOS  r76032
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 
40 typedef 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;
48 } Type_Widget;
49 
50 /* Pixel storage modes */
51 typedef struct {
60 
70 
72  GLsizei,
73  GLsizei,
75  const void *);
80  const void *);
85  const void *);
86 
87 /*
88  * internal function declarations
89  */
92 static GLint is_index(GLenum format);
94 static void fill_image(const PixelStorageModes *,
96  GLenum type, GLboolean index_format,
97  const void *userdata, GLushort *newimage);
98 static void empty_image(const PixelStorageModes *,
100  GLenum type, GLboolean index_format,
101  const GLushort *oldimage, void *userdata);
102 static void scale_internal(GLint components, GLint widthin, GLint heightin,
103  const GLushort *datain,
104  GLint widthout, GLint heightout,
105  GLushort *dataout);
106 
107 static void scale_internal_ubyte(GLint components, GLint widthin,
108  GLint heightin, const GLubyte *datain,
109  GLint widthout, GLint heightout,
110  GLubyte *dataout, GLint element_size,
111  GLint ysize, GLint group_size);
112 static void scale_internal_byte(GLint components, GLint widthin,
113  GLint heightin, const GLbyte *datain,
114  GLint widthout, GLint heightout,
115  GLbyte *dataout, GLint element_size,
116  GLint ysize, GLint group_size);
117 static void scale_internal_ushort(GLint components, GLint widthin,
118  GLint heightin, const GLushort *datain,
119  GLint widthout, GLint heightout,
120  GLushort *dataout, GLint element_size,
121  GLint ysize, GLint group_size,
122  GLint myswap_bytes);
123 static void scale_internal_short(GLint components, GLint widthin,
124  GLint heightin, const GLshort *datain,
125  GLint widthout, GLint heightout,
126  GLshort *dataout, GLint element_size,
127  GLint ysize, GLint group_size,
128  GLint myswap_bytes);
129 static void scale_internal_uint(GLint components, GLint widthin,
130  GLint heightin, const GLuint *datain,
131  GLint widthout, GLint heightout,
132  GLuint *dataout, GLint element_size,
133  GLint ysize, GLint group_size,
134  GLint myswap_bytes);
135 static void scale_internal_int(GLint components, GLint widthin,
136  GLint heightin, const GLint *datain,
137  GLint widthout, GLint heightout,
138  GLint *dataout, GLint element_size,
139  GLint ysize, GLint group_size,
140  GLint myswap_bytes);
141 static void scale_internal_float(GLint components, GLint widthin,
142  GLint heightin, const GLfloat *datain,
143  GLint widthout, GLint heightout,
144  GLfloat *dataout, GLint element_size,
145  GLint ysize, GLint group_size,
146  GLint myswap_bytes);
147 
148 static int checkMipmapArgs(GLenum, GLenum, GLenum);
150 static GLboolean legalType(GLenum);
154 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
155  GLint *, GLint *);
156 
157 /* all extract/shove routines must return double to handle unsigned ints */
158 static GLdouble extractUbyte(int, const void *);
159 static void shoveUbyte(GLdouble, int, void *);
160 static GLdouble extractSbyte(int, const void *);
161 static void shoveSbyte(GLdouble, int, void *);
162 static GLdouble extractUshort(int, const void *);
163 static void shoveUshort(GLdouble, int, void *);
164 static GLdouble extractSshort(int, const void *);
165 static void shoveSshort(GLdouble, int, void *);
166 static GLdouble extractUint(int, const void *);
167 static void shoveUint(GLdouble, int, void *);
168 static GLdouble extractSint(int, const void *);
169 static void shoveSint(GLdouble, int, void *);
170 static GLdouble extractFloat(int, const void *);
171 static void shoveFloat(GLdouble, int, void *);
172 static void halveImageSlice(int, GLdouble (*)(int, const void *),
173  void (*)(GLdouble, int, void *),
174  GLint, GLint, GLint,
175  const void *, void *,
176  GLint, GLint, GLint, GLint, GLint);
177 static void halveImage3D(int, GLdouble (*)(int, const void *),
178  void (*)(GLdouble, int, void *),
179  GLint, GLint, GLint,
180  const void *, void *,
181  GLint, GLint, GLint, GLint, GLint);
182 
183 /* packedpixel type scale routines */
184 static void extract332(int,const void *, GLfloat []);
185 static void shove332(const GLfloat [],int ,void *);
186 static void extract233rev(int,const void *, GLfloat []);
187 static void shove233rev(const GLfloat [],int ,void *);
188 static void extract565(int,const void *, GLfloat []);
189 static void shove565(const GLfloat [],int ,void *);
190 static void extract565rev(int,const void *, GLfloat []);
191 static void shove565rev(const GLfloat [],int ,void *);
192 static void extract4444(int,const void *, GLfloat []);
193 static void shove4444(const GLfloat [],int ,void *);
194 static void extract4444rev(int,const void *, GLfloat []);
195 static void shove4444rev(const GLfloat [],int ,void *);
196 static void extract5551(int,const void *, GLfloat []);
197 static void shove5551(const GLfloat [],int ,void *);
198 static void extract1555rev(int,const void *, GLfloat []);
199 static void shove1555rev(const GLfloat [],int ,void *);
200 static void extract8888(int,const void *, GLfloat []);
201 static void shove8888(const GLfloat [],int ,void *);
202 static void extract8888rev(int,const void *, GLfloat []);
203 static void shove8888rev(const GLfloat [],int ,void *);
204 static void extract1010102(int,const void *, GLfloat []);
205 static void shove1010102(const GLfloat [],int ,void *);
206 static void extract2101010rev(int,const void *, GLfloat []);
207 static void shove2101010rev(const GLfloat [],int ,void *);
208 static 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);
213 static 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);
218 static 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 
224 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
225  GLubyte *, GLint, GLint, GLint);
226 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
227  GLint, GLint, GLint);
228 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
229  GLushort *, GLint, GLint, GLint, GLint);
230 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
231  GLint, GLint, GLint, GLint);
232 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
233  GLint, GLint, GLint, GLint);
234 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
235  GLint, GLint, GLint, GLint);
236 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
237  GLint, GLint, GLint, GLint);
238 
240 static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
241  GLenum, GLboolean, const void *, GLushort *);
242 static void emptyImage3D(const PixelStorageModes *,
243  GLint, GLint, GLint, GLenum,
244  GLenum, GLboolean,
245  const GLushort *, void *);
246 static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
247  GLint, GLint, GLint, 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 */
381  halve1Dimage_ubyte(components,width,height,datain,dataout,
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 */
483  halve1Dimage_byte(components,width,height,datain,dataout,
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 */
583  halve1Dimage_ushort(components,width,height,datain,dataout,
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) {
651  ushort[0]= __GLU_SWAP_2_BYTES(src);
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) {
683  ushort[0]= __GLU_SWAP_2_BYTES(src);
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 */
722  halve1Dimage_short(components,width,height,datain,dataout,
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;
755  b = __GLU_SWAP_2_BYTES(t);
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 */
868  halve1Dimage_uint(components,width,height,datain,dataout,
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 */
902  GLdouble buf;
903  buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
904  (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
905  (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
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
941  GLuint uint[BOX2];
942  if (myswap_bytes) {
943  uint[0]= __GLU_SWAP_4_BYTES(src);
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
973  GLuint uint[BOX2];
974  if (myswap_bytes) {
975  uint[0]= __GLU_SWAP_4_BYTES(src);
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;
1045  b = __GLU_SWAP_4_BYTES(t);
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) {
1089  uint[0]= __GLU_SWAP_4_BYTES(src);
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) {
1121  uint[0]= __GLU_SWAP_4_BYTES(src);
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 */
1160  halve1Dimage_float(components,width,height,datain,dataout,
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 
1289 static 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 
3279  if (!isLegalFormatForPackedPixelType(format, type)) {
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 {
3341  assert(legalType(type));
3342 
3343  if (type == GL_UNSIGNED_BYTE_3_3_2 ||
3344  type == GL_UNSIGNED_BYTE_2_3_3_REV ||
3345  type == GL_UNSIGNED_SHORT_5_6_5 ||
3346  type == GL_UNSIGNED_SHORT_5_6_5_REV ||
3347  type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3349  type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3351  type == GL_UNSIGNED_INT_8_8_8_8 ||
3352  type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3353  type == GL_UNSIGNED_INT_10_10_10_2 ||
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 */
3369  if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
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  */
3377  if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3379  type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3381  type == GL_UNSIGNED_INT_8_8_8_8 ||
3382  type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3383  type == GL_UNSIGNED_INT_10_10_10_2 ||
3384  type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
3385  (format != GL_RGBA &&
3386  format != GL_BGRA)) {
3387  return GL_FALSE;
3388  }
3389 
3390  return GL_TRUE;
3391 } /* isLegalFormatForPackedPixelType() */
3392 
3393 static 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? */
3433  if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
3434  proxyTarget = GL_PROXY_TEXTURE_2D;
3435  glTexImage2D(proxyTarget, 1, /* must be non-zero */
3436  internalFormat,
3437  widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3438  } else
3439 #if defined(GL_ARB_texture_cube_map)
3440  if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
3441  (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
3442  (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
3443  (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
3444  (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
3445  (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
3446  proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3447  glTexImage2D(proxyTarget, 1, /* must be non-zero */
3448  internalFormat,
3449  widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3450  } else
3451 #endif /* GL_ARB_texture_cube_map */
3452  {
3453  assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
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 
3485 noProxyTextures:
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;
3506  PixelStorageModes psm;
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  }
3517  if (!isLegalFormatForPackedPixelType(format, typein)) {
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);
3536  components = elements_per_group(format, 0);
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;
3555  GLint level, levels;
3556  GLushort *newImage;
3557  GLint newImage_width;
3558  GLushort *otherImage;
3559  GLushort *imageTemp;
3560  GLint memreq;
3561  GLint cmpts;
3562  PixelStorageModes psm;
3563 
3564  assert(checkMipmapArgs(internalFormat,format,type) == 0);
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 *)
3576  malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
3577  newImage_width = width;
3578  if (newImage == NULL) {
3579  return GLU_OUT_OF_MEMORY;
3580  }
3581  fill_image(&psm,width, 1, format, type, is_index(format),
3582  data, newImage);
3583  cmpts = elements_per_group(format,type);
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 
3651  int rc= checkMipmapArgs(internalFormat,format,type);
3652  if (rc != 0) return rc;
3653 
3654  if (width < 1) {
3655  return GLU_INVALID_VALUE;
3656  }
3657 
3658  levels = computeLog(width);
3659 
3660  levels+= userLevel;
3661  if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
3662  return GLU_INVALID_VALUE;
3663 
3664  return gluBuild1DMipmapLevelsCore(target, internalFormat,
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 
3680  int rc= checkMipmapArgs(internalFormat,format,type);
3681  if (rc != 0) return rc;
3682 
3683  if (width < 1) {
3684  return GLU_INVALID_VALUE;
3685  }
3686 
3687  closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
3688  levels = computeLog(widthPowerOf2);
3689 
3690  return gluBuild1DMipmapLevelsCore(target,internalFormat,
3691  width,
3692  widthPowerOf2,
3693  format,type,0,0,levels,data);
3694 }
3695 
3698  GLenum type, const void *data)
3699 {
3700  GLint newwidth, newheight;
3701  GLint level, levels;
3702  GLushort *newImage;
3703  GLint newImage_width;
3704  GLint newImage_height;
3705  GLushort *otherImage;
3706  GLushort *imageTemp;
3707  GLint memreq;
3708  GLint cmpts;
3709  PixelStorageModes psm;
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
3720  closestFit(target,width,height,internalFormat,format,type,
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 *)
3729  malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
3730  newImage_width = width;
3731  newImage_height = height;
3732  if (newImage == NULL) {
3733  return GLU_OUT_OF_MEMORY;
3734  }
3735 
3736  fill_image(&psm,width, height, format, type, is_index(format),
3737  data, newImage);
3738 
3739  cmpts = elements_per_group(format,type);
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;
3812  GLint level, levels;
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;
3821  PixelStorageModes psm;
3822 
3823  assert(checkMipmapArgs(internalFormat,format,type) == 0);
3824  assert(width >= 1 && height >= 1);
3825 
3826  if(type == GL_BITMAP) {
3827  return bitmapBuild2DMipmaps(target, internalFormat, width, height,
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;
3843  cmpts = elements_per_group(format,type);
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) {
3873  glTexImage2D(target, level, internalFormat, width,
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:
3950  halveImage_ubyte(cmpts, width, height,
3951  (const GLubyte *)usersImage, (GLubyte *)dstImage,
3952  element_size, rowsize, group_size);
3953  break;
3954  case GL_BYTE:
3955  halveImage_byte(cmpts, width, height,
3956  (const GLbyte *)usersImage, (GLbyte *)dstImage,
3957  element_size, rowsize, group_size);
3958  break;
3959  case GL_UNSIGNED_SHORT:
3960  halveImage_ushort(cmpts, width, height,
3961  (const GLushort *)usersImage, (GLushort *)dstImage,
3962  element_size, rowsize, group_size, myswap_bytes);
3963  break;
3964  case GL_SHORT:
3965  halveImage_short(cmpts, width, height,
3966  (const GLshort *)usersImage, (GLshort *)dstImage,
3967  element_size, rowsize, group_size, myswap_bytes);
3968  break;
3969  case GL_UNSIGNED_INT:
3970  halveImage_uint(cmpts, width, height,
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:
3980  halveImage_float(cmpts, width, height,
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:
4172  scale_internal_ubyte(cmpts, width, height,
4173  (const GLubyte *)usersImage, newwidth, newheight,
4174  (GLubyte *)dstImage, element_size,
4175  rowsize, group_size);
4176  break;
4177  case GL_BYTE:
4178  scale_internal_byte(cmpts, width, height,
4179  (const GLbyte *)usersImage, newwidth, newheight,
4180  (GLbyte *)dstImage, element_size,
4181  rowsize, group_size);
4182  break;
4183  case GL_UNSIGNED_SHORT:
4184  scale_internal_ushort(cmpts, width, height,
4185  (const GLushort *)usersImage, newwidth, newheight,
4186  (GLushort *)dstImage, element_size,
4187  rowsize, group_size, myswap_bytes);
4188  break;
4189  case GL_SHORT:
4190  scale_internal_short(cmpts, width, height,
4191  (const GLshort *)usersImage, newwidth, newheight,
4192  (GLshort *)dstImage, element_size,
4193  rowsize, group_size, myswap_bytes);
4194  break;
4195  case GL_UNSIGNED_INT:
4196  scale_internal_uint(cmpts, width, height,
4197  (const GLuint *)usersImage, newwidth, newheight,
4198  (GLuint *)dstImage, element_size,
4199  rowsize, group_size, myswap_bytes);
4200  break;
4201  case GL_INT:
4202  scale_internal_int(cmpts, width, height,
4203  (const GLint *)usersImage, newwidth, newheight,
4204  (GLint *)dstImage, element_size,
4205  rowsize, group_size, myswap_bytes);
4206  break;
4207  case GL_FLOAT:
4208  scale_internal_float(cmpts, width, height,
4209  (const GLfloat *)usersImage, newwidth, newheight,
4210  (GLfloat *)dstImage, element_size,
4211  rowsize, group_size, myswap_bytes);
4212  break;
4215  width, height,usersImage,
4216  newwidth,newheight,(void *)dstImage,
4217  element_size,rowsize,myswap_bytes);
4218  break;
4221  width, height,usersImage,
4222  newwidth,newheight,(void *)dstImage,
4223  element_size,rowsize,myswap_bytes);
4224  break;
4227  width, height,usersImage,
4228  newwidth,newheight,(void *)dstImage,
4229  element_size,rowsize,myswap_bytes);
4230  break;
4233  width, height,usersImage,
4234  newwidth,newheight,(void *)dstImage,
4235  element_size,rowsize,myswap_bytes);
4236  break;
4239  width, height,usersImage,
4240  newwidth,newheight,(void *)dstImage,
4241  element_size,rowsize,myswap_bytes);
4242  break;
4245  width, height,usersImage,
4246  newwidth,newheight,(void *)dstImage,
4247  element_size,rowsize,myswap_bytes);
4248  break;
4251  width, height,usersImage,
4252  newwidth,newheight,(void *)dstImage,
4253  element_size,rowsize,myswap_bytes);
4254  break;
4257  width, height,usersImage,
4258  newwidth,newheight,(void *)dstImage,
4259  element_size,rowsize,myswap_bytes);
4260  break;
4263  width, height,usersImage,
4264  newwidth,newheight,(void *)dstImage,
4265  element_size,rowsize,myswap_bytes);
4266  break;
4269  width, height,usersImage,
4270  newwidth,newheight,(void *)dstImage,
4271  element_size,rowsize,myswap_bytes);
4272  break;
4275  width, height,usersImage,
4276  newwidth,newheight,(void *)dstImage,
4277  element_size,rowsize,myswap_bytes);
4278  break;
4281  width, height,usersImage,
4282  newwidth,newheight,(void *)dstImage,
4283  element_size,rowsize,myswap_bytes);
4284  break;
4285  default:
4286  assert(0);
4287  break;
4288  }
4289  myswap_bytes = 0;
4290  rowsize = newwidth * group_size;
4291  /* Swap dstImage and srcImage */
4292  __GLU_SWAP_IMAGE(srcImage,dstImage);
4293 
4294  if(levels != 0) { /* use as little memory as possible */
4295  {
4296  int nextWidth= newwidth/2;
4297  int nextHeight= newheight/2;
4298  if (nextWidth < 1) nextWidth= 1;
4299  if (nextHeight < 1) nextHeight= 1;
4300 
4301  memreq = image_size(nextWidth, nextHeight, format, type);
4302  }
4303 
4304  switch(type) {
4305  case GL_UNSIGNED_BYTE:
4306  dstImage = (GLubyte *)malloc(memreq);
4307  break;
4308  case GL_BYTE:
4309  dstImage = (GLbyte *)malloc(memreq);
4310  break;
4311  case GL_UNSIGNED_SHORT:
4312  dstImage = (GLushort *)malloc(memreq);
4313  break;
4314  case GL_SHORT:
4315  dstImage = (GLshort *)malloc(memreq);
4316  break;
4317  case GL_UNSIGNED_INT:
4318  dstImage = (GLuint *)malloc(memreq);
4319  break;
4320  case GL_INT:
4321  dstImage = (GLint *)malloc(memreq);
4322  break;
4323  case GL_FLOAT:
4324  dstImage = (GLfloat *)malloc(memreq);
4325  break;
4328  dstImage = (GLubyte *)malloc(memreq);
4329  break;
4336  dstImage = (GLushort *)malloc(memreq);
4337  break;
4342  dstImage = (GLuint *)malloc(memreq);
4343  break;
4344  default:
4345  return GLU_INVALID_ENUM;
4346  }
4347  if (dstImage == NULL) {
4353  free(srcImage);
4354  return GLU_OUT_OF_MEMORY;
4355  }
4356  }
4357  /* level userLevel is in srcImage; nothing saved yet */
4358  level = userLevel;
4359  }
4360 
4362  if (baseLevel <= level && level <= maxLevel) {
4363  glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4364  format, type, (void *)srcImage);
4365  }
4366 
4367  level++; /* update current level for the loop */
4368  for (; level <= levels; level++) {
4369  switch(type) {
4370  case GL_UNSIGNED_BYTE:
4371  halveImage_ubyte(cmpts, newwidth, newheight,
4372  (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4373  rowsize, group_size);
4374  break;
4375  case GL_BYTE:
4376  halveImage_byte(cmpts, newwidth, newheight,
4377  (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4378  rowsize, group_size);
4379  break;
4380  case GL_UNSIGNED_SHORT:
4381  halveImage_ushort(cmpts, newwidth, newheight,
4382  (GLushort *)srcImage, (GLushort *)dstImage, element_size,
4383  rowsize, group_size, myswap_bytes);
4384  break;
4385  case GL_SHORT:
4386  halveImage_short(cmpts, newwidth, newheight,
4387  (GLshort *)srcImage, (GLshort *)dstImage, element_size,
4388  rowsize, group_size, myswap_bytes);
4389  break;
4390  case GL_UNSIGNED_INT:
4391  halveImage_uint(cmpts, newwidth, newheight,
4392  (GLuint *)srcImage, (GLuint *)dstImage, element_size,
4393  rowsize, group_size, myswap_bytes);
4394  break;
4395  case GL_INT:
4396  halveImage_int(cmpts, newwidth, newheight,
4397  (GLint *)srcImage, (GLint *)dstImage, element_size,
4398  rowsize, group_size, myswap_bytes);
4399  break;
4400  case GL_FLOAT:
4401  halveImage_float(cmpts, newwidth, newheight,
4402  (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4403  rowsize, group_size, myswap_bytes);
4404  break;
4407  newwidth,newheight,
4408  srcImage,dstImage,element_size,rowsize,
4409  myswap_bytes);
4410  break;
4413  newwidth,newheight,
4414  srcImage,dstImage,element_size,rowsize,
4415  myswap_bytes);
4416  break;
4419  newwidth,newheight,
4420  srcImage,dstImage,element_size,rowsize,
4421  myswap_bytes);
4422  break;
4425  newwidth,newheight,
4426  srcImage,dstImage,element_size,rowsize,
4427  myswap_bytes);
4428  break;
4431  newwidth,newheight,
4432  srcImage,dstImage,element_size,rowsize,
4433  myswap_bytes);
4434  break;
4437  newwidth,newheight,
4438  srcImage,dstImage,element_size,rowsize,
4439  myswap_bytes);
4440  break;
4443  newwidth,newheight,
4444  srcImage,dstImage,element_size,rowsize,
4445  myswap_bytes);
4446  break;
4449  newwidth,newheight,
4450  srcImage,dstImage,element_size,rowsize,
4451  myswap_bytes);
4452  break;
4455  newwidth,newheight,
4456  srcImage,dstImage,element_size,rowsize,
4457  myswap_bytes);
4458  break;
4461  newwidth,newheight,
4462  srcImage,dstImage,element_size,rowsize,
4463  myswap_bytes);
4464  break;
4467  newwidth,newheight,
4468  srcImage,dstImage,element_size,rowsize,
4469  myswap_bytes);
4470  break;
4473  newwidth,newheight,
4474  srcImage,dstImage,element_size,rowsize,
4475  myswap_bytes);
4476  break;
4477  default:
4478  assert(0);
4479  break;
4480  }
4481 
4482  __GLU_SWAP_IMAGE(srcImage,dstImage);
4483 
4484  if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4485  if (newheight > 1) newheight /= 2;
4486  {
4487  /* compute amount to pad per row, if any */
4488  int rowPad= rowsize % psm.unpack_alignment;
4489 
4490  /* should row be padded? */
4491  if (rowPad == 0) { /* nope, row should not be padded */
4492  /* call tex image with srcImage untouched since it's not padded */
4493  if (baseLevel <= level && level <= maxLevel) {
4494  glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4495  format, type, (void *) srcImage);
4496  }
4497  }
4498  else { /* yes, row should be padded */
4499  /* compute length of new row in bytes, including padding */
4500  int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4501  int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4502 
4503  /* allocate new image for mipmap of size newRowLength x newheight */
4504  void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
4505  if (newMipmapImage == NULL) {
4506  /* out of memory so return */
4512  return GLU_OUT_OF_MEMORY;
4513  }
4514 
4515  /* copy image from srcImage into newMipmapImage by rows */
4516  for (ii= 0,
4517  dstTrav= (unsigned char *) newMipmapImage,
4518  srcTrav= (unsigned char *) srcImage;
4519  ii< newheight;
4520  ii++,
4521  dstTrav+= newRowLength, /* make sure the correct distance... */
4522  srcTrav+= rowsize) { /* ...is skipped */
4523  memcpy(dstTrav,srcTrav,rowsize);
4524  /* note that the pad bytes are not visited and will contain
4525  * garbage, which is ok.
4526  */
4527  }
4528 
4529  /* ...and use this new image for mipmapping instead */
4530  if (baseLevel <= level && level <= maxLevel) {
4531  glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4532  format, type, newMipmapImage);
4533  }
4534  free(newMipmapImage); /* don't forget to free it! */
4535  } /* else */
4536  }
4537  } /* for level */
4543 
4544  free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4545  if (dstImage) { /* if it's non-rectangular and only 1 level */
4546  free(dstImage);
4547  }
4548  return 0;
4549 } /* gluBuild2DMipmapLevelsCore() */
4550 
4555  GLint userLevel, GLint baseLevel, GLint maxLevel,
4556  const void *data)
4557 {
4558  int level, levels;
4559 
4560  int rc= checkMipmapArgs(internalFormat,format,type);
4561  if (rc != 0) return rc;
4562 
4563  if (width < 1 || height < 1) {
4564  return GLU_INVALID_VALUE;
4565  }
4566 
4567  levels = computeLog(width);
4568  level = computeLog(height);
4569  if (level > levels) levels=level;
4570 
4571  levels+= userLevel;
4572  if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
4573  return GLU_INVALID_VALUE;
4574 
4575  return gluBuild2DMipmapLevelsCore(target, internalFormat,
4576  width, height,
4577  width, height,
4578  format, type,
4579  userLevel, baseLevel, maxLevel,
4580  data);
4581 } /* gluBuild2DMipmapLevels() */
4582 
4587  const void *data)
4588 {
4589  GLint widthPowerOf2, heightPowerOf2;
4590  int level, levels;
4591 
4592  int rc= checkMipmapArgs(internalFormat,format,type);
4593  if (rc != 0) return rc;
4594 
4595  if (width < 1 || height < 1) {
4596  return GLU_INVALID_VALUE;
4597  }
4598 
4599  closestFit(target,width,height,internalFormat,format,type,
4600  &widthPowerOf2,&heightPowerOf2);
4601 
4602  levels = computeLog(widthPowerOf2);
4603  level = computeLog(heightPowerOf2);
4604  if (level > levels) levels=level;
4605 
4606  return gluBuild2DMipmapLevelsCore(target,internalFormat,
4607  width, height,
4608  widthPowerOf2,heightPowerOf2,
4609  format,type,
4610  0,0,levels,data);
4611 } /* gluBuild2DMipmaps() */
4612 
4613 #if 0
4614 /*
4615 ** This routine is for the limited case in which
4616 ** type == GL_UNSIGNED_BYTE && format != index &&
4617 ** unpack_alignment = 1 && unpack_swap_bytes == false
4618 **
4619 ** so all of the work data can be kept as ubytes instead of shorts.
4620 */
4621 static int fastBuild2DMipmaps(const PixelStorageModes *psm,
4624  GLenum type, void *data)
4625 {
4626  GLint newwidth, newheight;
4627  GLint level, levels;
4628  GLubyte *newImage;
4629  GLint newImage_width;
4630  GLint newImage_height;
4631  GLubyte *otherImage;
4632  GLubyte *imageTemp;
4633  GLint memreq;
4634  GLint cmpts;
4635 
4636 
4637 #if 0
4639  newwidth = nearestPower(width);
4640  if (newwidth > maxsize) newwidth = maxsize;
4641  newheight = nearestPower(height);
4642  if (newheight > maxsize) newheight = maxsize;
4643 #else
4644  closestFit(target,width,height,components,format,type,
4645  &newwidth,&newheight);
4646 #endif
4647  levels = computeLog(newwidth);
4648  level = computeLog(newheight);
4649  if (level > levels) levels=level;
4650 
4651  cmpts = elements_per_group(format,type);
4652 
4653  otherImage = NULL;
4658  if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
4659  newImage = (GLubyte *)data;
4660  newImage_width = width;
4661  newImage_height = height;
4662  } else {
4663  GLint rowsize;
4664  GLint groups_per_line;
4665  GLint elements_per_line;
4666  const GLubyte *start;
4667  const GLubyte *iter;
4668  GLubyte *iter2;
4669  GLint i, j;
4670 
4671  newImage = (GLubyte *)
4672  malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
4673  newImage_width = width;
4674  newImage_height = height;
4675  if (newImage == NULL) {
4676  return GLU_OUT_OF_MEMORY;
4677  }
4678 
4679  /*
4680  ** Abbreviated version of fill_image for this restricted case.
4681  */
4682  if (psm->unpack_row_length > 0) {
4683  groups_per_line = psm->unpack_row_length;
4684  } else {
4685  groups_per_line = width;
4686  }
4687  rowsize = groups_per_line * cmpts;
4688  elements_per_line = width * cmpts;
4689  start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
4690  psm->unpack_skip_pixels * cmpts;
4691  iter2 = newImage;
4692 
4693  for (i = 0; i < height; i++) {
4694  iter = start;
4695  for (j = 0; j < elements_per_line; j++) {
4696  *iter2 = *iter;
4697  iter++;
4698  iter2++;
4699  }
4700  start += rowsize;
4701  }
4702  }
4703 
4704 
4710 
4711  for (level = 0; level <= levels; level++) {
4712  if (newImage_width == newwidth && newImage_height == newheight) {
4713  /* Use newImage for this level */
4714  glTexImage2D(target, level, components, newImage_width,
4715  newImage_height, 0, format, GL_UNSIGNED_BYTE,
4716  (void *) newImage);
4717  } else {
4718  if (otherImage == NULL) {
4719  memreq =
4720  image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
4721  otherImage = (GLubyte *) malloc(memreq);
4722  if (otherImage == NULL) {
4728  return GLU_OUT_OF_MEMORY;
4729  }
4730  }
4731 /*
4732  scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4733  newImage, newwidth, newheight, otherImage);
4734 */
4735  /* Swap newImage and otherImage */
4736  imageTemp = otherImage;
4737  otherImage = newImage;
4738  newImage = imageTemp;
4739 
4740  newImage_width = newwidth;
4741  newImage_height = newheight;
4742  glTexImage2D(target, level, components, newImage_width,
4743  newImage_height, 0, format, GL_UNSIGNED_BYTE,
4744  (void *) newImage);
4745  }
4746  if (newwidth > 1) newwidth /= 2;
4747  if (newheight > 1) newheight /= 2;
4748  }
4754 
4755  if (newImage != (const GLubyte *)data) {
4756  free((GLbyte *) newImage);
4757  }
4758  if (otherImage && otherImage != (const GLubyte *)data) {
4759  free((GLbyte *) otherImage);
4760  }
4761  return 0;
4762 }
4763 #endif
4764 
4765 /*
4766  * Utility Routines
4767  */
4769 {
4770  /*
4771  * Return the number of elements per group of a specified format
4772  */
4773 
4774  /* If the type is packedpixels then answer is 1 (ignore format) */
4775  if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4776  type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4777  type == GL_UNSIGNED_SHORT_5_6_5 ||
4778  type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4779  type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4781  type == GL_UNSIGNED_SHORT_5_5_5_1 ||
4783  type == GL_UNSIGNED_INT_8_8_8_8 ||
4784  type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4785  type == GL_UNSIGNED_INT_10_10_10_2 ||
4787  return 1;
4788  }
4789 
4790  /* Types are not packed pixels, so get elements per group */
4791  switch(format) {
4792  case GL_RGB:
4793  case GL_BGR:
4794  return 3;
4795  case GL_LUMINANCE_ALPHA:
4796  return 2;
4797  case GL_RGBA:
4798  case GL_BGRA:
4799  return 4;
4800  default:
4801  return 1;
4802  }
4803 }
4804 
4806 {
4807  /*
4808  * Return the number of bytes per element, based on the element type
4809  */
4810  switch(type) {
4811  case GL_BITMAP:
4812  return 1.0 / 8.0;
4813  case GL_UNSIGNED_SHORT:
4814  return(sizeof(GLushort));
4815  case GL_SHORT:
4816  return(sizeof(GLshort));
4817  case GL_UNSIGNED_BYTE:
4818  return(sizeof(GLubyte));
4819  case GL_BYTE:
4820  return(sizeof(GLbyte));
4821  case GL_INT:
4822  return(sizeof(GLint));
4823  case GL_UNSIGNED_INT:
4824  return(sizeof(GLuint));
4825  case GL_FLOAT:
4826  return(sizeof(GLfloat));
4829  return(sizeof(GLubyte));
4836  return(sizeof(GLushort));
4841  return(sizeof(GLuint));
4842  default:
4843  return 4;
4844  }
4845 }
4846 
4847 static GLint is_index(GLenum format)
4848 {
4849  return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4850 }
4851 
4852 /*
4853 ** Compute memory required for internal packed array of data of given type
4854 ** and format.
4855 */
4856 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4857 {
4858  int bytes_per_row;
4859  int components;
4860 
4861 assert(width > 0);
4862 assert(height > 0);
4863  components = elements_per_group(format,type);
4864  if (type == GL_BITMAP) {
4865  bytes_per_row = (width + 7) / 8;
4866  } else {
4867  bytes_per_row = bytes_per_element(type) * width;
4868  }
4869  return bytes_per_row * height * components;
4870 }
4871 
4872 /*
4873 ** Extract array from user's data applying all pixel store modes.
4874 ** The internal format used is an array of unsigned shorts.
4875 */
4876 static void fill_image(const PixelStorageModes *psm,
4877  GLint width, GLint height, GLenum format,
4878  GLenum type, GLboolean index_format,
4879  const void *userdata, GLushort *newimage)
4880 {
4881  GLint components;
4882  GLint element_size;
4883  GLint rowsize;
4884  GLint padding;
4885  GLint groups_per_line;
4886  GLint group_size;
4887  GLint elements_per_line;
4888  const GLubyte *start;
4889  const GLubyte *iter;
4890  GLushort *iter2;
4891  GLint i, j, k;
4892  GLint myswap_bytes;
4893 
4894  myswap_bytes = psm->unpack_swap_bytes;
4895  components = elements_per_group(format,type);
4896  if (psm->unpack_row_length > 0) {
4897  groups_per_line = psm->unpack_row_length;
4898  } else {
4899  groups_per_line = width;
4900  }
4901 
4902  /* All formats except GL_BITMAP fall out trivially */
4903  if (type == GL_BITMAP) {
4904  GLint bit_offset;
4905  GLint current_bit;
4906 
4907  rowsize = (groups_per_line * components + 7) / 8;
4908  padding = (rowsize % psm->unpack_alignment);
4909  if (padding) {
4910  rowsize += psm->unpack_alignment - padding;
4911  }
4912  start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4913  (psm->unpack_skip_pixels * components / 8);
4914  elements_per_line = width * components;
4915  iter2 = newimage;
4916  for (i = 0; i < height; i++) {
4917  iter = start;
4918  bit_offset = (psm->unpack_skip_pixels * components) % 8;
4919  for (j = 0; j < elements_per_line; j++) {
4920  /* Retrieve bit */
4921  if (psm->unpack_lsb_first) {
4922  current_bit = iter[0] & (1 << bit_offset);
4923  } else {
4924  current_bit = iter[0] & (1 << (7 - bit_offset));
4925  }
4926  if (current_bit) {
4927  if (index_format) {
4928  *iter2 = 1;
4929  } else {
4930  *iter2 = 65535;
4931  }
4932  } else {
4933  *iter2 = 0;
4934  }
4935  bit_offset++;
4936  if (bit_offset == 8) {
4937  bit_offset = 0;
4938  iter++;
4939  }
4940  iter2++;
4941  }
4942  start += rowsize;
4943  }
4944  } else {
4945  element_size = bytes_per_element(type);
4946  group_size = element_size * components;
4947  if (element_size == 1) myswap_bytes = 0;
4948 
4949  rowsize = groups_per_line * group_size;
4950  padding = (rowsize % psm->unpack_alignment);
4951  if (padding) {
4952  rowsize += psm->unpack_alignment - padding;
4953  }
4954  start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4955  psm->unpack_skip_pixels * group_size;
4956  elements_per_line = width * components;
4957 
4958  iter2 = newimage;
4959  for (i = 0; i < height; i++) {
4960  iter = start;
4961  for (j = 0; j < elements_per_line; j++) {
4962  Type_Widget widget;
4963  float extractComponents[4];
4964 
4965  switch(type) {
4967  extract332(0,iter,extractComponents);
4968  for (k = 0; k < 3; k++) {
4969  *iter2++ = (GLushort)(extractComponents[k]*65535);
4970  }
4971  break;
4973  extract233rev(0,iter,extractComponents);
4974  for (k = 0; k < 3; k++) {
4975  *iter2++ = (GLushort)(extractComponents[k]*65535);
4976  }
4977  break;
4978  case GL_UNSIGNED_BYTE:
4979  if (index_format) {
4980  *iter2++ = *iter;
4981  } else {
4982  *iter2++ = (*iter) * 257;
4983  }
4984  break;
4985  case GL_BYTE:
4986  if (index_format) {
4987  *iter2++ = *((const GLbyte *) iter);
4988  } else {
4989  /* rough approx */
4990  *iter2++ = (*((const GLbyte *) iter)) * 516;
4991  }
4992  break;
4994  extract565(myswap_bytes,iter,extractComponents);
4995  for (k = 0; k < 3; k++) {
4996  *iter2++ = (GLushort)(extractComponents[k]*65535);
4997  }
4998  break;
5000  extract565rev(myswap_bytes,iter,extractComponents);
5001  for (k = 0; k < 3; k++) {
5002  *iter2++ = (GLushort)(extractComponents[k]*65535);
5003  }
5004  break;
5006  extract4444(myswap_bytes,iter,extractComponents);
5007  for (k = 0; k < 4; k++) {
5008  *iter2++ = (GLushort)(extractComponents[k]*65535);
5009  }
5010  break;
5012  extract4444rev(myswap_bytes,iter,extractComponents);
5013  for (k = 0; k < 4; k++) {
5014  *iter2++ = (GLushort)(extractComponents[k]*65535);
5015  }
5016  break;
5018  extract5551(myswap_bytes,iter,extractComponents);
5019  for (k = 0; k < 4; k++) {
5020  *iter2++ = (GLushort)(extractComponents[k]*65535);
5021  }
5022  break;
5024  extract1555rev(myswap_bytes,iter,extractComponents);
5025  for (k = 0; k < 4; k++) {
5026  *iter2++ = (GLushort)(extractComponents[k]*65535);
5027  }
5028  break;
5029  case GL_UNSIGNED_SHORT:
5030  case GL_SHORT:
5031  if (myswap_bytes) {
5032  widget.ub[0] = iter[1];
5033  widget.ub[1] = iter[0];
5034  } else {
5035  widget.ub[0] = iter[0];
5036  widget.ub[1] = iter[1];
5037  }
5038  if (type == GL_SHORT) {
5039  if (index_format) {
5040  *iter2++ = widget.s[0];
5041  } else {
5042  /* rough approx */
5043  *iter2++ = widget.s[0]*2;
5044  }
5045  } else {
5046  *iter2++ = widget.us[0];
5047  }
5048  break;
5050  extract8888(myswap_bytes,iter,extractComponents);
5051  for (k = 0; k < 4; k++) {
5052  *iter2++ = (GLushort)(extractComponents[k]*65535);
5053  }
5054  break;
5056  extract8888rev(myswap_bytes,iter,extractComponents);
5057  for (k = 0; k < 4; k++) {
5058  *iter2++ = (GLushort)(extractComponents[k]*65535);
5059  }
5060  break;
5062  extract1010102(myswap_bytes,iter,extractComponents);
5063  for (k = 0; k < 4; k++) {
5064  *iter2++ = (GLushort)(extractComponents[k]*65535);
5065  }
5066  break;
5068  extract2101010rev(myswap_bytes,iter,extractComponents);
5069  for (k = 0; k < 4; k++) {
5070  *iter2++ = (GLushort)(extractComponents[k]*65535);
5071  }
5072  break;
5073  case GL_INT:
5074  case GL_UNSIGNED_INT:
5075  case GL_FLOAT:
5076  if (myswap_bytes) {
5077  widget.ub[0] = iter[3];
5078  widget.ub[1] = iter[2];
5079  widget.ub[2] = iter[1];
5080  widget.ub[3] = iter[0];
5081  } else {
5082  widget.ub[0] = iter[0];
5083  widget.ub[1] = iter[1];
5084  widget.ub[2] = iter[2];
5085  widget.ub[3] = iter[3];
5086  }
5087  if (type == GL_FLOAT) {
5088  if (index_format) {
5089  *iter2++ = widget.f;
5090  } else {
5091  *iter2++ = 65535 * widget.f;
5092  }
5093  } else if (type == GL_UNSIGNED_INT) {
5094  if (index_format) {
5095  *iter2++ = widget.ui;
5096  } else {
5097  *iter2++ = widget.ui >> 16;
5098  }
5099  } else {
5100  if (index_format) {
5101  *iter2++ = widget.i;
5102  } else {
5103  *iter2++ = widget.i >> 15;
5104  }
5105  }
5106  break;
5107  }
5108  iter += element_size;
5109  } /* for j */
5110  start += rowsize;
5111 #if 1
5112  /* want 'iter' pointing at start, not within, row for assertion
5113  * purposes
5114  */
5115  iter= start;
5116 #endif
5117  } /* for i */
5118 
5119  /* iterators should be one byte past end */
5120  if (!isTypePackedPixel(type)) {
5121  assert(iter2 == &newimage[width*height*components]);
5122  }
5123  else {
5124  assert(iter2 == &newimage[width*height*
5125  elements_per_group(format,0)]);
5126  }
5127  assert( iter == &((const GLubyte *)userdata)[rowsize*height +
5128  psm->unpack_skip_rows * rowsize +
5129  psm->unpack_skip_pixels * group_size] );
5130 
5131  } /* else */
5132 } /* fill_image() */
5133 
5134 /*
5135 ** Insert array into user's data applying all pixel store modes.
5136 ** The internal format is an array of unsigned shorts.
5137 ** empty_image() because it is the opposite of fill_image().
5138 */
5139 static void empty_image(const PixelStorageModes *psm,
5140  GLint width, GLint height, GLenum format,
5141  GLenum type, GLboolean index_format,
5142  const GLushort *oldimage, void *userdata)
5143 {
5144  GLint components;
5145  GLint element_size;
5146  GLint rowsize;
5147  GLint padding;
5148  GLint groups_per_line;
5149  GLint group_size;
5150  GLint elements_per_line;
5151  GLubyte *start;
5152  GLubyte *iter;
5153  const GLushort *iter2;
5154  GLint i, j, k;
5155  GLint myswap_bytes;
5156 
5157  myswap_bytes = psm->pack_swap_bytes;
5158  components = elements_per_group(format,type);
5159  if (psm->pack_row_length > 0) {
5160  groups_per_line = psm->pack_row_length;
5161  } else {
5162  groups_per_line = width;
5163  }
5164 
5165  /* All formats except GL_BITMAP fall out trivially */
5166  if (type == GL_BITMAP) {
5167  GLint bit_offset;
5168  GLint current_bit;
5169 
5170  rowsize = (groups_per_line * components + 7) / 8;
5171  padding = (rowsize % psm->pack_alignment);
5172  if (padding) {
5173  rowsize += psm->pack_alignment - padding;
5174  }
5175  start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5176  (psm->pack_skip_pixels * components / 8);
5177  elements_per_line = width * components;
5178  iter2 = oldimage;
5179  for (i = 0; i < height; i++) {
5180  iter = start;
5181  bit_offset = (psm->pack_skip_pixels * components) % 8;
5182  for (j = 0; j < elements_per_line; j++) {
5183  if (index_format) {
5184  current_bit = iter2[0] & 1;
5185  } else {
5186  if (iter2[0] > 32767) {
5187  current_bit = 1;
5188  } else {
5189  current_bit = 0;
5190  }
5191  }
5192 
5193  if (current_bit) {
5194  if (psm->pack_lsb_first) {
5195  *iter |= (1 << bit_offset);
5196  } else {
5197  *iter |= (1 << (7 - bit_offset));
5198  }
5199  } else {
5200  if (psm->pack_lsb_first) {
5201  *iter &= ~(1 << bit_offset);
5202  } else {
5203  *iter &= ~(1 << (7 - bit_offset));
5204  }
5205  }
5206 
5207  bit_offset++;
5208  if (bit_offset == 8) {
5209  bit_offset = 0;
5210  iter++;
5211  }
5212  iter2++;
5213  }
5214  start += rowsize;
5215  }
5216  } else {
5217  float shoveComponents[4];
5218 
5219  element_size = bytes_per_element(type);
5220  group_size = element_size * components;
5221  if (element_size == 1) myswap_bytes = 0;
5222 
5223  rowsize = groups_per_line * group_size;
5224  padding = (rowsize % psm->pack_alignment);
5225  if (padding) {
5226  rowsize += psm->pack_alignment - padding;
5227  }
5228  start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5229  psm->pack_skip_pixels * group_size;
5230  elements_per_line = width * components;
5231 
5232  iter2 = oldimage;
5233  for (i = 0; i < height; i++) {
5234  iter = start;
5235  for (j = 0; j < elements_per_line; j++) {
5236  Type_Widget widget;
5237 
5238  switch(type) {
5240  for (k = 0; k < 3; k++) {
5241  shoveComponents[k]= *iter2++ / 65535.0;
5242  }
5243  shove332(shoveComponents,0,(void *)iter);
5244  break;
5246  for (k = 0; k < 3; k++) {
5247  shoveComponents[k]= *iter2++ / 65535.0;
5248  }
5249  shove233rev(shoveComponents,0,(void *)iter);
5250  break;
5251  case GL_UNSIGNED_BYTE:
5252  if (index_format) {
5253  *iter = *iter2++;
5254  } else {
5255  *iter = *iter2++ >> 8;
5256  }
5257  break;
5258  case GL_BYTE:
5259  if (index_format) {
5260  *((GLbyte *) iter) = *iter2++;
5261  } else {
5262  *((GLbyte *) iter) = *iter2++ >> 9;
5263  }
5264  break;
5266  for (k = 0; k < 3; k++) {
5267  shoveComponents[k]= *iter2++ / 65535.0;
5268  }
5269  shove565(shoveComponents,0,(void *)&widget.us[0]);
5270  if (myswap_bytes) {
5271  iter[0] = widget.ub[1];
5272  iter[1] = widget.ub[0];
5273  }
5274  else {
5275  *(GLushort *)iter = widget.us[0];
5276  }
5277  break;
5279  for (k = 0; k < 3; k++) {
5280  shoveComponents[k]= *iter2++ / 65535.0;
5281  }
5282  shove565rev(shoveComponents,0,(void *)&widget.us[0]);
5283  if (myswap_bytes) {
5284  iter[0] = widget.ub[1];
5285  iter[1] = widget.ub[0];
5286  }
5287  else {
5288  *(GLushort *)iter = widget.us[0];
5289  }
5290  break;
5292  for (k = 0; k < 4; k++) {
5293  shoveComponents[k]= *iter2++ / 65535.0;
5294  }
5295  shove4444(shoveComponents,0,(void *)&widget.us[0]);
5296  if (myswap_bytes) {
5297  iter[0] = widget.ub[1];
5298  iter[1] = widget.ub[0];
5299  } else {
5300  *(GLushort *)iter = widget.us[0];
5301  }
5302  break;
5304  for (k = 0; k < 4; k++) {
5305  shoveComponents[k]= *iter2++ / 65535.0;
5306  }
5307  shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
5308  if (myswap_bytes) {
5309  iter[0] = widget.ub[1];
5310  iter[1] = widget.ub[0];
5311  } else {
5312  *(GLushort *)iter = widget.us[0];
5313  }
5314  break;
5316  for (k = 0; k < 4; k++) {
5317  shoveComponents[k]= *iter2++ / 65535.0;
5318  }
5319  shove5551(shoveComponents,0,(void *)&widget.