Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 
33
#include 
34
#include 
35
#include 
36
#include 
37
#include 		/* UINT_MAX */
38
#include 
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 {
52
   GLint pack_alignment;
53
   GLint pack_row_length;
54
   GLint pack_skip_rows;
55
   GLint pack_skip_pixels;
56
   GLint pack_lsb_first;
57
   GLint pack_swap_bytes;
58
   GLint pack_skip_images;
59
   GLint pack_image_height;
60
 
61
   GLint unpack_alignment;
62
   GLint unpack_row_length;
63
   GLint unpack_skip_rows;
64
   GLint unpack_skip_pixels;
65
   GLint unpack_lsb_first;
66
   GLint unpack_swap_bytes;
67
   GLint unpack_skip_images;
68
   GLint unpack_image_height;
69
} PixelStorageModes;
70
 
71
static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
72
				      GLsizei,
73
				      GLsizei,
74
				      GLenum, GLenum, GLint, GLint, GLint,
75
				      const void *);
76
static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
77
				      GLsizei, GLsizei,
78
				      GLsizei, GLsizei,
79
				      GLenum, GLenum, GLint, GLint, GLint,
80
				      const void *);
81
static int gluBuild3DMipmapLevelsCore(GLenum, GLint,
82
				      GLsizei, GLsizei, GLsizei,
83
				      GLsizei, GLsizei, GLsizei,
84
				      GLenum, GLenum, GLint, GLint, GLint,
85
				      const void *);
86
 
87
/*
88
 * internal function declarations
89
 */
90
static GLfloat bytes_per_element(GLenum type);
91
static GLint elements_per_group(GLenum format, GLenum type);
92
static GLint is_index(GLenum format);
93
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
94
static void fill_image(const PixelStorageModes *,
95
		       GLint width, GLint height, GLenum format,
96
		       GLenum type, GLboolean index_format,
97
		       const void *userdata, GLushort *newimage);
98
static void empty_image(const PixelStorageModes *,
99
			GLint width, GLint height, GLenum format,
100
			GLenum type, GLboolean index_format,
101
			const GLushort *oldimage, void *userdata);
102
static void scale_internal(GLint components, GLint widthin, GLint heightin,
103
			   const GLushort *datain,
104
			   GLint widthout, GLint heightout,
105
			   GLushort *dataout);
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);
149
static GLboolean legalFormat(GLenum);
150
static GLboolean legalType(GLenum);
151
static GLboolean isTypePackedPixel(GLenum);
152
static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
153
static GLboolean isLegalLevels(GLint, GLint, GLint, GLint);
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
 
239
static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum);
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
 
249
static void retrieveStoreModes(PixelStorageModes *psm)
250
{
251
    glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
252
    glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
253
    glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
254
    glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
255
    glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
256
    glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
257
 
258
    glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
259
    glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
260
    glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
261
    glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
262
    glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
263
    glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
264
}
265
 
266
static void retrieveStoreModes3D(PixelStorageModes *psm)
267
{
268
    glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
269
    glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
270
    glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
271
    glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
272
    glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
273
    glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
274
    glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images);
275
    glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height);
276
 
277
    glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
278
    glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
279
    glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
280
    glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
281
    glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
282
    glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
283
    glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
284
    glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
285
}
286
 
287
static int computeLog(GLuint value)
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
*/
311
static int nearestPower(GLuint value)
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
 
339
static void halveImage(GLint components, GLuint width, GLuint height,
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
 
368
static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
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
/* */
410
static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
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
 
469
static void halveImage_byte(GLint components, GLuint width, GLuint height,
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
 
511
static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
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
 
569
static void halveImage_ushort(GLint components, GLuint width, GLuint height,
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
 
627
static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
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
649
	    GLushort ushort[BOX2];
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
681
	    GLushort ushort[BOX2];
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
 
708
static void halveImage_short(GLint components, GLuint width, GLuint height,
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
 
773
static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
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
 
854
static void halveImage_uint(GLint components, GLuint width, GLuint height,
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
/* */
919
static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
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
 
999
static void halveImage_int(GLint components, GLuint width, GLuint height,
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
/* */
1065
static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
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
 
1146
static void halveImage_float(GLint components, GLuint width, GLuint height,
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
/* */
1211
static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
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
 
1385
static void scale_internal_ubyte(GLint components, GLint widthin,
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
 
1602
static void scale_internal_byte(GLint components, GLint widthin,
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
 
1819
static void scale_internal_ushort(GLint components, GLint widthin,
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
 
2099
static void scale_internal_short(GLint components, GLint widthin,
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
 
2393
static void scale_internal_uint(GLint components, GLint widthin,
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
 
2680
static void scale_internal_int(GLint components, GLint widthin,
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
 
2976
static void scale_internal_float(GLint components, GLint widthin,
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
 
3270
static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
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
 
3286
static GLboolean legalFormat(GLenum format)
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
 
3309
static GLboolean legalType(GLenum type)
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:
3320
      case GL_UNSIGNED_BYTE_3_3_2:
3321
      case GL_UNSIGNED_BYTE_2_3_3_REV:
3322
      case GL_UNSIGNED_SHORT_5_6_5:
3323
      case GL_UNSIGNED_SHORT_5_6_5_REV:
3324
      case GL_UNSIGNED_SHORT_4_4_4_4:
3325
      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3326
      case GL_UNSIGNED_SHORT_5_5_5_1:
3327
      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3328
      case GL_UNSIGNED_INT_8_8_8_8:
3329
      case GL_UNSIGNED_INT_8_8_8_8_REV:
3330
      case GL_UNSIGNED_INT_10_10_10_2:
3331
      case GL_UNSIGNED_INT_2_10_10_10_REV:
3332
	 return GL_TRUE;
3333
      default:
3334
	return GL_FALSE;
3335
    }
3336
}
3337
 
3338
/* */
3339
static GLboolean isTypePackedPixel(GLenum type)
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 ||
3348
       type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3349
       type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3350
       type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
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 ||
3354
       type == GL_UNSIGNED_INT_2_10_10_10_REV) {
3355
      return 1;
3356
   }
3357
   else return 0;
3358
} /* isTypePackedPixel() */
3359
 
3360
/* Determines if the packed pixel type is compatible with the format */
3361
static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
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||
3370
	type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_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 ||
3378
	type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3379
	type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3380
	type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
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
 */
3410
static void closestFit(GLenum target, GLint width, GLint height,
3411
		       GLint internalFormat, GLenum format, GLenum type,
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
 
3487
      glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
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
 
3497
GLint GLAPIENTRY
3498
gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
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
 
3547
int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
3548
			       GLsizei width,
3549
			       GLsizei widthPowerOf2,
3550
			       GLenum format, GLenum type,
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);
3584
    glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3585
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3586
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3587
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3588
    /*
3589
    ** If swap_bytes was set, swapping occurred in fill_image.
3590
    */
3591
    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
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) {
3605
		    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3606
		    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3607
		    glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3608
		    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3609
		    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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
    }
3629
    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3630
    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3631
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3632
    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3633
    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3634
 
3635
    free((GLbyte *) newImage);
3636
    if (otherImage) {
3637
	free((GLbyte *) otherImage);
3638
    }
3639
    return 0;
3640
}
3641
 
3642
GLint GLAPIENTRY
3643
gluBuild1DMipmapLevels(GLenum target, GLint internalFormat,
3644
			     GLsizei width,
3645
			     GLenum format, GLenum type,
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
 
3671
GLint GLAPIENTRY
3672
gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
3673
			GLenum format, GLenum type,
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
 
3696
static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
3697
		     GLint width, GLint height, GLenum format,
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
3714
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
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);
3740
    glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3741
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3742
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3743
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3744
    /*
3745
    ** If swap_bytes was set, swapping occurred in fill_image.
3746
    */
3747
    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
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) {
3760
		    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3761
		    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3762
		    glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3763
		    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3764
		    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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
    }
3785
    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3786
    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3787
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3788
    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3789
    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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
 
3802
static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3803
				      GLsizei width, GLsizei height,
3804
				      GLsizei widthPowerOf2,
3805
				      GLsizei heightPowerOf2,
3806
				      GLenum format, GLenum type,
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 */
3815
    __GLU_INIT_SWAP_IMAGE;
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
 
3862
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3863
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3864
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
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) {
3872
        glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3873
	glTexImage2D(target, level, internalFormat, width,
3874
		height, 0, format, type,
3875
		usersImage);
3876
	}
3877
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3878
	if(levels == 0) { /* we're done. clean up and return */
3879
	  glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3880
	  glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3881
	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3882
	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3883
	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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;
3918
	case GL_UNSIGNED_BYTE_3_3_2:
3919
	case GL_UNSIGNED_BYTE_2_3_3_REV:
3920
	  dstImage = (GLubyte *)malloc(memreq);
3921
	  break;
3922
	case GL_UNSIGNED_SHORT_5_6_5:
3923
	case GL_UNSIGNED_SHORT_5_6_5_REV:
3924
	case GL_UNSIGNED_SHORT_4_4_4_4:
3925
	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3926
	case GL_UNSIGNED_SHORT_5_5_5_1:
3927
	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3928
	  dstImage = (GLushort *)malloc(memreq);
3929
	  break;
3930
	case GL_UNSIGNED_INT_8_8_8_8:
3931
	case GL_UNSIGNED_INT_8_8_8_8_REV:
3932
	case GL_UNSIGNED_INT_10_10_10_2:
3933
	case GL_UNSIGNED_INT_2_10_10_10_REV:
3934
	  dstImage = (GLuint *)malloc(memreq);
3935
	  break;
3936
	default:
3937
	  return GLU_INVALID_ENUM;
3938
	}
3939
	if (dstImage == NULL) {
3940
	  glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3941
	  glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3942
	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3943
	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3944
	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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;
3984
	  case GL_UNSIGNED_BYTE_3_3_2:
3985
	    assert(format == GL_RGB);
3986
	    halveImagePackedPixel(3,extract332,shove332,
3987
				  width,height,usersImage,dstImage,
3988
				  element_size,rowsize,myswap_bytes);
3989
	    break;
3990
	  case GL_UNSIGNED_BYTE_2_3_3_REV:
3991
	    assert(format == GL_RGB);
3992
	    halveImagePackedPixel(3,extract233rev,shove233rev,
3993
				  width,height,usersImage,dstImage,
3994
				  element_size,rowsize,myswap_bytes);
3995
	    break;
3996
	  case GL_UNSIGNED_SHORT_5_6_5:
3997
	    halveImagePackedPixel(3,extract565,shove565,
3998
				  width,height,usersImage,dstImage,
3999
				  element_size,rowsize,myswap_bytes);
4000
	    break;
4001
	  case GL_UNSIGNED_SHORT_5_6_5_REV:
4002
	    halveImagePackedPixel(3,extract565rev,shove565rev,
4003
				  width,height,usersImage,dstImage,
4004
				  element_size,rowsize,myswap_bytes);
4005
	    break;
4006
	  case GL_UNSIGNED_SHORT_4_4_4_4:
4007
	    halveImagePackedPixel(4,extract4444,shove4444,
4008
				  width,height,usersImage,dstImage,
4009
				  element_size,rowsize,myswap_bytes);
4010
	    break;
4011
	  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4012
	    halveImagePackedPixel(4,extract4444rev,shove4444rev,
4013
				  width,height,usersImage,dstImage,
4014
				  element_size,rowsize,myswap_bytes);
4015
	    break;
4016
	  case GL_UNSIGNED_SHORT_5_5_5_1:
4017
	    halveImagePackedPixel(4,extract5551,shove5551,
4018
				  width,height,usersImage,dstImage,
4019
				  element_size,rowsize,myswap_bytes);
4020
	    break;
4021
	  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4022
	    halveImagePackedPixel(4,extract1555rev,shove1555rev,
4023
				  width,height,usersImage,dstImage,
4024
				  element_size,rowsize,myswap_bytes);
4025
	    break;
4026
	  case GL_UNSIGNED_INT_8_8_8_8:
4027
	    halveImagePackedPixel(4,extract8888,shove8888,
4028
				  width,height,usersImage,dstImage,
4029
				  element_size,rowsize,myswap_bytes);
4030
	    break;
4031
	  case GL_UNSIGNED_INT_8_8_8_8_REV:
4032
	    halveImagePackedPixel(4,extract8888rev,shove8888rev,
4033
				  width,height,usersImage,dstImage,
4034
				  element_size,rowsize,myswap_bytes);
4035
	    break;
4036
	  case GL_UNSIGNED_INT_10_10_10_2:
4037
	    halveImagePackedPixel(4,extract1010102,shove1010102,
4038
				  width,height,usersImage,dstImage,
4039
				  element_size,rowsize,myswap_bytes);
4040
	    break;
4041
	  case GL_UNSIGNED_INT_2_10_10_10_REV:
4042
	    halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
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;
4083
	case GL_UNSIGNED_BYTE_3_3_2:
4084
	case GL_UNSIGNED_BYTE_2_3_3_REV:
4085
	  dstImage = (GLubyte *)malloc(memreq);
4086
	  break;
4087
	case GL_UNSIGNED_SHORT_5_6_5:
4088
	case GL_UNSIGNED_SHORT_5_6_5_REV:
4089
	case GL_UNSIGNED_SHORT_4_4_4_4:
4090
	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4091
	case GL_UNSIGNED_SHORT_5_5_5_1:
4092
	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4093
	  dstImage = (GLushort *)malloc(memreq);
4094
	  break;
4095
	case GL_UNSIGNED_INT_8_8_8_8:
4096
	case GL_UNSIGNED_INT_8_8_8_8_REV:
4097
	case GL_UNSIGNED_INT_10_10_10_2:
4098
	case GL_UNSIGNED_INT_2_10_10_10_REV:
4099
	  dstImage = (GLuint *)malloc(memreq);
4100
	  break;
4101
	default:
4102
	  return GLU_INVALID_ENUM;
4103
	}
4104
	if (dstImage == NULL) {
4105
	  glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4106
	  glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4107
	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4108
	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4109
	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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;
4139
	    case GL_UNSIGNED_BYTE_3_3_2:
4140
	    case GL_UNSIGNED_BYTE_2_3_3_REV:
4141
		dstImage = (GLubyte *)malloc(memreq);
4142
		break;
4143
	    case GL_UNSIGNED_SHORT_5_6_5:
4144
	    case GL_UNSIGNED_SHORT_5_6_5_REV:
4145
	    case GL_UNSIGNED_SHORT_4_4_4_4:
4146
	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4147
	    case GL_UNSIGNED_SHORT_5_5_5_1:
4148
	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4149
		dstImage = (GLushort *)malloc(memreq);
4150
		break;
4151
	    case GL_UNSIGNED_INT_8_8_8_8:
4152
	    case GL_UNSIGNED_INT_8_8_8_8_REV:
4153
	    case GL_UNSIGNED_INT_10_10_10_2:
4154
	    case GL_UNSIGNED_INT_2_10_10_10_REV:
4155
		dstImage = (GLuint *)malloc(memreq);
4156
		break;
4157
	    default:
4158
		return GLU_INVALID_ENUM;
4159
	}
4160
 
4161
	if (dstImage == NULL) {
4162
	    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4163
	    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4164
	    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4165
	    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4166
	    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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;
4213
	case GL_UNSIGNED_BYTE_3_3_2:
4214
	    scaleInternalPackedPixel(3,extract332,shove332,
4215
				     width, height,usersImage,
4216
				     newwidth,newheight,(void *)dstImage,
4217
				     element_size,rowsize,myswap_bytes);
4218
	    break;
4219
	case GL_UNSIGNED_BYTE_2_3_3_REV:
4220
	    scaleInternalPackedPixel(3,extract233rev,shove233rev,
4221
				     width, height,usersImage,
4222
				     newwidth,newheight,(void *)dstImage,
4223
				     element_size,rowsize,myswap_bytes);
4224
	    break;
4225
	case GL_UNSIGNED_SHORT_5_6_5:
4226
	    scaleInternalPackedPixel(3,extract565,shove565,
4227
				     width, height,usersImage,
4228
				     newwidth,newheight,(void *)dstImage,
4229
				     element_size,rowsize,myswap_bytes);
4230
	    break;
4231
	case GL_UNSIGNED_SHORT_5_6_5_REV:
4232
	    scaleInternalPackedPixel(3,extract565rev,shove565rev,
4233
				     width, height,usersImage,
4234
				     newwidth,newheight,(void *)dstImage,
4235
				     element_size,rowsize,myswap_bytes);
4236
	    break;
4237
	case GL_UNSIGNED_SHORT_4_4_4_4:
4238
	    scaleInternalPackedPixel(4,extract4444,shove4444,
4239
				     width, height,usersImage,
4240
				     newwidth,newheight,(void *)dstImage,
4241
				     element_size,rowsize,myswap_bytes);
4242
	    break;
4243
	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4244
	    scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4245
				     width, height,usersImage,
4246
				     newwidth,newheight,(void *)dstImage,
4247
				     element_size,rowsize,myswap_bytes);
4248
	    break;
4249
	case GL_UNSIGNED_SHORT_5_5_5_1:
4250
	    scaleInternalPackedPixel(4,extract5551,shove5551,
4251
				     width, height,usersImage,
4252
				     newwidth,newheight,(void *)dstImage,
4253
				     element_size,rowsize,myswap_bytes);
4254
	    break;
4255
	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4256
	    scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4257
				     width, height,usersImage,
4258
				     newwidth,newheight,(void *)dstImage,
4259
				     element_size,rowsize,myswap_bytes);
4260
	    break;
4261
	case GL_UNSIGNED_INT_8_8_8_8:
4262
	    scaleInternalPackedPixel(4,extract8888,shove8888,
4263
				     width, height,usersImage,
4264
				     newwidth,newheight,(void *)dstImage,
4265
				     element_size,rowsize,myswap_bytes);
4266
	    break;
4267
	case GL_UNSIGNED_INT_8_8_8_8_REV:
4268
	    scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4269
				     width, height,usersImage,
4270
				     newwidth,newheight,(void *)dstImage,
4271
				     element_size,rowsize,myswap_bytes);
4272
	    break;
4273
	case GL_UNSIGNED_INT_10_10_10_2:
4274
	    scaleInternalPackedPixel(4,extract1010102,shove1010102,
4275
				     width, height,usersImage,
4276
				     newwidth,newheight,(void *)dstImage,
4277
				     element_size,rowsize,myswap_bytes);
4278
	    break;
4279
	case GL_UNSIGNED_INT_2_10_10_10_REV:
4280
	    scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
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;
4326
	  case GL_UNSIGNED_BYTE_3_3_2:
4327
	  case GL_UNSIGNED_BYTE_2_3_3_REV:
4328
	    dstImage = (GLubyte *)malloc(memreq);
4329
	    break;
4330
	  case GL_UNSIGNED_SHORT_5_6_5:
4331
	  case GL_UNSIGNED_SHORT_5_6_5_REV:
4332
	  case GL_UNSIGNED_SHORT_4_4_4_4:
4333
	  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4334
	  case GL_UNSIGNED_SHORT_5_5_5_1:
4335
	  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4336
	    dstImage = (GLushort *)malloc(memreq);
4337
	    break;
4338
	  case GL_UNSIGNED_INT_8_8_8_8:
4339
	  case GL_UNSIGNED_INT_8_8_8_8_REV:
4340
	  case GL_UNSIGNED_INT_10_10_10_2:
4341
	  case GL_UNSIGNED_INT_2_10_10_10_REV:
4342
	    dstImage = (GLuint *)malloc(memreq);
4343
	    break;
4344
	  default:
4345
	    return GLU_INVALID_ENUM;
4346
	  }
4347
	  if (dstImage == NULL) {
4348
	    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4349
	    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4350
	    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4351
	    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4352
	    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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
 
4361
    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
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;
4405
	    case GL_UNSIGNED_BYTE_3_3_2:
4406
		halveImagePackedPixel(3,extract332,shove332,
4407
				      newwidth,newheight,
4408
				      srcImage,dstImage,element_size,rowsize,
4409
				      myswap_bytes);
4410
		break;
4411
	    case GL_UNSIGNED_BYTE_2_3_3_REV:
4412
		halveImagePackedPixel(3,extract233rev,shove233rev,
4413
				      newwidth,newheight,
4414
				      srcImage,dstImage,element_size,rowsize,
4415
				      myswap_bytes);
4416
		break;
4417
	    case GL_UNSIGNED_SHORT_5_6_5:
4418
		halveImagePackedPixel(3,extract565,shove565,
4419
				      newwidth,newheight,
4420
				      srcImage,dstImage,element_size,rowsize,
4421
				      myswap_bytes);
4422
		break;
4423
	    case GL_UNSIGNED_SHORT_5_6_5_REV:
4424
		halveImagePackedPixel(3,extract565rev,shove565rev,
4425
				      newwidth,newheight,
4426
				      srcImage,dstImage,element_size,rowsize,
4427
				      myswap_bytes);
4428
		break;
4429
	    case GL_UNSIGNED_SHORT_4_4_4_4:
4430
		halveImagePackedPixel(4,extract4444,shove4444,
4431
				      newwidth,newheight,
4432
				      srcImage,dstImage,element_size,rowsize,
4433
				      myswap_bytes);
4434
		break;
4435
	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4436
		halveImagePackedPixel(4,extract4444rev,shove4444rev,
4437
				      newwidth,newheight,
4438
				      srcImage,dstImage,element_size,rowsize,
4439
				      myswap_bytes);
4440
		break;
4441
	    case GL_UNSIGNED_SHORT_5_5_5_1:
4442
		halveImagePackedPixel(4,extract5551,shove5551,
4443
				      newwidth,newheight,
4444
				      srcImage,dstImage,element_size,rowsize,
4445
				      myswap_bytes);
4446
		break;
4447
	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4448
		halveImagePackedPixel(4,extract1555rev,shove1555rev,
4449
				      newwidth,newheight,
4450
				      srcImage,dstImage,element_size,rowsize,
4451
				      myswap_bytes);
4452
		break;
4453
	    case GL_UNSIGNED_INT_8_8_8_8:
4454
		halveImagePackedPixel(4,extract8888,shove8888,
4455
				      newwidth,newheight,
4456
				      srcImage,dstImage,element_size,rowsize,
4457
				      myswap_bytes);
4458
		break;
4459
	    case GL_UNSIGNED_INT_8_8_8_8_REV:
4460
		halveImagePackedPixel(4,extract8888rev,shove8888rev,
4461
				      newwidth,newheight,
4462
				      srcImage,dstImage,element_size,rowsize,
4463
				      myswap_bytes);
4464
		break;
4465
	    case GL_UNSIGNED_INT_10_10_10_2:
4466
		halveImagePackedPixel(4,extract1010102,shove1010102,
4467
				      newwidth,newheight,
4468
				      srcImage,dstImage,element_size,rowsize,
4469
				      myswap_bytes);
4470
		break;
4471
	    case GL_UNSIGNED_INT_2_10_10_10_REV:
4472
		halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
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 */
4507
	     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4508
	     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4509
	     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4510
	     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4511
	     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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 */
4538
    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4539
    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4540
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4541
    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4542
    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
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
 
4551
GLint GLAPIENTRY
4552
gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
4553
			     GLsizei width, GLsizei height,
4554
			     GLenum format, GLenum type,
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
 
4583
GLint GLAPIENTRY
4584
gluBuild2DMipmaps(GLenum target, GLint internalFormat,
4585
			GLsizei width, GLsizei height,
4586
			GLenum format, GLenum type,
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,
4622
		       GLenum target, GLint components, GLint width,
4623
		     GLint height, GLenum format,
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
4638
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
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;
4654
    /**
4655
    ** No need to copy the user data if its in the packed correctly.
4656
    ** Make sure that later routines don't change that data.
4657
    */
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
 
4705
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4706
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
4707
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
4708
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
4709
    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
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) {
4723
		    glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4724
		    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4725
		    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4726
		    glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
4727
		    glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
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
    }
4749
    glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4750
    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4751
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4752
    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
4753
    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
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
 */
4768
static GLint elements_per_group(GLenum format, GLenum type)
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 ||
4780
	type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4781
	type == GL_UNSIGNED_SHORT_5_5_5_1  ||
4782
	type == GL_UNSIGNED_SHORT_1_5_5_5_REV  ||
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 ||
4786
	type == GL_UNSIGNED_INT_2_10_10_10_REV) {
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
 
4805
static GLfloat bytes_per_element(GLenum type)
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));
4827
      case GL_UNSIGNED_BYTE_3_3_2:
4828
      case GL_UNSIGNED_BYTE_2_3_3_REV:
4829
	return(sizeof(GLubyte));
4830
      case GL_UNSIGNED_SHORT_5_6_5:
4831
      case GL_UNSIGNED_SHORT_5_6_5_REV:
4832
      case GL_UNSIGNED_SHORT_4_4_4_4:
4833
      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4834
      case GL_UNSIGNED_SHORT_5_5_5_1:
4835
      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4836
	return(sizeof(GLushort));
4837
      case GL_UNSIGNED_INT_8_8_8_8:
4838
      case GL_UNSIGNED_INT_8_8_8_8_REV:
4839
      case GL_UNSIGNED_INT_10_10_10_2:
4840
      case GL_UNSIGNED_INT_2_10_10_10_REV:
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) {
4966
		  case GL_UNSIGNED_BYTE_3_3_2:
4967
		    extract332(0,iter,extractComponents);
4968
		    for (k = 0; k < 3; k++) {
4969
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
4970
		    }
4971
		    break;
4972
		  case GL_UNSIGNED_BYTE_2_3_3_REV:
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;
4993
		  case GL_UNSIGNED_SHORT_5_6_5:
4994
		    extract565(myswap_bytes,iter,extractComponents);
4995
		    for (k = 0; k < 3; k++) {
4996
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
4997
		    }
4998
		    break;
4999
		  case GL_UNSIGNED_SHORT_5_6_5_REV:
5000
		    extract565rev(myswap_bytes,iter,extractComponents);
5001
		    for (k = 0; k < 3; k++) {
5002
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5003
		    }
5004
		    break;
5005
		  case GL_UNSIGNED_SHORT_4_4_4_4:
5006
		    extract4444(myswap_bytes,iter,extractComponents);
5007
		    for (k = 0; k < 4; k++) {
5008
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5009
		    }
5010
		    break;
5011
		  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5012
		    extract4444rev(myswap_bytes,iter,extractComponents);
5013
		    for (k = 0; k < 4; k++) {
5014
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5015
		    }
5016
		    break;
5017
		  case GL_UNSIGNED_SHORT_5_5_5_1:
5018
		    extract5551(myswap_bytes,iter,extractComponents);
5019
		    for (k = 0; k < 4; k++) {
5020
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5021
		    }
5022
		    break;
5023
		  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
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;
5049
		  case GL_UNSIGNED_INT_8_8_8_8:
5050
		    extract8888(myswap_bytes,iter,extractComponents);
5051
		    for (k = 0; k < 4; k++) {
5052
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5053
		    }
5054
		    break;
5055
		  case GL_UNSIGNED_INT_8_8_8_8_REV:
5056
		    extract8888rev(myswap_bytes,iter,extractComponents);
5057
		    for (k = 0; k < 4; k++) {
5058
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5059
		    }
5060
		    break;
5061
		  case GL_UNSIGNED_INT_10_10_10_2:
5062
		    extract1010102(myswap_bytes,iter,extractComponents);
5063
		    for (k = 0; k < 4; k++) {
5064
		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5065
		    }
5066
		    break;
5067
		  case GL_UNSIGNED_INT_2_10_10_10_REV:
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) {
5239
		  case GL_UNSIGNED_BYTE_3_3_2:
5240
		    for (k = 0; k < 3; k++) {
5241
		       shoveComponents[k]= *iter2++ / 65535.0;
5242
		    }
5243
		    shove332(shoveComponents,0,(void *)iter);
5244
		    break;
5245
		  case GL_UNSIGNED_BYTE_2_3_3_REV:
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;
5265
		  case GL_UNSIGNED_SHORT_5_6_5:
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;
5278
		  case GL_UNSIGNED_SHORT_5_6_5_REV:
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;
5291
		  case GL_UNSIGNED_SHORT_4_4_4_4:
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;
5303
		  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
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;
5315
		  case GL_UNSIGNED_SHORT_5_5_5_1:
5316
		    for (k = 0; k < 4; k++) {
5317
		       shoveComponents[k]= *iter2++ / 65535.0;
5318
		    }
5319
		    shove5551(shoveComponents,0,(void *)&widget.us[0]);
5320
		    if (myswap_bytes) {
5321
		       iter[0] = widget.ub[1];
5322
		       iter[1] = widget.ub[0];
5323
		    } else {
5324
		       *(GLushort *)iter = widget.us[0];
5325
		    }
5326
		    break;
5327
		  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5328
		    for (k = 0; k < 4; k++) {
5329
		       shoveComponents[k]= *iter2++ / 65535.0;
5330
		    }
5331
		    shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
5332
		    if (myswap_bytes) {
5333
		       iter[0] = widget.ub[1];
5334
		       iter[1] = widget.ub[0];
5335
		    } else {
5336
		       *(GLushort *)iter = widget.us[0];
5337
		    }
5338
		    break;
5339
		  case GL_UNSIGNED_SHORT:
5340
		  case GL_SHORT:
5341
		    if (type == GL_SHORT) {
5342
			if (index_format) {
5343
			    widget.s[0] = *iter2++;
5344
			} else {
5345
			    widget.s[0] = *iter2++ >> 1;
5346
			}
5347
		    } else {
5348
			widget.us[0] = *iter2++;
5349
		    }
5350
		    if (myswap_bytes) {
5351
			iter[0] = widget.ub[1];
5352
			iter[1] = widget.ub[0];
5353
		    } else {
5354
			iter[0] = widget.ub[0];
5355
			iter[1] = widget.ub[1];
5356
		    }
5357
		    break;
5358
		  case GL_UNSIGNED_INT_8_8_8_8:
5359
		    for (k = 0; k < 4; k++) {
5360
		       shoveComponents[k]= *iter2++ / 65535.0;
5361
		    }
5362
		    shove8888(shoveComponents,0,(void *)&widget.ui);
5363
		    if (myswap_bytes) {
5364
			iter[3] = widget.ub[0];
5365
			iter[2] = widget.ub[1];
5366
			iter[1] = widget.ub[2];
5367
			iter[0] = widget.ub[3];
5368
		    } else {
5369
			*(GLuint *)iter= widget.ui;
5370
		    }
5371
 
5372
		    break;
5373
		  case GL_UNSIGNED_INT_8_8_8_8_REV:
5374
		    for (k = 0; k < 4; k++) {
5375
		       shoveComponents[k]= *iter2++ / 65535.0;
5376
		    }
5377
		    shove8888rev(shoveComponents,0,(void *)&widget.ui);
5378
		    if (myswap_bytes) {
5379
			iter[3] = widget.ub[0];
5380
			iter[2] = widget.ub[1];
5381
			iter[1] = widget.ub[2];
5382
			iter[0] = widget.ub[3];
5383
		    } else {
5384
			*(GLuint *)iter= widget.ui;
5385
		    }
5386
		    break;
5387
		  case GL_UNSIGNED_INT_10_10_10_2:
5388
		    for (k = 0; k < 4; k++) {
5389
		       shoveComponents[k]= *iter2++ / 65535.0;
5390
		    }
5391
		    shove1010102(shoveComponents,0,(void *)&widget.ui);
5392
		    if (myswap_bytes) {
5393
			iter[3] = widget.ub[0];
5394
			iter[2] = widget.ub[1];
5395
			iter[1] = widget.ub[2];
5396
			iter[0] = widget.ub[3];
5397
		    } else {
5398
			*(GLuint *)iter= widget.ui;
5399
		    }
5400
		    break;
5401
		  case GL_UNSIGNED_INT_2_10_10_10_REV:
5402
		    for (k = 0; k < 4; k++) {
5403
		       shoveComponents[k]= *iter2++ / 65535.0;
5404
		    }
5405
		    shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5406
		    if (myswap_bytes) {
5407
			iter[3] = widget.ub[0];
5408
			iter[2] = widget.ub[1];
5409
			iter[1] = widget.ub[2];
5410
			iter[0] = widget.ub[3];
5411
		    } else {
5412
			*(GLuint *)iter= widget.ui;
5413
		    }
5414
		    break;
5415
		  case GL_INT:
5416
		  case GL_UNSIGNED_INT:
5417
		  case GL_FLOAT:
5418
		    if (type == GL_FLOAT) {
5419
			if (index_format) {
5420
			    widget.f = *iter2++;
5421
			} else {
5422
			    widget.f = *iter2++ / (float) 65535.0;
5423
			}
5424
		    } else if (type == GL_UNSIGNED_INT) {
5425
			if (index_format) {
5426
			    widget.ui = *iter2++;
5427
			} else {
5428
			    widget.ui = (unsigned int) *iter2++ * 65537;
5429
			}
5430
		    } else {
5431
			if (index_format) {
5432
			    widget.i = *iter2++;
5433
			} else {
5434
			    widget.i = ((unsigned int) *iter2++ * 65537)/2;
5435
			}
5436
		    }
5437
		    if (myswap_bytes) {
5438
			iter[3] = widget.ub[0];
5439
			iter[2] = widget.ub[1];
5440
			iter[1] = widget.ub[2];
5441
			iter[0] = widget.ub[3];
5442
		    } else {
5443
			iter[0] = widget.ub[0];
5444
			iter[1] = widget.ub[1];
5445
			iter[2] = widget.ub[2];
5446
			iter[3] = widget.ub[3];
5447
		    }
5448
		    break;
5449
		}
5450
		iter += element_size;
5451
	    } /* for j */
5452
	    start += rowsize;
5453
#if 1
5454
	    /* want 'iter' pointing at start, not within, row for assertion
5455
	     * purposes
5456
	     */
5457
	    iter= start;
5458
#endif
5459
	} /* for i */
5460
 
5461
	/* iterators should be one byte past end */
5462
	if (!isTypePackedPixel(type)) {
5463
	   assert(iter2 == &oldimage[width*height*components]);
5464
	}
5465
	else {
5466
	   assert(iter2 == &oldimage[width*height*
5467
				     elements_per_group(format,0)]);
5468
	}
5469
	assert( iter == &((GLubyte *)userdata)[rowsize*height +
5470
					psm->pack_skip_rows * rowsize +
5471
					psm->pack_skip_pixels * group_size] );
5472
 
5473
    } /* else */
5474
} /* empty_image() */
5475
 
5476
/*--------------------------------------------------------------------------
5477
 * Decimation of packed pixel types
5478
 *--------------------------------------------------------------------------
5479
 */
5480
static void extract332(int isSwap,
5481
		       const void *packedPixel, GLfloat extractComponents[])
5482
{
5483
   GLubyte ubyte= *(const GLubyte *)packedPixel;
5484
 
5485
   isSwap= isSwap;		/* turn off warnings */
5486
 
5487
   /* 11100000 == 0xe0 */
5488
   /* 00011100 == 0x1c */
5489
   /* 00000011 == 0x03 */
5490
 
5491
   extractComponents[0]=   (float)((ubyte & 0xe0)  >> 5) / 7.0;
5492
   extractComponents[1]=   (float)((ubyte & 0x1c)  >> 2) / 7.0; /* 7 = 2^3-1 */
5493
   extractComponents[2]=   (float)((ubyte & 0x03)      ) / 3.0; /* 3 = 2^2-1 */
5494
} /* extract332() */
5495
 
5496
static void shove332(const GLfloat shoveComponents[],
5497
		     int index, void *packedPixel)
5498
{
5499
   /* 11100000 == 0xe0 */
5500
   /* 00011100 == 0x1c */
5501
   /* 00000011 == 0x03 */
5502
 
5503
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5504
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5505
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5506
 
5507
   /* due to limited precision, need to round before shoving */
5508
   ((GLubyte *)packedPixel)[index]  =
5509
     ((GLubyte)((shoveComponents[0] * 7)+0.5)  << 5) & 0xe0;
5510
   ((GLubyte *)packedPixel)[index] |=
5511
     ((GLubyte)((shoveComponents[1] * 7)+0.5)  << 2) & 0x1c;
5512
   ((GLubyte *)packedPixel)[index]  |=
5513
     ((GLubyte)((shoveComponents[2] * 3)+0.5)	   ) & 0x03;
5514
} /* shove332() */
5515
 
5516
static void extract233rev(int isSwap,
5517
			  const void *packedPixel, GLfloat extractComponents[])
5518
{
5519
   GLubyte ubyte= *(const GLubyte *)packedPixel;
5520
 
5521
   isSwap= isSwap;		/* turn off warnings */
5522
 
5523
   /* 0000,0111 == 0x07 */
5524
   /* 0011,1000 == 0x38 */
5525
   /* 1100,0000 == 0xC0 */
5526
 
5527
   extractComponents[0]= (float)((ubyte & 0x07)     ) / 7.0;
5528
   extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5529
   extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5530
} /* extract233rev() */
5531
 
5532
static void shove233rev(const GLfloat shoveComponents[],
5533
			int index, void *packedPixel)
5534
{
5535
   /* 0000,0111 == 0x07 */
5536
   /* 0011,1000 == 0x38 */
5537
   /* 1100,0000 == 0xC0 */
5538
 
5539
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5540
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5541
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5542
 
5543
   /* due to limited precision, need to round before shoving */
5544
   ((GLubyte *)packedPixel)[index] =
5545
     ((GLubyte)((shoveComponents[0] * 7.0)+0.5)     ) & 0x07;
5546
   ((GLubyte *)packedPixel)[index]|=
5547
     ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5548
   ((GLubyte *)packedPixel)[index]|=
5549
     ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5550
} /* shove233rev() */
5551
 
5552
static void extract565(int isSwap,
5553
		       const void *packedPixel, GLfloat extractComponents[])
5554
{
5555
   GLushort ushort;
5556
 
5557
   if (isSwap) {
5558
     ushort= __GLU_SWAP_2_BYTES(packedPixel);
5559
   }
5560
   else {
5561
     ushort= *(const GLushort *)packedPixel;
5562
   }
5563
 
5564
   /* 11111000,00000000 == 0xf800 */
5565
   /* 00000111,11100000 == 0x07e0 */
5566
   /* 00000000,00011111 == 0x001f */
5567
 
5568
   extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5569
   extractComponents[1]=(float)((ushort & 0x07e0) >>  5) / 63.0;/* 63 = 2^6-1*/
5570
   extractComponents[2]=(float)((ushort & 0x001f)      ) / 31.0;
5571
} /* extract565() */
5572
 
5573
static void shove565(const GLfloat shoveComponents[],
5574
		     int index,void *packedPixel)
5575
{
5576
   /* 11111000,00000000 == 0xf800 */
5577
   /* 00000111,11100000 == 0x07e0 */
5578
   /* 00000000,00011111 == 0x001f */
5579
 
5580
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5581
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5582
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5583
 
5584
   /* due to limited precision, need to round before shoving */
5585
   ((GLushort *)packedPixel)[index] =
5586
     ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5587
   ((GLushort *)packedPixel)[index]|=
5588
     ((GLushort)((shoveComponents[1] * 63)+0.5) <<  5) & 0x07e0;
5589
   ((GLushort *)packedPixel)[index]|=
5590
     ((GLushort)((shoveComponents[2] * 31)+0.5)      ) & 0x001f;
5591
} /* shove565() */
5592
 
5593
static void extract565rev(int isSwap,
5594
			  const void *packedPixel, GLfloat extractComponents[])
5595
{
5596
   GLushort ushort;
5597
 
5598
   if (isSwap) {
5599
     ushort= __GLU_SWAP_2_BYTES(packedPixel);
5600
   }
5601
   else {
5602
     ushort= *(const GLushort *)packedPixel;
5603
   }
5604
 
5605
   /* 00000000,00011111 == 0x001f */
5606
   /* 00000111,11100000 == 0x07e0 */
5607
   /* 11111000,00000000 == 0xf800 */
5608
 
5609
   extractComponents[0]= (float)((ushort & 0x001F)	) / 31.0;
5610
   extractComponents[1]= (float)((ushort & 0x07E0) >>  5) / 63.0;
5611
   extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5612
} /* extract565rev() */
5613
 
5614
static void shove565rev(const GLfloat shoveComponents[],
5615
			int index,void *packedPixel)
5616
{
5617
   /* 00000000,00011111 == 0x001f */
5618
   /* 00000111,11100000 == 0x07e0 */
5619
   /* 11111000,00000000 == 0xf800 */
5620
 
5621
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5622
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5623
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5624
 
5625
   /* due to limited precision, need to round before shoving */
5626
   ((GLushort *)packedPixel)[index] =
5627
     ((GLushort)((shoveComponents[0] * 31.0)+0.5)      ) & 0x001F;
5628
   ((GLushort *)packedPixel)[index]|=
5629
     ((GLushort)((shoveComponents[1] * 63.0)+0.5) <<  5) & 0x07E0;
5630
   ((GLushort *)packedPixel)[index]|=
5631
     ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5632
} /* shove565rev() */
5633
 
5634
static void extract4444(int isSwap,const void *packedPixel,
5635
			GLfloat extractComponents[])
5636
{
5637
   GLushort ushort;
5638
 
5639
   if (isSwap) {
5640
     ushort= __GLU_SWAP_2_BYTES(packedPixel);
5641
   }
5642
   else {
5643
     ushort= *(const GLushort *)packedPixel;
5644
   }
5645
 
5646
   /* 11110000,00000000 == 0xf000 */
5647
   /* 00001111,00000000 == 0x0f00 */
5648
   /* 00000000,11110000 == 0x00f0 */
5649
   /* 00000000,00001111 == 0x000f */
5650
 
5651
   extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5652
   extractComponents[1]= (float)((ushort & 0x0f00) >>  8) / 15.0;
5653
   extractComponents[2]= (float)((ushort & 0x00f0) >>  4) / 15.0;
5654
   extractComponents[3]= (float)((ushort & 0x000f)	) / 15.0;
5655
} /* extract4444() */
5656
 
5657
static void shove4444(const GLfloat shoveComponents[],
5658
		      int index,void *packedPixel)
5659
{
5660
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5661
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5662
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5663
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5664
 
5665
   /* due to limited precision, need to round before shoving */
5666
   ((GLushort *)packedPixel)[index] =
5667
     ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5668
   ((GLushort *)packedPixel)[index]|=
5669
     ((GLushort)((shoveComponents[1] * 15)+0.5) <<  8) & 0x0f00;
5670
   ((GLushort *)packedPixel)[index]|=
5671
     ((GLushort)((shoveComponents[2] * 15)+0.5) <<  4) & 0x00f0;
5672
   ((GLushort *)packedPixel)[index]|=
5673
     ((GLushort)((shoveComponents[3] * 15)+0.5)      ) & 0x000f;
5674
} /* shove4444() */
5675
 
5676
static void extract4444rev(int isSwap,const void *packedPixel,
5677
			   GLfloat extractComponents[])
5678
{
5679
   GLushort ushort;
5680
 
5681
   if (isSwap) {
5682
     ushort= __GLU_SWAP_2_BYTES(packedPixel);
5683
   }
5684
   else {
5685
     ushort= *(const GLushort *)packedPixel;
5686
   }
5687
 
5688
   /* 00000000,00001111 == 0x000f */
5689
   /* 00000000,11110000 == 0x00f0 */
5690
   /* 00001111,00000000 == 0x0f00 */
5691
   /* 11110000,00000000 == 0xf000 */
5692
 
5693
   /* 15 = 2^4-1 */
5694
   extractComponents[0]= (float)((ushort & 0x000F)	) / 15.0;
5695
   extractComponents[1]= (float)((ushort & 0x00F0) >>  4) / 15.0;
5696
   extractComponents[2]= (float)((ushort & 0x0F00) >>  8) / 15.0;
5697
   extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5698
} /* extract4444rev() */
5699
 
5700
static void shove4444rev(const GLfloat shoveComponents[],
5701
			 int index,void *packedPixel)
5702
{
5703
   /* 00000000,00001111 == 0x000f */
5704
   /* 00000000,11110000 == 0x00f0 */
5705
   /* 00001111,00000000 == 0x0f00 */
5706
   /* 11110000,00000000 == 0xf000 */
5707
 
5708
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5709
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5710
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5711
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5712
 
5713
   /* due to limited precision, need to round before shoving */
5714
   ((GLushort *)packedPixel)[index] =
5715
     ((GLushort)((shoveComponents[0] * 15)+0.5)      ) & 0x000F;
5716
   ((GLushort *)packedPixel)[index]|=
5717
     ((GLushort)((shoveComponents[1] * 15)+0.5) <<  4) & 0x00F0;
5718
   ((GLushort *)packedPixel)[index]|=
5719
     ((GLushort)((shoveComponents[2] * 15)+0.5) <<  8) & 0x0F00;
5720
   ((GLushort *)packedPixel)[index]|=
5721
     ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5722
} /* shove4444rev() */
5723
 
5724
static void extract5551(int isSwap,const void *packedPixel,
5725
			GLfloat extractComponents[])
5726
{
5727
   GLushort ushort;
5728
 
5729
   if (isSwap) {
5730
     ushort= __GLU_SWAP_2_BYTES(packedPixel);
5731
   }
5732
   else {
5733
     ushort= *(const GLushort *)packedPixel;
5734
   }
5735
 
5736
   /* 11111000,00000000 == 0xf800 */
5737
   /* 00000111,11000000 == 0x07c0 */
5738
   /* 00000000,00111110 == 0x003e */
5739
   /* 00000000,00000001 == 0x0001 */
5740
 
5741
   extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5742
   extractComponents[1]=(float)((ushort & 0x07c0) >>  6) / 31.0;
5743
   extractComponents[2]=(float)((ushort & 0x003e) >>  1) / 31.0;
5744
   extractComponents[3]=(float)((ushort & 0x0001)      );
5745
} /* extract5551() */
5746
 
5747
static void shove5551(const GLfloat shoveComponents[],
5748
		      int index,void *packedPixel)
5749
{
5750
   /* 11111000,00000000 == 0xf800 */
5751
   /* 00000111,11000000 == 0x07c0 */
5752
   /* 00000000,00111110 == 0x003e */
5753
   /* 00000000,00000001 == 0x0001 */
5754
 
5755
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5756
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5757
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5758
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5759
 
5760
   /* due to limited precision, need to round before shoving */
5761
   ((GLushort *)packedPixel)[index]  =
5762
     ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5763
   ((GLushort *)packedPixel)[index]|=
5764
     ((GLushort)((shoveComponents[1] * 31)+0.5) <<  6) & 0x07c0;
5765
   ((GLushort *)packedPixel)[index]|=
5766
     ((GLushort)((shoveComponents[2] * 31)+0.5) <<  1) & 0x003e;
5767
   ((GLushort *)packedPixel)[index]|=
5768
     ((GLushort)((shoveComponents[3])+0.5)	     ) & 0x0001;
5769
} /* shove5551() */
5770
 
5771
static void extract1555rev(int isSwap,const void *packedPixel,
5772
			   GLfloat extractComponents[])
5773
{
5774
   GLushort ushort;
5775
 
5776
   if (isSwap) {
5777
     ushort= __GLU_SWAP_2_BYTES(packedPixel);
5778
   }
5779
   else {
5780
     ushort= *(const GLushort *)packedPixel;
5781
   }
5782
 
5783
   /* 00000000,00011111 == 0x001F */
5784
   /* 00000011,11100000 == 0x03E0 */
5785
   /* 01111100,00000000 == 0x7C00 */
5786
   /* 10000000,00000000 == 0x8000 */
5787
 
5788
   /* 31 = 2^5-1 */
5789
   extractComponents[0]= (float)((ushort & 0x001F)	) / 31.0;
5790
   extractComponents[1]= (float)((ushort & 0x03E0) >>  5) / 31.0;
5791
   extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5792
   extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5793
} /* extract1555rev() */
5794
 
5795
static void shove1555rev(const GLfloat shoveComponents[],
5796
			 int index,void *packedPixel)
5797
{
5798
   /* 00000000,00011111 == 0x001F */
5799
   /* 00000011,11100000 == 0x03E0 */
5800
   /* 01111100,00000000 == 0x7C00 */
5801
   /* 10000000,00000000 == 0x8000 */
5802
 
5803
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5804
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5805
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5806
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5807
 
5808
   /* due to limited precision, need to round before shoving */
5809
   ((GLushort *)packedPixel)[index] =
5810
     ((GLushort)((shoveComponents[0] * 31)+0.5)      ) & 0x001F;
5811
   ((GLushort *)packedPixel)[index]|=
5812
     ((GLushort)((shoveComponents[1] * 31)+0.5) <<  5) & 0x03E0;
5813
   ((GLushort *)packedPixel)[index]|=
5814
     ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5815
   ((GLushort *)packedPixel)[index]|=
5816
     ((GLushort)((shoveComponents[3])+0.5)	<< 15) & 0x8000;
5817
} /* shove1555rev() */
5818
 
5819
static void extract8888(int isSwap,
5820
			const void *packedPixel, GLfloat extractComponents[])
5821
{
5822
   GLuint uint;
5823
 
5824
   if (isSwap) {
5825
     uint= __GLU_SWAP_4_BYTES(packedPixel);
5826
   }
5827
   else {
5828
     uint= *(const GLuint *)packedPixel;
5829
   }
5830
 
5831
   /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5832
   /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5833
   /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5834
   /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5835
 
5836
   /* 255 = 2^8-1 */
5837
   extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5838
   extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5839
   extractComponents[2]= (float)((uint & 0x0000ff00) >>  8) / 255.0;
5840
   extractComponents[3]= (float)((uint & 0x000000ff)	  ) / 255.0;
5841
} /* extract8888() */
5842
 
5843
static void shove8888(const GLfloat shoveComponents[],
5844
		      int index,void *packedPixel)
5845
{
5846
   /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5847
   /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5848
   /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5849
   /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5850
 
5851
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5852
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5853
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5854
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5855
 
5856
   /* due to limited precision, need to round before shoving */
5857
   ((GLuint *)packedPixel)[index] =
5858
     ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5859
   ((GLuint *)packedPixel)[index]|=
5860
     ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5861
   ((GLuint *)packedPixel)[index]|=
5862
     ((GLuint)((shoveComponents[2] * 255)+0.5) <<  8) & 0x0000ff00;
5863
   ((GLuint *)packedPixel)[index]|=
5864
     ((GLuint)((shoveComponents[3] * 255)+0.5)	    ) & 0x000000ff;
5865
} /* shove8888() */
5866
 
5867
static void extract8888rev(int isSwap,
5868
			   const void *packedPixel,GLfloat extractComponents[])
5869
{
5870
   GLuint uint;
5871
 
5872
   if (isSwap) {
5873
     uint= __GLU_SWAP_4_BYTES(packedPixel);
5874
   }
5875
   else {
5876
     uint= *(const GLuint *)packedPixel;
5877
   }
5878
 
5879
   /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5880
   /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5881
   /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5882
   /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5883
 
5884
   /* 255 = 2^8-1 */
5885
   extractComponents[0]= (float)((uint & 0x000000FF)	  ) / 255.0;
5886
   extractComponents[1]= (float)((uint & 0x0000FF00) >>  8) / 255.0;
5887
   extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5888
   extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5889
} /* extract8888rev() */
5890
 
5891
static void shove8888rev(const GLfloat shoveComponents[],
5892
			 int index,void *packedPixel)
5893
{
5894
   /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5895
   /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5896
   /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5897
   /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5898
 
5899
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5900
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5901
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5902
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5903
 
5904
   /* due to limited precision, need to round before shoving */
5905
   ((GLuint *)packedPixel)[index] =
5906
     ((GLuint)((shoveComponents[0] * 255)+0.5)	    ) & 0x000000FF;
5907
   ((GLuint *)packedPixel)[index]|=
5908
     ((GLuint)((shoveComponents[1] * 255)+0.5) <<  8) & 0x0000FF00;
5909
   ((GLuint *)packedPixel)[index]|=
5910
     ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5911
   ((GLuint *)packedPixel)[index]|=
5912
     ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5913
} /* shove8888rev() */
5914
 
5915
static void extract1010102(int isSwap,
5916
			   const void *packedPixel,GLfloat extractComponents[])
5917
{
5918
   GLuint uint;
5919
 
5920
   if (isSwap) {
5921
     uint= __GLU_SWAP_4_BYTES(packedPixel);
5922
   }
5923
   else {
5924
     uint= *(const GLuint *)packedPixel;
5925
   }
5926
 
5927
   /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5928
   /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5929
   /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5930
   /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5931
 
5932
   /* 1023 = 2^10-1 */
5933
   extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5934
   extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5935
   extractComponents[2]= (float)((uint & 0x00000ffc) >>  2) / 1023.0;
5936
   extractComponents[3]= (float)((uint & 0x00000003)	  ) / 3.0;
5937
} /* extract1010102() */
5938
 
5939
static void shove1010102(const GLfloat shoveComponents[],
5940
			 int index,void *packedPixel)
5941
{
5942
   /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5943
   /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5944
   /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5945
   /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5946
 
5947
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5948
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5949
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5950
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5951
 
5952
   /* due to limited precision, need to round before shoving */
5953
   ((GLuint *)packedPixel)[index] =
5954
     ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5955
   ((GLuint *)packedPixel)[index]|=
5956
     ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5957
   ((GLuint *)packedPixel)[index]|=
5958
     ((GLuint)((shoveComponents[2] * 1023)+0.5) <<  2) & 0x00000ffc;
5959
   ((GLuint *)packedPixel)[index]|=
5960
     ((GLuint)((shoveComponents[3] * 3)+0.5)	     ) & 0x00000003;
5961
} /* shove1010102() */
5962
 
5963
static void extract2101010rev(int isSwap,
5964
			      const void *packedPixel,
5965
			      GLfloat extractComponents[])
5966
{
5967
   GLuint uint;
5968
 
5969
   if (isSwap) {
5970
     uint= __GLU_SWAP_4_BYTES(packedPixel);
5971
   }
5972
   else {
5973
     uint= *(const GLuint *)packedPixel;
5974
   }
5975
 
5976
   /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5977
   /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5978
   /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5979
   /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5980
 
5981
   /* 1023 = 2^10-1 */
5982
   extractComponents[0]= (float)((uint & 0x000003FF)	  ) / 1023.0;
5983
   extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5984
   extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5985
   extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5986
   /* 3 = 2^2-1 */
5987
} /* extract2101010rev() */
5988
 
5989
static void shove2101010rev(const GLfloat shoveComponents[],
5990
			    int index,void *packedPixel)
5991
{
5992
   /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5993
   /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5994
   /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5995
   /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5996
 
5997
   assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5998
   assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5999
   assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
6000
   assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
6001
 
6002
   /* due to limited precision, need to round before shoving */
6003
   ((GLuint *)packedPixel)[index] =
6004
     ((GLuint)((shoveComponents[0] * 1023)+0.5)      ) & 0x000003FF;
6005
   ((GLuint *)packedPixel)[index]|=
6006
     ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
6007
   ((GLuint *)packedPixel)[index]|=
6008
     ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
6009
   ((GLuint *)packedPixel)[index]|=
6010
     ((GLuint)((shoveComponents[3] * 3)+0.5)	<< 30) & 0xC0000000;
6011
} /* shove2101010rev() */
6012
 
6013
static void scaleInternalPackedPixel(int components,
6014
				     void (*extractPackedPixel)
6015
				     (int, const void *,GLfloat []),
6016
				     void (*shovePackedPixel)
6017
				     (const GLfloat [], int, void *),
6018
				     GLint widthIn,GLint heightIn,
6019
				     const void *dataIn,
6020
				     GLint widthOut,GLint heightOut,
6021
				     void *dataOut,
6022
				     GLint pixelSizeInBytes,
6023
				     GLint rowSizeInBytes,GLint isSwap)
6024
{
6025
    float convx;
6026
    float convy;
6027
    float percent;
6028
 
6029
    /* Max components in a format is 4, so... */
6030
    float totals[4];
6031
    float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
6032
 
6033
    float area;
6034
    int i,j,k,xindex;
6035
 
6036
    const char *temp, *temp0;
6037
    int outindex;
6038
 
6039
    int lowx_int, highx_int, lowy_int, highy_int;
6040
    float x_percent, y_percent;
6041
    float lowx_float, highx_float, lowy_float, highy_float;
6042
    float convy_float, convx_float;
6043
    int convy_int, convx_int;
6044
    int l, m;
6045
    const char *left, *right;
6046
 
6047
    if (widthIn == widthOut*2 && heightIn == heightOut*2) {
6048
	halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6049
			      widthIn, heightIn, dataIn, dataOut,
6050
			      pixelSizeInBytes,rowSizeInBytes,isSwap);
6051
	return;
6052
    }
6053
    convy = (float) heightIn/heightOut;
6054
    convx = (float) widthIn/widthOut;
6055
    convy_int = floor(convy);
6056
    convy_float = convy - convy_int;
6057
    convx_int = floor(convx);
6058
    convx_float = convx - convx_int;
6059
 
6060
    area = convx * convy;
6061
 
6062
    lowy_int = 0;
6063
    lowy_float = 0;
6064
    highy_int = convy_int;
6065
    highy_float = convy_float;
6066
 
6067
    for (i = 0; i < heightOut; i++) {
6068
	lowx_int = 0;
6069
	lowx_float = 0;
6070
	highx_int = convx_int;
6071
	highx_float = convx_float;
6072
 
6073
	for (j = 0; j < widthOut; j++) {
6074
	    /*
6075
	    ** Ok, now apply box filter to box that goes from (lowx, lowy)
6076
	    ** to (highx, highy) on input data into this pixel on output
6077
	    ** data.
6078
	    */
6079
	    totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6080
 
6081
	    /* calculate the value for pixels in the 1st row */
6082
	    xindex = lowx_int*pixelSizeInBytes;
6083
	    if((highy_int>lowy_int) && (highx_int>lowx_int)) {
6084
 
6085
		y_percent = 1-lowy_float;
6086
		temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6087
		percent = y_percent * (1-lowx_float);
6088
#if 0
6089
		for (k = 0, temp_index = temp; k < components;
6090
		     k++, temp_index += element_size) {
6091
		    if (myswap_bytes) {
6092
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6093
		    } else {
6094
			totals[k] += *(const GLushort*)temp_index * percent;
6095
		    }
6096
		}
6097
#else
6098
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6099
		for (k = 0; k < components; k++) {
6100
		   totals[k]+= extractTotals[k] * percent;
6101
		}
6102
#endif
6103
		left = temp;
6104
		for(l = lowx_int+1; l < highx_int; l++) {
6105
		    temp += pixelSizeInBytes;
6106
#if 0
6107
		    for (k = 0, temp_index = temp; k < components;
6108
			 k++, temp_index += element_size) {
6109
			if (myswap_bytes) {
6110
			    totals[k] +=
6111
				 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6112
			} else {
6113
			    totals[k] += *(const GLushort*)temp_index * y_percent;
6114
			}
6115
		    }
6116
#else
6117
		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6118
		    for (k = 0; k < components; k++) {
6119
		       totals[k]+= extractTotals[k] * y_percent;
6120
		    }
6121
#endif
6122
		}
6123
		temp += pixelSizeInBytes;
6124
		right = temp;
6125
		percent = y_percent * highx_float;
6126
#if 0
6127
		for (k = 0, temp_index = temp; k < components;
6128
		     k++, temp_index += element_size) {
6129
		    if (myswap_bytes) {
6130
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6131
		    } else {
6132
			totals[k] += *(const GLushort*)temp_index * percent;
6133
		    }
6134
		}
6135
#else
6136
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6137
		for (k = 0; k < components; k++) {
6138
		   totals[k]+= extractTotals[k] * percent;
6139
		}
6140
#endif
6141
 
6142
		/* calculate the value for pixels in the last row */
6143
 
6144
		y_percent = highy_float;
6145
		percent = y_percent * (1-lowx_float);
6146
		temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
6147
#if 0
6148
		for (k = 0, temp_index = temp; k < components;
6149
		     k++, temp_index += element_size) {
6150
		    if (myswap_bytes) {
6151
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6152
		    } else {
6153
			totals[k] += *(const GLushort*)temp_index * percent;
6154
		    }
6155
		}
6156
#else
6157
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6158
		for (k = 0; k < components; k++) {
6159
		   totals[k]+= extractTotals[k] * percent;
6160
		}
6161
#endif
6162
		for(l = lowx_int+1; l < highx_int; l++) {
6163
		    temp += pixelSizeInBytes;
6164
#if 0
6165
		    for (k = 0, temp_index = temp; k < components;
6166
			 k++, temp_index += element_size) {
6167
			if (myswap_bytes) {
6168
			    totals[k] +=
6169
				 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6170
			} else {
6171
			    totals[k] += *(const GLushort*)temp_index * y_percent;
6172
			}
6173
		    }
6174
#else
6175
		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6176
		    for (k = 0; k < components; k++) {
6177
		       totals[k]+= extractTotals[k] * y_percent;
6178
		    }
6179
#endif
6180
 
6181
		}
6182
		temp += pixelSizeInBytes;
6183
		percent = y_percent * highx_float;
6184
#if 0
6185
		for (k = 0, temp_index = temp; k < components;
6186
		     k++, temp_index += element_size) {
6187
		    if (myswap_bytes) {
6188
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6189
		    } else {
6190
			totals[k] += *(const GLushort*)temp_index * percent;
6191
		    }
6192
		}
6193
#else
6194
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6195
		for (k = 0; k < components; k++) {
6196
		   totals[k]+= extractTotals[k] * percent;
6197
		}
6198
#endif
6199
 
6200
		/* calculate the value for pixels in the 1st and last column */
6201
		for(m = lowy_int+1; m < highy_int; m++) {
6202
		    left += rowSizeInBytes;
6203
		    right += rowSizeInBytes;
6204
#if 0
6205
		    for (k = 0; k < components;
6206
			 k++, left += element_size, right += element_size) {
6207
			if (myswap_bytes) {
6208
			    totals[k] +=
6209
				__GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
6210
				__GLU_SWAP_2_BYTES(right) * highx_float;
6211
			} else {
6212
			    totals[k] += *(const GLushort*)left * (1-lowx_float)
6213
				       + *(const GLushort*)right * highx_float;
6214
			}
6215
		    }
6216
#else
6217
		    (*extractPackedPixel)(isSwap,left,extractTotals);
6218
		    (*extractPackedPixel)(isSwap,right,extractMoreTotals);
6219
		    for (k = 0; k < components; k++) {
6220
		       totals[k]+= (extractTotals[k]*(1-lowx_float) +
6221
				   extractMoreTotals[k]*highx_float);
6222
		    }
6223
#endif
6224
		}
6225
	    } else if (highy_int > lowy_int) {
6226
		x_percent = highx_float - lowx_float;
6227
		percent = (1-lowy_float)*x_percent;
6228
		temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6229
#if 0
6230
		for (k = 0, temp_index = temp; k < components;
6231
		     k++, temp_index += element_size) {
6232
		    if (myswap_bytes) {
6233
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6234
		    } else {
6235
			totals[k] += *(const GLushort*)temp_index * percent;
6236
		    }
6237
		}
6238
#else
6239
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6240
		for (k = 0; k < components; k++) {
6241
		   totals[k]+= extractTotals[k] * percent;
6242
		}
6243
#endif
6244
		for(m = lowy_int+1; m < highy_int; m++) {
6245
		    temp += rowSizeInBytes;
6246
#if 0
6247
		    for (k = 0, temp_index = temp; k < components;
6248
			 k++, temp_index += element_size) {
6249
			if (myswap_bytes) {
6250
			    totals[k] +=
6251
				__GLU_SWAP_2_BYTES(temp_index) * x_percent;
6252
			} else {
6253
			    totals[k] += *(const GLushort*)temp_index * x_percent;
6254
			}
6255
		    }
6256
#else
6257
		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6258
		    for (k = 0; k < components; k++) {
6259
		       totals[k]+= extractTotals[k] * x_percent;
6260
		    }
6261
#endif
6262
		}
6263
		percent = x_percent * highy_float;
6264
		temp += rowSizeInBytes;
6265
#if 0
6266
		for (k = 0, temp_index = temp; k < components;
6267
		     k++, temp_index += element_size) {
6268
		    if (myswap_bytes) {
6269
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6270
		    } else {
6271
			totals[k] += *(const GLushort*)temp_index * percent;
6272
		    }
6273
		}
6274
#else
6275
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6276
		for (k = 0; k < components; k++) {
6277
		   totals[k]+= extractTotals[k] * percent;
6278
		}
6279
#endif
6280
	    } else if (highx_int > lowx_int) {
6281
		y_percent = highy_float - lowy_float;
6282
		percent = (1-lowx_float)*y_percent;
6283
		temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6284
#if 0
6285
		for (k = 0, temp_index = temp; k < components;
6286
		     k++, temp_index += element_size) {
6287
		    if (myswap_bytes) {
6288
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6289
		    } else {
6290
			totals[k] += *(const GLushort*)temp_index * percent;
6291
		    }
6292
		}
6293
#else
6294
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6295
		for (k = 0; k < components; k++) {
6296
		   totals[k]+= extractTotals[k] * percent;
6297
		}
6298
#endif
6299
		for (l = lowx_int+1; l < highx_int; l++) {
6300
		    temp += pixelSizeInBytes;
6301
#if 0
6302
		    for (k = 0, temp_index = temp; k < components;
6303
			 k++, temp_index += element_size) {
6304
			if (myswap_bytes) {
6305
			    totals[k] +=
6306
				__GLU_SWAP_2_BYTES(temp_index) * y_percent;
6307
			} else {
6308
			    totals[k] += *(const GLushort*)temp_index * y_percent;
6309
			}
6310
		    }
6311
#else
6312
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6313
		for (k = 0; k < components; k++) {
6314
		   totals[k]+= extractTotals[k] * y_percent;
6315
		}
6316
#endif
6317
		}
6318
		temp += pixelSizeInBytes;
6319
		percent = y_percent * highx_float;
6320
#if 0
6321
		for (k = 0, temp_index = temp; k < components;
6322
		     k++, temp_index += element_size) {
6323
		    if (myswap_bytes) {
6324
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6325
		    } else {
6326
			totals[k] += *(const GLushort*)temp_index * percent;
6327
		    }
6328
		}
6329
#else
6330
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6331
		for (k = 0; k < components; k++) {
6332
		   totals[k]+= extractTotals[k] * percent;
6333
		}
6334
#endif
6335
	    } else {
6336
		percent = (highy_float-lowy_float)*(highx_float-lowx_float);
6337
		temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6338
#if 0
6339
		for (k = 0, temp_index = temp; k < components;
6340
		     k++, temp_index += element_size) {
6341
		    if (myswap_bytes) {
6342
			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6343
		    } else {
6344
			totals[k] += *(const GLushort*)temp_index * percent;
6345
		    }
6346
		}
6347
#else
6348
		(*extractPackedPixel)(isSwap,temp,extractTotals);
6349
		for (k = 0; k < components; k++) {
6350
		   totals[k]+= extractTotals[k] * percent;
6351
		}
6352
#endif
6353
	    }
6354
 
6355
	    /* this is for the pixels in the body */
6356
	    temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
6357
	    for (m = lowy_int+1; m < highy_int; m++) {
6358
		temp = temp0;
6359
		for(l = lowx_int+1; l < highx_int; l++) {
6360
#if 0
6361
		    for (k = 0, temp_index = temp; k < components;
6362
			 k++, temp_index += element_size) {
6363
			if (myswap_bytes) {
6364
			    totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6365
			} else {
6366
			    totals[k] += *(const GLushort*)temp_index;
6367
			}
6368
		    }
6369
#else
6370
		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6371
		    for (k = 0; k < components; k++) {
6372
		       totals[k]+= extractTotals[k];
6373
		    }
6374
#endif
6375
		    temp += pixelSizeInBytes;
6376
		}
6377
		temp0 += rowSizeInBytes;
6378
	    }
6379
 
6380
	    outindex = (j + (i * widthOut)); /* * (components == 1) */
6381
#if 0
6382
	    for (k = 0; k < components; k++) {
6383
		dataout[outindex + k] = totals[k]/area;
6384
		/*printf("totals[%d] = %f\n", k, totals[k]);*/
6385
	    }
6386
#else
6387
	    for (k = 0; k < components; k++) {
6388
		shoveTotals[k]= totals[k]/area;
6389
	    }
6390
	    (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6391
#endif
6392
	    lowx_int = highx_int;
6393
	    lowx_float = highx_float;
6394
	    highx_int += convx_int;
6395
	    highx_float += convx_float;
6396
	    if(highx_float > 1) {
6397
		highx_float -= 1.0;
6398
		highx_int++;
6399
	    }
6400
	}
6401
	lowy_int = highy_int;
6402
	lowy_float = highy_float;
6403
	highy_int += convy_int;
6404
	highy_float += convy_float;
6405
	if(highy_float > 1) {
6406
	    highy_float -= 1.0;
6407
	    highy_int++;
6408
	}
6409
    }
6410
 
6411
    assert(outindex == (widthOut*heightOut - 1));
6412
} /* scaleInternalPackedPixel() */
6413
 
6414
/* rowSizeInBytes is at least the width (in bytes) due to padding on
6415
 *  inputs; not always equal. Output NEVER has row padding.
6416
 */
6417
static void halveImagePackedPixel(int components,
6418
				  void (*extractPackedPixel)
6419
				  (int, const void *,GLfloat []),
6420
				  void (*shovePackedPixel)
6421
				  (const GLfloat [],int, void *),
6422
				  GLint width, GLint height,
6423
				  const void *dataIn, void *dataOut,
6424
				  GLint pixelSizeInBytes,
6425
				  GLint rowSizeInBytes, GLint isSwap)
6426
{
6427
   /* handle case where there is only 1 column/row */
6428
   if (width == 1 || height == 1) {
6429
      assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6430
      halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6431
			      width,height,dataIn,dataOut,pixelSizeInBytes,
6432
			      rowSizeInBytes,isSwap);
6433
      return;
6434
   }
6435
 
6436
   {
6437
      int ii, jj;
6438
 
6439
      int halfWidth= width / 2;
6440
      int halfHeight= height / 2;
6441
      const char *src= (const char *) dataIn;
6442
      int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6443
      int outIndex= 0;
6444
 
6445
      for (ii= 0; ii< halfHeight; ii++) {
6446
	 for (jj= 0; jj< halfWidth; jj++) {
6447
#define BOX4 4
6448
	    float totals[4];	/* 4 is maximum components */
6449
	    float extractTotals[BOX4][4]; /* 4 is maximum components */
6450
	    int cc;
6451
 
6452
	    (*extractPackedPixel)(isSwap,src,
6453
				  &extractTotals[0][0]);
6454
	    (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6455
				  &extractTotals[1][0]);
6456
	    (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6457
				  &extractTotals[2][0]);
6458
	    (*extractPackedPixel)(isSwap,
6459
				  (src+rowSizeInBytes+pixelSizeInBytes),
6460
				  &extractTotals[3][0]);
6461
	    for (cc = 0; cc < components; cc++) {
6462
	       int kk;
6463
 
6464
	       /* grab 4 pixels to average */
6465
	       totals[cc]= 0.0;
6466
	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6467
		*	       extractTotals[2][RED]+extractTotals[3][RED];
6468
		* totals[RED]/= 4.0;
6469
		*/
6470
	       for (kk = 0; kk < BOX4; kk++) {
6471
		  totals[cc]+= extractTotals[kk][cc];
6472
	       }
6473
	       totals[cc]/= (float)BOX4;
6474
	    }
6475
	    (*shovePackedPixel)(totals,outIndex,dataOut);
6476
 
6477
	    outIndex++;
6478
	    /* skip over to next square of 4 */
6479
	    src+= pixelSizeInBytes + pixelSizeInBytes;
6480
	 }
6481
	 /* skip past pad bytes, if any, to get to next row */
6482
	 src+= padBytes;
6483
 
6484
	 /* src is at beginning of a row here, but it's the second row of
6485
	  * the square block of 4 pixels that we just worked on so we
6486
	  * need to go one more row.
6487
	  * i.e.,
6488
	  *		      OO...
6489
	  *	      here -->OO...
6490
	  *	  but want -->OO...
6491
	  *		      OO...
6492
	  *		      ...
6493
	  */
6494
	 src+= rowSizeInBytes;
6495
      }
6496
 
6497
      /* both pointers must reach one byte after the end */
6498
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6499
      assert(outIndex == halfWidth * halfHeight);
6500
   }
6501
} /* halveImagePackedPixel() */
6502
 
6503
static void halve1DimagePackedPixel(int components,
6504
				    void (*extractPackedPixel)
6505
				    (int, const void *,GLfloat []),
6506
				    void (*shovePackedPixel)
6507
				    (const GLfloat [],int, void *),
6508
				    GLint width, GLint height,
6509
				    const void *dataIn, void *dataOut,
6510
				    GLint pixelSizeInBytes,
6511
				    GLint rowSizeInBytes, GLint isSwap)
6512
{
6513
   int halfWidth= width / 2;
6514
   int halfHeight= height / 2;
6515
   const char *src= (const char *) dataIn;
6516
   int jj;
6517
 
6518
   assert(width == 1 || height == 1); /* must be 1D */
6519
   assert(width != height);	/* can't be square */
6520
 
6521
   if (height == 1) {	/* 1 row */
6522
      int outIndex= 0;
6523
 
6524
      assert(width != 1);	/* widthxheight can't be 1x1 */
6525
      halfHeight= 1;
6526
 
6527
      /* one horizontal row with possible pad bytes */
6528
 
6529
      for (jj= 0; jj< halfWidth; jj++) {
6530
#define BOX2 2
6531
	 float totals[4];	/* 4 is maximum components */
6532
	 float extractTotals[BOX2][4]; /* 4 is maximum components */
6533
	 int cc;
6534
 
6535
	 /* average two at a time, instead of four */
6536
	 (*extractPackedPixel)(isSwap,src,
6537
			       &extractTotals[0][0]);
6538
	 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6539
			       &extractTotals[1][0]);
6540
	 for (cc = 0; cc < components; cc++) {
6541
	    int kk;
6542
 
6543
	    /* grab 2 pixels to average */
6544
	    totals[cc]= 0.0;
6545
	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6546
	     * totals[RED]/= 2.0;
6547
	     */
6548
	    for (kk = 0; kk < BOX2; kk++) {
6549
	       totals[cc]+= extractTotals[kk][cc];
6550
	    }
6551
	    totals[cc]/= (float)BOX2;
6552
	 }
6553
	 (*shovePackedPixel)(totals,outIndex,dataOut);
6554
 
6555
	 outIndex++;
6556
	 /* skip over to next group of 2 */
6557
	 src+= pixelSizeInBytes + pixelSizeInBytes;
6558
      }
6559
 
6560
      {
6561
	 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6562
	 src+= padBytes;	/* for assertion only */
6563
      }
6564
      assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6565
      assert(outIndex == halfWidth * halfHeight);
6566
   }
6567
   else if (width == 1) { /* 1 column */
6568
      int outIndex= 0;
6569
 
6570
      assert(height != 1);	/* widthxheight can't be 1x1 */
6571
      halfWidth= 1;
6572
      /* one vertical column with possible pad bytes per row */
6573
      /* average two at a time */
6574
 
6575
      for (jj= 0; jj< halfHeight; jj++) {
6576
#define BOX2 2
6577
	 float totals[4];	/* 4 is maximum components */
6578
	 float extractTotals[BOX2][4]; /* 4 is maximum components */
6579
	 int cc;
6580
 
6581
	 /* average two at a time, instead of four */
6582
	 (*extractPackedPixel)(isSwap,src,
6583
			       &extractTotals[0][0]);
6584
	 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6585
			       &extractTotals[1][0]);
6586
	 for (cc = 0; cc < components; cc++) {
6587
	    int kk;
6588
 
6589
	    /* grab 2 pixels to average */
6590
	    totals[cc]= 0.0;
6591
	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6592
	     * totals[RED]/= 2.0;
6593
	     */
6594
	    for (kk = 0; kk < BOX2; kk++) {
6595
	       totals[cc]+= extractTotals[kk][cc];
6596
	    }
6597
	    totals[cc]/= (float)BOX2;
6598
	 }
6599
	 (*shovePackedPixel)(totals,outIndex,dataOut);
6600
 
6601
	 outIndex++;
6602
	 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6603
      }
6604
 
6605
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6606
      assert(outIndex == halfWidth * halfHeight);
6607
   }
6608
} /* halve1DimagePackedPixel() */
6609
 
6610
/*===========================================================================*/
6611
 
6612
#ifdef RESOLVE_3D_TEXTURE_SUPPORT
6613
/*
6614
 * This section ensures that GLU 1.3 will load and run on
6615
 * a GL 1.1 implementation. It dynamically resolves the
6616
 * call to glTexImage3D() which might not be available.
6617
 * Or is it might be supported as an extension.
6618
 * Contributed by Gerk Huisma .
6619
 */
6620
 
6621
typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
6622
						 GLenum internalFormat,
6623
						 GLsizei width, GLsizei height,
6624
						 GLsizei depth, GLint border,
6625
						 GLenum format, GLenum type,
6626
						 const GLvoid *pixels );
6627
 
6628
static TexImage3Dproc pTexImage3D = 0;
6629
 
6630
#if !defined(_WIN32) && !defined(__WIN32__)
6631
#  include 
6632
#  include 
6633
#else
6634
  WINGDIAPI PROC  WINAPI wglGetProcAddress(LPCSTR);
6635
#endif
6636
 
6637
static void gluTexImage3D( GLenum target, GLint level,
6638
			   GLenum internalFormat,
6639
			   GLsizei width, GLsizei height,
6640
			   GLsizei depth, GLint border,
6641
			   GLenum format, GLenum type,
6642
			   const GLvoid *pixels )
6643
{
6644
   if (!pTexImage3D) {
6645
#if defined(_WIN32) || defined(__WIN32__)
6646
      pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
6647
      if (!pTexImage3D)
6648
	 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
6649
#else
6650
      void *libHandle = dlopen("libgl.so", RTLD_LAZY);
6651
      pTexImage3D = TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
6652
      if (!pTexImage3D)
6653
	 pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
6654
      dlclose(libHandle);
6655
#endif
6656
   }
6657
 
6658
   /* Now call glTexImage3D */
6659
   if (pTexImage3D)
6660
      pTexImage3D(target, level, internalFormat, width, height,
6661
		  depth, border, format, type, pixels);
6662
}
6663
 
6664
#else
6665
 
6666
/* Only bind to a GL 1.2 implementation: */
6667
#define gluTexImage3D glTexImage3D
6668
 
6669
#endif
6670
 
6671
static GLint imageSize3D(GLint width, GLint height, GLint depth,
6672
			 GLenum format, GLenum type)
6673
{
6674
    int components= elements_per_group(format,type);
6675
    int bytes_per_row=	bytes_per_element(type) * width;
6676
 
6677
assert(width > 0 && height > 0 && depth > 0);
6678
assert(type != GL_BITMAP);
6679
 
6680
    return bytes_per_row * height * depth * components;
6681
} /* imageSize3D() */
6682
 
6683
static void fillImage3D(const PixelStorageModes *psm,
6684
			GLint width, GLint height, GLint depth, GLenum format,
6685
			GLenum type, GLboolean indexFormat,
6686
			const void *userImage, GLushort *newImage)
6687
{
6688
   int myswapBytes;
6689
   int components;
6690
   int groupsPerLine;
6691
   int elementSize;
6692
   int groupSize;
6693
   int rowSize;
6694
   int padding;
6695
   int elementsPerLine;
6696
   int rowsPerImage;
6697
   int imageSize;
6698
   const GLubyte *start, *rowStart, *iter;
6699
   GLushort *iter2;
6700
   int ww, hh, dd, k;
6701
 
6702
   myswapBytes= psm->unpack_swap_bytes;
6703
   components= elements_per_group(format,type);
6704
   if (psm->unpack_row_length > 0) {
6705
      groupsPerLine= psm->unpack_row_length;
6706
   }
6707
   else {
6708
      groupsPerLine= width;
6709
   }
6710
   elementSize= bytes_per_element(type);
6711
   groupSize= elementSize * components;
6712
   if (elementSize == 1) myswapBytes= 0;
6713
 
6714
   /* 3dstuff begin */
6715
   if (psm->unpack_image_height > 0) {
6716
      rowsPerImage= psm->unpack_image_height;
6717
   }
6718
   else {
6719
      rowsPerImage= height;
6720
   }
6721
   /* 3dstuff end */
6722
 
6723
   rowSize= groupsPerLine * groupSize;
6724
   padding= rowSize % psm->unpack_alignment;
6725
   if (padding) {
6726
      rowSize+= psm->unpack_alignment - padding;
6727
   }
6728
 
6729
   imageSize= rowsPerImage * rowSize; /* 3dstuff */
6730
 
6731
   start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
6732
				 psm->unpack_skip_pixels * groupSize +
6733
				 /*3dstuff*/
6734
				 psm->unpack_skip_images * imageSize;
6735
   elementsPerLine = width * components;
6736
 
6737
   iter2= newImage;
6738
   for (dd= 0; dd < depth; dd++) {
6739
      rowStart= start;
6740
 
6741
      for (hh= 0; hh < height; hh++) {
6742
	 iter= rowStart;
6743
 
6744
	 for (ww= 0; ww < elementsPerLine; ww++) {
6745
	    Type_Widget widget;
6746
	    float extractComponents[4];
6747
 
6748
	    switch(type) {
6749
	    case GL_UNSIGNED_BYTE:
6750
	      if (indexFormat) {
6751
		  *iter2++ = *iter;
6752
	      } else {
6753
		  *iter2++ = (*iter) * 257;
6754
	      }
6755
	      break;
6756
	    case GL_BYTE:
6757
	      if (indexFormat) {
6758
		  *iter2++ = *((const GLbyte *) iter);
6759
	      } else {
6760
		  /* rough approx */
6761
		  *iter2++ = (*((const GLbyte *) iter)) * 516;
6762
	      }
6763
	      break;
6764
	    case GL_UNSIGNED_BYTE_3_3_2:
6765
	      extract332(0,iter,extractComponents);
6766
	      for (k = 0; k < 3; k++) {
6767
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6768
	      }
6769
	      break;
6770
	    case GL_UNSIGNED_BYTE_2_3_3_REV:
6771
	      extract233rev(0,iter,extractComponents);
6772
	      for (k = 0; k < 3; k++) {
6773
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6774
	      }
6775
	      break;
6776
	    case GL_UNSIGNED_SHORT_5_6_5:
6777
	      extract565(myswapBytes,iter,extractComponents);
6778
	      for (k = 0; k < 3; k++) {
6779
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6780
	      }
6781
	      break;
6782
	    case GL_UNSIGNED_SHORT_5_6_5_REV:
6783
	      extract565rev(myswapBytes,iter,extractComponents);
6784
	      for (k = 0; k < 3; k++) {
6785
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6786
	      }
6787
	      break;
6788
	    case GL_UNSIGNED_SHORT_4_4_4_4:
6789
	      extract4444(myswapBytes,iter,extractComponents);
6790
	      for (k = 0; k < 4; k++) {
6791
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6792
	      }
6793
	      break;
6794
	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
6795
	      extract4444rev(myswapBytes,iter,extractComponents);
6796
	      for (k = 0; k < 4; k++) {
6797
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6798
	      }
6799
	      break;
6800
	    case GL_UNSIGNED_SHORT_5_5_5_1:
6801
	      extract5551(myswapBytes,iter,extractComponents);
6802
	      for (k = 0; k < 4; k++) {
6803
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6804
	      }
6805
	      break;
6806
	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
6807
	      extract1555rev(myswapBytes,iter,extractComponents);
6808
	      for (k = 0; k < 4; k++) {
6809
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6810
	      }
6811
	      break;
6812
	    case GL_UNSIGNED_SHORT:
6813
	    case GL_SHORT:
6814
	      if (myswapBytes) {
6815
		  widget.ub[0] = iter[1];
6816
		  widget.ub[1] = iter[0];
6817
	      } else {
6818
		  widget.ub[0] = iter[0];
6819
		  widget.ub[1] = iter[1];
6820
	      }
6821
	      if (type == GL_SHORT) {
6822
		  if (indexFormat) {
6823
		      *iter2++ = widget.s[0];
6824
		  } else {
6825
		      /* rough approx */
6826
		      *iter2++ = widget.s[0]*2;
6827
		  }
6828
	      } else {
6829
		  *iter2++ = widget.us[0];
6830
	      }
6831
	      break;
6832
	    case GL_UNSIGNED_INT_8_8_8_8:
6833
	      extract8888(myswapBytes,iter,extractComponents);
6834
	      for (k = 0; k < 4; k++) {
6835
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6836
	      }
6837
	      break;
6838
	    case GL_UNSIGNED_INT_8_8_8_8_REV:
6839
	      extract8888rev(myswapBytes,iter,extractComponents);
6840
	      for (k = 0; k < 4; k++) {
6841
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6842
	      }
6843
	      break;
6844
	    case GL_UNSIGNED_INT_10_10_10_2:
6845
	      extract1010102(myswapBytes,iter,extractComponents);
6846
	      for (k = 0; k < 4; k++) {
6847
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6848
	      }
6849
	      break;
6850
	    case GL_UNSIGNED_INT_2_10_10_10_REV:
6851
	      extract2101010rev(myswapBytes,iter,extractComponents);
6852
	      for (k = 0; k < 4; k++) {
6853
		*iter2++ = (GLushort)(extractComponents[k]*65535);
6854
	      }
6855
	      break;
6856
	    case GL_INT:
6857
	    case GL_UNSIGNED_INT:
6858
	    case GL_FLOAT:
6859
	      if (myswapBytes) {
6860
		  widget.ub[0] = iter[3];
6861
		  widget.ub[1] = iter[2];
6862
		  widget.ub[2] = iter[1];
6863
		  widget.ub[3] = iter[0];
6864
	      } else {
6865
		  widget.ub[0] = iter[0];
6866
		  widget.ub[1] = iter[1];
6867
		  widget.ub[2] = iter[2];
6868
		  widget.ub[3] = iter[3];
6869
	      }
6870
	      if (type == GL_FLOAT) {
6871
		  if (indexFormat) {
6872
		      *iter2++ = widget.f;
6873
		  } else {
6874
		      *iter2++ = 65535 * widget.f;
6875
		  }
6876
	      } else if (type == GL_UNSIGNED_INT) {
6877
		  if (indexFormat) {
6878
		      *iter2++ = widget.ui;
6879
		  } else {
6880
		      *iter2++ = widget.ui >> 16;
6881
		  }
6882
	      } else {
6883
		  if (indexFormat) {
6884
		      *iter2++ = widget.i;
6885
		  } else {
6886
		      *iter2++ = widget.i >> 15;
6887
		  }
6888
	      }
6889
	      break;
6890
	    default:
6891
	      assert(0);
6892
	    }
6893
 
6894
	    iter+= elementSize;
6895
	 } /* for ww */
6896
	 rowStart+= rowSize;
6897
 
6898
	 iter= rowStart;	/* for assertion purposes */
6899
      } /* for hh */
6900
 
6901
      start+= imageSize;
6902
   } /* for dd */
6903
 
6904
   /* iterators should be one byte past end */
6905
   if (!isTypePackedPixel(type)) {
6906
      assert(iter2 == &newImage[width*height*depth*components]);
6907
   }
6908
   else {
6909
      assert(iter2 == &newImage[width*height*depth*
6910
				elements_per_group(format,0)]);
6911
   }
6912
   assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
6913
					psm->unpack_skip_rows * rowSize +
6914
					psm->unpack_skip_pixels * groupSize +
6915
					/*3dstuff*/
6916
					psm->unpack_skip_images * imageSize] );
6917
} /* fillImage3D () */
6918
 
6919
static void scaleInternal3D(GLint components,
6920
			    GLint widthIn, GLint heightIn, GLint depthIn,
6921
			    const GLushort *dataIn,
6922
			    GLint widthOut, GLint heightOut, GLint depthOut,
6923
			    GLushort *dataOut)
6924
{
6925
    float x, lowx, highx, convx, halfconvx;
6926
    float y, lowy, highy, convy, halfconvy;
6927
    float z, lowz, highz, convz, halfconvz;
6928
    float xpercent,ypercent,zpercent;
6929
    float percent;
6930
    /* Max components in a format is 4, so... */
6931
    float totals[4];
6932
    float volume;
6933
    int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
6934
    int temp;
6935
 
6936
    convz = (float) depthIn/depthOut;
6937
    convy = (float) heightIn/heightOut;
6938
    convx = (float) widthIn/widthOut;
6939
    halfconvx = convx/2;
6940
    halfconvy = convy/2;
6941
    halfconvz = convz/2;
6942
    for (d = 0; d < depthOut; d++) {
6943
       z = convz * (d+0.5);
6944
       if (depthIn > depthOut) {
6945
	   highz = z + halfconvz;
6946
	   lowz = z - halfconvz;
6947
       } else {
6948
	   highz = z + 0.5;
6949
	   lowz = z - 0.5;
6950
       }
6951
       for (i = 0; i < heightOut; i++) {
6952
	   y = convy * (i+0.5);
6953
	   if (heightIn > heightOut) {
6954
	       highy = y + halfconvy;
6955
	       lowy = y - halfconvy;
6956
	   } else {
6957
	       highy = y + 0.5;
6958
	       lowy = y - 0.5;
6959
	   }
6960
	   for (j = 0; j < widthOut; j++) {
6961
	       x = convx * (j+0.5);
6962
	       if (widthIn > widthOut) {
6963
		   highx = x + halfconvx;
6964
		   lowx = x - halfconvx;
6965
	       } else {
6966
		   highx = x + 0.5;
6967
		   lowx = x - 0.5;
6968
	       }
6969
 
6970
	       /*
6971
	       ** Ok, now apply box filter to box that goes from (lowx, lowy,
6972
	       ** lowz) to (highx, highy, highz) on input data into this pixel
6973
	       ** on output data.
6974
	       */
6975
	       totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6976
	       volume = 0.0;
6977
 
6978
	       z = lowz;
6979
	       zint = floor(z);
6980
	       while (z < highz) {
6981
		  zindex = (zint + depthIn) % depthIn;
6982
		  if (highz < zint+1) {
6983
		      zpercent = highz - z;
6984
		  } else {
6985
		      zpercent = zint+1 - z;
6986
		  }
6987
 
6988
		  y = lowy;
6989
		  yint = floor(y);
6990
		  while (y < highy) {
6991
		      yindex = (yint + heightIn) % heightIn;
6992
		      if (highy < yint+1) {
6993
			  ypercent = highy - y;
6994
		      } else {
6995
			  ypercent = yint+1 - y;
6996
		      }
6997
 
6998
		      x = lowx;
6999
		      xint = floor(x);
7000
 
7001
		      while (x < highx) {
7002
			  xindex = (xint + widthIn) % widthIn;
7003
			  if (highx < xint+1) {
7004
			      xpercent = highx - x;
7005
			  } else {
7006
			      xpercent = xint+1 - x;
7007
			  }
7008
 
7009
			  percent = xpercent * ypercent * zpercent;
7010
			  volume += percent;
7011
 
7012
			  temp = (xindex + (yindex*widthIn) +
7013
				  (zindex*widthIn*heightIn)) * components;
7014
			  for (k = 0; k < components; k++) {
7015
			      assert(0 <= (temp+k) &&
7016
				     (temp+k) <
7017
				     (widthIn*heightIn*depthIn*components));
7018
			      totals[k] += dataIn[temp + k] * percent;
7019
			  }
7020
 
7021
			  xint++;
7022
			  x = xint;
7023
		      } /* while x */
7024
 
7025
		      yint++;
7026
		      y = yint;
7027
		  } /* while y */
7028
 
7029
		  zint++;
7030
		  z = zint;
7031
	       } /* while z */
7032
 
7033
	       temp = (j + (i * widthOut) +
7034
		       (d*widthOut*heightOut)) * components;
7035
	       for (k = 0; k < components; k++) {
7036
		   /* totals[] should be rounded in the case of enlarging an
7037
		    * RGB ramp when the type is 332 or 4444
7038
		    */
7039
		   assert(0 <= (temp+k) &&
7040
			  (temp+k) < (widthOut*heightOut*depthOut*components));
7041
		   dataOut[temp + k] = (totals[k]+0.5)/volume;
7042
	       }
7043
	   } /* for j */
7044
       } /* for i */
7045
    } /* for d */
7046
} /* scaleInternal3D() */
7047
 
7048
static void emptyImage3D(const PixelStorageModes *psm,
7049
			 GLint width, GLint height, GLint depth,
7050
			 GLenum format, GLenum type, GLboolean indexFormat,
7051
			 const GLushort *oldImage, void *userImage)
7052
{
7053
   int myswapBytes;
7054
   int components;
7055
   int groupsPerLine;
7056
   int elementSize;
7057
   int groupSize;
7058
   int rowSize;
7059
   int padding;
7060
   GLubyte *start, *rowStart, *iter;
7061
   int elementsPerLine;
7062
   const GLushort *iter2;
7063
   int ii, jj, dd, k;
7064
   int rowsPerImage;
7065
   int imageSize;
7066
 
7067
   myswapBytes= psm->pack_swap_bytes;
7068
   components = elements_per_group(format,type);
7069
   if (psm->pack_row_length > 0) {
7070
      groupsPerLine = psm->pack_row_length;
7071
   }
7072
   else {
7073
      groupsPerLine = width;
7074
   }
7075
 
7076
   elementSize= bytes_per_element(type);
7077
   groupSize= elementSize * components;
7078
   if (elementSize == 1) myswapBytes= 0;
7079
 
7080
   /* 3dstuff begin */
7081
   if (psm->pack_image_height > 0) {
7082
      rowsPerImage= psm->pack_image_height;
7083
   }
7084
   else {
7085
      rowsPerImage= height;
7086
   }
7087
 
7088
   /* 3dstuff end */
7089
 
7090
   rowSize = groupsPerLine * groupSize;
7091
   padding = rowSize % psm->pack_alignment;
7092
   if (padding) {
7093
      rowSize+= psm->pack_alignment - padding;
7094
   }
7095
 
7096
   imageSize= rowsPerImage * rowSize; /* 3dstuff */
7097
 
7098
   start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
7099
				  psm->pack_skip_pixels * groupSize +
7100
				  /*3dstuff*/
7101
				  psm->pack_skip_images * imageSize;
7102
   elementsPerLine= width * components;
7103
 
7104
   iter2 = oldImage;
7105
   for (dd= 0; dd < depth; dd++) {
7106
      rowStart= start;
7107
 
7108
      for (ii= 0; ii< height; ii++) {
7109
	 iter = rowStart;
7110
 
7111
	 for (jj = 0; jj < elementsPerLine; jj++) {
7112
	    Type_Widget widget;
7113
	    float shoveComponents[4];
7114
 
7115
	    switch(type){
7116
	    case GL_UNSIGNED_BYTE:
7117
	      if (indexFormat) {
7118
		  *iter = *iter2++;
7119
	      } else {
7120
		  *iter = *iter2++ >> 8;
7121
	      }
7122
	      break;
7123
	    case GL_BYTE:
7124
	      if (indexFormat) {
7125
		  *((GLbyte *) iter) = *iter2++;
7126
	      } else {
7127
		  *((GLbyte *) iter) = *iter2++ >> 9;
7128
	      }
7129
	      break;
7130
	    case GL_UNSIGNED_BYTE_3_3_2:
7131
	      for (k = 0; k < 3; k++) {
7132
		 shoveComponents[k]= *iter2++ / 65535.0;
7133
	      }
7134
	      shove332(shoveComponents,0,(void *)iter);
7135
	      break;
7136
	    case GL_UNSIGNED_BYTE_2_3_3_REV:
7137
	      for (k = 0; k < 3; k++) {
7138
		 shoveComponents[k]= *iter2++ / 65535.0;
7139
	      }
7140
	      shove233rev(shoveComponents,0,(void *)iter);
7141
	      break;
7142
	    case GL_UNSIGNED_SHORT_5_6_5:
7143
	      for (k = 0; k < 3; k++) {
7144
		 shoveComponents[k]= *iter2++ / 65535.0;
7145
	      }
7146
	      shove565(shoveComponents,0,(void *)&widget.us[0]);
7147
	      if (myswapBytes) {
7148
		 iter[0] = widget.ub[1];
7149
		 iter[1] = widget.ub[0];
7150
	      }
7151
	      else {
7152
		 *(GLushort *)iter = widget.us[0];
7153
	      }
7154
	      break;
7155
	    case GL_UNSIGNED_SHORT_5_6_5_REV:
7156
	      for (k = 0; k < 3; k++) {
7157
		 shoveComponents[k]= *iter2++ / 65535.0;
7158
	      }
7159
	      shove565rev(shoveComponents,0,(void *)&widget.us[0]);
7160
	      if (myswapBytes) {
7161
		 iter[0] = widget.ub[1];
7162
		 iter[1] = widget.ub[0];
7163
	      }
7164
	      else {
7165
		 *(GLushort *)iter = widget.us[0];
7166
	      }
7167
	      break;
7168
	    case GL_UNSIGNED_SHORT_4_4_4_4:
7169
	      for (k = 0; k < 4; k++) {
7170
		 shoveComponents[k]= *iter2++ / 65535.0;
7171
	      }
7172
	      shove4444(shoveComponents,0,(void *)&widget.us[0]);
7173
	      if (myswapBytes) {
7174
		 iter[0] = widget.ub[1];
7175
		 iter[1] = widget.ub[0];
7176
	      } else {
7177
		 *(GLushort *)iter = widget.us[0];
7178
	      }
7179
	      break;
7180
	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7181
	      for (k = 0; k < 4; k++) {
7182
		 shoveComponents[k]= *iter2++ / 65535.0;
7183
	      }
7184
	      shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
7185
	      if (myswapBytes) {
7186
		 iter[0] = widget.ub[1];
7187
		 iter[1] = widget.ub[0];
7188
	      } else {
7189
		 *(GLushort *)iter = widget.us[0];
7190
	      }
7191
	      break;
7192
	    case GL_UNSIGNED_SHORT_5_5_5_1:
7193
	      for (k = 0; k < 4; k++) {
7194
		 shoveComponents[k]= *iter2++ / 65535.0;
7195
	      }
7196
	      shove5551(shoveComponents,0,(void *)&widget.us[0]);
7197
	      if (myswapBytes) {
7198
		 iter[0] = widget.ub[1];
7199
		 iter[1] = widget.ub[0];
7200
	      } else {
7201
		 *(GLushort *)iter = widget.us[0];
7202
	      }
7203
	      break;
7204
	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7205
	      for (k = 0; k < 4; k++) {
7206
		 shoveComponents[k]= *iter2++ / 65535.0;
7207
	      }
7208
	      shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
7209
	      if (myswapBytes) {
7210
		 iter[0] = widget.ub[1];
7211
		 iter[1] = widget.ub[0];
7212
	      } else {
7213
		 *(GLushort *)iter = widget.us[0];
7214
	      }
7215
	      break;
7216
	    case GL_UNSIGNED_SHORT:
7217
	    case GL_SHORT:
7218
	      if (type == GL_SHORT) {
7219
		  if (indexFormat) {
7220
		      widget.s[0] = *iter2++;
7221
		  } else {
7222
		      widget.s[0] = *iter2++ >> 1;
7223
		  }
7224
	      } else {
7225
		  widget.us[0] = *iter2++;
7226
	      }
7227
	      if (myswapBytes) {
7228
		  iter[0] = widget.ub[1];
7229
		  iter[1] = widget.ub[0];
7230
	      } else {
7231
		  iter[0] = widget.ub[0];
7232
		  iter[1] = widget.ub[1];
7233
	      }
7234
	      break;
7235
	    case GL_UNSIGNED_INT_8_8_8_8:
7236
	       for (k = 0; k < 4; k++) {
7237
		  shoveComponents[k]= *iter2++ / 65535.0;
7238
	       }
7239
	       shove8888(shoveComponents,0,(void *)&widget.ui);
7240
	       if (myswapBytes) {
7241
		   iter[3] = widget.ub[0];
7242
		   iter[2] = widget.ub[1];
7243
		   iter[1] = widget.ub[2];
7244
		   iter[0] = widget.ub[3];
7245
	       } else {
7246
		   *(GLuint *)iter= widget.ui;
7247
	       }
7248
	       break;
7249
	    case GL_UNSIGNED_INT_8_8_8_8_REV:
7250
	       for (k = 0; k < 4; k++) {
7251
		  shoveComponents[k]= *iter2++ / 65535.0;
7252
	       }
7253
	       shove8888rev(shoveComponents,0,(void *)&widget.ui);
7254
	       if (myswapBytes) {
7255
		   iter[3] = widget.ub[0];
7256
		   iter[2] = widget.ub[1];
7257
		   iter[1] = widget.ub[2];
7258
		   iter[0] = widget.ub[3];
7259
	       } else {
7260
		   *(GLuint *)iter= widget.ui;
7261
	       }
7262
	       break;
7263
	    case GL_UNSIGNED_INT_10_10_10_2:
7264
	       for (k = 0; k < 4; k++) {
7265
		  shoveComponents[k]= *iter2++ / 65535.0;
7266
	       }
7267
	       shove1010102(shoveComponents,0,(void *)&widget.ui);
7268
	       if (myswapBytes) {
7269
		   iter[3] = widget.ub[0];
7270
		   iter[2] = widget.ub[1];
7271
		   iter[1] = widget.ub[2];
7272
		   iter[0] = widget.ub[3];
7273
	       } else {
7274
		   *(GLuint *)iter= widget.ui;
7275
	       }
7276
	       break;
7277
	    case GL_UNSIGNED_INT_2_10_10_10_REV:
7278
	       for (k = 0; k < 4; k++) {
7279
		  shoveComponents[k]= *iter2++ / 65535.0;
7280
	       }
7281
	       shove2101010rev(shoveComponents,0,(void *)&widget.ui);
7282
	       if (myswapBytes) {
7283
		   iter[3] = widget.ub[0];
7284
		   iter[2] = widget.ub[1];
7285
		   iter[1] = widget.ub[2];
7286
		   iter[0] = widget.ub[3];
7287
	       } else {
7288
		   *(GLuint *)iter= widget.ui;
7289
	       }
7290
	       break;
7291
	    case GL_INT:
7292
	    case GL_UNSIGNED_INT:
7293
	    case GL_FLOAT:
7294
	      if (type == GL_FLOAT) {
7295
		  if (indexFormat) {
7296
		      widget.f = *iter2++;
7297
		  } else {
7298
		      widget.f = *iter2++ / (float) 65535.0;
7299
		  }
7300
	      } else if (type == GL_UNSIGNED_INT) {
7301
		  if (indexFormat) {
7302
		      widget.ui = *iter2++;
7303
		  } else {
7304
		      widget.ui = (unsigned int) *iter2++ * 65537;
7305
		  }
7306
	      } else {
7307
		  if (indexFormat) {
7308
		      widget.i = *iter2++;
7309
		  } else {
7310
		      widget.i = ((unsigned int) *iter2++ * 65537)/2;
7311
		  }
7312
	      }
7313
	      if (myswapBytes) {
7314
		  iter[3] = widget.ub[0];
7315
		  iter[2] = widget.ub[1];
7316
		  iter[1] = widget.ub[2];
7317
		  iter[0] = widget.ub[3];
7318
	      } else {
7319
		  iter[0] = widget.ub[0];
7320
		  iter[1] = widget.ub[1];
7321
		  iter[2] = widget.ub[2];
7322
		  iter[3] = widget.ub[3];
7323
	      }
7324
	      break;
7325
	    default:
7326
	       assert(0);
7327
	    }
7328
 
7329
	    iter+= elementSize;
7330
	 }  /* for jj */
7331
 
7332
	 rowStart+= rowSize;
7333
      } /* for ii */
7334
 
7335
      start+= imageSize;
7336
   } /* for dd */
7337
 
7338
   /* iterators should be one byte past end */
7339
   if (!isTypePackedPixel(type)) {
7340
      assert(iter2 == &oldImage[width*height*depth*components]);
7341
   }
7342
   else {
7343
      assert(iter2 == &oldImage[width*height*depth*
7344
				elements_per_group(format,0)]);
7345
   }
7346
   assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
7347
					psm->unpack_skip_rows * rowSize +
7348
					psm->unpack_skip_pixels * groupSize +
7349
					/*3dstuff*/
7350
					psm->unpack_skip_images * imageSize] );
7351
} /* emptyImage3D() */
7352
 
7353
static
7354
int gluScaleImage3D(GLenum format,
7355
		    GLint widthIn, GLint heightIn, GLint depthIn,
7356
		    GLenum typeIn, const void *dataIn,
7357
		    GLint widthOut, GLint heightOut, GLint depthOut,
7358
		    GLenum typeOut, void *dataOut)
7359
{
7360
   int components;
7361
   GLushort *beforeImage, *afterImage;
7362
   PixelStorageModes psm;
7363
 
7364
   if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
7365
       widthOut == 0 || heightOut == 0 || depthOut == 0) {
7366
      return 0;
7367
   }
7368
 
7369
   if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
7370
       widthOut < 0 || heightOut < 0 || depthOut < 0) {
7371
      return GLU_INVALID_VALUE;
7372
   }
7373
 
7374
   if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
7375
       typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
7376
      return GLU_INVALID_ENUM;
7377
   }
7378
   if (!isLegalFormatForPackedPixelType(format, typeIn)) {
7379
      return GLU_INVALID_OPERATION;
7380
   }
7381
   if (!isLegalFormatForPackedPixelType(format, typeOut)) {
7382
      return GLU_INVALID_OPERATION;
7383
   }
7384
 
7385
   beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
7386
				    GL_UNSIGNED_SHORT));
7387
   afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
7388
				   GL_UNSIGNED_SHORT));
7389
   if (beforeImage == NULL || afterImage == NULL) {
7390
       free(beforeImage);
7391
       free(afterImage);
7392
       return GLU_OUT_OF_MEMORY;
7393
   }
7394
   retrieveStoreModes3D(&psm);
7395
 
7396
   fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
7397
	       dataIn, beforeImage);
7398
   components = elements_per_group(format,0);
7399
   scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
7400
		   widthOut,heightOut,depthOut,afterImage);
7401
   emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
7402
		is_index(format),afterImage, dataOut);
7403
   free((void *) beforeImage);
7404
   free((void *) afterImage);
7405
 
7406
   return 0;
7407
} /* gluScaleImage3D() */
7408
 
7409
 
7410
static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
7411
			 GLint internalFormat, GLenum format, GLenum type,
7412
			 GLint *newWidth, GLint *newHeight, GLint *newDepth)
7413
{
7414
   GLint widthPowerOf2= nearestPower(width);
7415
   GLint heightPowerOf2= nearestPower(height);
7416
   GLint depthPowerOf2= nearestPower(depth);
7417
   GLint proxyWidth;
7418
 
7419
   do {
7420
      /* compute level 1 width & height & depth, clamping each at 1 */
7421
      GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
7422
			      widthPowerOf2 >> 1 :
7423
			      widthPowerOf2;
7424
      GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
7425
			       heightPowerOf2 >> 1 :
7426
			       heightPowerOf2;
7427
      GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
7428
			      depthPowerOf2 >> 1 :
7429
			      depthPowerOf2;
7430
      GLenum proxyTarget = GL_PROXY_TEXTURE_3D;
7431
      assert(widthAtLevelOne > 0);
7432
      assert(heightAtLevelOne > 0);
7433
      assert(depthAtLevelOne > 0);
7434
 
7435
      /* does width x height x depth at level 1 & all their mipmaps fit? */
7436
      assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D);
7437
      gluTexImage3D(proxyTarget, 1, /* must be non-zero */
7438
                    internalFormat,
7439
                    widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
7440
                    0,format,type,NULL);
7441
      glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
7442
      /* does it fit??? */
7443
      if (proxyWidth == 0) { /* nope, so try again with these sizes */
7444
	 if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
7445
	     depthPowerOf2 == 1) {
7446
	    *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
7447
	    return;
7448
	 }
7449
	 widthPowerOf2= widthAtLevelOne;
7450
	 heightPowerOf2= heightAtLevelOne;
7451
	 depthPowerOf2= depthAtLevelOne;
7452
      }
7453
      /* else it does fit */
7454
   } while (proxyWidth == 0);
7455
   /* loop must terminate! */
7456
 
7457
   /* return the width & height at level 0 that fits */
7458
   *newWidth= widthPowerOf2;
7459
   *newHeight= heightPowerOf2;
7460
   *newDepth= depthPowerOf2;
7461
/*printf("Proxy Textures\n");*/
7462
} /* closestFit3D() */
7463
 
7464
static void halveImagePackedPixelSlice(int components,
7465
				       void (*extractPackedPixel)
7466
				       (int, const void *,GLfloat []),
7467
				       void (*shovePackedPixel)
7468
				       (const GLfloat [],int, void *),
7469
				       GLint width, GLint height, GLint depth,
7470
				       const void *dataIn, void *dataOut,
7471
				       GLint pixelSizeInBytes,
7472
				       GLint rowSizeInBytes,
7473
				       GLint imageSizeInBytes,
7474
				       GLint isSwap)
7475
{
7476
   int ii, jj;
7477
   int halfWidth= width / 2;
7478
   int halfHeight= height / 2;
7479
   int halfDepth= depth / 2;
7480
   const char *src= (const char *)dataIn;
7481
   int outIndex= 0;
7482
 
7483
   assert((width == 1 || height == 1) && depth >= 2);
7484
 
7485
   if (width == height) {	/* a 1-pixel column viewed from top */
7486
      assert(width == 1 && height == 1);
7487
      assert(depth >= 2);
7488
 
7489
      for (ii= 0; ii< halfDepth; ii++) {
7490
	 float totals[4];
7491
	 float extractTotals[BOX2][4];
7492
	 int cc;
7493
 
7494
	 (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
7495
	 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7496
			       &extractTotals[1][0]);
7497
	 for (cc = 0; cc < components; cc++) {
7498
	    int kk;
7499
 
7500
	    /* average 2 pixels since only a column */
7501
	    totals[cc]= 0.0;
7502
	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7503
	     * totals[RED]/= 2.0;
7504
	     */
7505
	    for (kk = 0; kk < BOX2; kk++) {
7506
	      totals[cc]+= extractTotals[kk][cc];
7507
	    }
7508
	    totals[cc]/= (float)BOX2;
7509
	 } /* for cc */
7510
 
7511
	 (*shovePackedPixel)(totals,outIndex,dataOut);
7512
	 outIndex++;
7513
	 /* skip over to next group of 2 */
7514
	 src+= imageSizeInBytes + imageSizeInBytes;
7515
      } /* for ii */
7516
   }
7517
   else if (height == 1) {	/* horizontal slice viewed from top */
7518
      assert(width != 1);
7519
 
7520
      for (ii= 0; ii< halfDepth; ii++) {
7521
	 for (jj= 0; jj< halfWidth; jj++) {
7522
	     float totals[4];
7523
	     float extractTotals[BOX4][4];
7524
	     int cc;
7525
 
7526
	     (*extractPackedPixel)(isSwap,src,
7527
				   &extractTotals[0][0]);
7528
	     (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7529
				   &extractTotals[1][0]);
7530
	     (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7531
				   &extractTotals[2][0]);
7532
	     (*extractPackedPixel)(isSwap,
7533
				   (src+imageSizeInBytes+pixelSizeInBytes),
7534
				   &extractTotals[3][0]);
7535
	     for (cc = 0; cc < components; cc++) {
7536
		int kk;
7537
 
7538
		/* grab 4 pixels to average */
7539
		totals[cc]= 0.0;
7540
		/* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7541
		 *		extractTotals[2][RED]+extractTotals[3][RED];
7542
		 * totals[RED]/= 4.0;
7543
		 */
7544
		for (kk = 0; kk < BOX4; kk++) {
7545
		   totals[cc]+= extractTotals[kk][cc];
7546
		}
7547
		totals[cc]/= (float)BOX4;
7548
	     }
7549
	     (*shovePackedPixel)(totals,outIndex,dataOut);
7550
 
7551
	     outIndex++;
7552
	     /* skip over to next horizontal square of 4 */
7553
	     src+= imageSizeInBytes + imageSizeInBytes;
7554
	 }
7555
      }
7556
 
7557
      /* assert() */
7558
   }
7559
   else if (width == 1) {	/* vertical slice viewed from top */
7560
      assert(height != 1);
7561
 
7562
      for (ii= 0; ii< halfDepth; ii++) {
7563
	 for (jj= 0; jj< halfHeight; jj++) {
7564
	    float totals[4];
7565
	    float extractTotals[BOX4][4];
7566
	    int cc;
7567
 
7568
	    (*extractPackedPixel)(isSwap,src,
7569
				  &extractTotals[0][0]);
7570
	    (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7571
				  &extractTotals[1][0]);
7572
	    (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7573
				  &extractTotals[2][0]);
7574
	    (*extractPackedPixel)(isSwap,
7575
				  (src+imageSizeInBytes+rowSizeInBytes),
7576
				  &extractTotals[3][0]);
7577
	    for (cc = 0; cc < components; cc++) {
7578
	       int kk;
7579
 
7580
	       /* grab 4 pixels to average */
7581
	       totals[cc]= 0.0;
7582
	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7583
		*	       extractTotals[2][RED]+extractTotals[3][RED];
7584
		* totals[RED]/= 4.0;
7585
		*/
7586
	       for (kk = 0; kk < BOX4; kk++) {
7587
		  totals[cc]+= extractTotals[kk][cc];
7588
	       }
7589
	       totals[cc]/= (float)BOX4;
7590
	    }
7591
	    (*shovePackedPixel)(totals,outIndex,dataOut);
7592
 
7593
	    outIndex++;
7594
 
7595
	    /* skip over to next vertical square of 4 */
7596
	    src+= imageSizeInBytes + imageSizeInBytes;
7597
	 }
7598
      }
7599
      /* assert() */
7600
   }
7601
 
7602
} /* halveImagePackedPixelSlice() */
7603
 
7604
static void halveImagePackedPixel3D(int components,
7605
				    void (*extractPackedPixel)
7606
				    (int, const void *,GLfloat []),
7607
				    void (*shovePackedPixel)
7608
				    (const GLfloat [],int, void *),
7609
				    GLint width, GLint height, GLint depth,
7610
				    const void *dataIn, void *dataOut,
7611
				    GLint pixelSizeInBytes,
7612
				    GLint rowSizeInBytes,
7613
				    GLint imageSizeInBytes,
7614
				    GLint isSwap)
7615
{
7616
   if (depth == 1) {
7617
      assert(1 <= width && 1 <= height);
7618
 
7619
      halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
7620
			    width,height,dataIn,dataOut,pixelSizeInBytes,
7621
			    rowSizeInBytes,isSwap);
7622
      return;
7623
   }
7624
   /* a horizontal or vertical slice viewed from top */
7625
   else if (width == 1 || height == 1) {
7626
      assert(1 <= depth);
7627
 
7628
      halveImagePackedPixelSlice(components,
7629
				 extractPackedPixel,shovePackedPixel,
7630
				 width, height, depth, dataIn, dataOut,
7631
				 pixelSizeInBytes, rowSizeInBytes,
7632
				 imageSizeInBytes, isSwap);
7633
      return;
7634
   }
7635
   {
7636
      int ii, jj, dd;
7637
 
7638
      int halfWidth= width / 2;
7639
      int halfHeight= height / 2;
7640
      int halfDepth= depth / 2;
7641
      const char *src= (const char *) dataIn;
7642
      int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
7643
      int outIndex= 0;
7644
 
7645
      for (dd= 0; dd < halfDepth; dd++) {
7646
	 for (ii= 0; ii< halfHeight; ii++) {
7647
	    for (jj= 0; jj< halfWidth; jj++) {
7648
#define BOX8 8
7649
	       float totals[4]; /* 4 is maximum components */
7650
	       float extractTotals[BOX8][4]; /* 4 is maximum components */
7651
	       int cc;
7652
 
7653
	       (*extractPackedPixel)(isSwap,src,
7654
				     &extractTotals[0][0]);
7655
	       (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7656
				     &extractTotals[1][0]);
7657
	       (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7658
				     &extractTotals[2][0]);
7659
	       (*extractPackedPixel)(isSwap,
7660
				     (src+rowSizeInBytes+pixelSizeInBytes),
7661
				     &extractTotals[3][0]);
7662
 
7663
	       (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7664
				     &extractTotals[4][0]);
7665
	       (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
7666
				     &extractTotals[5][0]);
7667
	       (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
7668
				     &extractTotals[6][0]);
7669
	       (*extractPackedPixel)(isSwap,
7670
				     (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
7671
				     &extractTotals[7][0]);
7672
	       for (cc = 0; cc < components; cc++) {
7673
		  int kk;
7674
 
7675
		  /* grab 8 pixels to average */
7676
		  totals[cc]= 0.0;
7677
		  /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7678
		   *		  extractTotals[2][RED]+extractTotals[3][RED]+
7679
		   *		  extractTotals[4][RED]+extractTotals[5][RED]+
7680
		   *		  extractTotals[6][RED]+extractTotals[7][RED];
7681
		   * totals[RED]/= 8.0;
7682
		   */
7683
		  for (kk = 0; kk < BOX8; kk++) {
7684
		     totals[cc]+= extractTotals[kk][cc];
7685
		  }
7686
		  totals[cc]/= (float)BOX8;
7687
	       }
7688
	       (*shovePackedPixel)(totals,outIndex,dataOut);
7689
 
7690
	       outIndex++;
7691
	       /* skip over to next square of 4 */
7692
	       src+= pixelSizeInBytes + pixelSizeInBytes;
7693
	    }
7694
	    /* skip past pad bytes, if any, to get to next row */
7695
	    src+= padBytes;
7696
 
7697
	    /* src is at beginning of a row here, but it's the second row of
7698
	     * the square block of 4 pixels that we just worked on so we
7699
	     * need to go one more row.
7700
	     * i.e.,
7701
	     *			 OO...
7702
	     *		 here -->OO...
7703
	     *	     but want -->OO...
7704
	     *			 OO...
7705
	     *			 ...
7706
	     */
7707
	    src+= rowSizeInBytes;
7708
	 }
7709
 
7710
	 src+= imageSizeInBytes;
7711
      } /* for dd */
7712
 
7713
      /* both pointers must reach one byte after the end */
7714
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
7715
      assert(outIndex == halfWidth * halfHeight * halfDepth);
7716
   } /* for dd */
7717
 
7718
} /* halveImagePackedPixel3D() */
7719
 
7720
static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
7721
				      GLsizei width,
7722
				      GLsizei height,
7723
				      GLsizei depth,
7724
				      GLsizei widthPowerOf2,
7725
				      GLsizei heightPowerOf2,
7726
				      GLsizei depthPowerOf2,
7727
				      GLenum format, GLenum type,
7728
				      GLint userLevel,
7729
				      GLint baseLevel,GLint maxLevel,
7730
				      const void *data)
7731
{
7732
   GLint newWidth, newHeight, newDepth;
7733
   GLint level, levels;
7734
   const void *usersImage;
7735
   void *srcImage, *dstImage;
7736
   __GLU_INIT_SWAP_IMAGE;
7737
   GLint memReq;
7738
   GLint cmpts;
7739
 
7740
   GLint myswapBytes, groupsPerLine, elementSize, groupSize;
7741
   GLint rowsPerImage, imageSize;
7742
   GLint rowSize, padding;
7743
   PixelStorageModes psm;
7744
 
7745
   assert(checkMipmapArgs(internalFormat,format,type) == 0);
7746
   assert(width >= 1 && height >= 1 && depth >= 1);
7747
   assert(type != GL_BITMAP);
7748
 
7749
   srcImage = dstImage = NULL;
7750
 
7751
   newWidth= widthPowerOf2;
7752
   newHeight= heightPowerOf2;
7753
   newDepth= depthPowerOf2;
7754
   levels = computeLog(newWidth);
7755
   level = computeLog(newHeight);
7756
   if (level > levels) levels=level;
7757
   level = computeLog(newDepth);
7758
   if (level > levels) levels=level;
7759
 
7760
   levels+= userLevel;
7761
 
7762
   retrieveStoreModes3D(&psm);
7763
   myswapBytes = psm.unpack_swap_bytes;
7764
   cmpts = elements_per_group(format,type);
7765
   if (psm.unpack_row_length > 0) {
7766
       groupsPerLine = psm.unpack_row_length;
7767
   } else {
7768
       groupsPerLine = width;
7769
   }
7770
 
7771
   elementSize = bytes_per_element(type);
7772
   groupSize = elementSize * cmpts;
7773
   if (elementSize == 1) myswapBytes = 0;
7774
 
7775
   /* 3dstuff begin */
7776
   if (psm.unpack_image_height > 0) {
7777
      rowsPerImage= psm.unpack_image_height;
7778
   }
7779
   else {
7780
      rowsPerImage= height;
7781
   }
7782
 
7783
   /* 3dstuff end */
7784
   rowSize = groupsPerLine * groupSize;
7785
   padding = (rowSize % psm.unpack_alignment);
7786
   if (padding) {
7787
       rowSize += psm.unpack_alignment - padding;
7788
   }
7789
 
7790
   imageSize= rowsPerImage * rowSize; /* 3dstuff */
7791
 
7792
   usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
7793
				  psm.unpack_skip_pixels * groupSize +
7794
				  /* 3dstuff */
7795
				  psm.unpack_skip_images * imageSize;
7796
 
7797
   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
7798
   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
7799
   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
7800
   glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
7801
   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
7802
 
7803
   level = userLevel;
7804
 
7805
   if (width == newWidth && height == newHeight && depth == newDepth) {
7806
       /* Use usersImage for level userLevel */
7807
       if (baseLevel <= level && level <= maxLevel) {
7808
	  gluTexImage3D(target, level, internalFormat, width,
7809
		       height, depth, 0, format, type,
7810
		       usersImage);
7811
       }
7812
       if(levels == 0) { /* we're done. clean up and return */
7813
	 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7814
	 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7815
	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7816
	 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7817
	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7818
	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7819
	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7820
	 return 0;
7821
       }
7822
       {
7823
	  int nextWidth= newWidth/2;
7824
	  int nextHeight= newHeight/2;
7825
	  int nextDepth= newDepth/2;
7826
 
7827
	  /* clamp to 1 */
7828
	  if (nextWidth < 1) nextWidth= 1;
7829
	  if (nextHeight < 1) nextHeight= 1;
7830
	  if (nextDepth < 1) nextDepth= 1;
7831
       memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
7832
       }
7833
       switch(type) {
7834
       case GL_UNSIGNED_BYTE:
7835
	 dstImage = (GLubyte *)malloc(memReq);
7836
	 break;
7837
       case GL_BYTE:
7838
	 dstImage = (GLbyte *)malloc(memReq);
7839
	 break;
7840
       case GL_UNSIGNED_SHORT:
7841
	 dstImage = (GLushort *)malloc(memReq);
7842
	 break;
7843
       case GL_SHORT:
7844
	 dstImage = (GLshort *)malloc(memReq);
7845
	 break;
7846
       case GL_UNSIGNED_INT:
7847
	 dstImage = (GLuint *)malloc(memReq);
7848
	 break;
7849
       case GL_INT:
7850
	 dstImage = (GLint *)malloc(memReq);
7851
	 break;
7852
       case GL_FLOAT:
7853
	 dstImage = (GLfloat *)malloc(memReq);
7854
	 break;
7855
       case GL_UNSIGNED_BYTE_3_3_2:
7856
       case GL_UNSIGNED_BYTE_2_3_3_REV:
7857
	 dstImage = (GLubyte *)malloc(memReq);
7858
	 break;
7859
       case GL_UNSIGNED_SHORT_5_6_5:
7860
       case GL_UNSIGNED_SHORT_5_6_5_REV:
7861
       case GL_UNSIGNED_SHORT_4_4_4_4:
7862
       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7863
       case GL_UNSIGNED_SHORT_5_5_5_1:
7864
       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7865
	 dstImage = (GLushort *)malloc(memReq);
7866
	 break;
7867
       case GL_UNSIGNED_INT_8_8_8_8:
7868
       case GL_UNSIGNED_INT_8_8_8_8_REV:
7869
       case GL_UNSIGNED_INT_10_10_10_2:
7870
       case GL_UNSIGNED_INT_2_10_10_10_REV:
7871
	 dstImage = (GLuint *)malloc(memReq);
7872
	 break;
7873
       default:
7874
	 return GLU_INVALID_ENUM; /* assertion */
7875
       }
7876
       if (dstImage == NULL) {
7877
	 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7878
	 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7879
	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7880
	 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7881
	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7882
	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7883
	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7884
	 return GLU_OUT_OF_MEMORY;
7885
       }
7886
       else
7887
	 switch(type) {
7888
	 case GL_UNSIGNED_BYTE:
7889
	   if (depth > 1) {
7890
	     halveImage3D(cmpts,extractUbyte,shoveUbyte,
7891
			  width,height,depth,
7892
			  usersImage,dstImage,elementSize,groupSize,rowSize,
7893
			  imageSize,myswapBytes);
7894
	   }
7895
	   else {
7896
	     halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
7897
			      elementSize,rowSize,groupSize);
7898
	   }
7899
	   break;
7900
	 case GL_BYTE:
7901
	   if (depth > 1) {
7902
	   halveImage3D(cmpts,extractSbyte,shoveSbyte,
7903
			width,height,depth,
7904
			usersImage,dstImage,elementSize,groupSize,rowSize,
7905
			imageSize,myswapBytes);
7906
	   }
7907
	   else {
7908
	     halveImage_byte(cmpts,width,height,usersImage,dstImage,
7909
			     elementSize,rowSize,groupSize);
7910
	   }
7911
	   break;
7912
	 case GL_UNSIGNED_SHORT:
7913
	   if (depth > 1) {
7914
	   halveImage3D(cmpts,extractUshort,shoveUshort,
7915
			width,height,depth,
7916
			usersImage,dstImage,elementSize,groupSize,rowSize,
7917
			imageSize,myswapBytes);
7918
	   }
7919
	   else {
7920
	     halveImage_ushort(cmpts,width,height,usersImage,dstImage,
7921
			       elementSize,rowSize,groupSize,myswapBytes);
7922
	   }
7923
	   break;
7924
	 case GL_SHORT:
7925
	   if (depth > 1) {
7926
	   halveImage3D(cmpts,extractSshort,shoveSshort,
7927
			width,height,depth,
7928
			usersImage,dstImage,elementSize,groupSize,rowSize,
7929
			imageSize,myswapBytes);
7930
	   }
7931
	   else {
7932
	     halveImage_short(cmpts,width,height,usersImage,dstImage,
7933
			      elementSize,rowSize,groupSize,myswapBytes);
7934
	   }
7935
	   break;
7936
	 case GL_UNSIGNED_INT:
7937
	   if (depth > 1) {
7938
	   halveImage3D(cmpts,extractUint,shoveUint,
7939
			width,height,depth,
7940
			usersImage,dstImage,elementSize,groupSize,rowSize,
7941
			imageSize,myswapBytes);
7942
	   }
7943
	   else {
7944
	     halveImage_uint(cmpts,width,height,usersImage,dstImage,
7945
			     elementSize,rowSize,groupSize,myswapBytes);
7946
	   }
7947
	   break;
7948
	 case GL_INT:
7949
	   if (depth > 1) {
7950
	   halveImage3D(cmpts,extractSint,shoveSint,
7951
			width,height,depth,
7952
			usersImage,dstImage,elementSize,groupSize,rowSize,
7953
			imageSize,myswapBytes);
7954
	   }
7955
	   else {
7956
	     halveImage_int(cmpts,width,height,usersImage,dstImage,
7957
			    elementSize,rowSize,groupSize,myswapBytes);
7958
	   }
7959
	   break;
7960
	 case GL_FLOAT:
7961
	   if (depth > 1 ) {
7962
	   halveImage3D(cmpts,extractFloat,shoveFloat,
7963
			width,height,depth,
7964
			usersImage,dstImage,elementSize,groupSize,rowSize,
7965
			imageSize,myswapBytes);
7966
	   }
7967
	   else {
7968
	     halveImage_float(cmpts,width,height,usersImage,dstImage,
7969
			      elementSize,rowSize,groupSize,myswapBytes);
7970
	   }
7971
	   break;
7972
	 case GL_UNSIGNED_BYTE_3_3_2:
7973
	   assert(format == GL_RGB);
7974
	   halveImagePackedPixel3D(3,extract332,shove332,
7975
				   width,height,depth,usersImage,dstImage,
7976
				   elementSize,rowSize,imageSize,myswapBytes);
7977
	   break;
7978
	 case GL_UNSIGNED_BYTE_2_3_3_REV:
7979
	   assert(format == GL_RGB);
7980
	   halveImagePackedPixel3D(3,extract233rev,shove233rev,
7981
				   width,height,depth,usersImage,dstImage,
7982
				   elementSize,rowSize,imageSize,myswapBytes);
7983
	   break;
7984
	 case GL_UNSIGNED_SHORT_5_6_5:
7985
	   halveImagePackedPixel3D(3,extract565,shove565,
7986
				   width,height,depth,usersImage,dstImage,
7987
				   elementSize,rowSize,imageSize,myswapBytes);
7988
	   break;
7989
	 case GL_UNSIGNED_SHORT_5_6_5_REV:
7990
	   halveImagePackedPixel3D(3,extract565rev,shove565rev,
7991
				   width,height,depth,usersImage,dstImage,
7992
				   elementSize,rowSize,imageSize,myswapBytes);
7993
	   break;
7994
	 case GL_UNSIGNED_SHORT_4_4_4_4:
7995
	   halveImagePackedPixel3D(4,extract4444,shove4444,
7996
				   width,height,depth,usersImage,dstImage,
7997
				   elementSize,rowSize,imageSize,myswapBytes);
7998
	   break;
7999
	 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8000
	   halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8001
				   width,height,depth,usersImage,dstImage,
8002
				   elementSize,rowSize,imageSize,myswapBytes);
8003
	   break;
8004
	 case GL_UNSIGNED_SHORT_5_5_5_1:
8005
	   halveImagePackedPixel3D(4,extract5551,shove5551,
8006
				   width,height,depth,usersImage,dstImage,
8007
				   elementSize,rowSize,imageSize,myswapBytes);
8008
	   break;
8009
	 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8010
	   halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8011
				   width,height,depth,usersImage,dstImage,
8012
				   elementSize,rowSize,imageSize,myswapBytes);
8013
	   break;
8014
	 case GL_UNSIGNED_INT_8_8_8_8:
8015
	   halveImagePackedPixel3D(4,extract8888,shove8888,
8016
				   width,height,depth,usersImage,dstImage,
8017
				   elementSize,rowSize,imageSize,myswapBytes);
8018
	   break;
8019
	 case GL_UNSIGNED_INT_8_8_8_8_REV:
8020
	   halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8021
				   width,height,depth,usersImage,dstImage,
8022
				   elementSize,rowSize,imageSize,myswapBytes);
8023
	   break;
8024
	 case GL_UNSIGNED_INT_10_10_10_2:
8025
	   halveImagePackedPixel3D(4,extract1010102,shove1010102,
8026
				   width,height,depth,usersImage,dstImage,
8027
				   elementSize,rowSize,imageSize,myswapBytes);
8028
	   break;
8029
	 case GL_UNSIGNED_INT_2_10_10_10_REV:
8030
	   halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8031
				   width,height,depth,usersImage,dstImage,
8032
				   elementSize,rowSize,imageSize,myswapBytes);
8033
	   break;
8034
	 default:
8035
	   assert(0);
8036
	   break;
8037
	 }
8038
       newWidth = width/2;
8039
       newHeight = height/2;
8040
       newDepth = depth/2;
8041
       /* clamp to 1 */
8042
       if (newWidth < 1) newWidth= 1;
8043
       if (newHeight < 1) newHeight= 1;
8044
       if (newDepth < 1) newDepth= 1;
8045
 
8046
       myswapBytes = 0;
8047
       rowSize = newWidth * groupSize;
8048
       imageSize= rowSize * newHeight; /* 3dstuff */
8049
       memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8050
       /* Swap srcImage and dstImage */
8051
       __GLU_SWAP_IMAGE(srcImage,dstImage);
8052
       switch(type) {
8053
       case GL_UNSIGNED_BYTE:
8054
	 dstImage = (GLubyte *)malloc(memReq);
8055
	 break;
8056
       case GL_BYTE:
8057
	 dstImage = (GLbyte *)malloc(memReq);
8058
	 break;
8059
       case GL_UNSIGNED_SHORT:
8060
	 dstImage = (GLushort *)malloc(memReq);
8061
	 break;
8062
       case GL_SHORT:
8063
	 dstImage = (GLshort *)malloc(memReq);
8064
	 break;
8065
       case GL_UNSIGNED_INT:
8066
	 dstImage = (GLuint *)malloc(memReq);
8067
	 break;
8068
       case GL_INT:
8069
	 dstImage = (GLint *)malloc(memReq);
8070
	 break;
8071
       case GL_FLOAT:
8072
	 dstImage = (GLfloat *)malloc(memReq);
8073
	 break;
8074
       case GL_UNSIGNED_BYTE_3_3_2:
8075
       case GL_UNSIGNED_BYTE_2_3_3_REV:
8076
	 dstImage = (GLubyte *)malloc(memReq);
8077
	 break;
8078
       case GL_UNSIGNED_SHORT_5_6_5:
8079
       case GL_UNSIGNED_SHORT_5_6_5_REV:
8080
       case GL_UNSIGNED_SHORT_4_4_4_4:
8081
       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8082
       case GL_UNSIGNED_SHORT_5_5_5_1:
8083
       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8084
	 dstImage = (GLushort *)malloc(memReq);
8085
	 break;
8086
       case GL_UNSIGNED_INT_8_8_8_8:
8087
       case GL_UNSIGNED_INT_8_8_8_8_REV:
8088
       case GL_UNSIGNED_INT_10_10_10_2:
8089
       case GL_UNSIGNED_INT_2_10_10_10_REV:
8090
	 dstImage = (GLuint *)malloc(memReq);
8091
	 break;
8092
       default:
8093
	 return GLU_INVALID_ENUM; /* assertion */
8094
       }
8095
       if (dstImage == NULL) {
8096
	 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8097
	 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8098
	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8099
	 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8100
	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8101
	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8102
	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8103
	 free(srcImage);
8104
	 return GLU_OUT_OF_MEMORY;
8105
       }
8106
       /* level userLevel+1 is in srcImage; level userLevel already saved */
8107
       level = userLevel+1;
8108
   } else {/* user's image is *not* nice power-of-2 sized square */
8109
       memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8110
       switch(type) {
8111
	   case GL_UNSIGNED_BYTE:
8112
	       dstImage = (GLubyte *)malloc(memReq);
8113
	       break;
8114
	   case GL_BYTE:
8115
	       dstImage = (GLbyte *)malloc(memReq);
8116
	       break;
8117
	   case GL_UNSIGNED_SHORT:
8118
	       dstImage = (GLushort *)malloc(memReq);
8119
	       break;
8120
	   case GL_SHORT:
8121
	       dstImage = (GLshort *)malloc(memReq);
8122
	       break;
8123
	   case GL_UNSIGNED_INT:
8124
	       dstImage = (GLuint *)malloc(memReq);
8125
	       break;
8126
	   case GL_INT:
8127
	       dstImage = (GLint *)malloc(memReq);
8128
	       break;
8129
	   case GL_FLOAT:
8130
	       dstImage = (GLfloat *)malloc(memReq);
8131
	       break;
8132
	   case GL_UNSIGNED_BYTE_3_3_2:
8133
	   case GL_UNSIGNED_BYTE_2_3_3_REV:
8134
	       dstImage = (GLubyte *)malloc(memReq);
8135
	       break;
8136
	   case GL_UNSIGNED_SHORT_5_6_5:
8137
	   case GL_UNSIGNED_SHORT_5_6_5_REV:
8138
	   case GL_UNSIGNED_SHORT_4_4_4_4:
8139
	   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8140
	   case GL_UNSIGNED_SHORT_5_5_5_1:
8141
	   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8142
	       dstImage = (GLushort *)malloc(memReq);
8143
	       break;
8144
	   case GL_UNSIGNED_INT_8_8_8_8:
8145
	   case GL_UNSIGNED_INT_8_8_8_8_REV:
8146
	   case GL_UNSIGNED_INT_10_10_10_2:
8147
	   case GL_UNSIGNED_INT_2_10_10_10_REV:
8148
	       dstImage = (GLuint *)malloc(memReq);
8149
	       break;
8150
	   default:
8151
	       return GLU_INVALID_ENUM; /* assertion */
8152
       }
8153
 
8154
       if (dstImage == NULL) {
8155
	   glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8156
	   glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8157
	   glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8158
	   glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8159
	   glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8160
	   glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8161
	   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8162
	   return GLU_OUT_OF_MEMORY;
8163
       }
8164
       /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8165
       width,height,depth,newWidth,newHeight,newDepth);*/
8166
 
8167
       gluScaleImage3D(format, width, height, depth, type, usersImage,
8168
		       newWidth, newHeight, newDepth, type, dstImage);
8169
 
8170
       myswapBytes = 0;
8171
       rowSize = newWidth * groupSize;
8172
       imageSize = rowSize * newHeight; /* 3dstuff */
8173
       /* Swap dstImage and srcImage */
8174
       __GLU_SWAP_IMAGE(srcImage,dstImage);
8175
 
8176
       if(levels != 0) { /* use as little memory as possible */
8177
	 {
8178
	    int nextWidth= newWidth/2;
8179
	    int nextHeight= newHeight/2;
8180
	    int nextDepth= newDepth/2;
8181
	    if (nextWidth < 1) nextWidth= 1;
8182
	    if (nextHeight < 1) nextHeight= 1;
8183
	    if (nextDepth < 1) nextDepth= 1;
8184
 
8185
	 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
8186
	 }
8187
	 switch(type) {
8188
	 case GL_UNSIGNED_BYTE:
8189
	   dstImage = (GLubyte *)malloc(memReq);
8190
	   break;
8191
	 case GL_BYTE:
8192
	   dstImage = (GLbyte *)malloc(memReq);
8193
	   break;
8194
	 case GL_UNSIGNED_SHORT:
8195
	   dstImage = (GLushort *)malloc(memReq);
8196
	   break;
8197
	 case GL_SHORT:
8198
	   dstImage = (GLshort *)malloc(memReq);
8199
	   break;
8200
	 case GL_UNSIGNED_INT:
8201
	   dstImage = (GLuint *)malloc(memReq);
8202
	   break;
8203
	 case GL_INT:
8204
	   dstImage = (GLint *)malloc(memReq);
8205
	   break;
8206
	 case GL_FLOAT:
8207
	   dstImage = (GLfloat *)malloc(memReq);
8208
	   break;
8209
	 case GL_UNSIGNED_BYTE_3_3_2:
8210
	 case GL_UNSIGNED_BYTE_2_3_3_REV:
8211
	   dstImage = (GLubyte *)malloc(memReq);
8212
	   break;
8213
	 case GL_UNSIGNED_SHORT_5_6_5:
8214
	 case GL_UNSIGNED_SHORT_5_6_5_REV:
8215
	 case GL_UNSIGNED_SHORT_4_4_4_4:
8216
	 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8217
	 case GL_UNSIGNED_SHORT_5_5_5_1:
8218
	 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8219
	   dstImage = (GLushort *)malloc(memReq);
8220
	   break;
8221
	 case GL_UNSIGNED_INT_8_8_8_8:
8222
	 case GL_UNSIGNED_INT_8_8_8_8_REV:
8223
	 case GL_UNSIGNED_INT_10_10_10_2:
8224
	 case GL_UNSIGNED_INT_2_10_10_10_REV:
8225
	   dstImage = (GLuint *)malloc(memReq);
8226
	   break;
8227
	 default:
8228
	   return GLU_INVALID_ENUM; /* assertion */
8229
	 }
8230
	 if (dstImage == NULL) {
8231
	   glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8232
	   glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8233
	   glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8234
	   glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8235
	   glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8236
	   glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8237
	   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8238
	   free(srcImage);
8239
	   return GLU_OUT_OF_MEMORY;
8240
	 }
8241
       }
8242
       /* level userLevel is in srcImage; nothing saved yet */
8243
       level = userLevel;
8244
   }
8245
 
8246
   glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
8247
   if (baseLevel <= level && level <= maxLevel) {
8248
     gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
8249
		  0,format, type, (void *)srcImage);
8250
   }
8251
   level++; /* update current level for the loop */
8252
   for (; level <= levels; level++) {
8253
       switch(type) {
8254
	   case GL_UNSIGNED_BYTE:
8255
	       if (newDepth > 1) {
8256
	       halveImage3D(cmpts,extractUbyte,shoveUbyte,
8257
			    newWidth,newHeight,newDepth,
8258
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8259
			    imageSize,myswapBytes);
8260
	       }
8261
	       else {
8262
		 halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
8263
				  elementSize,rowSize,groupSize);
8264
	       }
8265
	       break;
8266
	   case GL_BYTE:
8267
	       if (newDepth > 1) {
8268
	       halveImage3D(cmpts,extractSbyte,shoveSbyte,
8269
			    newWidth,newHeight,newDepth,
8270
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8271
			    imageSize,myswapBytes);
8272
	       }
8273
	       else {
8274
		 halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
8275
				  elementSize,rowSize,groupSize);
8276
	       }
8277
	       break;
8278
	   case GL_UNSIGNED_SHORT:
8279
	       if (newDepth > 1) {
8280
	       halveImage3D(cmpts,extractUshort,shoveUshort,
8281
			    newWidth,newHeight,newDepth,
8282
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8283
			    imageSize,myswapBytes);
8284
	       }
8285
	       else {
8286
		 halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
8287
				   elementSize,rowSize,groupSize,myswapBytes);
8288
	       }
8289
	       break;
8290
	   case GL_SHORT:
8291
	       if (newDepth > 1) {
8292
	       halveImage3D(cmpts,extractSshort,shoveSshort,
8293
			    newWidth,newHeight,newDepth,
8294
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8295
			    imageSize,myswapBytes);
8296
	       }
8297
	       else {
8298
		 halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
8299
				  elementSize,rowSize,groupSize,myswapBytes);
8300
	       }
8301
	       break;
8302
	   case GL_UNSIGNED_INT:
8303
	       if (newDepth > 1) {
8304
	       halveImage3D(cmpts,extractUint,shoveUint,
8305
			    newWidth,newHeight,newDepth,
8306
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8307
			    imageSize,myswapBytes);
8308
	       }
8309
	       else {
8310
		 halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
8311
				 elementSize,rowSize,groupSize,myswapBytes);
8312
	       }
8313
	       break;
8314
	   case GL_INT:
8315
	       if (newDepth > 1) {
8316
	       halveImage3D(cmpts,extractSint,shoveSint,
8317
			    newWidth,newHeight,newDepth,
8318
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8319
			    imageSize,myswapBytes);
8320
	       }
8321
	       else {
8322
		 halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
8323
				elementSize,rowSize,groupSize,myswapBytes);
8324
	       }
8325
	       break;
8326
	   case GL_FLOAT:
8327
	       if (newDepth > 1) {
8328
	       halveImage3D(cmpts,extractFloat,shoveFloat,
8329
			    newWidth,newHeight,newDepth,
8330
			    srcImage,dstImage,elementSize,groupSize,rowSize,
8331
			    imageSize,myswapBytes);
8332
	       }
8333
	       else {
8334
		 halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
8335
				  elementSize,rowSize,groupSize,myswapBytes);
8336
	       }
8337
	       break;
8338
	   case GL_UNSIGNED_BYTE_3_3_2:
8339
	       halveImagePackedPixel3D(3,extract332,shove332,
8340
				       newWidth,newHeight,newDepth,
8341
				       srcImage,dstImage,elementSize,rowSize,
8342
				       imageSize,myswapBytes);
8343
	       break;
8344
	   case GL_UNSIGNED_BYTE_2_3_3_REV:
8345
	       halveImagePackedPixel3D(3,extract233rev,shove233rev,
8346
				       newWidth,newHeight,newDepth,
8347
				       srcImage,dstImage,elementSize,rowSize,
8348
				       imageSize,myswapBytes);
8349
	       break;
8350
	   case GL_UNSIGNED_SHORT_5_6_5:
8351
	       halveImagePackedPixel3D(3,extract565,shove565,
8352
				       newWidth,newHeight,newDepth,
8353
				       srcImage,dstImage,elementSize,rowSize,
8354
				       imageSize,myswapBytes);
8355
	       break;
8356
	   case GL_UNSIGNED_SHORT_5_6_5_REV:
8357
	       halveImagePackedPixel3D(3,extract565rev,shove565rev,
8358
				       newWidth,newHeight,newDepth,
8359
				       srcImage,dstImage,elementSize,rowSize,
8360
				       imageSize,myswapBytes);
8361
	       break;
8362
	   case GL_UNSIGNED_SHORT_4_4_4_4:
8363
	       halveImagePackedPixel3D(4,extract4444,shove4444,
8364
				       newWidth,newHeight,newDepth,
8365
				       srcImage,dstImage,elementSize,rowSize,
8366
				       imageSize,myswapBytes);
8367
	       break;
8368
	   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8369
	       halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8370
				       newWidth,newHeight,newDepth,
8371
				       srcImage,dstImage,elementSize,rowSize,
8372
				       imageSize,myswapBytes);
8373
	       break;
8374
	   case GL_UNSIGNED_SHORT_5_5_5_1:
8375
	       halveImagePackedPixel3D(4,extract5551,shove5551,
8376
				       newWidth,newHeight,newDepth,
8377
				       srcImage,dstImage,elementSize,rowSize,
8378
				       imageSize,myswapBytes);
8379
	       break;
8380
	   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8381
	       halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8382
				       newWidth,newHeight,newDepth,
8383
				       srcImage,dstImage,elementSize,rowSize,
8384
				       imageSize,myswapBytes);
8385
	       break;
8386
	   case GL_UNSIGNED_INT_8_8_8_8:
8387
	       halveImagePackedPixel3D(4,extract8888,shove8888,
8388
				       newWidth,newHeight,newDepth,
8389
				       srcImage,dstImage,elementSize,rowSize,
8390
				       imageSize,myswapBytes);
8391
	       break;
8392
	   case GL_UNSIGNED_INT_8_8_8_8_REV:
8393
	       halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8394
				       newWidth,newHeight,newDepth,
8395
				       srcImage,dstImage,elementSize,rowSize,
8396
				       imageSize,myswapBytes);
8397
	       break;
8398
	   case GL_UNSIGNED_INT_10_10_10_2:
8399
	       halveImagePackedPixel3D(4,extract1010102,shove1010102,
8400
				       newWidth,newHeight,newDepth,
8401
				       srcImage,dstImage,elementSize,rowSize,
8402
				       imageSize,myswapBytes);
8403
	       break;
8404
	   case GL_UNSIGNED_INT_2_10_10_10_REV:
8405
	       halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8406
				       newWidth,newHeight,newDepth,
8407
				       srcImage,dstImage,elementSize,rowSize,
8408
				       imageSize,myswapBytes);
8409
	       break;
8410
	   default:
8411
	       assert(0);
8412
	       break;
8413
       }
8414
 
8415
       __GLU_SWAP_IMAGE(srcImage,dstImage);
8416
 
8417
       if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
8418
       if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
8419
       if (newDepth > 1) newDepth /= 2;
8420
       {
8421
	  /* call tex image with srcImage untouched since it's not padded */
8422
	  if (baseLevel <= level && level <= maxLevel) {
8423
	    gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
8424
			 newDepth,0, format, type, (void *) srcImage);
8425
	  }
8426
       }
8427
   } /* for level */
8428
   glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8429
   glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8430
   glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8431
   glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8432
   glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8433
   glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8434
   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8435
 
8436
   free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
8437
   if (dstImage) { /* if it's non-rectangular and only 1 level */
8438
     free(dstImage);
8439
   }
8440
   return 0;
8441
} /* gluBuild3DMipmapLevelsCore() */
8442
 
8443
GLint GLAPIENTRY
8444
gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
8445
			     GLsizei width, GLsizei height, GLsizei depth,
8446
			     GLenum format, GLenum type,
8447
			     GLint userLevel, GLint baseLevel, GLint maxLevel,
8448
			     const void *data)
8449
{
8450
   int level, levels;
8451
 
8452
   int rc= checkMipmapArgs(internalFormat,format,type);
8453
   if (rc != 0) return rc;
8454
 
8455
   if (width < 1 || height < 1 || depth < 1) {
8456
       return GLU_INVALID_VALUE;
8457
   }
8458
 
8459
   if(type == GL_BITMAP) {
8460
      return GLU_INVALID_ENUM;
8461
   }
8462
 
8463
   levels = computeLog(width);
8464
   level = computeLog(height);
8465
   if (level > levels) levels=level;
8466
   level = computeLog(depth);
8467
   if (level > levels) levels=level;
8468
 
8469
   levels+= userLevel;
8470
   if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
8471
      return GLU_INVALID_VALUE;
8472
 
8473
   return gluBuild3DMipmapLevelsCore(target, internalFormat,
8474
				     width, height, depth,
8475
				     width, height, depth,
8476
				     format, type,
8477
				     userLevel, baseLevel, maxLevel,
8478
				     data);
8479
} /* gluBuild3DMipmapLevels() */
8480
 
8481
GLint GLAPIENTRY
8482
gluBuild3DMipmaps(GLenum target, GLint internalFormat,
8483
			GLsizei width, GLsizei height, GLsizei depth,
8484
			GLenum format, GLenum type, const void *data)
8485
{
8486
   GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
8487
   int level, levels;
8488
 
8489
   int rc= checkMipmapArgs(internalFormat,format,type);
8490
   if (rc != 0) return rc;
8491
 
8492
   if (width < 1 || height < 1 || depth < 1) {
8493
       return GLU_INVALID_VALUE;
8494
   }
8495
 
8496
   if(type == GL_BITMAP) {
8497
      return GLU_INVALID_ENUM;
8498
   }
8499
 
8500
   closestFit3D(target,width,height,depth,internalFormat,format,type,
8501
		&widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
8502
 
8503
   levels = computeLog(widthPowerOf2);
8504
   level = computeLog(heightPowerOf2);
8505
   if (level > levels) levels=level;
8506
   level = computeLog(depthPowerOf2);
8507
   if (level > levels) levels=level;
8508
 
8509
   return gluBuild3DMipmapLevelsCore(target, internalFormat,
8510
				     width, height, depth,
8511
				     widthPowerOf2, heightPowerOf2,
8512
				     depthPowerOf2,
8513
				     format, type, 0, 0, levels,
8514
				     data);
8515
} /* gluBuild3DMipmaps() */
8516
 
8517
static GLdouble extractUbyte(int isSwap, const void *ubyte)
8518
{
8519
   isSwap= isSwap;		/* turn off warnings */
8520
 
8521
   assert(*((const GLubyte *)ubyte) <= 255);
8522
 
8523
   return (GLdouble)(*((const GLubyte *)ubyte));
8524
} /* extractUbyte() */
8525
 
8526
static void shoveUbyte(GLdouble value, int index, void *data)
8527
{
8528
   assert(0.0 <= value && value < 256.0);
8529
 
8530
   ((GLubyte *)data)[index]= (GLubyte)value;
8531
} /* shoveUbyte() */
8532
 
8533
static GLdouble extractSbyte(int isSwap, const void *sbyte)
8534
{
8535
   isSwap= isSwap;		/* turn off warnings */
8536
 
8537
   assert(*((const GLbyte *)sbyte) <= 127);
8538
 
8539
   return (GLdouble)(*((const GLbyte *)sbyte));
8540
} /* extractSbyte() */
8541
 
8542
static void shoveSbyte(GLdouble value, int index, void *data)
8543
{
8544
   ((GLbyte *)data)[index]= (GLbyte)value;
8545
} /* shoveSbyte() */
8546
 
8547
static GLdouble extractUshort(int isSwap, const void *uitem)
8548
{
8549
   GLushort ushort;
8550
 
8551
   if (isSwap) {
8552
     ushort= __GLU_SWAP_2_BYTES(uitem);
8553
   }
8554
   else {
8555
     ushort= *(const GLushort *)uitem;
8556
   }
8557
 
8558
   assert(ushort <= 65535);
8559
 
8560
   return (GLdouble)ushort;
8561
} /* extractUshort() */
8562
 
8563
static void shoveUshort(GLdouble value, int index, void *data)
8564
{
8565
   assert(0.0 <= value && value < 65536.0);
8566
 
8567
   ((GLushort *)data)[index]= (GLushort)value;
8568
} /* shoveUshort() */
8569
 
8570
static GLdouble extractSshort(int isSwap, const void *sitem)
8571
{
8572
   GLshort sshort;
8573
 
8574
   if (isSwap) {
8575
     sshort= __GLU_SWAP_2_BYTES(sitem);
8576
   }
8577
   else {
8578
     sshort= *(const GLshort *)sitem;
8579
   }
8580
 
8581
   assert(sshort <= 32767);
8582
 
8583
   return (GLdouble)sshort;
8584
} /* extractSshort() */
8585
 
8586
static void shoveSshort(GLdouble value, int index, void *data)
8587
{
8588
   assert(0.0 <= value && value < 32768.0);
8589
 
8590
   ((GLshort *)data)[index]= (GLshort)value;
8591
} /* shoveSshort() */
8592
 
8593
static GLdouble extractUint(int isSwap, const void *uitem)
8594
{
8595
   GLuint uint;
8596
 
8597
   if (isSwap) {
8598
     uint= __GLU_SWAP_4_BYTES(uitem);
8599
   }
8600
   else {
8601
     uint= *(const GLuint *)uitem;
8602
   }
8603
 
8604
   assert(uint <= 0xffffffff);
8605
 
8606
   return (GLdouble)uint;
8607
} /* extractUint() */
8608
 
8609
static void shoveUint(GLdouble value, int index, void *data)
8610
{
8611
   assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
8612
 
8613
   ((GLuint *)data)[index]= (GLuint)value;
8614
} /* shoveUint() */
8615
 
8616
static GLdouble extractSint(int isSwap, const void *sitem)
8617
{
8618
   GLint sint;
8619
 
8620
   if (isSwap) {
8621
     sint= __GLU_SWAP_4_BYTES(sitem);
8622
   }
8623
   else {
8624
     sint= *(const GLint *)sitem;
8625
   }
8626
 
8627
   assert(sint <= 0x7fffffff);
8628
 
8629
   return (GLdouble)sint;
8630
} /* extractSint() */
8631
 
8632
static void shoveSint(GLdouble value, int index, void *data)
8633
{
8634
   assert(0.0 <= value && value <= (GLdouble) INT_MAX);
8635
 
8636
   ((GLint *)data)[index]= (GLint)value;
8637
} /* shoveSint() */
8638
 
8639
static GLdouble extractFloat(int isSwap, const void *item)
8640
{
8641
   GLfloat ffloat;
8642
 
8643
   if (isSwap) {
8644
     ffloat= __GLU_SWAP_4_BYTES(item);
8645
   }
8646
   else {
8647
     ffloat= *(const GLfloat *)item;
8648
   }
8649
 
8650
   assert(ffloat <= 1.0);
8651
 
8652
   return (GLdouble)ffloat;
8653
} /* extractFloat() */
8654
 
8655
static void shoveFloat(GLdouble value, int index, void *data)
8656
{
8657
   assert(0.0 <= value && value <= 1.0);
8658
 
8659
   ((GLfloat *)data)[index]= value;
8660
} /* shoveFloat() */
8661
 
8662
static void halveImageSlice(int components,
8663
			    GLdouble (*extract)(int, const void *),
8664
			    void (*shove)(GLdouble, int, void *),
8665
			    GLint width, GLint height, GLint depth,
8666
			    const void *dataIn, void *dataOut,
8667
			    GLint elementSizeInBytes,
8668
			    GLint groupSizeInBytes,
8669
			    GLint rowSizeInBytes,
8670
			    GLint imageSizeInBytes,
8671
			    GLint isSwap)
8672
{
8673
   int ii, jj;
8674
   int halfWidth= width / 2;
8675
   int halfHeight= height / 2;
8676
   int halfDepth= depth / 2;
8677
   const char *src= (const char *)dataIn;
8678
   int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes);
8679
   int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8680
   int outIndex= 0;
8681
 
8682
   assert((width == 1 || height == 1) && depth >= 2);
8683
 
8684
   if (width == height) {	/* a 1-pixel column viewed from top */
8685
      /* printf("1-column\n");*/
8686
      assert(width == 1 && height == 1);
8687
      assert(depth >= 2);
8688
 
8689
      for (ii= 0; ii< halfDepth; ii++) {
8690
	 int cc;
8691
 
8692
	 for (cc = 0; cc < components; cc++) {
8693
	    double totals[4];
8694
	    double extractTotals[BOX2][4];
8695
	    int kk;
8696
 
8697
	    extractTotals[0][cc]= (*extract)(isSwap,src);
8698
	    extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
8699
 
8700
	    /* average 2 pixels since only a column */
8701
	    totals[cc]= 0.0;
8702
	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8703
	     * totals[RED]/= 2.0;
8704
	     */
8705
	    for (kk = 0; kk < BOX2; kk++) {
8706
	      totals[cc]+= extractTotals[kk][cc];
8707
	    }
8708
	    totals[cc]/= (double)BOX2;
8709
 
8710
	    (*shove)(totals[cc],outIndex,dataOut);
8711
	    outIndex++;
8712
	    src+= elementSizeInBytes;
8713
	 } /* for cc */
8714
 
8715
	 /* skip over to next group of 2 */
8716
	 src+= rowSizeInBytes;
8717
      } /* for ii */
8718
 
8719
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8720
      assert(outIndex == halfDepth * components);
8721
   }
8722
   else if (height == 1) {	/* horizontal slice viewed from top */
8723
      /* printf("horizontal slice\n"); */
8724
      assert(width != 1);
8725
 
8726
      for (ii= 0; ii< halfDepth; ii++) {
8727
	 for (jj= 0; jj< halfWidth; jj++) {
8728
	    int cc;
8729
 
8730
	    for (cc = 0; cc < components; cc++) {
8731
	       int kk;
8732
	       double totals[4];
8733
	       double extractTotals[BOX4][4];
8734
 
8735
	       extractTotals[0][cc]=(*extract)(isSwap,src);
8736
	       extractTotals[1][cc]=(*extract)(isSwap,
8737
					       (src+groupSizeInBytes));
8738
	       extractTotals[2][cc]=(*extract)(isSwap,
8739
					       (src+imageSizeInBytes));
8740
	       extractTotals[3][cc]=(*extract)(isSwap,
8741
					       (src+imageSizeInBytes+groupSizeInBytes));
8742
 
8743
	       /* grab 4 pixels to average */
8744
	       totals[cc]= 0.0;
8745
	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8746
		*	       extractTotals[2][RED]+extractTotals[3][RED];
8747
		* totals[RED]/= 4.0;
8748
		*/
8749
	       for (kk = 0; kk < BOX4; kk++) {
8750
		  totals[cc]+= extractTotals[kk][cc];
8751
	       }
8752
	       totals[cc]/= (double)BOX4;
8753
 
8754
	       (*shove)(totals[cc],outIndex,dataOut);
8755
	       outIndex++;
8756
 
8757
	       src+= elementSizeInBytes;
8758
	    } /* for cc */
8759
 
8760
	    /* skip over to next horizontal square of 4 */
8761
	    src+= groupSizeInBytes;
8762
	 } /* for jj */
8763
	 src+= rowPadBytes;
8764
 
8765
	 src+= rowSizeInBytes;
8766
      } /* for ii */
8767
 
8768
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8769
      assert(outIndex == halfWidth * halfDepth * components);
8770
   }
8771
   else if (width == 1) {	/* vertical slice viewed from top */
8772
      /* printf("vertical slice\n"); */
8773
      assert(height != 1);
8774
 
8775
      for (ii= 0; ii< halfDepth; ii++) {
8776
	 for (jj= 0; jj< halfHeight; jj++) {
8777
	    int cc;
8778
 
8779
	    for (cc = 0; cc < components; cc++) {
8780
	       int kk;
8781
	       double totals[4];
8782
	       double extractTotals[BOX4][4];
8783
 
8784
	       extractTotals[0][cc]=(*extract)(isSwap,src);
8785
	       extractTotals[1][cc]=(*extract)(isSwap,
8786
					       (src+rowSizeInBytes));
8787
	       extractTotals[2][cc]=(*extract)(isSwap,
8788
					       (src+imageSizeInBytes));
8789
	       extractTotals[3][cc]=(*extract)(isSwap,
8790
					       (src+imageSizeInBytes+rowSizeInBytes));
8791
 
8792
	       /* grab 4 pixels to average */
8793
	       totals[cc]= 0.0;
8794
	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8795
		*	       extractTotals[2][RED]+extractTotals[3][RED];
8796
		* totals[RED]/= 4.0;
8797
		*/
8798
	       for (kk = 0; kk < BOX4; kk++) {
8799
		  totals[cc]+= extractTotals[kk][cc];
8800
	       }
8801
	       totals[cc]/= (double)BOX4;
8802
 
8803
	       (*shove)(totals[cc],outIndex,dataOut);
8804
	       outIndex++;
8805
 
8806
	       src+= elementSizeInBytes;
8807
	    } /* for cc */
8808
	    src+= rowPadBytes;
8809
 
8810
	    /* skip over to next vertical square of 4 */
8811
	    src+= rowSizeInBytes;
8812
	 } /* for jj */
8813
         src+= imagePadBytes;
8814
 
8815
	 src+= imageSizeInBytes;
8816
      } /* for ii */
8817
 
8818
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8819
      assert(outIndex == halfHeight * halfDepth * components);
8820
   }
8821
 
8822
} /* halveImageSlice() */
8823
 
8824
static void halveImage3D(int components,
8825
			 GLdouble (*extract)(int, const void *),
8826
			 void (*shove)(GLdouble, int, void *),
8827
			 GLint width, GLint height, GLint depth,
8828
			 const void *dataIn, void *dataOut,
8829
			 GLint elementSizeInBytes,
8830
			 GLint groupSizeInBytes,
8831
			 GLint rowSizeInBytes,
8832
			 GLint imageSizeInBytes,
8833
			 GLint isSwap)
8834
{
8835
   assert(depth > 1);
8836
 
8837
   /* a horizontal/vertical/one-column slice viewed from top */
8838
   if (width == 1 || height == 1) {
8839
      assert(1 <= depth);
8840
 
8841
      halveImageSlice(components,extract,shove, width, height, depth,
8842
		      dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
8843
		      rowSizeInBytes, imageSizeInBytes, isSwap);
8844
      return;
8845
   }
8846
   {
8847
      int ii, jj, dd;
8848
 
8849
      int halfWidth= width / 2;
8850
      int halfHeight= height / 2;
8851
      int halfDepth= depth / 2;
8852
      const char *src= (const char *) dataIn;
8853
      int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes);
8854
      int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8855
      int outIndex= 0;
8856
 
8857
      for (dd= 0; dd < halfDepth; dd++) {
8858
	 for (ii= 0; ii< halfHeight; ii++) {
8859
	    for (jj= 0; jj< halfWidth; jj++) {
8860
	       int cc;
8861
 
8862
	       for (cc= 0; cc < components; cc++) {
8863
		  int kk;
8864
#define BOX8 8
8865
		  double totals[4];	/* 4 is maximum components */
8866
		  double extractTotals[BOX8][4]; /* 4 is maximum components */
8867
 
8868
		  extractTotals[0][cc]= (*extract)(isSwap,src);
8869
		  extractTotals[1][cc]= (*extract)(isSwap,
8870
						   (src+groupSizeInBytes));
8871
		  extractTotals[2][cc]= (*extract)(isSwap,
8872
						   (src+rowSizeInBytes));
8873
		  extractTotals[3][cc]= (*extract)(isSwap,
8874
						   (src+rowSizeInBytes+groupSizeInBytes));
8875
 
8876
		  extractTotals[4][cc]= (*extract)(isSwap,
8877
						   (src+imageSizeInBytes));
8878
 
8879
		  extractTotals[5][cc]= (*extract)(isSwap,
8880
						   (src+groupSizeInBytes+imageSizeInBytes));
8881
		  extractTotals[6][cc]= (*extract)(isSwap,
8882
						   (src+rowSizeInBytes+imageSizeInBytes));
8883
		  extractTotals[7][cc]= (*extract)(isSwap,
8884
						   (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
8885
 
8886
		  totals[cc]= 0.0;
8887
 
8888
		  /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8889
		   *		  extractTotals[2][RED]+extractTotals[3][RED]+
8890
		   *		  extractTotals[4][RED]+extractTotals[5][RED]+
8891
		   *		  extractTotals[6][RED]+extractTotals[7][RED];
8892
		   * totals[RED]/= 8.0;
8893
		   */
8894
		  for (kk = 0; kk < BOX8; kk++) {
8895
		     totals[cc]+= extractTotals[kk][cc];
8896
		  }
8897
		  totals[cc]/= (double)BOX8;
8898
 
8899
		  (*shove)(totals[cc],outIndex,dataOut);
8900
 
8901
		  outIndex++;
8902
 
8903
		  src+= elementSizeInBytes; /* go to next component */
8904
	       } /* for cc */
8905
 
8906
	       /* skip over to next square of 4 */
8907
	       src+= groupSizeInBytes;
8908
	    } /* for jj */
8909
	    /* skip past pad bytes, if any, to get to next row */
8910
	    src+= rowPadBytes;
8911
 
8912
	    /* src is at beginning of a row here, but it's the second row of
8913
	     * the square block of 4 pixels that we just worked on so we
8914
	     * need to go one more row.
8915
	     * i.e.,
8916
	     *			 OO...
8917
	     *		 here -->OO...
8918
	     *	     but want -->OO...
8919
	     *			 OO...
8920
	     *			 ...
8921
	     */
8922
	    src+= rowSizeInBytes;
8923
	 } /* for ii */
8924
 
8925
	 /* skip past pad bytes, if any, to get to next image */
8926
	 src+= imagePadBytes;
8927
 
8928
	 src+= imageSizeInBytes;
8929
      } /* for dd */
8930
 
8931
      /* both pointers must reach one byte after the end */
8932
      assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8933
      assert(outIndex == halfWidth * halfHeight * halfDepth * components);
8934
   }
8935
} /* halveImage3D() */
8936
 
8937
 
8938
 
8939
/*** mipmap.c ***/
8940