Synchronize with trunk's revision r57629.
[reactos.git] / dll / opengl / glu32 / src / libutil / mipmap.c
1 /*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31 #include "gluos.h"
32 #include <assert.h>
33 #include <GL/glu.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <limits.h> /* UINT_MAX */
38 #include <math.h>
39
40 typedef union {
41 unsigned char ub[4];
42 unsigned short us[2];
43 unsigned int ui;
44 char b[4];
45 short s[2];
46 int i;
47 float f;
48 } Type_Widget;
49
50 /* Pixel storage modes */
51 typedef struct {
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 }