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 } 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 GLAPI 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 free(srcImage); 4513 free(dstImage); 4514 return GLU_OUT_OF_MEMORY; 4515 } 4516 4517 /* copy image from srcImage into newMipmapImage by rows */ 4518 for (ii= 0, 4519 dstTrav= (unsigned char *) newMipmapImage, 4520 srcTrav= (unsigned char *) srcImage; 4521 ii< newheight; 4522 ii++, 4523 dstTrav+= newRowLength, /* make sure the correct distance... */ 4524 srcTrav+= rowsize) { /* ...is skipped */ 4525 memcpy(dstTrav,srcTrav,rowsize); 4526 /* note that the pad bytes are not visited and will contain 4527 * garbage, which is ok. 4528 */ 4529 } 4530 4531 /* ...and use this new image for mipmapping instead */ 4532 if (baseLevel <= level && level <= maxLevel) { 4533 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, 4534 format, type, newMipmapImage); 4535 } 4536 free(newMipmapImage); /* don't forget to free it! */ 4537 } /* else */ 4538 } 4539 } /* for level */ 4540 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 4541 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 4542 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 4543 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 4544 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 4545 4546 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ 4547 if (dstImage) { /* if it's non-rectangular and only 1 level */ 4548 free(dstImage); 4549 } 4550 return 0; 4551 } /* gluBuild2DMipmapLevelsCore() */ 4552 4553 GLint GLAPIENTRY 4554 gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, 4555 GLsizei width, GLsizei height, 4556 GLenum format, GLenum type, 4557 GLint userLevel, GLint baseLevel, GLint maxLevel, 4558 const void *data) 4559 { 4560 int level, levels; 4561 4562 int rc= checkMipmapArgs(internalFormat,format,type); 4563 if (rc != 0) return rc; 4564 4565 if (width < 1 || height < 1) { 4566 return GLU_INVALID_VALUE; 4567 } 4568 4569 levels = computeLog(width); 4570 level = computeLog(height); 4571 if (level > levels) levels=level; 4572 4573 levels+= userLevel; 4574 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) 4575 return GLU_INVALID_VALUE; 4576 4577 return gluBuild2DMipmapLevelsCore(target, internalFormat, 4578 width, height, 4579 width, height, 4580 format, type, 4581 userLevel, baseLevel, maxLevel, 4582 data); 4583 } /* gluBuild2DMipmapLevels() */ 4584 4585 GLint GLAPIENTRY 4586 gluBuild2DMipmaps(GLenum target, GLint internalFormat, 4587 GLsizei width, GLsizei height, 4588 GLenum format, GLenum type, 4589 const void *data) 4590 { 4591 GLint widthPowerOf2, heightPowerOf2; 4592 int level, levels; 4593 4594 int rc= checkMipmapArgs(internalFormat,format,type); 4595 if (rc != 0) return rc; 4596 4597 if (width < 1 || height < 1) { 4598 return GLU_INVALID_VALUE; 4599 } 4600 4601 closestFit(target,width,height,internalFormat,format,type, 4602 &widthPowerOf2,&heightPowerOf2); 4603 4604 levels = computeLog(widthPowerOf2); 4605 level = computeLog(heightPowerOf2); 4606 if (level > levels) levels=level; 4607 4608 return gluBuild2DMipmapLevelsCore(target,internalFormat, 4609 width, height, 4610 widthPowerOf2,heightPowerOf2, 4611 format,type, 4612 0,0,levels,data); 4613 } /* gluBuild2DMipmaps() */ 4614 4615 #if 0 4616 /* 4617 ** This routine is for the limited case in which 4618 ** type == GL_UNSIGNED_BYTE && format != index && 4619 ** unpack_alignment = 1 && unpack_swap_bytes == false 4620 ** 4621 ** so all of the work data can be kept as ubytes instead of shorts. 4622 */ 4623 static int fastBuild2DMipmaps(const PixelStorageModes *psm, 4624 GLenum target, GLint components, GLint width, 4625 GLint height, GLenum format, 4626 GLenum type, void *data) 4627 { 4628 GLint newwidth, newheight; 4629 GLint level, levels; 4630 GLubyte *newImage; 4631 GLint newImage_width; 4632 GLint newImage_height; 4633 GLubyte *otherImage; 4634 GLubyte *imageTemp; 4635 GLint memreq; 4636 GLint cmpts; 4637 4638 4639 #if 0 4640 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); 4641 newwidth = nearestPower(width); 4642 if (newwidth > maxsize) newwidth = maxsize; 4643 newheight = nearestPower(height); 4644 if (newheight > maxsize) newheight = maxsize; 4645 #else 4646 closestFit(target,width,height,components,format,type, 4647 &newwidth,&newheight); 4648 #endif 4649 levels = computeLog(newwidth); 4650 level = computeLog(newheight); 4651 if (level > levels) levels=level; 4652 4653 cmpts = elements_per_group(format,type); 4654 4655 otherImage = NULL; 4656 /** 4657 ** No need to copy the user data if its in the packed correctly. 4658 ** Make sure that later routines don't change that data. 4659 */ 4660 if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) { 4661 newImage = (GLubyte *)data; 4662 newImage_width = width; 4663 newImage_height = height; 4664 } else { 4665 GLint rowsize; 4666 GLint groups_per_line; 4667 GLint elements_per_line; 4668 const GLubyte *start; 4669 const GLubyte *iter; 4670 GLubyte *iter2; 4671 GLint i, j; 4672 4673 newImage = (GLubyte *) 4674 malloc(image_size(width, height, format, GL_UNSIGNED_BYTE)); 4675 newImage_width = width; 4676 newImage_height = height; 4677 if (newImage == NULL) { 4678 return GLU_OUT_OF_MEMORY; 4679 } 4680 4681 /* 4682 ** Abbreviated version of fill_image for this restricted case. 4683 */ 4684 if (psm->unpack_row_length > 0) { 4685 groups_per_line = psm->unpack_row_length; 4686 } else { 4687 groups_per_line = width; 4688 } 4689 rowsize = groups_per_line * cmpts; 4690 elements_per_line = width * cmpts; 4691 start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize + 4692 psm->unpack_skip_pixels * cmpts; 4693 iter2 = newImage; 4694 4695 for (i = 0; i < height; i++) { 4696 iter = start; 4697 for (j = 0; j < elements_per_line; j++) { 4698 *iter2 = *iter; 4699 iter++; 4700 iter2++; 4701 } 4702 start += rowsize; 4703 } 4704 } 4705 4706 4707 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 4708 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 4709 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 4710 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 4711 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 4712 4713 for (level = 0; level <= levels; level++) { 4714 if (newImage_width == newwidth && newImage_height == newheight) { 4715 /* Use newImage for this level */ 4716 glTexImage2D(target, level, components, newImage_width, 4717 newImage_height, 0, format, GL_UNSIGNED_BYTE, 4718 (void *) newImage); 4719 } else { 4720 if (otherImage == NULL) { 4721 memreq = 4722 image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE); 4723 otherImage = (GLubyte *) malloc(memreq); 4724 if (otherImage == NULL) { 4725 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment); 4726 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows); 4727 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels); 4728 glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length); 4729 glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes); 4730 return GLU_OUT_OF_MEMORY; 4731 } 4732 } 4733 /* 4734 scale_internal_ubyte(cmpts, newImage_width, newImage_height, 4735 newImage, newwidth, newheight, otherImage); 4736 */ 4737 /* Swap newImage and otherImage */ 4738 imageTemp = otherImage; 4739 otherImage = newImage; 4740 newImage = imageTemp; 4741 4742 newImage_width = newwidth; 4743 newImage_height = newheight; 4744 glTexImage2D(target, level, components, newImage_width, 4745 newImage_height, 0, format, GL_UNSIGNED_BYTE, 4746 (void *) newImage); 4747 } 4748 if (newwidth > 1) newwidth /= 2; 4749 if (newheight > 1) newheight /= 2; 4750 } 4751 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment); 4752 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows); 4753 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels); 4754 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length); 4755 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes); 4756 4757 if (newImage != (const GLubyte *)data) { 4758 free((GLbyte *) newImage); 4759 } 4760 if (otherImage && otherImage != (const GLubyte *)data) { 4761 free((GLbyte *) otherImage); 4762 } 4763 return 0; 4764 } 4765 #endif 4766 4767 /* 4768 * Utility Routines 4769 */ 4770 static GLint elements_per_group(GLenum format, GLenum type) 4771 { 4772 /* 4773 * Return the number of elements per group of a specified format 4774 */ 4775 4776 /* If the type is packedpixels then answer is 1 (ignore format) */ 4777 if (type == GL_UNSIGNED_BYTE_3_3_2 || 4778 type == GL_UNSIGNED_BYTE_2_3_3_REV || 4779 type == GL_UNSIGNED_SHORT_5_6_5 || 4780 type == GL_UNSIGNED_SHORT_5_6_5_REV || 4781 type == GL_UNSIGNED_SHORT_4_4_4_4 || 4782 type == GL_UNSIGNED_SHORT_4_4_4_4_REV || 4783 type == GL_UNSIGNED_SHORT_5_5_5_1 || 4784 type == GL_UNSIGNED_SHORT_1_5_5_5_REV || 4785 type == GL_UNSIGNED_INT_8_8_8_8 || 4786 type == GL_UNSIGNED_INT_8_8_8_8_REV || 4787 type == GL_UNSIGNED_INT_10_10_10_2 || 4788 type == GL_UNSIGNED_INT_2_10_10_10_REV) { 4789 return 1; 4790 } 4791 4792 /* Types are not packed pixels, so get elements per group */ 4793 switch(format) { 4794 case GL_RGB: 4795 case GL_BGR: 4796 return 3; 4797 case GL_LUMINANCE_ALPHA: 4798 return 2; 4799 case GL_RGBA: 4800 case GL_BGRA: 4801 return 4; 4802 default: 4803 return 1; 4804 } 4805 } 4806 4807 static GLfloat bytes_per_element(GLenum type) 4808 { 4809 /* 4810 * Return the number of bytes per element, based on the element type 4811 */ 4812 switch(type) { 4813 case GL_BITMAP: 4814 return 1.0 / 8.0; 4815 case GL_UNSIGNED_SHORT: 4816 return(sizeof(GLushort)); 4817 case GL_SHORT: 4818 return(sizeof(GLshort)); 4819 case GL_UNSIGNED_BYTE: 4820 return(sizeof(GLubyte)); 4821 case GL_BYTE: 4822 return(sizeof(GLbyte)); 4823 case GL_INT: 4824 return(sizeof(GLint)); 4825 case GL_UNSIGNED_INT: 4826 return(sizeof(GLuint)); 4827 case GL_FLOAT: 4828 return(sizeof(GLfloat)); 4829 case GL_UNSIGNED_BYTE_3_3_2: 4830 case GL_UNSIGNED_BYTE_2_3_3_REV: 4831 return(sizeof(GLubyte)); 4832 case GL_UNSIGNED_SHORT_5_6_5: 4833 case GL_UNSIGNED_SHORT_5_6_5_REV: 4834 case GL_UNSIGNED_SHORT_4_4_4_4: 4835 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 4836 case GL_UNSIGNED_SHORT_5_5_5_1: 4837 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 4838 return(sizeof(GLushort)); 4839 case GL_UNSIGNED_INT_8_8_8_8: 4840 case GL_UNSIGNED_INT_8_8_8_8_REV: 4841 case GL_UNSIGNED_INT_10_10_10_2: 4842 case GL_UNSIGNED_INT_2_10_10_10_REV: 4843 return(sizeof(GLuint)); 4844 default: 4845 return 4; 4846 } 4847 } 4848 4849 static GLint is_index(GLenum format) 4850 { 4851 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX; 4852 } 4853 4854 /* 4855 ** Compute memory required for internal packed array of data of given type 4856 ** and format. 4857 */ 4858 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type) 4859 { 4860 int bytes_per_row; 4861 int components; 4862 4863 assert(width > 0); 4864 assert(height > 0); 4865 components = elements_per_group(format,type); 4866 if (type == GL_BITMAP) { 4867 bytes_per_row = (width + 7) / 8; 4868 } else { 4869 bytes_per_row = bytes_per_element(type) * width; 4870 } 4871 return bytes_per_row * height * components; 4872 } 4873 4874 /* 4875 ** Extract array from user's data applying all pixel store modes. 4876 ** The internal format used is an array of unsigned shorts. 4877 */ 4878 static void fill_image(const PixelStorageModes *psm, 4879 GLint width, GLint height, GLenum format, 4880 GLenum type, GLboolean index_format, 4881 const void *userdata, GLushort *newimage) 4882 { 4883 GLint components; 4884 GLint element_size; 4885 GLint rowsize; 4886 GLint padding; 4887 GLint groups_per_line; 4888 GLint group_size; 4889 GLint elements_per_line; 4890 const GLubyte *start; 4891 const GLubyte *iter; 4892 GLushort *iter2; 4893 GLint i, j, k; 4894 GLint myswap_bytes; 4895 4896 myswap_bytes = psm->unpack_swap_bytes; 4897 components = elements_per_group(format,type); 4898 if (psm->unpack_row_length > 0) { 4899 groups_per_line = psm->unpack_row_length; 4900 } else { 4901 groups_per_line = width; 4902 } 4903 4904 /* All formats except GL_BITMAP fall out trivially */ 4905 if (type == GL_BITMAP) { 4906 GLint bit_offset; 4907 GLint current_bit; 4908 4909 rowsize = (groups_per_line * components + 7) / 8; 4910 padding = (rowsize % psm->unpack_alignment); 4911 if (padding) { 4912 rowsize += psm->unpack_alignment - padding; 4913 } 4914 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + 4915 (psm->unpack_skip_pixels * components / 8); 4916 elements_per_line = width * components; 4917 iter2 = newimage; 4918 for (i = 0; i < height; i++) { 4919 iter = start; 4920 bit_offset = (psm->unpack_skip_pixels * components) % 8; 4921 for (j = 0; j < elements_per_line; j++) { 4922 /* Retrieve bit */ 4923 if (psm->unpack_lsb_first) { 4924 current_bit = iter[0] & (1 << bit_offset); 4925 } else { 4926 current_bit = iter[0] & (1 << (7 - bit_offset)); 4927 } 4928 if (current_bit) { 4929 if (index_format) { 4930 *iter2 = 1; 4931 } else { 4932 *iter2 = 65535; 4933 } 4934 } else { 4935 *iter2 = 0; 4936 } 4937 bit_offset++; 4938 if (bit_offset == 8) { 4939 bit_offset = 0; 4940 iter++; 4941 } 4942 iter2++; 4943 } 4944 start += rowsize; 4945 } 4946 } else { 4947 element_size = bytes_per_element(type); 4948 group_size = element_size * components; 4949 if (element_size == 1) myswap_bytes = 0; 4950 4951 rowsize = groups_per_line * group_size; 4952 padding = (rowsize % psm->unpack_alignment); 4953 if (padding) { 4954 rowsize += psm->unpack_alignment - padding; 4955 } 4956 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + 4957 psm->unpack_skip_pixels * group_size; 4958 elements_per_line = width * components; 4959 4960 iter2 = newimage; 4961 for (i = 0; i < height; i++) { 4962 iter = start; 4963 for (j = 0; j < elements_per_line; j++) { 4964 Type_Widget widget; 4965 float extractComponents[4]; 4966 4967 switch(type) { 4968 case GL_UNSIGNED_BYTE_3_3_2: 4969 extract332(0,iter,extractComponents); 4970 for (k = 0; k < 3; k++) { 4971 *iter2++ = (GLushort)(extractComponents[k]*65535); 4972 } 4973 break; 4974 case GL_UNSIGNED_BYTE_2_3_3_REV: 4975 extract233rev(0,iter,extractComponents); 4976 for (k = 0; k < 3; k++) { 4977 *iter2++ = (GLushort)(extractComponents[k]*65535); 4978 } 4979 break; 4980 case GL_UNSIGNED_BYTE: 4981 if (index_format) { 4982 *iter2++ = *iter; 4983 } else { 4984 *iter2++ = (*iter) * 257; 4985 } 4986 break; 4987 case GL_BYTE: 4988 if (index_format) { 4989 *iter2++ = *((const GLbyte *) iter); 4990 } else { 4991 /* rough approx */ 4992 *iter2++ = (*((const GLbyte *) iter)) * 516; 4993 } 4994 break; 4995 case GL_UNSIGNED_SHORT_5_6_5: 4996 extract565(myswap_bytes,iter,extractComponents); 4997 for (k = 0; k < 3; k++) { 4998 *iter2++ = (GLushort)(extractComponents[k]*65535); 4999 } 5000 break; 5001 case GL_UNSIGNED_SHORT_5_6_5_REV: 5002 extract565rev(myswap_bytes,iter,extractComponents); 5003 for (k = 0; k < 3; k++) { 5004 *iter2++ = (GLushort)(extractComponents[k]*65535); 5005 } 5006 break; 5007 case GL_UNSIGNED_SHORT_4_4_4_4: 5008 extract4444(myswap_bytes,iter,extractComponents); 5009 for (k = 0; k < 4; k++) { 5010 *iter2++ = (GLushort)(extractComponents[k]*65535); 5011 } 5012 break; 5013 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 5014 extract4444rev(myswap_bytes,iter,extractComponents); 5015 for (k = 0; k < 4; k++) { 5016 *iter2++ = (GLushort)(extractComponents[k]*65535); 5017 } 5018 break; 5019 case GL_UNSIGNED_SHORT_5_5_5_1: 5020 extract5551(myswap_bytes,iter,extractComponents); 5021 for (k = 0; k < 4; k++) { 5022 *iter2++ = (GLushort)(extractComponents[k]*65535); 5023 } 5024 break; 5025 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 5026 extract1555rev(myswap_bytes,iter,extractComponents); 5027 for (k = 0; k < 4; k++) { 5028 *iter2++ = (GLushort)(extractComponents[k]*65535); 5029 } 5030 break; 5031 case GL_UNSIGNED_SHORT: 5032 case GL_SHORT: 5033 if (myswap_bytes) { 5034 widget.ub[0] = iter[1]; 5035 widget.ub[1] = iter[0]; 5036 } else { 5037 widget.ub[0] = iter[0]; 5038 widget.ub[1] = iter[1]; 5039 } 5040 if (type == GL_SHORT) { 5041 if (index_format) { 5042 *iter2++ = widget.s[0]; 5043 } else { 5044 /* rough approx */ 5045 *iter2++ = widget.s[0]*2; 5046 } 5047 } else { 5048 *iter2++ = widget.us[0]; 5049 } 5050 break; 5051 case GL_UNSIGNED_INT_8_8_8_8: 5052 extract8888(myswap_bytes,iter,extractComponents); 5053 for (k = 0; k < 4; k++) { 5054 *iter2++ = (GLushort)(extractComponents[k]*65535); 5055 } 5056 break; 5057 case GL_UNSIGNED_INT_8_8_8_8_REV: 5058 extract8888rev(myswap_bytes,iter,extractComponents); 5059 for (k = 0; k < 4; k++) { 5060 *iter2++ = (GLushort)(extractComponents[k]*65535); 5061 } 5062 break; 5063 case GL_UNSIGNED_INT_10_10_10_2: 5064 extract1010102(myswap_bytes,iter,extractComponents); 5065 for (k = 0; k < 4; k++) { 5066 *iter2++ = (GLushort)(extractComponents[k]*65535); 5067 } 5068 break; 5069 case GL_UNSIGNED_INT_2_10_10_10_REV: 5070 extract2101010rev(myswap_bytes,iter,extractComponents); 5071 for (k = 0; k < 4; k++) { 5072 *iter2++ = (GLushort)(extractComponents[k]*65535); 5073 } 5074 break; 5075 case GL_INT: 5076 case GL_UNSIGNED_INT: 5077 case GL_FLOAT: 5078 if (myswap_bytes) { 5079 widget.ub[0] = iter[3]; 5080 widget.ub[1] = iter[2]; 5081 widget.ub[2] = iter[1]; 5082 widget.ub[3] = iter[0]; 5083 } else { 5084 widget.ub[0] = iter[0]; 5085 widget.ub[1] = iter[1]; 5086 widget.ub[2] = iter[2]; 5087 widget.ub[3] = iter[3]; 5088 } 5089 if (type == GL_FLOAT) { 5090 if (index_format) { 5091 *iter2++ = widget.f; 5092 } else { 5093 *iter2++ = 65535 * widget.f; 5094 } 5095 } else if (type == GL_UNSIGNED_INT) { 5096 if (index_format) { 5097 *iter2++ = widget.ui; 5098 } else { 5099 *iter2++ = widget.ui >> 16; 5100 } 5101 } else { 5102 if (index_format) { 5103 *iter2++ = widget.i; 5104 } else { 5105 *iter2++ = widget.i >> 15; 5106 } 5107 } 5108 break; 5109 } 5110 iter += element_size; 5111 } /* for j */ 5112 start += rowsize; 5113 #if 1 5114 /* want 'iter' pointing at start, not within, row for assertion 5115 * purposes 5116 */ 5117 iter= start; 5118 #endif 5119 } /* for i */ 5120 5121 /* iterators should be one byte past end */ 5122 if (!isTypePackedPixel(type)) { 5123 assert(iter2 == &newimage[width*height*components]); 5124 } 5125 else { 5126 assert(iter2 == &newimage[width*height* 5127 elements_per_group(format,0)]); 5128 } 5129 assert( iter == &((const GLubyte *)userdata)[rowsize*height + 5130 psm->unpack_skip_rows * rowsize + 5131 psm->unpack_skip_pixels * group_size] ); 5132 5133 } /* else */ 5134 } /* fill_image() */ 5135 5136 /* 5137 ** Insert array into user's data applying all pixel store modes. 5138 ** The internal format is an array of unsigned shorts. 5139 ** empty_image() because it is the opposite of fill_image(). 5140 */ 5141 static void empty_image(const PixelStorageModes *psm, 5142 GLint width, GLint height, GLenum format, 5143 GLenum type, GLboolean index_format, 5144 const GLushort *oldimage, void *userdata) 5145 { 5146 GLint components; 5147 GLint element_size; 5148 GLint rowsize; 5149 GLint padding; 5150 GLint groups_per_line; 5151 GLint group_size; 5152 GLint elements_per_line; 5153 GLubyte *start; 5154 GLubyte *iter; 5155 const GLushort *iter2; 5156 GLint i, j, k; 5157 GLint myswap_bytes; 5158 5159 myswap_bytes = psm->pack_swap_bytes; 5160 components = elements_per_group(format,type); 5161 if (psm->pack_row_length > 0) { 5162 groups_per_line = psm->pack_row_length; 5163 } else { 5164 groups_per_line = width; 5165 } 5166 5167 /* All formats except GL_BITMAP fall out trivially */ 5168 if (type == GL_BITMAP) { 5169 GLint bit_offset; 5170 GLint current_bit; 5171 5172 rowsize = (groups_per_line * components + 7) / 8; 5173 padding = (rowsize % psm->pack_alignment); 5174 if (padding) { 5175 rowsize += psm->pack_alignment - padding; 5176 } 5177 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + 5178 (psm->pack_skip_pixels * components / 8); 5179 elements_per_line = width * components; 5180 iter2 = oldimage; 5181 for (i = 0; i < height; i++) { 5182 iter = start; 5183 bit_offset = (psm->pack_skip_pixels * components) % 8; 5184 for (j = 0; j < elements_per_line; j++) { 5185 if (index_format) { 5186 current_bit = iter2[0] & 1; 5187 } else { 5188 if (iter2[0] > 32767) { 5189 current_bit = 1; 5190 } else { 5191 current_bit = 0; 5192 } 5193 } 5194 5195 if (current_bit) { 5196 if (psm->pack_lsb_first) { 5197 *iter |= (1 << bit_offset); 5198 } else { 5199 *iter |= (1 << (7 - bit_offset)); 5200 } 5201 } else { 5202 if (psm->pack_lsb_first) { 5203 *iter &= ~(1 << bit_offset); 5204 } else { 5205 *iter &= ~(1 << (7 - bit_offset)); 5206 } 5207 } 5208 5209 bit_offset++; 5210 if (bit_offset == 8) { 5211 bit_offset = 0; 5212 iter++; 5213 } 5214 iter2++; 5215 } 5216 start += rowsize; 5217 } 5218 } else { 5219 float shoveComponents[4]; 5220 5221 element_size = bytes_per_element(type); 5222 group_size = element_size * components; 5223 if (element_size == 1) myswap_bytes = 0; 5224 5225 rowsize = groups_per_line * group_size; 5226 padding = (rowsize % psm->pack_alignment); 5227 if (padding) { 5228 rowsize += psm->pack_alignment - padding; 5229 } 5230 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + 5231 psm->pack_skip_pixels * group_size; 5232 elements_per_line = width * components; 5233 5234 iter2 = oldimage; 5235 for (i = 0; i < height; i++) { 5236 iter = start; 5237 for (j = 0; j < elements_per_line; j++) { 5238 Type_Widget widget; 5239 5240 switch(type) { 5241 case GL_UNSIGNED_BYTE_3_3_2: 5242 for (k = 0; k < 3; k++) { 5243 shoveComponents[k]= *iter2++ / 65535.0; 5244 } 5245 shove332(shoveComponents,0,(void *)iter); 5246 break; 5247 case GL_UNSIGNED_BYTE_2_3_3_REV: 5248 for (k = 0; k < 3; k++) { 5249 shoveComponents[k]= *iter2++ / 65535.0; 5250 } 5251 shove233rev(shoveComponents,0,(void *)iter); 5252 break; 5253 case GL_UNSIGNED_BYTE: 5254 if (index_format) { 5255 *iter = *iter2++; 5256 } else { 5257 *iter = *iter2++ >> 8; 5258 } 5259 break; 5260 case GL_BYTE: 5261 if (index_format) { 5262 *((GLbyte *) iter) = *iter2++; 5263 } else { 5264 *((GLbyte *) iter) = *iter2++ >> 9; 5265 } 5266 break; 5267 case GL_UNSIGNED_SHORT_5_6_5: 5268 for (k = 0; k < 3; k++) { 5269 shoveComponents[k]= *iter2++ / 65535.0; 5270 } 5271 shove565(shoveComponents,0,(void *)&widget.us[0]); 5272 if (myswap_bytes) { 5273 iter[0] = widget.ub[1]; 5274 iter[1] = widget.ub[0]; 5275 } 5276 else { 5277 *(GLushort *)iter = widget.us[0]; 5278 } 5279 break; 5280 case GL_UNSIGNED_SHORT_5_6_5_REV: 5281 for (k = 0; k < 3; k++) { 5282 shoveComponents[k]= *iter2++ / 65535.0; 5283 } 5284 shove565rev(shoveComponents,0,(void *)&widget.us[0]); 5285 if (myswap_bytes) { 5286 iter[0] = widget.ub[1]; 5287 iter[1] = widget.ub[0]; 5288 } 5289 else { 5290 *(GLushort *)iter = widget.us[0]; 5291 } 5292 break; 5293 case GL_UNSIGNED_SHORT_4_4_4_4: 5294 for (k = 0; k < 4; k++) { 5295 shoveComponents[k]= *iter2++ / 65535.0; 5296 } 5297 shove4444(shoveComponents,0,(void *)&widget.us[0]); 5298 if (myswap_bytes) { 5299 iter[0] = widget.ub[1]; 5300 iter[1] = widget.ub[0]; 5301 } else { 5302 *(GLushort *)iter = widget.us[0]; 5303 } 5304 break; 5305 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 5306 for (k = 0; k < 4; k++) { 5307 shoveComponents[k]= *iter2++ / 65535.0; 5308 } 5309 shove4444rev(shoveComponents,0,(void *)&widget.us[0]); 5310 if (myswap_bytes) { 5311 iter[0] = widget.ub[1]; 5312 iter[1] = widget.ub[0]; 5313 } else { 5314 *(GLushort *)iter = widget.us[0]; 5315 } 5316 break; 5317 case GL_UNSIGNED_SHORT_5_5_5_1: 5318 for (k = 0; k < 4; k++) { 5319 shoveComponents[k]= *iter2++ / 65535.0; 5320 } 5321 shove5551(shoveComponents,0,(void *)&widget.us[0]); 5322 if (myswap_bytes) { 5323 iter[0] = widget.ub[1]; 5324 iter[1] = widget.ub[0]; 5325 } else { 5326 *(GLushort *)iter = widget.us[0]; 5327 } 5328 break; 5329 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 5330 for (k = 0; k < 4; k++) { 5331 shoveComponents[k]= *iter2++ / 65535.0; 5332 } 5333 shove1555rev(shoveComponents,0,(void *)&widget.us[0]); 5334 if (myswap_bytes) { 5335 iter[0] = widget.ub[1]; 5336 iter[1] = widget.ub[0]; 5337 } else { 5338 *(GLushort *)iter = widget.us[0]; 5339 } 5340 break; 5341 case GL_UNSIGNED_SHORT: 5342 case GL_SHORT: 5343 if (type == GL_SHORT) { 5344 if (index_format) { 5345 widget.s[0] = *iter2++; 5346 } else { 5347 widget.s[0] = *iter2++ >> 1; 5348 } 5349 } else { 5350 widget.us[0] = *iter2++; 5351 } 5352 if (myswap_bytes) { 5353 iter[0] = widget.ub[1]; 5354 iter[1] = widget.ub[0]; 5355 } else { 5356 iter[0] = widget.ub[0]; 5357 iter[1] = widget.ub[1]; 5358 } 5359 break; 5360 case GL_UNSIGNED_INT_8_8_8_8: 5361 for (k = 0; k < 4; k++) { 5362 shoveComponents[k]= *iter2++ / 65535.0; 5363 } 5364 shove8888(shoveComponents,0,(void *)&widget.ui); 5365 if (myswap_bytes) { 5366 iter[3] = widget.ub[0]; 5367 iter[2] = widget.ub[1]; 5368 iter[1] = widget.ub[2]; 5369 iter[0] = widget.ub[3]; 5370 } else { 5371 *(GLuint *)iter= widget.ui; 5372 } 5373 5374 break; 5375 case GL_UNSIGNED_INT_8_8_8_8_REV: 5376 for (k = 0; k < 4; k++) { 5377 shoveComponents[k]= *iter2++ / 65535.0; 5378 } 5379 shove8888rev(shoveComponents,0,(void *)&widget.ui); 5380 if (myswap_bytes) { 5381 iter[3] = widget.ub[0]; 5382 iter[2] = widget.ub[1]; 5383 iter[1] = widget.ub[2]; 5384 iter[0] = widget.ub[3]; 5385 } else { 5386 *(GLuint *)iter= widget.ui; 5387 } 5388 break; 5389 case GL_UNSIGNED_INT_10_10_10_2: 5390 for (k = 0; k < 4; k++) { 5391 shoveComponents[k]= *iter2++ / 65535.0; 5392 } 5393 shove1010102(shoveComponents,0,(void *)&widget.ui); 5394 if (myswap_bytes) { 5395 iter[3] = widget.ub[0]; 5396 iter[2] = widget.ub[1]; 5397 iter[1] = widget.ub[2]; 5398 iter[0] = widget.ub[3]; 5399 } else { 5400 *(GLuint *)iter= widget.ui; 5401 } 5402 break; 5403 case GL_UNSIGNED_INT_2_10_10_10_REV: 5404 for (k = 0; k < 4; k++) { 5405 shoveComponents[k]= *iter2++ / 65535.0; 5406 } 5407 shove2101010rev(shoveComponents,0,(void *)&widget.ui); 5408 if (myswap_bytes) { 5409 iter[3] = widget.ub[0]; 5410 iter[2] = widget.ub[1]; 5411 iter[1] = widget.ub[2]; 5412 iter[0] = widget.ub[3]; 5413 } else { 5414 *(GLuint *)iter= widget.ui; 5415 } 5416 break; 5417 case GL_INT: 5418 case GL_UNSIGNED_INT: 5419 case GL_FLOAT: 5420 if (type == GL_FLOAT) { 5421 if (index_format) { 5422 widget.f = *iter2++; 5423 } else { 5424 widget.f = *iter2++ / (float) 65535.0; 5425 } 5426 } else if (type == GL_UNSIGNED_INT) { 5427 if (index_format) { 5428 widget.ui = *iter2++; 5429 } else { 5430 widget.ui = (unsigned int) *iter2++ * 65537; 5431 } 5432 } else { 5433 if (index_format) { 5434 widget.i = *iter2++; 5435 } else { 5436 widget.i = ((unsigned int) *iter2++ * 65537)/2; 5437 } 5438 } 5439 if (myswap_bytes) { 5440 iter[3] = widget.ub[0]; 5441 iter[2] = widget.ub[1]; 5442 iter[1] = widget.ub[2]; 5443 iter[0] = widget.ub[3]; 5444 } else { 5445 iter[0] = widget.ub[0]; 5446 iter[1] = widget.ub[1]; 5447 iter[2] = widget.ub[2]; 5448 iter[3] = widget.ub[3]; 5449 } 5450 break; 5451 } 5452 iter += element_size; 5453 } /* for j */ 5454 start += rowsize; 5455 #if 1 5456 /* want 'iter' pointing at start, not within, row for assertion 5457 * purposes 5458 */ 5459 iter= start; 5460 #endif 5461 } /* for i */ 5462 5463 /* iterators should be one byte past end */ 5464 if (!isTypePackedPixel(type)) { 5465 assert(iter2 == &oldimage[width*height*components]); 5466 } 5467 else { 5468 assert(iter2 == &oldimage[width*height* 5469 elements_per_group(format,0)]); 5470 } 5471 assert( iter == &((GLubyte *)userdata)[rowsize*height + 5472 psm->pack_skip_rows * rowsize + 5473 psm->pack_skip_pixels * group_size] ); 5474 5475 } /* else */ 5476 } /* empty_image() */ 5477 5478 /*-------------------------------------------------------------------------- 5479 * Decimation of packed pixel types 5480 *-------------------------------------------------------------------------- 5481 */ 5482 static void extract332(int isSwap, 5483 const void *packedPixel, GLfloat extractComponents[]) 5484 { 5485 GLubyte ubyte= *(const GLubyte *)packedPixel; 5486 5487 isSwap= isSwap; /* turn off warnings */ 5488 5489 /* 11100000 == 0xe0 */ 5490 /* 00011100 == 0x1c */ 5491 /* 00000011 == 0x03 */ 5492 5493 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0; 5494 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */ 5495 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */ 5496 } /* extract332() */ 5497 5498 static void shove332(const GLfloat shoveComponents[], 5499 int index, void *packedPixel) 5500 { 5501 /* 11100000 == 0xe0 */ 5502 /* 00011100 == 0x1c */ 5503 /* 00000011 == 0x03 */ 5504 5505 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5506 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5507 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5508 5509 /* due to limited precision, need to round before shoving */ 5510 ((GLubyte *)packedPixel)[index] = 5511 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0; 5512 ((GLubyte *)packedPixel)[index] |= 5513 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c; 5514 ((GLubyte *)packedPixel)[index] |= 5515 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03; 5516 } /* shove332() */ 5517 5518 static void extract233rev(int isSwap, 5519 const void *packedPixel, GLfloat extractComponents[]) 5520 { 5521 GLubyte ubyte= *(const GLubyte *)packedPixel; 5522 5523 isSwap= isSwap; /* turn off warnings */ 5524 5525 /* 0000,0111 == 0x07 */ 5526 /* 0011,1000 == 0x38 */ 5527 /* 1100,0000 == 0xC0 */ 5528 5529 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0; 5530 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0; 5531 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0; 5532 } /* extract233rev() */ 5533 5534 static void shove233rev(const GLfloat shoveComponents[], 5535 int index, void *packedPixel) 5536 { 5537 /* 0000,0111 == 0x07 */ 5538 /* 0011,1000 == 0x38 */ 5539 /* 1100,0000 == 0xC0 */ 5540 5541 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5542 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5543 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5544 5545 /* due to limited precision, need to round before shoving */ 5546 ((GLubyte *)packedPixel)[index] = 5547 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07; 5548 ((GLubyte *)packedPixel)[index]|= 5549 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38; 5550 ((GLubyte *)packedPixel)[index]|= 5551 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0; 5552 } /* shove233rev() */ 5553 5554 static void extract565(int isSwap, 5555 const void *packedPixel, GLfloat extractComponents[]) 5556 { 5557 GLushort ushort; 5558 5559 if (isSwap) { 5560 ushort= __GLU_SWAP_2_BYTES(packedPixel); 5561 } 5562 else { 5563 ushort= *(const GLushort *)packedPixel; 5564 } 5565 5566 /* 11111000,00000000 == 0xf800 */ 5567 /* 00000111,11100000 == 0x07e0 */ 5568 /* 00000000,00011111 == 0x001f */ 5569 5570 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ 5571 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/ 5572 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0; 5573 } /* extract565() */ 5574 5575 static void shove565(const GLfloat shoveComponents[], 5576 int index,void *packedPixel) 5577 { 5578 /* 11111000,00000000 == 0xf800 */ 5579 /* 00000111,11100000 == 0x07e0 */ 5580 /* 00000000,00011111 == 0x001f */ 5581 5582 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5583 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5584 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5585 5586 /* due to limited precision, need to round before shoving */ 5587 ((GLushort *)packedPixel)[index] = 5588 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; 5589 ((GLushort *)packedPixel)[index]|= 5590 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0; 5591 ((GLushort *)packedPixel)[index]|= 5592 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f; 5593 } /* shove565() */ 5594 5595 static void extract565rev(int isSwap, 5596 const void *packedPixel, GLfloat extractComponents[]) 5597 { 5598 GLushort ushort; 5599 5600 if (isSwap) { 5601 ushort= __GLU_SWAP_2_BYTES(packedPixel); 5602 } 5603 else { 5604 ushort= *(const GLushort *)packedPixel; 5605 } 5606 5607 /* 00000000,00011111 == 0x001f */ 5608 /* 00000111,11100000 == 0x07e0 */ 5609 /* 11111000,00000000 == 0xf800 */ 5610 5611 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; 5612 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0; 5613 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0; 5614 } /* extract565rev() */ 5615 5616 static void shove565rev(const GLfloat shoveComponents[], 5617 int index,void *packedPixel) 5618 { 5619 /* 00000000,00011111 == 0x001f */ 5620 /* 00000111,11100000 == 0x07e0 */ 5621 /* 11111000,00000000 == 0xf800 */ 5622 5623 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5624 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5625 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5626 5627 /* due to limited precision, need to round before shoving */ 5628 ((GLushort *)packedPixel)[index] = 5629 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F; 5630 ((GLushort *)packedPixel)[index]|= 5631 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0; 5632 ((GLushort *)packedPixel)[index]|= 5633 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800; 5634 } /* shove565rev() */ 5635 5636 static void extract4444(int isSwap,const void *packedPixel, 5637 GLfloat extractComponents[]) 5638 { 5639 GLushort ushort; 5640 5641 if (isSwap) { 5642 ushort= __GLU_SWAP_2_BYTES(packedPixel); 5643 } 5644 else { 5645 ushort= *(const GLushort *)packedPixel; 5646 } 5647 5648 /* 11110000,00000000 == 0xf000 */ 5649 /* 00001111,00000000 == 0x0f00 */ 5650 /* 00000000,11110000 == 0x00f0 */ 5651 /* 00000000,00001111 == 0x000f */ 5652 5653 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */ 5654 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0; 5655 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0; 5656 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0; 5657 } /* extract4444() */ 5658 5659 static void shove4444(const GLfloat shoveComponents[], 5660 int index,void *packedPixel) 5661 { 5662 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5663 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5664 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5665 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5666 5667 /* due to limited precision, need to round before shoving */ 5668 ((GLushort *)packedPixel)[index] = 5669 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000; 5670 ((GLushort *)packedPixel)[index]|= 5671 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00; 5672 ((GLushort *)packedPixel)[index]|= 5673 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0; 5674 ((GLushort *)packedPixel)[index]|= 5675 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f; 5676 } /* shove4444() */ 5677 5678 static void extract4444rev(int isSwap,const void *packedPixel, 5679 GLfloat extractComponents[]) 5680 { 5681 GLushort ushort; 5682 5683 if (isSwap) { 5684 ushort= __GLU_SWAP_2_BYTES(packedPixel); 5685 } 5686 else { 5687 ushort= *(const GLushort *)packedPixel; 5688 } 5689 5690 /* 00000000,00001111 == 0x000f */ 5691 /* 00000000,11110000 == 0x00f0 */ 5692 /* 00001111,00000000 == 0x0f00 */ 5693 /* 11110000,00000000 == 0xf000 */ 5694 5695 /* 15 = 2^4-1 */ 5696 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0; 5697 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0; 5698 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0; 5699 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0; 5700 } /* extract4444rev() */ 5701 5702 static void shove4444rev(const GLfloat shoveComponents[], 5703 int index,void *packedPixel) 5704 { 5705 /* 00000000,00001111 == 0x000f */ 5706 /* 00000000,11110000 == 0x00f0 */ 5707 /* 00001111,00000000 == 0x0f00 */ 5708 /* 11110000,00000000 == 0xf000 */ 5709 5710 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5711 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5712 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5713 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5714 5715 /* due to limited precision, need to round before shoving */ 5716 ((GLushort *)packedPixel)[index] = 5717 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F; 5718 ((GLushort *)packedPixel)[index]|= 5719 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0; 5720 ((GLushort *)packedPixel)[index]|= 5721 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00; 5722 ((GLushort *)packedPixel)[index]|= 5723 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000; 5724 } /* shove4444rev() */ 5725 5726 static void extract5551(int isSwap,const void *packedPixel, 5727 GLfloat extractComponents[]) 5728 { 5729 GLushort ushort; 5730 5731 if (isSwap) { 5732 ushort= __GLU_SWAP_2_BYTES(packedPixel); 5733 } 5734 else { 5735 ushort= *(const GLushort *)packedPixel; 5736 } 5737 5738 /* 11111000,00000000 == 0xf800 */ 5739 /* 00000111,11000000 == 0x07c0 */ 5740 /* 00000000,00111110 == 0x003e */ 5741 /* 00000000,00000001 == 0x0001 */ 5742 5743 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ 5744 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0; 5745 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0; 5746 extractComponents[3]=(float)((ushort & 0x0001) ); 5747 } /* extract5551() */ 5748 5749 static void shove5551(const GLfloat shoveComponents[], 5750 int index,void *packedPixel) 5751 { 5752 /* 11111000,00000000 == 0xf800 */ 5753 /* 00000111,11000000 == 0x07c0 */ 5754 /* 00000000,00111110 == 0x003e */ 5755 /* 00000000,00000001 == 0x0001 */ 5756 5757 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5758 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5759 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5760 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5761 5762 /* due to limited precision, need to round before shoving */ 5763 ((GLushort *)packedPixel)[index] = 5764 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; 5765 ((GLushort *)packedPixel)[index]|= 5766 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0; 5767 ((GLushort *)packedPixel)[index]|= 5768 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e; 5769 ((GLushort *)packedPixel)[index]|= 5770 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001; 5771 } /* shove5551() */ 5772 5773 static void extract1555rev(int isSwap,const void *packedPixel, 5774 GLfloat extractComponents[]) 5775 { 5776 GLushort ushort; 5777 5778 if (isSwap) { 5779 ushort= __GLU_SWAP_2_BYTES(packedPixel); 5780 } 5781 else { 5782 ushort= *(const GLushort *)packedPixel; 5783 } 5784 5785 /* 00000000,00011111 == 0x001F */ 5786 /* 00000011,11100000 == 0x03E0 */ 5787 /* 01111100,00000000 == 0x7C00 */ 5788 /* 10000000,00000000 == 0x8000 */ 5789 5790 /* 31 = 2^5-1 */ 5791 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; 5792 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0; 5793 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0; 5794 extractComponents[3]= (float)((ushort & 0x8000) >> 15); 5795 } /* extract1555rev() */ 5796 5797 static void shove1555rev(const GLfloat shoveComponents[], 5798 int index,void *packedPixel) 5799 { 5800 /* 00000000,00011111 == 0x001F */ 5801 /* 00000011,11100000 == 0x03E0 */ 5802 /* 01111100,00000000 == 0x7C00 */ 5803 /* 10000000,00000000 == 0x8000 */ 5804 5805 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5806 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5807 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5808 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5809 5810 /* due to limited precision, need to round before shoving */ 5811 ((GLushort *)packedPixel)[index] = 5812 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F; 5813 ((GLushort *)packedPixel)[index]|= 5814 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0; 5815 ((GLushort *)packedPixel)[index]|= 5816 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00; 5817 ((GLushort *)packedPixel)[index]|= 5818 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000; 5819 } /* shove1555rev() */ 5820 5821 static void extract8888(int isSwap, 5822 const void *packedPixel, GLfloat extractComponents[]) 5823 { 5824 GLuint uint; 5825 5826 if (isSwap) { 5827 uint= __GLU_SWAP_4_BYTES(packedPixel); 5828 } 5829 else { 5830 uint= *(const GLuint *)packedPixel; 5831 } 5832 5833 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 5834 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 5835 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 5836 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 5837 5838 /* 255 = 2^8-1 */ 5839 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0; 5840 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0; 5841 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0; 5842 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0; 5843 } /* extract8888() */ 5844 5845 static void shove8888(const GLfloat shoveComponents[], 5846 int index,void *packedPixel) 5847 { 5848 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 5849 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 5850 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 5851 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 5852 5853 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5854 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5855 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5856 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5857 5858 /* due to limited precision, need to round before shoving */ 5859 ((GLuint *)packedPixel)[index] = 5860 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000; 5861 ((GLuint *)packedPixel)[index]|= 5862 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000; 5863 ((GLuint *)packedPixel)[index]|= 5864 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00; 5865 ((GLuint *)packedPixel)[index]|= 5866 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff; 5867 } /* shove8888() */ 5868 5869 static void extract8888rev(int isSwap, 5870 const void *packedPixel,GLfloat extractComponents[]) 5871 { 5872 GLuint uint; 5873 5874 if (isSwap) { 5875 uint= __GLU_SWAP_4_BYTES(packedPixel); 5876 } 5877 else { 5878 uint= *(const GLuint *)packedPixel; 5879 } 5880 5881 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 5882 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 5883 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 5884 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 5885 5886 /* 255 = 2^8-1 */ 5887 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0; 5888 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0; 5889 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0; 5890 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0; 5891 } /* extract8888rev() */ 5892 5893 static void shove8888rev(const GLfloat shoveComponents[], 5894 int index,void *packedPixel) 5895 { 5896 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 5897 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 5898 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 5899 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 5900 5901 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5902 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5903 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5904 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5905 5906 /* due to limited precision, need to round before shoving */ 5907 ((GLuint *)packedPixel)[index] = 5908 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF; 5909 ((GLuint *)packedPixel)[index]|= 5910 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00; 5911 ((GLuint *)packedPixel)[index]|= 5912 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000; 5913 ((GLuint *)packedPixel)[index]|= 5914 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000; 5915 } /* shove8888rev() */ 5916 5917 static void extract1010102(int isSwap, 5918 const void *packedPixel,GLfloat extractComponents[]) 5919 { 5920 GLuint uint; 5921 5922 if (isSwap) { 5923 uint= __GLU_SWAP_4_BYTES(packedPixel); 5924 } 5925 else { 5926 uint= *(const GLuint *)packedPixel; 5927 } 5928 5929 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ 5930 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ 5931 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ 5932 /* 00000000,00000000,00000000,00000011 == 0x00000003 */ 5933 5934 /* 1023 = 2^10-1 */ 5935 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0; 5936 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0; 5937 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0; 5938 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0; 5939 } /* extract1010102() */ 5940 5941 static void shove1010102(const GLfloat shoveComponents[], 5942 int index,void *packedPixel) 5943 { 5944 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ 5945 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ 5946 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ 5947 /* 00000000,00000000,00000000,00000011 == 0x00000003 */ 5948 5949 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 5950 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 5951 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 5952 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 5953 5954 /* due to limited precision, need to round before shoving */ 5955 ((GLuint *)packedPixel)[index] = 5956 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000; 5957 ((GLuint *)packedPixel)[index]|= 5958 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000; 5959 ((GLuint *)packedPixel)[index]|= 5960 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc; 5961 ((GLuint *)packedPixel)[index]|= 5962 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003; 5963 } /* shove1010102() */ 5964 5965 static void extract2101010rev(int isSwap, 5966 const void *packedPixel, 5967 GLfloat extractComponents[]) 5968 { 5969 GLuint uint; 5970 5971 if (isSwap) { 5972 uint= __GLU_SWAP_4_BYTES(packedPixel); 5973 } 5974 else { 5975 uint= *(const GLuint *)packedPixel; 5976 } 5977 5978 /* 00000000,00000000,00000011,11111111 == 0x000003FF */ 5979 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ 5980 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ 5981 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ 5982 5983 /* 1023 = 2^10-1 */ 5984 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0; 5985 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0; 5986 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0; 5987 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0; 5988 /* 3 = 2^2-1 */ 5989 } /* extract2101010rev() */ 5990 5991 static void shove2101010rev(const GLfloat shoveComponents[], 5992 int index,void *packedPixel) 5993 { 5994 /* 00000000,00000000,00000011,11111111 == 0x000003FF */ 5995 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ 5996 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ 5997 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ 5998 5999 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 6000 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 6001 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 6002 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 6003 6004 /* due to limited precision, need to round before shoving */ 6005 ((GLuint *)packedPixel)[index] = 6006 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF; 6007 ((GLuint *)packedPixel)[index]|= 6008 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00; 6009 ((GLuint *)packedPixel)[index]|= 6010 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000; 6011 ((GLuint *)packedPixel)[index]|= 6012 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000; 6013 } /* shove2101010rev() */ 6014 6015 static void scaleInternalPackedPixel(int components, 6016 void (*extractPackedPixel) 6017 (int, const void *,GLfloat []), 6018 void (*shovePackedPixel) 6019 (const GLfloat [], int, void *), 6020 GLint widthIn,GLint heightIn, 6021 const void *dataIn, 6022 GLint widthOut,GLint heightOut, 6023 void *dataOut, 6024 GLint pixelSizeInBytes, 6025 GLint rowSizeInBytes,GLint isSwap) 6026 { 6027 float convx; 6028 float convy; 6029 float percent; 6030 6031 /* Max components in a format is 4, so... */ 6032 float totals[4]; 6033 float extractTotals[4], extractMoreTotals[4], shoveTotals[4]; 6034 6035 float area; 6036 int i,j,k,xindex; 6037 6038 const char *temp, *temp0; 6039 int outindex; 6040 6041 int lowx_int, highx_int, lowy_int, highy_int; 6042 float x_percent, y_percent; 6043 float lowx_float, highx_float, lowy_float, highy_float; 6044 float convy_float, convx_float; 6045 int convy_int, convx_int; 6046 int l, m; 6047 const char *left, *right; 6048 6049 if (widthIn == widthOut*2 && heightIn == heightOut*2) { 6050 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, 6051 widthIn, heightIn, dataIn, dataOut, 6052 pixelSizeInBytes,rowSizeInBytes,isSwap); 6053 return; 6054 } 6055 convy = (float) heightIn/heightOut; 6056 convx = (float) widthIn/widthOut; 6057 convy_int = floor(convy); 6058 convy_float = convy - convy_int; 6059 convx_int = floor(convx); 6060 convx_float = convx - convx_int; 6061 6062 area = convx * convy; 6063 6064 lowy_int = 0; 6065 lowy_float = 0; 6066 highy_int = convy_int; 6067 highy_float = convy_float; 6068 6069 for (i = 0; i < heightOut; i++) { 6070 lowx_int = 0; 6071 lowx_float = 0; 6072 highx_int = convx_int; 6073 highx_float = convx_float; 6074 6075 for (j = 0; j < widthOut; j++) { 6076 /* 6077 ** Ok, now apply box filter to box that goes from (lowx, lowy) 6078 ** to (highx, highy) on input data into this pixel on output 6079 ** data. 6080 */ 6081 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 6082 6083 /* calculate the value for pixels in the 1st row */ 6084 xindex = lowx_int*pixelSizeInBytes; 6085 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 6086 6087 y_percent = 1-lowy_float; 6088 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; 6089 percent = y_percent * (1-lowx_float); 6090 #if 0 6091 for (k = 0, temp_index = temp; k < components; 6092 k++, temp_index += element_size) { 6093 if (myswap_bytes) { 6094 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6095 } else { 6096 totals[k] += *(const GLushort*)temp_index * percent; 6097 } 6098 } 6099 #else 6100 (*extractPackedPixel)(isSwap,temp,extractTotals); 6101 for (k = 0; k < components; k++) { 6102 totals[k]+= extractTotals[k] * percent; 6103 } 6104 #endif 6105 left = temp; 6106 for(l = lowx_int+1; l < highx_int; l++) { 6107 temp += pixelSizeInBytes; 6108 #if 0 6109 for (k = 0, temp_index = temp; k < components; 6110 k++, temp_index += element_size) { 6111 if (myswap_bytes) { 6112 totals[k] += 6113 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 6114 } else { 6115 totals[k] += *(const GLushort*)temp_index * y_percent; 6116 } 6117 } 6118 #else 6119 (*extractPackedPixel)(isSwap,temp,extractTotals); 6120 for (k = 0; k < components; k++) { 6121 totals[k]+= extractTotals[k] * y_percent; 6122 } 6123 #endif 6124 } 6125 temp += pixelSizeInBytes; 6126 right = temp; 6127 percent = y_percent * highx_float; 6128 #if 0 6129 for (k = 0, temp_index = temp; k < components; 6130 k++, temp_index += element_size) { 6131 if (myswap_bytes) { 6132 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6133 } else { 6134 totals[k] += *(const GLushort*)temp_index * percent; 6135 } 6136 } 6137 #else 6138 (*extractPackedPixel)(isSwap,temp,extractTotals); 6139 for (k = 0; k < components; k++) { 6140 totals[k]+= extractTotals[k] * percent; 6141 } 6142 #endif 6143 6144 /* calculate the value for pixels in the last row */ 6145 6146 y_percent = highy_float; 6147 percent = y_percent * (1-lowx_float); 6148 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes; 6149 #if 0 6150 for (k = 0, temp_index = temp; k < components; 6151 k++, temp_index += element_size) { 6152 if (myswap_bytes) { 6153 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6154 } else { 6155 totals[k] += *(const GLushort*)temp_index * percent; 6156 } 6157 } 6158 #else 6159 (*extractPackedPixel)(isSwap,temp,extractTotals); 6160 for (k = 0; k < components; k++) { 6161 totals[k]+= extractTotals[k] * percent; 6162 } 6163 #endif 6164 for(l = lowx_int+1; l < highx_int; l++) { 6165 temp += pixelSizeInBytes; 6166 #if 0 6167 for (k = 0, temp_index = temp; k < components; 6168 k++, temp_index += element_size) { 6169 if (myswap_bytes) { 6170 totals[k] += 6171 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 6172 } else { 6173 totals[k] += *(const GLushort*)temp_index * y_percent; 6174 } 6175 } 6176 #else 6177 (*extractPackedPixel)(isSwap,temp,extractTotals); 6178 for (k = 0; k < components; k++) { 6179 totals[k]+= extractTotals[k] * y_percent; 6180 } 6181 #endif 6182 6183 } 6184 temp += pixelSizeInBytes; 6185 percent = y_percent * highx_float; 6186 #if 0 6187 for (k = 0, temp_index = temp; k < components; 6188 k++, temp_index += element_size) { 6189 if (myswap_bytes) { 6190 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6191 } else { 6192 totals[k] += *(const GLushort*)temp_index * percent; 6193 } 6194 } 6195 #else 6196 (*extractPackedPixel)(isSwap,temp,extractTotals); 6197 for (k = 0; k < components; k++) { 6198 totals[k]+= extractTotals[k] * percent; 6199 } 6200 #endif 6201 6202 /* calculate the value for pixels in the 1st and last column */ 6203 for(m = lowy_int+1; m < highy_int; m++) { 6204 left += rowSizeInBytes; 6205 right += rowSizeInBytes; 6206 #if 0 6207 for (k = 0; k < components; 6208 k++, left += element_size, right += element_size) { 6209 if (myswap_bytes) { 6210 totals[k] += 6211 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + 6212 __GLU_SWAP_2_BYTES(right) * highx_float; 6213 } else { 6214 totals[k] += *(const GLushort*)left * (1-lowx_float) 6215 + *(const GLushort*)right * highx_float; 6216 } 6217 } 6218 #else 6219 (*extractPackedPixel)(isSwap,left,extractTotals); 6220 (*extractPackedPixel)(isSwap,right,extractMoreTotals); 6221 for (k = 0; k < components; k++) { 6222 totals[k]+= (extractTotals[k]*(1-lowx_float) + 6223 extractMoreTotals[k]*highx_float); 6224 } 6225 #endif 6226 } 6227 } else if (highy_int > lowy_int) { 6228 x_percent = highx_float - lowx_float; 6229 percent = (1-lowy_float)*x_percent; 6230 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; 6231 #if 0 6232 for (k = 0, temp_index = temp; k < components; 6233 k++, temp_index += element_size) { 6234 if (myswap_bytes) { 6235 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6236 } else { 6237 totals[k] += *(const GLushort*)temp_index * percent; 6238 } 6239 } 6240 #else 6241 (*extractPackedPixel)(isSwap,temp,extractTotals); 6242 for (k = 0; k < components; k++) { 6243 totals[k]+= extractTotals[k] * percent; 6244 } 6245 #endif 6246 for(m = lowy_int+1; m < highy_int; m++) { 6247 temp += rowSizeInBytes; 6248 #if 0 6249 for (k = 0, temp_index = temp; k < components; 6250 k++, temp_index += element_size) { 6251 if (myswap_bytes) { 6252 totals[k] += 6253 __GLU_SWAP_2_BYTES(temp_index) * x_percent; 6254 } else { 6255 totals[k] += *(const GLushort*)temp_index * x_percent; 6256 } 6257 } 6258 #else 6259 (*extractPackedPixel)(isSwap,temp,extractTotals); 6260 for (k = 0; k < components; k++) { 6261 totals[k]+= extractTotals[k] * x_percent; 6262 } 6263 #endif 6264 } 6265 percent = x_percent * highy_float; 6266 temp += rowSizeInBytes; 6267 #if 0 6268 for (k = 0, temp_index = temp; k < components; 6269 k++, temp_index += element_size) { 6270 if (myswap_bytes) { 6271 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6272 } else { 6273 totals[k] += *(const GLushort*)temp_index * percent; 6274 } 6275 } 6276 #else 6277 (*extractPackedPixel)(isSwap,temp,extractTotals); 6278 for (k = 0; k < components; k++) { 6279 totals[k]+= extractTotals[k] * percent; 6280 } 6281 #endif 6282 } else if (highx_int > lowx_int) { 6283 y_percent = highy_float - lowy_float; 6284 percent = (1-lowx_float)*y_percent; 6285 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; 6286 #if 0 6287 for (k = 0, temp_index = temp; k < components; 6288 k++, temp_index += element_size) { 6289 if (myswap_bytes) { 6290 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6291 } else { 6292 totals[k] += *(const GLushort*)temp_index * percent; 6293 } 6294 } 6295 #else 6296 (*extractPackedPixel)(isSwap,temp,extractTotals); 6297 for (k = 0; k < components; k++) { 6298 totals[k]+= extractTotals[k] * percent; 6299 } 6300 #endif 6301 for (l = lowx_int+1; l < highx_int; l++) { 6302 temp += pixelSizeInBytes; 6303 #if 0 6304 for (k = 0, temp_index = temp; k < components; 6305 k++, temp_index += element_size) { 6306 if (myswap_bytes) { 6307 totals[k] += 6308 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 6309 } else { 6310 totals[k] += *(const GLushort*)temp_index * y_percent; 6311 } 6312 } 6313 #else 6314 (*extractPackedPixel)(isSwap,temp,extractTotals); 6315 for (k = 0; k < components; k++) { 6316 totals[k]+= extractTotals[k] * y_percent; 6317 } 6318 #endif 6319 } 6320 temp += pixelSizeInBytes; 6321 percent = y_percent * highx_float; 6322 #if 0 6323 for (k = 0, temp_index = temp; k < components; 6324 k++, temp_index += element_size) { 6325 if (myswap_bytes) { 6326 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6327 } else { 6328 totals[k] += *(const GLushort*)temp_index * percent; 6329 } 6330 } 6331 #else 6332 (*extractPackedPixel)(isSwap,temp,extractTotals); 6333 for (k = 0; k < components; k++) { 6334 totals[k]+= extractTotals[k] * percent; 6335 } 6336 #endif 6337 } else { 6338 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 6339 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; 6340 #if 0 6341 for (k = 0, temp_index = temp; k < components; 6342 k++, temp_index += element_size) { 6343 if (myswap_bytes) { 6344 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 6345 } else { 6346 totals[k] += *(const GLushort*)temp_index * percent; 6347 } 6348 } 6349 #else 6350 (*extractPackedPixel)(isSwap,temp,extractTotals); 6351 for (k = 0; k < components; k++) { 6352 totals[k]+= extractTotals[k] * percent; 6353 } 6354 #endif 6355 } 6356 6357 /* this is for the pixels in the body */ 6358 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes; 6359 for (m = lowy_int+1; m < highy_int; m++) { 6360 temp = temp0; 6361 for(l = lowx_int+1; l < highx_int; l++) { 6362 #if 0 6363 for (k = 0, temp_index = temp; k < components; 6364 k++, temp_index += element_size) { 6365 if (myswap_bytes) { 6366 totals[k] += __GLU_SWAP_2_BYTES(temp_index); 6367 } else { 6368 totals[k] += *(const GLushort*)temp_index; 6369 } 6370 } 6371 #else 6372 (*extractPackedPixel)(isSwap,temp,extractTotals); 6373 for (k = 0; k < components; k++) { 6374 totals[k]+= extractTotals[k]; 6375 } 6376 #endif 6377 temp += pixelSizeInBytes; 6378 } 6379 temp0 += rowSizeInBytes; 6380 } 6381 6382 outindex = (j + (i * widthOut)); /* * (components == 1) */ 6383 #if 0 6384 for (k = 0; k < components; k++) { 6385 dataout[outindex + k] = totals[k]/area; 6386 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 6387 } 6388 #else 6389 for (k = 0; k < components; k++) { 6390 shoveTotals[k]= totals[k]/area; 6391 } 6392 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut); 6393 #endif 6394 lowx_int = highx_int; 6395 lowx_float = highx_float; 6396 highx_int += convx_int; 6397 highx_float += convx_float; 6398 if(highx_float > 1) { 6399 highx_float -= 1.0; 6400 highx_int++; 6401 } 6402 } 6403 lowy_int = highy_int; 6404 lowy_float = highy_float; 6405 highy_int += convy_int; 6406 highy_float += convy_float; 6407 if(highy_float > 1) { 6408 highy_float -= 1.0; 6409 highy_int++; 6410 } 6411 } 6412 6413 assert(outindex == (widthOut*heightOut - 1)); 6414 } /* scaleInternalPackedPixel() */ 6415 6416 /* rowSizeInBytes is at least the width (in bytes) due to padding on 6417 * inputs; not always equal. Output NEVER has row padding. 6418 */ 6419 static void halveImagePackedPixel(int components, 6420 void (*extractPackedPixel) 6421 (int, const void *,GLfloat []), 6422 void (*shovePackedPixel) 6423 (const GLfloat [],int, void *), 6424 GLint width, GLint height, 6425 const void *dataIn, void *dataOut, 6426 GLint pixelSizeInBytes, 6427 GLint rowSizeInBytes, GLint isSwap) 6428 { 6429 /* handle case where there is only 1 column/row */ 6430 if (width == 1 || height == 1) { 6431 assert(!(width == 1 && height == 1)); /* can't be 1x1 */ 6432 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel, 6433 width,height,dataIn,dataOut,pixelSizeInBytes, 6434 rowSizeInBytes,isSwap); 6435 return; 6436 } 6437 6438 { 6439 int ii, jj; 6440 6441 int halfWidth= width / 2; 6442 int halfHeight= height / 2; 6443 const char *src= (const char *) dataIn; 6444 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); 6445 int outIndex= 0; 6446 6447 for (ii= 0; ii< halfHeight; ii++) { 6448 for (jj= 0; jj< halfWidth; jj++) { 6449 #define BOX4 4 6450 float totals[4]; /* 4 is maximum components */ 6451 float extractTotals[BOX4][4]; /* 4 is maximum components */ 6452 int cc; 6453 6454 (*extractPackedPixel)(isSwap,src, 6455 &extractTotals[0][0]); 6456 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 6457 &extractTotals[1][0]); 6458 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 6459 &extractTotals[2][0]); 6460 (*extractPackedPixel)(isSwap, 6461 (src+rowSizeInBytes+pixelSizeInBytes), 6462 &extractTotals[3][0]); 6463 for (cc = 0; cc < components; cc++) { 6464 int kk; 6465 6466 /* grab 4 pixels to average */ 6467 totals[cc]= 0.0; 6468 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 6469 * extractTotals[2][RED]+extractTotals[3][RED]; 6470 * totals[RED]/= 4.0; 6471 */ 6472 for (kk = 0; kk < BOX4; kk++) { 6473 totals[cc]+= extractTotals[kk][cc]; 6474 } 6475 totals[cc]/= (float)BOX4; 6476 } 6477 (*shovePackedPixel)(totals,outIndex,dataOut); 6478 6479 outIndex++; 6480 /* skip over to next square of 4 */ 6481 src+= pixelSizeInBytes + pixelSizeInBytes; 6482 } 6483 /* skip past pad bytes, if any, to get to next row */ 6484 src+= padBytes; 6485 6486 /* src is at beginning of a row here, but it's the second row of 6487 * the square block of 4 pixels that we just worked on so we 6488 * need to go one more row. 6489 * i.e., 6490 * OO... 6491 * here -->OO... 6492 * but want -->OO... 6493 * OO... 6494 * ... 6495 */ 6496 src+= rowSizeInBytes; 6497 } 6498 6499 /* both pointers must reach one byte after the end */ 6500 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); 6501 assert(outIndex == halfWidth * halfHeight); 6502 } 6503 } /* halveImagePackedPixel() */ 6504 6505 static void halve1DimagePackedPixel(int components, 6506 void (*extractPackedPixel) 6507 (int, const void *,GLfloat []), 6508 void (*shovePackedPixel) 6509 (const GLfloat [],int, void *), 6510 GLint width, GLint height, 6511 const void *dataIn, void *dataOut, 6512 GLint pixelSizeInBytes, 6513 GLint rowSizeInBytes, GLint isSwap) 6514 { 6515 int halfWidth= width / 2; 6516 int halfHeight= height / 2; 6517 const char *src= (const char *) dataIn; 6518 int jj; 6519 6520 assert(width == 1 || height == 1); /* must be 1D */ 6521 assert(width != height); /* can't be square */ 6522 6523 if (height == 1) { /* 1 row */ 6524 int outIndex= 0; 6525 6526 assert(width != 1); /* widthxheight can't be 1x1 */ 6527 halfHeight= 1; 6528 6529 /* one horizontal row with possible pad bytes */ 6530 6531 for (jj= 0; jj< halfWidth; jj++) { 6532 #define BOX2 2 6533 float totals[4]; /* 4 is maximum components */ 6534 float extractTotals[BOX2][4]; /* 4 is maximum components */ 6535 int cc; 6536 6537 /* average two at a time, instead of four */ 6538 (*extractPackedPixel)(isSwap,src, 6539 &extractTotals[0][0]); 6540 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 6541 &extractTotals[1][0]); 6542 for (cc = 0; cc < components; cc++) { 6543 int kk; 6544 6545 /* grab 2 pixels to average */ 6546 totals[cc]= 0.0; 6547 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 6548 * totals[RED]/= 2.0; 6549 */ 6550 for (kk = 0; kk < BOX2; kk++) { 6551 totals[cc]+= extractTotals[kk][cc]; 6552 } 6553 totals[cc]/= (float)BOX2; 6554 } 6555 (*shovePackedPixel)(totals,outIndex,dataOut); 6556 6557 outIndex++; 6558 /* skip over to next group of 2 */ 6559 src+= pixelSizeInBytes + pixelSizeInBytes; 6560 } 6561 6562 { 6563 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); 6564 src+= padBytes; /* for assertion only */ 6565 } 6566 assert(src == &((const char *)dataIn)[rowSizeInBytes]); 6567 assert(outIndex == halfWidth * halfHeight); 6568 } 6569 else if (width == 1) { /* 1 column */ 6570 int outIndex= 0; 6571 6572 assert(height != 1); /* widthxheight can't be 1x1 */ 6573 halfWidth= 1; 6574 /* one vertical column with possible pad bytes per row */ 6575 /* average two at a time */ 6576 6577 for (jj= 0; jj< halfHeight; jj++) { 6578 #define BOX2 2 6579 float totals[4]; /* 4 is maximum components */ 6580 float extractTotals[BOX2][4]; /* 4 is maximum components */ 6581 int cc; 6582 6583 /* average two at a time, instead of four */ 6584 (*extractPackedPixel)(isSwap,src, 6585 &extractTotals[0][0]); 6586 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 6587 &extractTotals[1][0]); 6588 for (cc = 0; cc < components; cc++) { 6589 int kk; 6590 6591 /* grab 2 pixels to average */ 6592 totals[cc]= 0.0; 6593 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 6594 * totals[RED]/= 2.0; 6595 */ 6596 for (kk = 0; kk < BOX2; kk++) { 6597 totals[cc]+= extractTotals[kk][cc]; 6598 } 6599 totals[cc]/= (float)BOX2; 6600 } 6601 (*shovePackedPixel)(totals,outIndex,dataOut); 6602 6603 outIndex++; 6604 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */ 6605 } 6606 6607 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); 6608 assert(outIndex == halfWidth * halfHeight); 6609 } 6610 } /* halve1DimagePackedPixel() */ 6611 6612 /*===========================================================================*/ 6613 6614 #ifdef RESOLVE_3D_TEXTURE_SUPPORT 6615 /* 6616 * This section ensures that GLU 1.3 will load and run on 6617 * a GL 1.1 implementation. It dynamically resolves the 6618 * call to glTexImage3D() which might not be available. 6619 * Or is it might be supported as an extension. 6620 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>. 6621 */ 6622 6623 typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level, 6624 GLenum internalFormat, 6625 GLsizei width, GLsizei height, 6626 GLsizei depth, GLint border, 6627 GLenum format, GLenum type, 6628 const GLvoid *pixels ); 6629 6630 static TexImage3Dproc pTexImage3D = 0; 6631 6632 #if !defined(_WIN32) && !defined(__WIN32__) 6633 # include <dlfcn.h> 6634 # include <sys/types.h> 6635 #else 6636 WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); 6637 #endif 6638 6639 static void gluTexImage3D( GLenum target, GLint level, 6640 GLenum internalFormat, 6641 GLsizei width, GLsizei height, 6642 GLsizei depth, GLint border, 6643 GLenum format, GLenum type, 6644 const GLvoid *pixels ) 6645 { 6646 if (!pTexImage3D) { 6647 #if defined(_WIN32) || defined(__WIN32__) 6648 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D"); 6649 if (!pTexImage3D) 6650 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT"); 6651 #else 6652 void *libHandle = dlopen("libgl.so", RTLD_LAZY); 6653 pTexImage3D = (TexImage3Dproc) dlsym(libHandle, "glTexImage3D" ); 6654 if (!pTexImage3D) 6655 pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT"); 6656 dlclose(libHandle); 6657 #endif 6658 } 6659 6660 /* Now call glTexImage3D */ 6661 if (pTexImage3D) 6662 pTexImage3D(target, level, internalFormat, width, height, 6663 depth, border, format, type, pixels); 6664 } 6665 6666 #else 6667 6668 /* Only bind to a GL 1.2 implementation: */ 6669 #define gluTexImage3D glTexImage3D 6670 6671 #endif 6672 6673 static GLint imageSize3D(GLint width, GLint height, GLint depth, 6674 GLenum format, GLenum type) 6675 { 6676 int components= elements_per_group(format,type); 6677 int bytes_per_row= bytes_per_element(type) * width; 6678 6679 assert(width > 0 && height > 0 && depth > 0); 6680 assert(type != GL_BITMAP); 6681 6682 return bytes_per_row * height * depth * components; 6683 } /* imageSize3D() */ 6684 6685 static void fillImage3D(const PixelStorageModes *psm, 6686 GLint width, GLint height, GLint depth, GLenum format, 6687 GLenum type, GLboolean indexFormat, 6688 const void *userImage, GLushort *newImage) 6689 { 6690 int myswapBytes; 6691 int components; 6692 int groupsPerLine; 6693 int elementSize; 6694 int groupSize; 6695 int rowSize; 6696 int padding; 6697 int elementsPerLine; 6698 int rowsPerImage; 6699 int imageSize; 6700 const GLubyte *start, *rowStart, *iter; 6701 GLushort *iter2; 6702 int ww, hh, dd, k; 6703 6704 myswapBytes= psm->unpack_swap_bytes; 6705 components= elements_per_group(format,type); 6706 if (psm->unpack_row_length > 0) { 6707 groupsPerLine= psm->unpack_row_length; 6708 } 6709 else { 6710 groupsPerLine= width; 6711 } 6712 elementSize= bytes_per_element(type); 6713 groupSize= elementSize * components; 6714 if (elementSize == 1) myswapBytes= 0; 6715 6716 /* 3dstuff begin */ 6717 if (psm->unpack_image_height > 0) { 6718 rowsPerImage= psm->unpack_image_height; 6719 } 6720 else { 6721 rowsPerImage= height; 6722 } 6723 /* 3dstuff end */ 6724 6725 rowSize= groupsPerLine * groupSize; 6726 padding= rowSize % psm->unpack_alignment; 6727 if (padding) { 6728 rowSize+= psm->unpack_alignment - padding; 6729 } 6730 6731 imageSize= rowsPerImage * rowSize; /* 3dstuff */ 6732 6733 start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize + 6734 psm->unpack_skip_pixels * groupSize + 6735 /*3dstuff*/ 6736 psm->unpack_skip_images * imageSize; 6737 elementsPerLine = width * components; 6738 6739 iter2= newImage; 6740 for (dd= 0; dd < depth; dd++) { 6741 rowStart= start; 6742 6743 for (hh= 0; hh < height; hh++) { 6744 iter= rowStart; 6745 6746 for (ww= 0; ww < elementsPerLine; ww++) { 6747 Type_Widget widget; 6748 float extractComponents[4]; 6749 6750 switch(type) { 6751 case GL_UNSIGNED_BYTE: 6752 if (indexFormat) { 6753 *iter2++ = *iter; 6754 } else { 6755 *iter2++ = (*iter) * 257; 6756 } 6757 break; 6758 case GL_BYTE: 6759 if (indexFormat) { 6760 *iter2++ = *((const GLbyte *) iter); 6761 } else { 6762 /* rough approx */ 6763 *iter2++ = (*((const GLbyte *) iter)) * 516; 6764 } 6765 break; 6766 case GL_UNSIGNED_BYTE_3_3_2: 6767 extract332(0,iter,extractComponents); 6768 for (k = 0; k < 3; k++) { 6769 *iter2++ = (GLushort)(extractComponents[k]*65535); 6770 } 6771 break; 6772 case GL_UNSIGNED_BYTE_2_3_3_REV: 6773 extract233rev(0,iter,extractComponents); 6774 for (k = 0; k < 3; k++) { 6775 *iter2++ = (GLushort)(extractComponents[k]*65535); 6776 } 6777 break; 6778 case GL_UNSIGNED_SHORT_5_6_5: 6779 extract565(myswapBytes,iter,extractComponents); 6780 for (k = 0; k < 3; k++) { 6781 *iter2++ = (GLushort)(extractComponents[k]*65535); 6782 } 6783 break; 6784 case GL_UNSIGNED_SHORT_5_6_5_REV: 6785 extract565rev(myswapBytes,iter,extractComponents); 6786 for (k = 0; k < 3; k++) { 6787 *iter2++ = (GLushort)(extractComponents[k]*65535); 6788 } 6789 break; 6790 case GL_UNSIGNED_SHORT_4_4_4_4: 6791 extract4444(myswapBytes,iter,extractComponents); 6792 for (k = 0; k < 4; k++) { 6793 *iter2++ = (GLushort)(extractComponents[k]*65535); 6794 } 6795 break; 6796 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 6797 extract4444rev(myswapBytes,iter,extractComponents); 6798 for (k = 0; k < 4; k++) { 6799 *iter2++ = (GLushort)(extractComponents[k]*65535); 6800 } 6801 break; 6802 case GL_UNSIGNED_SHORT_5_5_5_1: 6803 extract5551(myswapBytes,iter,extractComponents); 6804 for (k = 0; k < 4; k++) { 6805 *iter2++ = (GLushort)(extractComponents[k]*65535); 6806 } 6807 break; 6808 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 6809 extract1555rev(myswapBytes,iter,extractComponents); 6810 for (k = 0; k < 4; k++) { 6811 *iter2++ = (GLushort)(extractComponents[k]*65535); 6812 } 6813 break; 6814 case GL_UNSIGNED_SHORT: 6815 case GL_SHORT: 6816 if (myswapBytes) { 6817 widget.ub[0] = iter[1]; 6818 widget.ub[1] = iter[0]; 6819 } else { 6820 widget.ub[0] = iter[0]; 6821 widget.ub[1] = iter[1]; 6822 } 6823 if (type == GL_SHORT) { 6824 if (indexFormat) { 6825 *iter2++ = widget.s[0]; 6826 } else { 6827 /* rough approx */ 6828 *iter2++ = widget.s[0]*2; 6829 } 6830 } else { 6831 *iter2++ = widget.us[0]; 6832 } 6833 break; 6834 case GL_UNSIGNED_INT_8_8_8_8: 6835 extract8888(myswapBytes,iter,extractComponents); 6836 for (k = 0; k < 4; k++) { 6837 *iter2++ = (GLushort)(extractComponents[k]*65535); 6838 } 6839 break; 6840 case GL_UNSIGNED_INT_8_8_8_8_REV: 6841 extract8888rev(myswapBytes,iter,extractComponents); 6842 for (k = 0; k < 4; k++) { 6843 *iter2++ = (GLushort)(extractComponents[k]*65535); 6844 } 6845 break; 6846 case GL_UNSIGNED_INT_10_10_10_2: 6847 extract1010102(myswapBytes,iter,extractComponents); 6848 for (k = 0; k < 4; k++) { 6849 *iter2++ = (GLushort)(extractComponents[k]*65535); 6850 } 6851 break; 6852 case GL_UNSIGNED_INT_2_10_10_10_REV: 6853 extract2101010rev(myswapBytes,iter,extractComponents); 6854 for (k = 0; k < 4; k++) { 6855 *iter2++ = (GLushort)(extractComponents[k]*65535); 6856 } 6857 break; 6858 case GL_INT: 6859 case GL_UNSIGNED_INT: 6860 case GL_FLOAT: 6861 if (myswapBytes) { 6862 widget.ub[0] = iter[3]; 6863 widget.ub[1] = iter[2]; 6864 widget.ub[2] = iter[1]; 6865 widget.ub[3] = iter[0]; 6866 } else { 6867 widget.ub[0] = iter[0]; 6868 widget.ub[1] = iter[1]; 6869 widget.ub[2] = iter[2]; 6870 widget.ub[3] = iter[3]; 6871 } 6872 if (type == GL_FLOAT) { 6873 if (indexFormat) { 6874 *iter2++ = widget.f; 6875 } else { 6876 *iter2++ = 65535 * widget.f; 6877 } 6878 } else if (type == GL_UNSIGNED_INT) { 6879 if (indexFormat) { 6880 *iter2++ = widget.ui; 6881 } else { 6882 *iter2++ = widget.ui >> 16; 6883 } 6884 } else { 6885 if (indexFormat) { 6886 *iter2++ = widget.i; 6887 } else { 6888 *iter2++ = widget.i >> 15; 6889 } 6890 } 6891 break; 6892 default: 6893 assert(0); 6894 } 6895 6896 iter+= elementSize; 6897 } /* for ww */ 6898 rowStart+= rowSize; 6899 6900 iter= rowStart; /* for assertion purposes */ 6901 } /* for hh */ 6902 6903 start+= imageSize; 6904 } /* for dd */ 6905 6906 /* iterators should be one byte past end */ 6907 if (!isTypePackedPixel(type)) { 6908 assert(iter2 == &newImage[width*height*depth*components]); 6909 } 6910 else { 6911 assert(iter2 == &newImage[width*height*depth* 6912 elements_per_group(format,0)]); 6913 } 6914 assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth + 6915 psm->unpack_skip_rows * rowSize + 6916 psm->unpack_skip_pixels * groupSize + 6917 /*3dstuff*/ 6918 psm->unpack_skip_images * imageSize] ); 6919 } /* fillImage3D () */ 6920 6921 static void scaleInternal3D(GLint components, 6922 GLint widthIn, GLint heightIn, GLint depthIn, 6923 const GLushort *dataIn, 6924 GLint widthOut, GLint heightOut, GLint depthOut, 6925 GLushort *dataOut) 6926 { 6927 float x, lowx, highx, convx, halfconvx; 6928 float y, lowy, highy, convy, halfconvy; 6929 float z, lowz, highz, convz, halfconvz; 6930 float xpercent,ypercent,zpercent; 6931 float percent; 6932 /* Max components in a format is 4, so... */ 6933 float totals[4]; 6934 float volume; 6935 int i,j,d,k,zint,yint,xint,xindex,yindex,zindex; 6936 int temp; 6937 6938 convz = (float) depthIn/depthOut; 6939 convy = (float) heightIn/heightOut; 6940 convx = (float) widthIn/widthOut; 6941 halfconvx = convx/2; 6942 halfconvy = convy/2; 6943 halfconvz = convz/2; 6944 for (d = 0; d < depthOut; d++) { 6945 z = convz * (d+0.5); 6946 if (depthIn > depthOut) { 6947 highz = z + halfconvz; 6948 lowz = z - halfconvz; 6949 } else { 6950 highz = z + 0.5; 6951 lowz = z - 0.5; 6952 } 6953 for (i = 0; i < heightOut; i++) { 6954 y = convy * (i+0.5); 6955 if (heightIn > heightOut) { 6956 highy = y + halfconvy; 6957 lowy = y - halfconvy; 6958 } else { 6959 highy = y + 0.5; 6960 lowy = y - 0.5; 6961 } 6962 for (j = 0; j < widthOut; j++) { 6963 x = convx * (j+0.5); 6964 if (widthIn > widthOut) { 6965 highx = x + halfconvx; 6966 lowx = x - halfconvx; 6967 } else { 6968 highx = x + 0.5; 6969 lowx = x - 0.5; 6970 } 6971 6972 /* 6973 ** Ok, now apply box filter to box that goes from (lowx, lowy, 6974 ** lowz) to (highx, highy, highz) on input data into this pixel 6975 ** on output data. 6976 */ 6977 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 6978 volume = 0.0; 6979 6980 z = lowz; 6981 zint = floor(z); 6982 while (z < highz) { 6983 zindex = (zint + depthIn) % depthIn; 6984 if (highz < zint+1) { 6985 zpercent = highz - z; 6986 } else { 6987 zpercent = zint+1 - z; 6988 } 6989 6990 y = lowy; 6991 yint = floor(y); 6992 while (y < highy) { 6993 yindex = (yint + heightIn) % heightIn; 6994 if (highy < yint+1) { 6995 ypercent = highy - y; 6996 } else { 6997 ypercent = yint+1 - y; 6998 } 6999 7000 x = lowx; 7001 xint = floor(x); 7002 7003 while (x < highx) { 7004 xindex = (xint + widthIn) % widthIn; 7005 if (highx < xint+1) { 7006 xpercent = highx - x; 7007 } else { 7008 xpercent = xint+1 - x; 7009 } 7010 7011 percent = xpercent * ypercent * zpercent; 7012 volume += percent; 7013 7014 temp = (xindex + (yindex*widthIn) + 7015 (zindex*widthIn*heightIn)) * components; 7016 for (k = 0; k < components; k++) { 7017 assert(0 <= (temp+k) && 7018 (temp+k) < 7019 (widthIn*heightIn*depthIn*components)); 7020 totals[k] += dataIn[temp + k] * percent; 7021 } 7022 7023 xint++; 7024 x = xint; 7025 } /* while x */ 7026 7027 yint++; 7028 y = yint; 7029 } /* while y */ 7030 7031 zint++; 7032 z = zint; 7033 } /* while z */ 7034 7035 temp = (j + (i * widthOut) + 7036 (d*widthOut*heightOut)) * components; 7037 for (k = 0; k < components; k++) { 7038 /* totals[] should be rounded in the case of enlarging an 7039 * RGB ramp when the type is 332 or 4444 7040 */ 7041 assert(0 <= (temp+k) && 7042 (temp+k) < (widthOut*heightOut*depthOut*components)); 7043 dataOut[temp + k] = (totals[k]+0.5)/volume; 7044 } 7045 } /* for j */ 7046 } /* for i */ 7047 } /* for d */ 7048 } /* scaleInternal3D() */ 7049 7050 static void emptyImage3D(const PixelStorageModes *psm, 7051 GLint width, GLint height, GLint depth, 7052 GLenum format, GLenum type, GLboolean indexFormat, 7053 const GLushort *oldImage, void *userImage) 7054 { 7055 int myswapBytes; 7056 int components; 7057 int groupsPerLine; 7058 int elementSize; 7059 int groupSize; 7060 int rowSize; 7061 int padding; 7062 GLubyte *start, *rowStart, *iter; 7063 int elementsPerLine; 7064 const GLushort *iter2; 7065 int ii, jj, dd, k; 7066 int rowsPerImage; 7067 int imageSize; 7068 7069 myswapBytes= psm->pack_swap_bytes; 7070 components = elements_per_group(format,type); 7071 if (psm->pack_row_length > 0) { 7072 groupsPerLine = psm->pack_row_length; 7073 } 7074 else { 7075 groupsPerLine = width; 7076 } 7077 7078 elementSize= bytes_per_element(type); 7079 groupSize= elementSize * components; 7080 if (elementSize == 1) myswapBytes= 0; 7081 7082 /* 3dstuff begin */ 7083 if (psm->pack_image_height > 0) { 7084 rowsPerImage= psm->pack_image_height; 7085 } 7086 else { 7087 rowsPerImage= height; 7088 } 7089 7090 /* 3dstuff end */ 7091 7092 rowSize = groupsPerLine * groupSize; 7093 padding = rowSize % psm->pack_alignment; 7094 if (padding) { 7095 rowSize+= psm->pack_alignment - padding; 7096 } 7097 7098 imageSize= rowsPerImage * rowSize; /* 3dstuff */ 7099 7100 start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize + 7101 psm->pack_skip_pixels * groupSize + 7102 /*3dstuff*/ 7103 psm->pack_skip_images * imageSize; 7104 elementsPerLine= width * components; 7105 7106 iter2 = oldImage; 7107 for (dd= 0; dd < depth; dd++) { 7108 rowStart= start; 7109 7110 for (ii= 0; ii< height; ii++) { 7111 iter = rowStart; 7112 7113 for (jj = 0; jj < elementsPerLine; jj++) { 7114 Type_Widget widget; 7115 float shoveComponents[4]; 7116 7117 switch(type){ 7118 case GL_UNSIGNED_BYTE: 7119 if (indexFormat) { 7120 *iter = *iter2++; 7121 } else { 7122 *iter = *iter2++ >> 8; 7123 } 7124 break; 7125 case GL_BYTE: 7126 if (indexFormat) { 7127 *((GLbyte *) iter) = *iter2++; 7128 } else { 7129 *((GLbyte *) iter) = *iter2++ >> 9; 7130 } 7131 break; 7132 case GL_UNSIGNED_BYTE_3_3_2: 7133 for (k = 0; k < 3; k++) { 7134 shoveComponents[k]= *iter2++ / 65535.0; 7135 } 7136 shove332(shoveComponents,0,(void *)iter); 7137 break; 7138 case GL_UNSIGNED_BYTE_2_3_3_REV: 7139 for (k = 0; k < 3; k++) { 7140 shoveComponents[k]= *iter2++ / 65535.0; 7141 } 7142 shove233rev(shoveComponents,0,(void *)iter); 7143 break; 7144 case GL_UNSIGNED_SHORT_5_6_5: 7145 for (k = 0; k < 3; k++) { 7146 shoveComponents[k]= *iter2++ / 65535.0; 7147 } 7148 shove565(shoveComponents,0,(void *)&widget.us[0]); 7149 if (myswapBytes) { 7150 iter[0] = widget.ub[1]; 7151 iter[1] = widget.ub[0]; 7152 } 7153 else { 7154 *(GLushort *)iter = widget.us[0]; 7155 } 7156 break; 7157 case GL_UNSIGNED_SHORT_5_6_5_REV: 7158 for (k = 0; k < 3; k++) { 7159 shoveComponents[k]= *iter2++ / 65535.0; 7160 } 7161 shove565rev(shoveComponents,0,(void *)&widget.us[0]); 7162 if (myswapBytes) { 7163 iter[0] = widget.ub[1]; 7164 iter[1] = widget.ub[0]; 7165 } 7166 else { 7167 *(GLushort *)iter = widget.us[0]; 7168 } 7169 break; 7170 case GL_UNSIGNED_SHORT_4_4_4_4: 7171 for (k = 0; k < 4; k++) { 7172 shoveComponents[k]= *iter2++ / 65535.0; 7173 } 7174 shove4444(shoveComponents,0,(void *)&widget.us[0]); 7175 if (myswapBytes) { 7176 iter[0] = widget.ub[1]; 7177 iter[1] = widget.ub[0]; 7178 } else { 7179 *(GLushort *)iter = widget.us[0]; 7180 } 7181 break; 7182 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 7183 for (k = 0; k < 4; k++) { 7184 shoveComponents[k]= *iter2++ / 65535.0; 7185 } 7186 shove4444rev(shoveComponents,0,(void *)&widget.us[0]); 7187 if (myswapBytes) { 7188 iter[0] = widget.ub[1]; 7189 iter[1] = widget.ub[0]; 7190 } else { 7191 *(GLushort *)iter = widget.us[0]; 7192 } 7193 break; 7194 case GL_UNSIGNED_SHORT_5_5_5_1: 7195 for (k = 0; k < 4; k++) { 7196 shoveComponents[k]= *iter2++ / 65535.0; 7197 } 7198 shove5551(shoveComponents,0,(void *)&widget.us[0]); 7199 if (myswapBytes) { 7200 iter[0] = widget.ub[1]; 7201 iter[1] = widget.ub[0]; 7202 } else { 7203 *(GLushort *)iter = widget.us[0]; 7204 } 7205 break; 7206 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 7207 for (k = 0; k < 4; k++) { 7208 shoveComponents[k]= *iter2++ / 65535.0; 7209 } 7210 shove1555rev(shoveComponents,0,(void *)&widget.us[0]); 7211 if (myswapBytes) { 7212 iter[0] = widget.ub[1]; 7213 iter[1] = widget.ub[0]; 7214 } else { 7215 *(GLushort *)iter = widget.us[0]; 7216 } 7217 break; 7218 case GL_UNSIGNED_SHORT: 7219 case GL_SHORT: 7220 if (type == GL_SHORT) { 7221 if (indexFormat) { 7222 widget.s[0] = *iter2++; 7223 } else { 7224 widget.s[0] = *iter2++ >> 1; 7225 } 7226 } else { 7227 widget.us[0] = *iter2++; 7228 } 7229 if (myswapBytes) { 7230 iter[0] = widget.ub[1]; 7231 iter[1] = widget.ub[0]; 7232 } else { 7233 iter[0] = widget.ub[0]; 7234 iter[1] = widget.ub[1]; 7235 } 7236 break; 7237 case GL_UNSIGNED_INT_8_8_8_8: 7238 for (k = 0; k < 4; k++) { 7239 shoveComponents[k]= *iter2++ / 65535.0; 7240 } 7241 shove8888(shoveComponents,0,(void *)&widget.ui); 7242 if (myswapBytes) { 7243 iter[3] = widget.ub[0]; 7244 iter[2] = widget.ub[1]; 7245 iter[1] = widget.ub[2]; 7246 iter[0] = widget.ub[3]; 7247 } else { 7248 *(GLuint *)iter= widget.ui; 7249 } 7250 break; 7251 case GL_UNSIGNED_INT_8_8_8_8_REV: 7252 for (k = 0; k < 4; k++) { 7253 shoveComponents[k]= *iter2++ / 65535.0; 7254 } 7255 shove8888rev(shoveComponents,0,(void *)&widget.ui); 7256 if (myswapBytes) { 7257 iter[3] = widget.ub[0]; 7258 iter[2] = widget.ub[1]; 7259 iter[1] = widget.ub[2]; 7260 iter[0] = widget.ub[3]; 7261 } else { 7262 *(GLuint *)iter= widget.ui; 7263 } 7264 break; 7265 case GL_UNSIGNED_INT_10_10_10_2: 7266 for (k = 0; k < 4; k++) { 7267 shoveComponents[k]= *iter2++ / 65535.0; 7268 } 7269 shove1010102(shoveComponents,0,(void *)&widget.ui); 7270 if (myswapBytes) { 7271 iter[3] = widget.ub[0]; 7272 iter[2] = widget.ub[1]; 7273 iter[1] = widget.ub[2]; 7274 iter[0] = widget.ub[3]; 7275 } else { 7276 *(GLuint *)iter= widget.ui; 7277 } 7278 break; 7279 case GL_UNSIGNED_INT_2_10_10_10_REV: 7280 for (k = 0; k < 4; k++) { 7281 shoveComponents[k]= *iter2++ / 65535.0; 7282 } 7283 shove2101010rev(shoveComponents,0,(void *)&widget.ui); 7284 if (myswapBytes) { 7285 iter[3] = widget.ub[0]; 7286 iter[2] = widget.ub[1]; 7287 iter[1] = widget.ub[2]; 7288 iter[0] = widget.ub[3]; 7289 } else { 7290 *(GLuint *)iter= widget.ui; 7291 } 7292 break; 7293 case GL_INT: 7294 case GL_UNSIGNED_INT: 7295 case GL_FLOAT: 7296 if (type == GL_FLOAT) { 7297 if (indexFormat) { 7298 widget.f = *iter2++; 7299 } else { 7300 widget.f = *iter2++ / (float) 65535.0; 7301 } 7302 } else if (type == GL_UNSIGNED_INT) { 7303 if (indexFormat) { 7304 widget.ui = *iter2++; 7305 } else { 7306 widget.ui = (unsigned int) *iter2++ * 65537; 7307 } 7308 } else { 7309 if (indexFormat) { 7310 widget.i = *iter2++; 7311 } else { 7312 widget.i = ((unsigned int) *iter2++ * 65537)/2; 7313 } 7314 } 7315 if (myswapBytes) { 7316 iter[3] = widget.ub[0]; 7317 iter[2] = widget.ub[1]; 7318 iter[1] = widget.ub[2]; 7319 iter[0] = widget.ub[3]; 7320 } else { 7321 iter[0] = widget.ub[0]; 7322 iter[1] = widget.ub[1]; 7323 iter[2] = widget.ub[2]; 7324 iter[3] = widget.ub[3]; 7325 } 7326 break; 7327 default: 7328 assert(0); 7329 } 7330 7331 iter+= elementSize; 7332 } /* for jj */ 7333 7334 rowStart+= rowSize; 7335 } /* for ii */ 7336 7337 start+= imageSize; 7338 } /* for dd */ 7339 7340 /* iterators should be one byte past end */ 7341 if (!isTypePackedPixel(type)) { 7342 assert(iter2 == &oldImage[width*height*depth*components]); 7343 } 7344 else { 7345 assert(iter2 == &oldImage[width*height*depth* 7346 elements_per_group(format,0)]); 7347 } 7348 assert( iter == &((GLubyte *)userImage)[rowSize*height*depth + 7349 psm->unpack_skip_rows * rowSize + 7350 psm->unpack_skip_pixels * groupSize + 7351 /*3dstuff*/ 7352 psm->unpack_skip_images * imageSize] ); 7353 } /* emptyImage3D() */ 7354 7355 static 7356 int gluScaleImage3D(GLenum format, 7357 GLint widthIn, GLint heightIn, GLint depthIn, 7358 GLenum typeIn, const void *dataIn, 7359 GLint widthOut, GLint heightOut, GLint depthOut, 7360 GLenum typeOut, void *dataOut) 7361 { 7362 int components; 7363 GLushort *beforeImage, *afterImage; 7364 PixelStorageModes psm; 7365 7366 if (widthIn == 0 || heightIn == 0 || depthIn == 0 || 7367 widthOut == 0 || heightOut == 0 || depthOut == 0) { 7368 return 0; 7369 } 7370 7371 if (widthIn < 0 || heightIn < 0 || depthIn < 0 || 7372 widthOut < 0 || heightOut < 0 || depthOut < 0) { 7373 return GLU_INVALID_VALUE; 7374 } 7375 7376 if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) || 7377 typeIn == GL_BITMAP || typeOut == GL_BITMAP) { 7378 return GLU_INVALID_ENUM; 7379 } 7380 if (!isLegalFormatForPackedPixelType(format, typeIn)) { 7381 return GLU_INVALID_OPERATION; 7382 } 7383 if (!isLegalFormatForPackedPixelType(format, typeOut)) { 7384 return GLU_INVALID_OPERATION; 7385 } 7386 7387 beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format, 7388 GL_UNSIGNED_SHORT)); 7389 afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format, 7390 GL_UNSIGNED_SHORT)); 7391 if (beforeImage == NULL || afterImage == NULL) { 7392 free(beforeImage); 7393 free(afterImage); 7394 return GLU_OUT_OF_MEMORY; 7395 } 7396 retrieveStoreModes3D(&psm); 7397 7398 fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format), 7399 dataIn, beforeImage); 7400 components = elements_per_group(format,0); 7401 scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage, 7402 widthOut,heightOut,depthOut,afterImage); 7403 emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut, 7404 is_index(format),afterImage, dataOut); 7405 free((void *) beforeImage); 7406 free((void *) afterImage); 7407 7408 return 0; 7409 } /* gluScaleImage3D() */ 7410 7411 7412 static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth, 7413 GLint internalFormat, GLenum format, GLenum type, 7414 GLint *newWidth, GLint *newHeight, GLint *newDepth) 7415 { 7416 GLint widthPowerOf2= nearestPower(width); 7417 GLint heightPowerOf2= nearestPower(height); 7418 GLint depthPowerOf2= nearestPower(depth); 7419 GLint proxyWidth; 7420 7421 do { 7422 /* compute level 1 width & height & depth, clamping each at 1 */ 7423 GLint widthAtLevelOne= (widthPowerOf2 > 1) ? 7424 widthPowerOf2 >> 1 : 7425 widthPowerOf2; 7426 GLint heightAtLevelOne= (heightPowerOf2 > 1) ? 7427 heightPowerOf2 >> 1 : 7428 heightPowerOf2; 7429 GLint depthAtLevelOne= (depthPowerOf2 > 1) ? 7430 depthPowerOf2 >> 1 : 7431 depthPowerOf2; 7432 GLenum proxyTarget = GL_PROXY_TEXTURE_3D; 7433 assert(widthAtLevelOne > 0); 7434 assert(heightAtLevelOne > 0); 7435 assert(depthAtLevelOne > 0); 7436 7437 /* does width x height x depth at level 1 & all their mipmaps fit? */ 7438 assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D); 7439 gluTexImage3D(proxyTarget, 1, /* must be non-zero */ 7440 internalFormat, 7441 widthAtLevelOne,heightAtLevelOne,depthAtLevelOne, 7442 0,format,type,NULL); 7443 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth); 7444 /* does it fit??? */ 7445 if (proxyWidth == 0) { /* nope, so try again with these sizes */ 7446 if (widthPowerOf2 == 1 && heightPowerOf2 == 1 && 7447 depthPowerOf2 == 1) { 7448 *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */ 7449 return; 7450 } 7451 widthPowerOf2= widthAtLevelOne; 7452 heightPowerOf2= heightAtLevelOne; 7453 depthPowerOf2= depthAtLevelOne; 7454 } 7455 /* else it does fit */ 7456 } while (proxyWidth == 0); 7457 /* loop must terminate! */ 7458 7459 /* return the width & height at level 0 that fits */ 7460 *newWidth= widthPowerOf2; 7461 *newHeight= heightPowerOf2; 7462 *newDepth= depthPowerOf2; 7463 /*printf("Proxy Textures\n");*/ 7464 } /* closestFit3D() */ 7465 7466 static void halveImagePackedPixelSlice(int components, 7467 void (*extractPackedPixel) 7468 (int, const void *,GLfloat []), 7469 void (*shovePackedPixel) 7470 (const GLfloat [],int, void *), 7471 GLint width, GLint height, GLint depth, 7472 const void *dataIn, void *dataOut, 7473 GLint pixelSizeInBytes, 7474 GLint rowSizeInBytes, 7475 GLint imageSizeInBytes, 7476 GLint isSwap) 7477 { 7478 int ii, jj; 7479 int halfWidth= width / 2; 7480 int halfHeight= height / 2; 7481 int halfDepth= depth / 2; 7482 const char *src= (const char *)dataIn; 7483 int outIndex= 0; 7484 7485 assert((width == 1 || height == 1) && depth >= 2); 7486 7487 if (width == height) { /* a 1-pixel column viewed from top */ 7488 assert(width == 1 && height == 1); 7489 assert(depth >= 2); 7490 7491 for (ii= 0; ii< halfDepth; ii++) { 7492 float totals[4]; 7493 float extractTotals[BOX2][4]; 7494 int cc; 7495 7496 (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]); 7497 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 7498 &extractTotals[1][0]); 7499 for (cc = 0; cc < components; cc++) { 7500 int kk; 7501 7502 /* average 2 pixels since only a column */ 7503 totals[cc]= 0.0; 7504 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 7505 * totals[RED]/= 2.0; 7506 */ 7507 for (kk = 0; kk < BOX2; kk++) { 7508 totals[cc]+= extractTotals[kk][cc]; 7509 } 7510 totals[cc]/= (float)BOX2; 7511 } /* for cc */ 7512 7513 (*shovePackedPixel)(totals,outIndex,dataOut); 7514 outIndex++; 7515 /* skip over to next group of 2 */ 7516 src+= imageSizeInBytes + imageSizeInBytes; 7517 } /* for ii */ 7518 } 7519 else if (height == 1) { /* horizontal slice viewed from top */ 7520 assert(width != 1); 7521 7522 for (ii= 0; ii< halfDepth; ii++) { 7523 for (jj= 0; jj< halfWidth; jj++) { 7524 float totals[4]; 7525 float extractTotals[BOX4][4]; 7526 int cc; 7527 7528 (*extractPackedPixel)(isSwap,src, 7529 &extractTotals[0][0]); 7530 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 7531 &extractTotals[1][0]); 7532 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 7533 &extractTotals[2][0]); 7534 (*extractPackedPixel)(isSwap, 7535 (src+imageSizeInBytes+pixelSizeInBytes), 7536 &extractTotals[3][0]); 7537 for (cc = 0; cc < components; cc++) { 7538 int kk; 7539 7540 /* grab 4 pixels to average */ 7541 totals[cc]= 0.0; 7542 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 7543 * extractTotals[2][RED]+extractTotals[3][RED]; 7544 * totals[RED]/= 4.0; 7545 */ 7546 for (kk = 0; kk < BOX4; kk++) { 7547 totals[cc]+= extractTotals[kk][cc]; 7548 } 7549 totals[cc]/= (float)BOX4; 7550 } 7551 (*shovePackedPixel)(totals,outIndex,dataOut); 7552 7553 outIndex++; 7554 /* skip over to next horizontal square of 4 */ 7555 src+= imageSizeInBytes + imageSizeInBytes; 7556 } 7557 } 7558 7559 /* assert() */ 7560 } 7561 else if (width == 1) { /* vertical slice viewed from top */ 7562 assert(height != 1); 7563 7564 for (ii= 0; ii< halfDepth; ii++) { 7565 for (jj= 0; jj< halfHeight; jj++) { 7566 float totals[4]; 7567 float extractTotals[BOX4][4]; 7568 int cc; 7569 7570 (*extractPackedPixel)(isSwap,src, 7571 &extractTotals[0][0]); 7572 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 7573 &extractTotals[1][0]); 7574 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 7575 &extractTotals[2][0]); 7576 (*extractPackedPixel)(isSwap, 7577 (src+imageSizeInBytes+rowSizeInBytes), 7578 &extractTotals[3][0]); 7579 for (cc = 0; cc < components; cc++) { 7580 int kk; 7581 7582 /* grab 4 pixels to average */ 7583 totals[cc]= 0.0; 7584 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 7585 * extractTotals[2][RED]+extractTotals[3][RED]; 7586 * totals[RED]/= 4.0; 7587 */ 7588 for (kk = 0; kk < BOX4; kk++) { 7589 totals[cc]+= extractTotals[kk][cc]; 7590 } 7591 totals[cc]/= (float)BOX4; 7592 } 7593 (*shovePackedPixel)(totals,outIndex,dataOut); 7594 7595 outIndex++; 7596 7597 /* skip over to next vertical square of 4 */ 7598 src+= imageSizeInBytes + imageSizeInBytes; 7599 } 7600 } 7601 /* assert() */ 7602 } 7603 7604 } /* halveImagePackedPixelSlice() */ 7605 7606 static void halveImagePackedPixel3D(int components, 7607 void (*extractPackedPixel) 7608 (int, const void *,GLfloat []), 7609 void (*shovePackedPixel) 7610 (const GLfloat [],int, void *), 7611 GLint width, GLint height, GLint depth, 7612 const void *dataIn, void *dataOut, 7613 GLint pixelSizeInBytes, 7614 GLint rowSizeInBytes, 7615 GLint imageSizeInBytes, 7616 GLint isSwap) 7617 { 7618 if (depth == 1) { 7619 assert(1 <= width && 1 <= height); 7620 7621 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, 7622 width,height,dataIn,dataOut,pixelSizeInBytes, 7623 rowSizeInBytes,isSwap); 7624 return; 7625 } 7626 /* a horizontal or vertical slice viewed from top */ 7627 else if (width == 1 || height == 1) { 7628 assert(1 <= depth); 7629 7630 halveImagePackedPixelSlice(components, 7631 extractPackedPixel,shovePackedPixel, 7632 width, height, depth, dataIn, dataOut, 7633 pixelSizeInBytes, rowSizeInBytes, 7634 imageSizeInBytes, isSwap); 7635 return; 7636 } 7637 { 7638 int ii, jj, dd; 7639 7640 int halfWidth= width / 2; 7641 int halfHeight= height / 2; 7642 int halfDepth= depth / 2; 7643 const char *src= (const char *) dataIn; 7644 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); 7645 int outIndex= 0; 7646 7647 for (dd= 0; dd < halfDepth; dd++) { 7648 for (ii= 0; ii< halfHeight; ii++) { 7649 for (jj= 0; jj< halfWidth; jj++) { 7650 #define BOX8 8 7651 float totals[4]; /* 4 is maximum components */ 7652 float extractTotals[BOX8][4]; /* 4 is maximum components */ 7653 int cc; 7654 7655 (*extractPackedPixel)(isSwap,src, 7656 &extractTotals[0][0]); 7657 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 7658 &extractTotals[1][0]); 7659 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 7660 &extractTotals[2][0]); 7661 (*extractPackedPixel)(isSwap, 7662 (src+rowSizeInBytes+pixelSizeInBytes), 7663 &extractTotals[3][0]); 7664 7665 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 7666 &extractTotals[4][0]); 7667 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes), 7668 &extractTotals[5][0]); 7669 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes), 7670 &extractTotals[6][0]); 7671 (*extractPackedPixel)(isSwap, 7672 (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes), 7673 &extractTotals[7][0]); 7674 for (cc = 0; cc < components; cc++) { 7675 int kk; 7676 7677 /* grab 8 pixels to average */ 7678 totals[cc]= 0.0; 7679 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 7680 * extractTotals[2][RED]+extractTotals[3][RED]+ 7681 * extractTotals[4][RED]+extractTotals[5][RED]+ 7682 * extractTotals[6][RED]+extractTotals[7][RED]; 7683 * totals[RED]/= 8.0; 7684 */ 7685 for (kk = 0; kk < BOX8; kk++) { 7686 totals[cc]+= extractTotals[kk][cc]; 7687 } 7688 totals[cc]/= (float)BOX8; 7689 } 7690 (*shovePackedPixel)(totals,outIndex,dataOut); 7691 7692 outIndex++; 7693 /* skip over to next square of 4 */ 7694 src+= pixelSizeInBytes + pixelSizeInBytes; 7695 } 7696 /* skip past pad bytes, if any, to get to next row */ 7697 src+= padBytes; 7698 7699 /* src is at beginning of a row here, but it's the second row of 7700 * the square block of 4 pixels that we just worked on so we 7701 * need to go one more row. 7702 * i.e., 7703 * OO... 7704 * here -->OO... 7705 * but want -->OO... 7706 * OO... 7707 * ... 7708 */ 7709 src+= rowSizeInBytes; 7710 } 7711 7712 src+= imageSizeInBytes; 7713 } /* for dd */ 7714 7715 /* both pointers must reach one byte after the end */ 7716 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 7717 assert(outIndex == halfWidth * halfHeight * halfDepth); 7718 } /* for dd */ 7719 7720 } /* halveImagePackedPixel3D() */ 7721 7722 static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat, 7723 GLsizei width, 7724 GLsizei height, 7725 GLsizei depth, 7726 GLsizei widthPowerOf2, 7727 GLsizei heightPowerOf2, 7728 GLsizei depthPowerOf2, 7729 GLenum format, GLenum type, 7730 GLint userLevel, 7731 GLint baseLevel,GLint maxLevel, 7732 const void *data) 7733 { 7734 GLint newWidth, newHeight, newDepth; 7735 GLint level, levels; 7736 const void *usersImage; 7737 void *srcImage, *dstImage; 7738 __GLU_INIT_SWAP_IMAGE; 7739 GLint memReq; 7740 GLint cmpts; 7741 7742 GLint myswapBytes, groupsPerLine, elementSize, groupSize; 7743 GLint rowsPerImage, imageSize; 7744 GLint rowSize, padding; 7745 PixelStorageModes psm; 7746 7747 assert(checkMipmapArgs(internalFormat,format,type) == 0); 7748 assert(width >= 1 && height >= 1 && depth >= 1); 7749 assert(type != GL_BITMAP); 7750 7751 srcImage = dstImage = NULL; 7752 7753 newWidth= widthPowerOf2; 7754 newHeight= heightPowerOf2; 7755 newDepth= depthPowerOf2; 7756 levels = computeLog(newWidth); 7757 level = computeLog(newHeight); 7758 if (level > levels) levels=level; 7759 level = computeLog(newDepth); 7760 if (level > levels) levels=level; 7761 7762 levels+= userLevel; 7763 7764 retrieveStoreModes3D(&psm); 7765 myswapBytes = psm.unpack_swap_bytes; 7766 cmpts = elements_per_group(format,type); 7767 if (psm.unpack_row_length > 0) { 7768 groupsPerLine = psm.unpack_row_length; 7769 } else { 7770 groupsPerLine = width; 7771 } 7772 7773 elementSize = bytes_per_element(type); 7774 groupSize = elementSize * cmpts; 7775 if (elementSize == 1) myswapBytes = 0; 7776 7777 /* 3dstuff begin */ 7778 if (psm.unpack_image_height > 0) { 7779 rowsPerImage= psm.unpack_image_height; 7780 } 7781 else { 7782 rowsPerImage= height; 7783 } 7784 7785 /* 3dstuff end */ 7786 rowSize = groupsPerLine * groupSize; 7787 padding = (rowSize % psm.unpack_alignment); 7788 if (padding) { 7789 rowSize += psm.unpack_alignment - padding; 7790 } 7791 7792 imageSize= rowsPerImage * rowSize; /* 3dstuff */ 7793 7794 usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize + 7795 psm.unpack_skip_pixels * groupSize + 7796 /* 3dstuff */ 7797 psm.unpack_skip_images * imageSize; 7798 7799 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 7800 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 7801 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 7802 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); 7803 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); 7804 7805 level = userLevel; 7806 7807 if (width == newWidth && height == newHeight && depth == newDepth) { 7808 /* Use usersImage for level userLevel */ 7809 if (baseLevel <= level && level <= maxLevel) { 7810 gluTexImage3D(target, level, internalFormat, width, 7811 height, depth, 0, format, type, 7812 usersImage); 7813 } 7814 if(levels == 0) { /* we're done. clean up and return */ 7815 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 7816 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 7817 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 7818 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 7819 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 7820 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 7821 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 7822 return 0; 7823 } 7824 { 7825 int nextWidth= newWidth/2; 7826 int nextHeight= newHeight/2; 7827 int nextDepth= newDepth/2; 7828 7829 /* clamp to 1 */ 7830 if (nextWidth < 1) nextWidth= 1; 7831 if (nextHeight < 1) nextHeight= 1; 7832 if (nextDepth < 1) nextDepth= 1; 7833 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); 7834 } 7835 switch(type) { 7836 case GL_UNSIGNED_BYTE: 7837 dstImage = (GLubyte *)malloc(memReq); 7838 break; 7839 case GL_BYTE: 7840 dstImage = (GLbyte *)malloc(memReq); 7841 break; 7842 case GL_UNSIGNED_SHORT: 7843 dstImage = (GLushort *)malloc(memReq); 7844 break; 7845 case GL_SHORT: 7846 dstImage = (GLshort *)malloc(memReq); 7847 break; 7848 case GL_UNSIGNED_INT: 7849 dstImage = (GLuint *)malloc(memReq); 7850 break; 7851 case GL_INT: 7852 dstImage = (GLint *)malloc(memReq); 7853 break; 7854 case GL_FLOAT: 7855 dstImage = (GLfloat *)malloc(memReq); 7856 break; 7857 case GL_UNSIGNED_BYTE_3_3_2: 7858 case GL_UNSIGNED_BYTE_2_3_3_REV: 7859 dstImage = (GLubyte *)malloc(memReq); 7860 break; 7861 case GL_UNSIGNED_SHORT_5_6_5: 7862 case GL_UNSIGNED_SHORT_5_6_5_REV: 7863 case GL_UNSIGNED_SHORT_4_4_4_4: 7864 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 7865 case GL_UNSIGNED_SHORT_5_5_5_1: 7866 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 7867 dstImage = (GLushort *)malloc(memReq); 7868 break; 7869 case GL_UNSIGNED_INT_8_8_8_8: 7870 case GL_UNSIGNED_INT_8_8_8_8_REV: 7871 case GL_UNSIGNED_INT_10_10_10_2: 7872 case GL_UNSIGNED_INT_2_10_10_10_REV: 7873 dstImage = (GLuint *)malloc(memReq); 7874 break; 7875 default: 7876 return GLU_INVALID_ENUM; /* assertion */ 7877 } 7878 if (dstImage == NULL) { 7879 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 7880 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 7881 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 7882 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 7883 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 7884 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 7885 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 7886 return GLU_OUT_OF_MEMORY; 7887 } 7888 else 7889 switch(type) { 7890 case GL_UNSIGNED_BYTE: 7891 if (depth > 1) { 7892 halveImage3D(cmpts,extractUbyte,shoveUbyte, 7893 width,height,depth, 7894 usersImage,dstImage,elementSize,groupSize,rowSize, 7895 imageSize,myswapBytes); 7896 } 7897 else { 7898 halveImage_ubyte(cmpts,width,height,usersImage,dstImage, 7899 elementSize,rowSize,groupSize); 7900 } 7901 break; 7902 case GL_BYTE: 7903 if (depth > 1) { 7904 halveImage3D(cmpts,extractSbyte,shoveSbyte, 7905 width,height,depth, 7906 usersImage,dstImage,elementSize,groupSize,rowSize, 7907 imageSize,myswapBytes); 7908 } 7909 else { 7910 halveImage_byte(cmpts,width,height,usersImage,dstImage, 7911 elementSize,rowSize,groupSize); 7912 } 7913 break; 7914 case GL_UNSIGNED_SHORT: 7915 if (depth > 1) { 7916 halveImage3D(cmpts,extractUshort,shoveUshort, 7917 width,height,depth, 7918 usersImage,dstImage,elementSize,groupSize,rowSize, 7919 imageSize,myswapBytes); 7920 } 7921 else { 7922 halveImage_ushort(cmpts,width,height,usersImage,dstImage, 7923 elementSize,rowSize,groupSize,myswapBytes); 7924 } 7925 break; 7926 case GL_SHORT: 7927 if (depth > 1) { 7928 halveImage3D(cmpts,extractSshort,shoveSshort, 7929 width,height,depth, 7930 usersImage,dstImage,elementSize,groupSize,rowSize, 7931 imageSize,myswapBytes); 7932 } 7933 else { 7934 halveImage_short(cmpts,width,height,usersImage,dstImage, 7935 elementSize,rowSize,groupSize,myswapBytes); 7936 } 7937 break; 7938 case GL_UNSIGNED_INT: 7939 if (depth > 1) { 7940 halveImage3D(cmpts,extractUint,shoveUint, 7941 width,height,depth, 7942 usersImage,dstImage,elementSize,groupSize,rowSize, 7943 imageSize,myswapBytes); 7944 } 7945 else { 7946 halveImage_uint(cmpts,width,height,usersImage,dstImage, 7947 elementSize,rowSize,groupSize,myswapBytes); 7948 } 7949 break; 7950 case GL_INT: 7951 if (depth > 1) { 7952 halveImage3D(cmpts,extractSint,shoveSint, 7953 width,height,depth, 7954 usersImage,dstImage,elementSize,groupSize,rowSize, 7955 imageSize,myswapBytes); 7956 } 7957 else { 7958 halveImage_int(cmpts,width,height,usersImage,dstImage, 7959 elementSize,rowSize,groupSize,myswapBytes); 7960 } 7961 break; 7962 case GL_FLOAT: 7963 if (depth > 1 ) { 7964 halveImage3D(cmpts,extractFloat,shoveFloat, 7965 width,height,depth, 7966 usersImage,dstImage,elementSize,groupSize,rowSize, 7967 imageSize,myswapBytes); 7968 } 7969 else { 7970 halveImage_float(cmpts,width,height,usersImage,dstImage, 7971 elementSize,rowSize,groupSize,myswapBytes); 7972 } 7973 break; 7974 case GL_UNSIGNED_BYTE_3_3_2: 7975 assert(format == GL_RGB); 7976 halveImagePackedPixel3D(3,extract332,shove332, 7977 width,height,depth,usersImage,dstImage, 7978 elementSize,rowSize,imageSize,myswapBytes); 7979 break; 7980 case GL_UNSIGNED_BYTE_2_3_3_REV: 7981 assert(format == GL_RGB); 7982 halveImagePackedPixel3D(3,extract233rev,shove233rev, 7983 width,height,depth,usersImage,dstImage, 7984 elementSize,rowSize,imageSize,myswapBytes); 7985 break; 7986 case GL_UNSIGNED_SHORT_5_6_5: 7987 halveImagePackedPixel3D(3,extract565,shove565, 7988 width,height,depth,usersImage,dstImage, 7989 elementSize,rowSize,imageSize,myswapBytes); 7990 break; 7991 case GL_UNSIGNED_SHORT_5_6_5_REV: 7992 halveImagePackedPixel3D(3,extract565rev,shove565rev, 7993 width,height,depth,usersImage,dstImage, 7994 elementSize,rowSize,imageSize,myswapBytes); 7995 break; 7996 case GL_UNSIGNED_SHORT_4_4_4_4: 7997 halveImagePackedPixel3D(4,extract4444,shove4444, 7998 width,height,depth,usersImage,dstImage, 7999 elementSize,rowSize,imageSize,myswapBytes); 8000 break; 8001 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 8002 halveImagePackedPixel3D(4,extract4444rev,shove4444rev, 8003 width,height,depth,usersImage,dstImage, 8004 elementSize,rowSize,imageSize,myswapBytes); 8005 break; 8006 case GL_UNSIGNED_SHORT_5_5_5_1: 8007 halveImagePackedPixel3D(4,extract5551,shove5551, 8008 width,height,depth,usersImage,dstImage, 8009 elementSize,rowSize,imageSize,myswapBytes); 8010 break; 8011 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 8012 halveImagePackedPixel3D(4,extract1555rev,shove1555rev, 8013 width,height,depth,usersImage,dstImage, 8014 elementSize,rowSize,imageSize,myswapBytes); 8015 break; 8016 case GL_UNSIGNED_INT_8_8_8_8: 8017 halveImagePackedPixel3D(4,extract8888,shove8888, 8018 width,height,depth,usersImage,dstImage, 8019 elementSize,rowSize,imageSize,myswapBytes); 8020 break; 8021 case GL_UNSIGNED_INT_8_8_8_8_REV: 8022 halveImagePackedPixel3D(4,extract8888rev,shove8888rev, 8023 width,height,depth,usersImage,dstImage, 8024 elementSize,rowSize,imageSize,myswapBytes); 8025 break; 8026 case GL_UNSIGNED_INT_10_10_10_2: 8027 halveImagePackedPixel3D(4,extract1010102,shove1010102, 8028 width,height,depth,usersImage,dstImage, 8029 elementSize,rowSize,imageSize,myswapBytes); 8030 break; 8031 case GL_UNSIGNED_INT_2_10_10_10_REV: 8032 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, 8033 width,height,depth,usersImage,dstImage, 8034 elementSize,rowSize,imageSize,myswapBytes); 8035 break; 8036 default: 8037 assert(0); 8038 break; 8039 } 8040 newWidth = width/2; 8041 newHeight = height/2; 8042 newDepth = depth/2; 8043 /* clamp to 1 */ 8044 if (newWidth < 1) newWidth= 1; 8045 if (newHeight < 1) newHeight= 1; 8046 if (newDepth < 1) newDepth= 1; 8047 8048 myswapBytes = 0; 8049 rowSize = newWidth * groupSize; 8050 imageSize= rowSize * newHeight; /* 3dstuff */ 8051 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); 8052 /* Swap srcImage and dstImage */ 8053 __GLU_SWAP_IMAGE(srcImage,dstImage); 8054 switch(type) { 8055 case GL_UNSIGNED_BYTE: 8056 dstImage = (GLubyte *)malloc(memReq); 8057 break; 8058 case GL_BYTE: 8059 dstImage = (GLbyte *)malloc(memReq); 8060 break; 8061 case GL_UNSIGNED_SHORT: 8062 dstImage = (GLushort *)malloc(memReq); 8063 break; 8064 case GL_SHORT: 8065 dstImage = (GLshort *)malloc(memReq); 8066 break; 8067 case GL_UNSIGNED_INT: 8068 dstImage = (GLuint *)malloc(memReq); 8069 break; 8070 case GL_INT: 8071 dstImage = (GLint *)malloc(memReq); 8072 break; 8073 case GL_FLOAT: 8074 dstImage = (GLfloat *)malloc(memReq); 8075 break; 8076 case GL_UNSIGNED_BYTE_3_3_2: 8077 case GL_UNSIGNED_BYTE_2_3_3_REV: 8078 dstImage = (GLubyte *)malloc(memReq); 8079 break; 8080 case GL_UNSIGNED_SHORT_5_6_5: 8081 case GL_UNSIGNED_SHORT_5_6_5_REV: 8082 case GL_UNSIGNED_SHORT_4_4_4_4: 8083 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 8084 case GL_UNSIGNED_SHORT_5_5_5_1: 8085 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 8086 dstImage = (GLushort *)malloc(memReq); 8087 break; 8088 case GL_UNSIGNED_INT_8_8_8_8: 8089 case GL_UNSIGNED_INT_8_8_8_8_REV: 8090 case GL_UNSIGNED_INT_10_10_10_2: 8091 case GL_UNSIGNED_INT_2_10_10_10_REV: 8092 dstImage = (GLuint *)malloc(memReq); 8093 break; 8094 default: 8095 return GLU_INVALID_ENUM; /* assertion */ 8096 } 8097 if (dstImage == NULL) { 8098 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 8099 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 8100 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 8101 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 8102 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 8103 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 8104 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 8105 free(srcImage); 8106 return GLU_OUT_OF_MEMORY; 8107 } 8108 /* level userLevel+1 is in srcImage; level userLevel already saved */ 8109 level = userLevel+1; 8110 } else {/* user's image is *not* nice power-of-2 sized square */ 8111 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); 8112 switch(type) { 8113 case GL_UNSIGNED_BYTE: 8114 dstImage = (GLubyte *)malloc(memReq); 8115 break; 8116 case GL_BYTE: 8117 dstImage = (GLbyte *)malloc(memReq); 8118 break; 8119 case GL_UNSIGNED_SHORT: 8120 dstImage = (GLushort *)malloc(memReq); 8121 break; 8122 case GL_SHORT: 8123 dstImage = (GLshort *)malloc(memReq); 8124 break; 8125 case GL_UNSIGNED_INT: 8126 dstImage = (GLuint *)malloc(memReq); 8127 break; 8128 case GL_INT: 8129 dstImage = (GLint *)malloc(memReq); 8130 break; 8131 case GL_FLOAT: 8132 dstImage = (GLfloat *)malloc(memReq); 8133 break; 8134 case GL_UNSIGNED_BYTE_3_3_2: 8135 case GL_UNSIGNED_BYTE_2_3_3_REV: 8136 dstImage = (GLubyte *)malloc(memReq); 8137 break; 8138 case GL_UNSIGNED_SHORT_5_6_5: 8139 case GL_UNSIGNED_SHORT_5_6_5_REV: 8140 case GL_UNSIGNED_SHORT_4_4_4_4: 8141 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 8142 case GL_UNSIGNED_SHORT_5_5_5_1: 8143 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 8144 dstImage = (GLushort *)malloc(memReq); 8145 break; 8146 case GL_UNSIGNED_INT_8_8_8_8: 8147 case GL_UNSIGNED_INT_8_8_8_8_REV: 8148 case GL_UNSIGNED_INT_10_10_10_2: 8149 case GL_UNSIGNED_INT_2_10_10_10_REV: 8150 dstImage = (GLuint *)malloc(memReq); 8151 break; 8152 default: 8153 return GLU_INVALID_ENUM; /* assertion */ 8154 } 8155 8156 if (dstImage == NULL) { 8157 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 8158 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 8159 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 8160 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 8161 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 8162 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 8163 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 8164 return GLU_OUT_OF_MEMORY; 8165 } 8166 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n", 8167 width,height,depth,newWidth,newHeight,newDepth);*/ 8168 8169 gluScaleImage3D(format, width, height, depth, type, usersImage, 8170 newWidth, newHeight, newDepth, type, dstImage); 8171 8172 myswapBytes = 0; 8173 rowSize = newWidth * groupSize; 8174 imageSize = rowSize * newHeight; /* 3dstuff */ 8175 /* Swap dstImage and srcImage */ 8176 __GLU_SWAP_IMAGE(srcImage,dstImage); 8177 8178 if(levels != 0) { /* use as little memory as possible */ 8179 { 8180 int nextWidth= newWidth/2; 8181 int nextHeight= newHeight/2; 8182 int nextDepth= newDepth/2; 8183 if (nextWidth < 1) nextWidth= 1; 8184 if (nextHeight < 1) nextHeight= 1; 8185 if (nextDepth < 1) nextDepth= 1; 8186 8187 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); 8188 } 8189 switch(type) { 8190 case GL_UNSIGNED_BYTE: 8191 dstImage = (GLubyte *)malloc(memReq); 8192 break; 8193 case GL_BYTE: 8194 dstImage = (GLbyte *)malloc(memReq); 8195 break; 8196 case GL_UNSIGNED_SHORT: 8197 dstImage = (GLushort *)malloc(memReq); 8198 break; 8199 case GL_SHORT: 8200 dstImage = (GLshort *)malloc(memReq); 8201 break; 8202 case GL_UNSIGNED_INT: 8203 dstImage = (GLuint *)malloc(memReq); 8204 break; 8205 case GL_INT: 8206 dstImage = (GLint *)malloc(memReq); 8207 break; 8208 case GL_FLOAT: 8209 dstImage = (GLfloat *)malloc(memReq); 8210 break; 8211 case GL_UNSIGNED_BYTE_3_3_2: 8212 case GL_UNSIGNED_BYTE_2_3_3_REV: 8213 dstImage = (GLubyte *)malloc(memReq); 8214 break; 8215 case GL_UNSIGNED_SHORT_5_6_5: 8216 case GL_UNSIGNED_SHORT_5_6_5_REV: 8217 case GL_UNSIGNED_SHORT_4_4_4_4: 8218 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 8219 case GL_UNSIGNED_SHORT_5_5_5_1: 8220 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 8221 dstImage = (GLushort *)malloc(memReq); 8222 break; 8223 case GL_UNSIGNED_INT_8_8_8_8: 8224 case GL_UNSIGNED_INT_8_8_8_8_REV: 8225 case GL_UNSIGNED_INT_10_10_10_2: 8226 case GL_UNSIGNED_INT_2_10_10_10_REV: 8227 dstImage = (GLuint *)malloc(memReq); 8228 break; 8229 default: 8230 return GLU_INVALID_ENUM; /* assertion */ 8231 } 8232 if (dstImage == NULL) { 8233 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 8234 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 8235 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 8236 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 8237 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 8238 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 8239 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 8240 free(srcImage); 8241 return GLU_OUT_OF_MEMORY; 8242 } 8243 } 8244 /* level userLevel is in srcImage; nothing saved yet */ 8245 level = userLevel; 8246 } 8247 8248 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 8249 if (baseLevel <= level && level <= maxLevel) { 8250 gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth, 8251 0,format, type, (void *)srcImage); 8252 } 8253 level++; /* update current level for the loop */ 8254 for (; level <= levels; level++) { 8255 switch(type) { 8256 case GL_UNSIGNED_BYTE: 8257 if (newDepth > 1) { 8258 halveImage3D(cmpts,extractUbyte,shoveUbyte, 8259 newWidth,newHeight,newDepth, 8260 srcImage,dstImage,elementSize,groupSize,rowSize, 8261 imageSize,myswapBytes); 8262 } 8263 else { 8264 halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage, 8265 elementSize,rowSize,groupSize); 8266 } 8267 break; 8268 case GL_BYTE: 8269 if (newDepth > 1) { 8270 halveImage3D(cmpts,extractSbyte,shoveSbyte, 8271 newWidth,newHeight,newDepth, 8272 srcImage,dstImage,elementSize,groupSize,rowSize, 8273 imageSize,myswapBytes); 8274 } 8275 else { 8276 halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage, 8277 elementSize,rowSize,groupSize); 8278 } 8279 break; 8280 case GL_UNSIGNED_SHORT: 8281 if (newDepth > 1) { 8282 halveImage3D(cmpts,extractUshort,shoveUshort, 8283 newWidth,newHeight,newDepth, 8284 srcImage,dstImage,elementSize,groupSize,rowSize, 8285 imageSize,myswapBytes); 8286 } 8287 else { 8288 halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage, 8289 elementSize,rowSize,groupSize,myswapBytes); 8290 } 8291 break; 8292 case GL_SHORT: 8293 if (newDepth > 1) { 8294 halveImage3D(cmpts,extractSshort,shoveSshort, 8295 newWidth,newHeight,newDepth, 8296 srcImage,dstImage,elementSize,groupSize,rowSize, 8297 imageSize,myswapBytes); 8298 } 8299 else { 8300 halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage, 8301 elementSize,rowSize,groupSize,myswapBytes); 8302 } 8303 break; 8304 case GL_UNSIGNED_INT: 8305 if (newDepth > 1) { 8306 halveImage3D(cmpts,extractUint,shoveUint, 8307 newWidth,newHeight,newDepth, 8308 srcImage,dstImage,elementSize,groupSize,rowSize, 8309 imageSize,myswapBytes); 8310 } 8311 else { 8312 halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage, 8313 elementSize,rowSize,groupSize,myswapBytes); 8314 } 8315 break; 8316 case GL_INT: 8317 if (newDepth > 1) { 8318 halveImage3D(cmpts,extractSint,shoveSint, 8319 newWidth,newHeight,newDepth, 8320 srcImage,dstImage,elementSize,groupSize,rowSize, 8321 imageSize,myswapBytes); 8322 } 8323 else { 8324 halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage, 8325 elementSize,rowSize,groupSize,myswapBytes); 8326 } 8327 break; 8328 case GL_FLOAT: 8329 if (newDepth > 1) { 8330 halveImage3D(cmpts,extractFloat,shoveFloat, 8331 newWidth,newHeight,newDepth, 8332 srcImage,dstImage,elementSize,groupSize,rowSize, 8333 imageSize,myswapBytes); 8334 } 8335 else { 8336 halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage, 8337 elementSize,rowSize,groupSize,myswapBytes); 8338 } 8339 break; 8340 case GL_UNSIGNED_BYTE_3_3_2: 8341 halveImagePackedPixel3D(3,extract332,shove332, 8342 newWidth,newHeight,newDepth, 8343 srcImage,dstImage,elementSize,rowSize, 8344 imageSize,myswapBytes); 8345 break; 8346 case GL_UNSIGNED_BYTE_2_3_3_REV: 8347 halveImagePackedPixel3D(3,extract233rev,shove233rev, 8348 newWidth,newHeight,newDepth, 8349 srcImage,dstImage,elementSize,rowSize, 8350 imageSize,myswapBytes); 8351 break; 8352 case GL_UNSIGNED_SHORT_5_6_5: 8353 halveImagePackedPixel3D(3,extract565,shove565, 8354 newWidth,newHeight,newDepth, 8355 srcImage,dstImage,elementSize,rowSize, 8356 imageSize,myswapBytes); 8357 break; 8358 case GL_UNSIGNED_SHORT_5_6_5_REV: 8359 halveImagePackedPixel3D(3,extract565rev,shove565rev, 8360 newWidth,newHeight,newDepth, 8361 srcImage,dstImage,elementSize,rowSize, 8362 imageSize,myswapBytes); 8363 break; 8364 case GL_UNSIGNED_SHORT_4_4_4_4: 8365 halveImagePackedPixel3D(4,extract4444,shove4444, 8366 newWidth,newHeight,newDepth, 8367 srcImage,dstImage,elementSize,rowSize, 8368 imageSize,myswapBytes); 8369 break; 8370 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 8371 halveImagePackedPixel3D(4,extract4444rev,shove4444rev, 8372 newWidth,newHeight,newDepth, 8373 srcImage,dstImage,elementSize,rowSize, 8374 imageSize,myswapBytes); 8375 break; 8376 case GL_UNSIGNED_SHORT_5_5_5_1: 8377 halveImagePackedPixel3D(4,extract5551,shove5551, 8378 newWidth,newHeight,newDepth, 8379 srcImage,dstImage,elementSize,rowSize, 8380 imageSize,myswapBytes); 8381 break; 8382 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 8383 halveImagePackedPixel3D(4,extract1555rev,shove1555rev, 8384 newWidth,newHeight,newDepth, 8385 srcImage,dstImage,elementSize,rowSize, 8386 imageSize,myswapBytes); 8387 break; 8388 case GL_UNSIGNED_INT_8_8_8_8: 8389 halveImagePackedPixel3D(4,extract8888,shove8888, 8390 newWidth,newHeight,newDepth, 8391 srcImage,dstImage,elementSize,rowSize, 8392 imageSize,myswapBytes); 8393 break; 8394 case GL_UNSIGNED_INT_8_8_8_8_REV: 8395 halveImagePackedPixel3D(4,extract8888rev,shove8888rev, 8396 newWidth,newHeight,newDepth, 8397 srcImage,dstImage,elementSize,rowSize, 8398 imageSize,myswapBytes); 8399 break; 8400 case GL_UNSIGNED_INT_10_10_10_2: 8401 halveImagePackedPixel3D(4,extract1010102,shove1010102, 8402 newWidth,newHeight,newDepth, 8403 srcImage,dstImage,elementSize,rowSize, 8404 imageSize,myswapBytes); 8405 break; 8406 case GL_UNSIGNED_INT_2_10_10_10_REV: 8407 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, 8408 newWidth,newHeight,newDepth, 8409 srcImage,dstImage,elementSize,rowSize, 8410 imageSize,myswapBytes); 8411 break; 8412 default: 8413 assert(0); 8414 break; 8415 } 8416 8417 __GLU_SWAP_IMAGE(srcImage,dstImage); 8418 8419 if (newWidth > 1) { newWidth /= 2; rowSize /= 2;} 8420 if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; } 8421 if (newDepth > 1) newDepth /= 2; 8422 { 8423 /* call tex image with srcImage untouched since it's not padded */ 8424 if (baseLevel <= level && level <= maxLevel) { 8425 gluTexImage3D(target, level, internalFormat, newWidth, newHeight, 8426 newDepth,0, format, type, (void *) srcImage); 8427 } 8428 } 8429 } /* for level */ 8430 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 8431 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 8432 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 8433 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 8434 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 8435 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 8436 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 8437 8438 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ 8439 if (dstImage) { /* if it's non-rectangular and only 1 level */ 8440 free(dstImage); 8441 } 8442 return 0; 8443 } /* gluBuild3DMipmapLevelsCore() */ 8444 8445 GLint GLAPIENTRY 8446 gluBuild3DMipmapLevels(GLenum target, GLint internalFormat, 8447 GLsizei width, GLsizei height, GLsizei depth, 8448 GLenum format, GLenum type, 8449 GLint userLevel, GLint baseLevel, GLint maxLevel, 8450 const void *data) 8451 { 8452 int level, levels; 8453 8454 int rc= checkMipmapArgs(internalFormat,format,type); 8455 if (rc != 0) return rc; 8456 8457 if (width < 1 || height < 1 || depth < 1) { 8458 return GLU_INVALID_VALUE; 8459 } 8460 8461 if(type == GL_BITMAP) { 8462 return GLU_INVALID_ENUM; 8463 } 8464 8465 levels = computeLog(width); 8466 level = computeLog(height); 8467 if (level > levels) levels=level; 8468 level = computeLog(depth); 8469 if (level > levels) levels=level; 8470 8471 levels+= userLevel; 8472 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) 8473 return GLU_INVALID_VALUE; 8474 8475 return gluBuild3DMipmapLevelsCore(target, internalFormat, 8476 width, height, depth, 8477 width, height, depth, 8478 format, type, 8479 userLevel, baseLevel, maxLevel, 8480 data); 8481 } /* gluBuild3DMipmapLevels() */ 8482 8483 GLint GLAPIENTRY 8484 gluBuild3DMipmaps(GLenum target, GLint internalFormat, 8485 GLsizei width, GLsizei height, GLsizei depth, 8486 GLenum format, GLenum type, const void *data) 8487 { 8488 GLint widthPowerOf2, heightPowerOf2, depthPowerOf2; 8489 int level, levels; 8490 8491 int rc= checkMipmapArgs(internalFormat,format,type); 8492 if (rc != 0) return rc; 8493 8494 if (width < 1 || height < 1 || depth < 1) { 8495 return GLU_INVALID_VALUE; 8496 } 8497 8498 if(type == GL_BITMAP) { 8499 return GLU_INVALID_ENUM; 8500 } 8501 8502 closestFit3D(target,width,height,depth,internalFormat,format,type, 8503 &widthPowerOf2,&heightPowerOf2,&depthPowerOf2); 8504 8505 levels = computeLog(widthPowerOf2); 8506 level = computeLog(heightPowerOf2); 8507 if (level > levels) levels=level; 8508 level = computeLog(depthPowerOf2); 8509 if (level > levels) levels=level; 8510 8511 return gluBuild3DMipmapLevelsCore(target, internalFormat, 8512 width, height, depth, 8513 widthPowerOf2, heightPowerOf2, 8514 depthPowerOf2, 8515 format, type, 0, 0, levels, 8516 data); 8517 } /* gluBuild3DMipmaps() */ 8518 8519 static GLdouble extractUbyte(int isSwap, const void *ubyte) 8520 { 8521 isSwap= isSwap; /* turn off warnings */ 8522 8523 assert(*((const GLubyte *)ubyte) <= 255); 8524 8525 return (GLdouble)(*((const GLubyte *)ubyte)); 8526 } /* extractUbyte() */ 8527 8528 static void shoveUbyte(GLdouble value, int index, void *data) 8529 { 8530 assert(0.0 <= value && value < 256.0); 8531 8532 ((GLubyte *)data)[index]= (GLubyte)value; 8533 } /* shoveUbyte() */ 8534 8535 static GLdouble extractSbyte(int isSwap, const void *sbyte) 8536 { 8537 isSwap= isSwap; /* turn off warnings */ 8538 8539 assert(*((const GLbyte *)sbyte) <= 127); 8540 8541 return (GLdouble)(*((const GLbyte *)sbyte)); 8542 } /* extractSbyte() */ 8543 8544 static void shoveSbyte(GLdouble value, int index, void *data) 8545 { 8546 ((GLbyte *)data)[index]= (GLbyte)value; 8547 } /* shoveSbyte() */ 8548 8549 static GLdouble extractUshort(int isSwap, const void *uitem) 8550 { 8551 GLushort ushort; 8552 8553 if (isSwap) { 8554 ushort= __GLU_SWAP_2_BYTES(uitem); 8555 } 8556 else { 8557 ushort= *(const GLushort *)uitem; 8558 } 8559 8560 assert(ushort <= 65535); 8561 8562 return (GLdouble)ushort; 8563 } /* extractUshort() */ 8564 8565 static void shoveUshort(GLdouble value, int index, void *data) 8566 { 8567 assert(0.0 <= value && value < 65536.0); 8568 8569 ((GLushort *)data)[index]= (GLushort)value; 8570 } /* shoveUshort() */ 8571 8572 static GLdouble extractSshort(int isSwap, const void *sitem) 8573 { 8574 GLshort sshort; 8575 8576 if (isSwap) { 8577 sshort= __GLU_SWAP_2_BYTES(sitem); 8578 } 8579 else { 8580 sshort= *(const GLshort *)sitem; 8581 } 8582 8583 assert(sshort <= 32767); 8584 8585 return (GLdouble)sshort; 8586 } /* extractSshort() */ 8587 8588 static void shoveSshort(GLdouble value, int index, void *data) 8589 { 8590 assert(0.0 <= value && value < 32768.0); 8591 8592 ((GLshort *)data)[index]= (GLshort)value; 8593 } /* shoveSshort() */ 8594 8595 static GLdouble extractUint(int isSwap, const void *uitem) 8596 { 8597 GLuint uint; 8598 8599 if (isSwap) { 8600 uint= __GLU_SWAP_4_BYTES(uitem); 8601 } 8602 else { 8603 uint= *(const GLuint *)uitem; 8604 } 8605 8606 assert(uint <= 0xffffffff); 8607 8608 return (GLdouble)uint; 8609 } /* extractUint() */ 8610 8611 static void shoveUint(GLdouble value, int index, void *data) 8612 { 8613 assert(0.0 <= value && value <= (GLdouble) UINT_MAX); 8614 8615 ((GLuint *)data)[index]= (GLuint)value; 8616 } /* shoveUint() */ 8617 8618 static GLdouble extractSint(int isSwap, const void *sitem) 8619 { 8620 GLint sint; 8621 8622 if (isSwap) { 8623 sint= __GLU_SWAP_4_BYTES(sitem); 8624 } 8625 else { 8626 sint= *(const GLint *)sitem; 8627 } 8628 8629 assert(sint <= 0x7fffffff); 8630 8631 return (GLdouble)sint; 8632 } /* extractSint() */ 8633 8634 static void shoveSint(GLdouble value, int index, void *data) 8635 { 8636 assert(0.0 <= value && value <= (GLdouble) INT_MAX); 8637 8638 ((GLint *)data)[index]= (GLint)value; 8639 } /* shoveSint() */ 8640 8641 static GLdouble extractFloat(int isSwap, const void *item) 8642 { 8643 GLfloat ffloat; 8644 8645 if (isSwap) { 8646 ffloat= __GLU_SWAP_4_BYTES(item); 8647 } 8648 else { 8649 ffloat= *(const GLfloat *)item; 8650 } 8651 8652 assert(ffloat <= 1.0); 8653 8654 return (GLdouble)ffloat; 8655 } /* extractFloat() */ 8656 8657 static void shoveFloat(GLdouble value, int index, void *data) 8658 { 8659 assert(0.0 <= value && value <= 1.0); 8660 8661 ((GLfloat *)data)[index]= value; 8662 } /* shoveFloat() */ 8663 8664 static void halveImageSlice(int components, 8665 GLdouble (*extract)(int, const void *), 8666 void (*shove)(GLdouble, int, void *), 8667 GLint width, GLint height, GLint depth, 8668 const void *dataIn, void *dataOut, 8669 GLint elementSizeInBytes, 8670 GLint groupSizeInBytes, 8671 GLint rowSizeInBytes, 8672 GLint imageSizeInBytes, 8673 GLint isSwap) 8674 { 8675 int ii, jj; 8676 int halfWidth= width / 2; 8677 int halfHeight= height / 2; 8678 int halfDepth= depth / 2; 8679 const char *src= (const char *)dataIn; 8680 int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes); 8681 int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); 8682 int outIndex= 0; 8683 8684 assert((width == 1 || height == 1) && depth >= 2); 8685 8686 if (width == height) { /* a 1-pixel column viewed from top */ 8687 /* printf("1-column\n");*/ 8688 assert(width == 1 && height == 1); 8689 assert(depth >= 2); 8690 8691 for (ii= 0; ii< halfDepth; ii++) { 8692 int cc; 8693 8694 for (cc = 0; cc < components; cc++) { 8695 double totals[4]; 8696 double extractTotals[BOX2][4]; 8697 int kk; 8698 8699 extractTotals[0][cc]= (*extract)(isSwap,src); 8700 extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes)); 8701 8702 /* average 2 pixels since only a column */ 8703 totals[cc]= 0.0; 8704 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 8705 * totals[RED]/= 2.0; 8706 */ 8707 for (kk = 0; kk < BOX2; kk++) { 8708 totals[cc]+= extractTotals[kk][cc]; 8709 } 8710 totals[cc]/= (double)BOX2; 8711 8712 (*shove)(totals[cc],outIndex,dataOut); 8713 outIndex++; 8714 src+= elementSizeInBytes; 8715 } /* for cc */ 8716 8717 /* skip over to next group of 2 */ 8718 src+= rowSizeInBytes; 8719 } /* for ii */ 8720 8721 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 8722 assert(outIndex == halfDepth * components); 8723 } 8724 else if (height == 1) { /* horizontal slice viewed from top */ 8725 /* printf("horizontal slice\n"); */ 8726 assert(width != 1); 8727 8728 for (ii= 0; ii< halfDepth; ii++) { 8729 for (jj= 0; jj< halfWidth; jj++) { 8730 int cc; 8731 8732 for (cc = 0; cc < components; cc++) { 8733 int kk; 8734 double totals[4]; 8735 double extractTotals[BOX4][4]; 8736 8737 extractTotals[0][cc]=(*extract)(isSwap,src); 8738 extractTotals[1][cc]=(*extract)(isSwap, 8739 (src+groupSizeInBytes)); 8740 extractTotals[2][cc]=(*extract)(isSwap, 8741 (src+imageSizeInBytes)); 8742 extractTotals[3][cc]=(*extract)(isSwap, 8743 (src+imageSizeInBytes+groupSizeInBytes)); 8744 8745 /* grab 4 pixels to average */ 8746 totals[cc]= 0.0; 8747 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 8748 * extractTotals[2][RED]+extractTotals[3][RED]; 8749 * totals[RED]/= 4.0; 8750 */ 8751 for (kk = 0; kk < BOX4; kk++) { 8752 totals[cc]+= extractTotals[kk][cc]; 8753 } 8754 totals[cc]/= (double)BOX4; 8755 8756 (*shove)(totals[cc],outIndex,dataOut); 8757 outIndex++; 8758 8759 src+= elementSizeInBytes; 8760 } /* for cc */ 8761 8762 /* skip over to next horizontal square of 4 */ 8763 src+= groupSizeInBytes; 8764 } /* for jj */ 8765 src+= rowPadBytes; 8766 8767 src+= rowSizeInBytes; 8768 } /* for ii */ 8769 8770 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 8771 assert(outIndex == halfWidth * halfDepth * components); 8772 } 8773 else if (width == 1) { /* vertical slice viewed from top */ 8774 /* printf("vertical slice\n"); */ 8775 assert(height != 1); 8776 8777 for (ii= 0; ii< halfDepth; ii++) { 8778 for (jj= 0; jj< halfHeight; jj++) { 8779 int cc; 8780 8781 for (cc = 0; cc < components; cc++) { 8782 int kk; 8783 double totals[4]; 8784 double extractTotals[BOX4][4]; 8785 8786 extractTotals[0][cc]=(*extract)(isSwap,src); 8787 extractTotals[1][cc]=(*extract)(isSwap, 8788 (src+rowSizeInBytes)); 8789 extractTotals[2][cc]=(*extract)(isSwap, 8790 (src+imageSizeInBytes)); 8791 extractTotals[3][cc]=(*extract)(isSwap, 8792 (src+imageSizeInBytes+rowSizeInBytes)); 8793 8794 /* grab 4 pixels to average */ 8795 totals[cc]= 0.0; 8796 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 8797 * extractTotals[2][RED]+extractTotals[3][RED]; 8798 * totals[RED]/= 4.0; 8799 */ 8800 for (kk = 0; kk < BOX4; kk++) { 8801 totals[cc]+= extractTotals[kk][cc]; 8802 } 8803 totals[cc]/= (double)BOX4; 8804 8805 (*shove)(totals[cc],outIndex,dataOut); 8806 outIndex++; 8807 8808 src+= elementSizeInBytes; 8809 } /* for cc */ 8810 src+= rowPadBytes; 8811 8812 /* skip over to next vertical square of 4 */ 8813 src+= rowSizeInBytes; 8814 } /* for jj */ 8815 src+= imagePadBytes; 8816 8817 src+= imageSizeInBytes; 8818 } /* for ii */ 8819 8820 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 8821 assert(outIndex == halfHeight * halfDepth * components); 8822 } 8823 8824 } /* halveImageSlice() */ 8825 8826 static void halveImage3D(int components, 8827 GLdouble (*extract)(int, const void *), 8828 void (*shove)(GLdouble, int, void *), 8829 GLint width, GLint height, GLint depth, 8830 const void *dataIn, void *dataOut, 8831 GLint elementSizeInBytes, 8832 GLint groupSizeInBytes, 8833 GLint rowSizeInBytes, 8834 GLint imageSizeInBytes, 8835 GLint isSwap) 8836 { 8837 assert(depth > 1); 8838 8839 /* a horizontal/vertical/one-column slice viewed from top */ 8840 if (width == 1 || height == 1) { 8841 assert(1 <= depth); 8842 8843 halveImageSlice(components,extract,shove, width, height, depth, 8844 dataIn, dataOut, elementSizeInBytes, groupSizeInBytes, 8845 rowSizeInBytes, imageSizeInBytes, isSwap); 8846 return; 8847 } 8848 { 8849 int ii, jj, dd; 8850 8851 int halfWidth= width / 2; 8852 int halfHeight= height / 2; 8853 int halfDepth= depth / 2; 8854 const char *src= (const char *) dataIn; 8855 int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes); 8856 int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); 8857 int outIndex= 0; 8858 8859 for (dd= 0; dd < halfDepth; dd++) { 8860 for (ii= 0; ii< halfHeight; ii++) { 8861 for (jj= 0; jj< halfWidth; jj++) { 8862 int cc; 8863 8864 for (cc= 0; cc < components; cc++) { 8865 int kk; 8866 #define BOX8 8 8867 double totals[4]; /* 4 is maximum components */ 8868 double extractTotals[BOX8][4]; /* 4 is maximum components */ 8869 8870 extractTotals[0][cc]= (*extract)(isSwap,src); 8871 extractTotals[1][cc]= (*extract)(isSwap, 8872 (src+groupSizeInBytes)); 8873 extractTotals[2][cc]= (*extract)(isSwap, 8874 (src+rowSizeInBytes)); 8875 extractTotals[3][cc]= (*extract)(isSwap, 8876 (src+rowSizeInBytes+groupSizeInBytes)); 8877 8878 extractTotals[4][cc]= (*extract)(isSwap, 8879 (src+imageSizeInBytes)); 8880 8881 extractTotals[5][cc]= (*extract)(isSwap, 8882 (src+groupSizeInBytes+imageSizeInBytes)); 8883 extractTotals[6][cc]= (*extract)(isSwap, 8884 (src+rowSizeInBytes+imageSizeInBytes)); 8885 extractTotals[7][cc]= (*extract)(isSwap, 8886 (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes)); 8887 8888 totals[cc]= 0.0; 8889 8890 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 8891 * extractTotals[2][RED]+extractTotals[3][RED]+ 8892 * extractTotals[4][RED]+extractTotals[5][RED]+ 8893 * extractTotals[6][RED]+extractTotals[7][RED]; 8894 * totals[RED]/= 8.0; 8895 */ 8896 for (kk = 0; kk < BOX8; kk++) { 8897 totals[cc]+= extractTotals[kk][cc]; 8898 } 8899 totals[cc]/= (double)BOX8; 8900 8901 (*shove)(totals[cc],outIndex,dataOut); 8902 8903 outIndex++; 8904 8905 src+= elementSizeInBytes; /* go to next component */ 8906 } /* for cc */ 8907 8908 /* skip over to next square of 4 */ 8909 src+= groupSizeInBytes; 8910 } /* for jj */ 8911 /* skip past pad bytes, if any, to get to next row */ 8912 src+= rowPadBytes; 8913 8914 /* src is at beginning of a row here, but it's the second row of 8915 * the square block of 4 pixels that we just worked on so we 8916 * need to go one more row. 8917 * i.e., 8918 * OO... 8919 * here -->OO... 8920 * but want -->OO... 8921 * OO... 8922 * ... 8923 */ 8924 src+= rowSizeInBytes; 8925 } /* for ii */ 8926 8927 /* skip past pad bytes, if any, to get to next image */ 8928 src+= imagePadBytes; 8929 8930 src+= imageSizeInBytes; 8931 } /* for dd */ 8932 8933 /* both pointers must reach one byte after the end */ 8934 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 8935 assert(outIndex == halfWidth * halfHeight * halfDepth * components); 8936 } 8937 } /* halveImage3D() */ 8938 8939 8940 8941 /*** mipmap.c ***/ 8942 8943