Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmipmap.c
Go to the documentation of this file.
00001 /* 00002 ** License Applicability. Except to the extent portions of this file are 00003 ** made subject to an alternative license as permitted in the SGI Free 00004 ** Software License B, Version 1.1 (the "License"), the contents of this 00005 ** file are subject only to the provisions of the License. You may not use 00006 ** this file except in compliance with the License. You may obtain a copy 00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 00009 ** 00010 ** http://oss.sgi.com/projects/FreeB 00011 ** 00012 ** Note that, as provided in the License, the Software is distributed on an 00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00017 ** 00018 ** Original Code. The Original Code is: OpenGL Sample Implementation, 00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 00021 ** Copyright in any portions created by third parties is as indicated 00022 ** elsewhere herein. All Rights Reserved. 00023 ** 00024 ** Additional Notice Provisions: The application programming interfaces 00025 ** established by SGI in conjunction with the Original Code are The 00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software 00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 00031 ** published by SGI, but has not been independently verified as being 00032 ** compliant with the OpenGL(R) version 1.2.1 Specification. 00033 ** 00034 */ 00035 00036 #include "gluos.h" 00037 #include <assert.h> 00038 #include <GL/gl.h> 00039 #include <GL/glext.h> 00040 #include <GL/glu.h> 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 #include <string.h> 00044 #include <limits.h> /* UINT_MAX */ 00045 #include <math.h> 00046 #include "gluint.h" 00047 00048 typedef union { 00049 unsigned char ub[4]; 00050 unsigned short us[2]; 00051 unsigned int ui; 00052 char b[4]; 00053 short s[2]; 00054 int i; 00055 float f; 00056 } Type_Widget; 00057 00058 /* Pixel storage modes */ 00059 typedef struct { 00060 GLint pack_alignment; 00061 GLint pack_row_length; 00062 GLint pack_skip_rows; 00063 GLint pack_skip_pixels; 00064 GLint pack_lsb_first; 00065 GLint pack_swap_bytes; 00066 GLint pack_skip_images; 00067 GLint pack_image_height; 00068 00069 GLint unpack_alignment; 00070 GLint unpack_row_length; 00071 GLint unpack_skip_rows; 00072 GLint unpack_skip_pixels; 00073 GLint unpack_lsb_first; 00074 GLint unpack_swap_bytes; 00075 GLint unpack_skip_images; 00076 GLint unpack_image_height; 00077 } PixelStorageModes; 00078 00079 static int gluBuild1DMipmapLevelsCore(GLenum, GLint, 00080 GLsizei, 00081 GLsizei, 00082 GLenum, GLenum, GLint, GLint, GLint, 00083 const void *); 00084 static int gluBuild2DMipmapLevelsCore(GLenum, GLint, 00085 GLsizei, GLsizei, 00086 GLsizei, GLsizei, 00087 GLenum, GLenum, GLint, GLint, GLint, 00088 const void *); 00089 static int gluBuild3DMipmapLevelsCore(GLenum, GLint, 00090 GLsizei, GLsizei, GLsizei, 00091 GLsizei, GLsizei, GLsizei, 00092 GLenum, GLenum, GLint, GLint, GLint, 00093 const void *); 00094 00095 /* 00096 * internal function declarations 00097 */ 00098 static GLfloat bytes_per_element(GLenum type); 00099 static GLint elements_per_group(GLenum format, GLenum type); 00100 static GLint is_index(GLenum format); 00101 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type); 00102 static void fill_image(const PixelStorageModes *, 00103 GLint width, GLint height, GLenum format, 00104 GLenum type, GLboolean index_format, 00105 const void *userdata, GLushort *newimage); 00106 static void empty_image(const PixelStorageModes *, 00107 GLint width, GLint height, GLenum format, 00108 GLenum type, GLboolean index_format, 00109 const GLushort *oldimage, void *userdata); 00110 static void scale_internal(GLint components, GLint widthin, GLint heightin, 00111 const GLushort *datain, 00112 GLint widthout, GLint heightout, 00113 GLushort *dataout); 00114 00115 static void scale_internal_ubyte(GLint components, GLint widthin, 00116 GLint heightin, const GLubyte *datain, 00117 GLint widthout, GLint heightout, 00118 GLubyte *dataout, GLint element_size, 00119 GLint ysize, GLint group_size); 00120 static void scale_internal_byte(GLint components, GLint widthin, 00121 GLint heightin, const GLbyte *datain, 00122 GLint widthout, GLint heightout, 00123 GLbyte *dataout, GLint element_size, 00124 GLint ysize, GLint group_size); 00125 static void scale_internal_ushort(GLint components, GLint widthin, 00126 GLint heightin, const GLushort *datain, 00127 GLint widthout, GLint heightout, 00128 GLushort *dataout, GLint element_size, 00129 GLint ysize, GLint group_size, 00130 GLint myswap_bytes); 00131 static void scale_internal_short(GLint components, GLint widthin, 00132 GLint heightin, const GLshort *datain, 00133 GLint widthout, GLint heightout, 00134 GLshort *dataout, GLint element_size, 00135 GLint ysize, GLint group_size, 00136 GLint myswap_bytes); 00137 static void scale_internal_uint(GLint components, GLint widthin, 00138 GLint heightin, const GLuint *datain, 00139 GLint widthout, GLint heightout, 00140 GLuint *dataout, GLint element_size, 00141 GLint ysize, GLint group_size, 00142 GLint myswap_bytes); 00143 static void scale_internal_int(GLint components, GLint widthin, 00144 GLint heightin, const GLint *datain, 00145 GLint widthout, GLint heightout, 00146 GLint *dataout, GLint element_size, 00147 GLint ysize, GLint group_size, 00148 GLint myswap_bytes); 00149 static void scale_internal_float(GLint components, GLint widthin, 00150 GLint heightin, const GLfloat *datain, 00151 GLint widthout, GLint heightout, 00152 GLfloat *dataout, GLint element_size, 00153 GLint ysize, GLint group_size, 00154 GLint myswap_bytes); 00155 00156 static int checkMipmapArgs(GLenum, GLenum, GLenum); 00157 static GLboolean legalFormat(GLenum); 00158 static GLboolean legalType(GLenum); 00159 static GLboolean isTypePackedPixel(GLenum); 00160 static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum); 00161 static GLboolean isLegalLevels(GLint, GLint, GLint, GLint); 00162 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum, 00163 GLint *, GLint *); 00164 00165 /* all extract/shove routines must return double to handle unsigned ints */ 00166 static GLdouble extractUbyte(int, const void *); 00167 static void shoveUbyte(GLdouble, int, void *); 00168 static GLdouble extractSbyte(int, const void *); 00169 static void shoveSbyte(GLdouble, int, void *); 00170 static GLdouble extractUshort(int, const void *); 00171 static void shoveUshort(GLdouble, int, void *); 00172 static GLdouble extractSshort(int, const void *); 00173 static void shoveSshort(GLdouble, int, void *); 00174 static GLdouble extractUint(int, const void *); 00175 static void shoveUint(GLdouble, int, void *); 00176 static GLdouble extractSint(int, const void *); 00177 static void shoveSint(GLdouble, int, void *); 00178 static GLdouble extractFloat(int, const void *); 00179 static void shoveFloat(GLdouble, int, void *); 00180 static void halveImageSlice(int, GLdouble (*)(int, const void *), 00181 void (*)(GLdouble, int, void *), 00182 GLint, GLint, GLint, 00183 const void *, void *, 00184 GLint, GLint, GLint, GLint, GLint); 00185 static void halveImage3D(int, GLdouble (*)(int, const void *), 00186 void (*)(GLdouble, int, void *), 00187 GLint, GLint, GLint, 00188 const void *, void *, 00189 GLint, GLint, GLint, GLint, GLint); 00190 00191 /* packedpixel type scale routines */ 00192 static void extract332(int,const void *, GLfloat []); 00193 static void shove332(const GLfloat [],int ,void *); 00194 static void extract233rev(int,const void *, GLfloat []); 00195 static void shove233rev(const GLfloat [],int ,void *); 00196 static void extract565(int,const void *, GLfloat []); 00197 static void shove565(const GLfloat [],int ,void *); 00198 static void extract565rev(int,const void *, GLfloat []); 00199 static void shove565rev(const GLfloat [],int ,void *); 00200 static void extract4444(int,const void *, GLfloat []); 00201 static void shove4444(const GLfloat [],int ,void *); 00202 static void extract4444rev(int,const void *, GLfloat []); 00203 static void shove4444rev(const GLfloat [],int ,void *); 00204 static void extract5551(int,const void *, GLfloat []); 00205 static void shove5551(const GLfloat [],int ,void *); 00206 static void extract1555rev(int,const void *, GLfloat []); 00207 static void shove1555rev(const GLfloat [],int ,void *); 00208 static void extract8888(int,const void *, GLfloat []); 00209 static void shove8888(const GLfloat [],int ,void *); 00210 static void extract8888rev(int,const void *, GLfloat []); 00211 static void shove8888rev(const GLfloat [],int ,void *); 00212 static void extract1010102(int,const void *, GLfloat []); 00213 static void shove1010102(const GLfloat [],int ,void *); 00214 static void extract2101010rev(int,const void *, GLfloat []); 00215 static void shove2101010rev(const GLfloat [],int ,void *); 00216 static void scaleInternalPackedPixel(int, 00217 void (*)(int, const void *,GLfloat []), 00218 void (*)(const GLfloat [],int, void *), 00219 GLint,GLint, const void *, 00220 GLint,GLint,void *,GLint,GLint,GLint); 00221 static void halveImagePackedPixel(int, 00222 void (*)(int, const void *,GLfloat []), 00223 void (*)(const GLfloat [],int, void *), 00224 GLint, GLint, const void *, 00225 void *, GLint, GLint, GLint); 00226 static void halve1DimagePackedPixel(int, 00227 void (*)(int, const void *,GLfloat []), 00228 void (*)(const GLfloat [],int, void *), 00229 GLint, GLint, const void *, 00230 void *, GLint, GLint, GLint); 00231 00232 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *, 00233 GLubyte *, GLint, GLint, GLint); 00234 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *, 00235 GLint, GLint, GLint); 00236 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *, 00237 GLushort *, GLint, GLint, GLint, GLint); 00238 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *, 00239 GLint, GLint, GLint, GLint); 00240 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *, 00241 GLint, GLint, GLint, GLint); 00242 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *, 00243 GLint, GLint, GLint, GLint); 00244 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *, 00245 GLint, GLint, GLint, GLint); 00246 00247 static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum); 00248 static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum, 00249 GLenum, GLboolean, const void *, GLushort *); 00250 static void emptyImage3D(const PixelStorageModes *, 00251 GLint, GLint, GLint, GLenum, 00252 GLenum, GLboolean, 00253 const GLushort *, void *); 00254 static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *, 00255 GLint, GLint, GLint, GLushort *); 00256 00257 static void retrieveStoreModes(PixelStorageModes *psm) 00258 { 00259 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment); 00260 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length); 00261 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows); 00262 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels); 00263 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first); 00264 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes); 00265 00266 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment); 00267 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length); 00268 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows); 00269 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels); 00270 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first); 00271 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes); 00272 } 00273 00274 static void retrieveStoreModes3D(PixelStorageModes *psm) 00275 { 00276 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment); 00277 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length); 00278 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows); 00279 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels); 00280 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first); 00281 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes); 00282 glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images); 00283 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height); 00284 00285 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment); 00286 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length); 00287 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows); 00288 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels); 00289 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first); 00290 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes); 00291 glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images); 00292 glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height); 00293 } 00294 00295 static int computeLog(GLuint value) 00296 { 00297 int i; 00298 00299 i = 0; 00300 00301 /* Error! */ 00302 if (value == 0) return -1; 00303 00304 for (;;) { 00305 if (value & 1) { 00306 /* Error ! */ 00307 if (value != 1) return -1; 00308 return i; 00309 } 00310 value = value >> 1; 00311 i++; 00312 } 00313 } 00314 00315 /* 00316 ** Compute the nearest power of 2 number. This algorithm is a little 00317 ** strange, but it works quite well. 00318 */ 00319 static int nearestPower(GLuint value) 00320 { 00321 int i; 00322 00323 i = 1; 00324 00325 /* Error! */ 00326 if (value == 0) return -1; 00327 00328 for (;;) { 00329 if (value == 1) { 00330 return i; 00331 } else if (value == 3) { 00332 return i*4; 00333 } 00334 value = value >> 1; 00335 i *= 2; 00336 } 00337 } 00338 00339 #define __GLU_SWAP_2_BYTES(s)\ 00340 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) 00341 00342 #define __GLU_SWAP_4_BYTES(s)\ 00343 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \ 00344 ((GLuint)((const GLubyte*)(s))[2])<<16 | \ 00345 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) 00346 00347 static void halveImage(GLint components, GLuint width, GLuint height, 00348 const GLushort *datain, GLushort *dataout) 00349 { 00350 int i, j, k; 00351 int newwidth, newheight; 00352 int delta; 00353 GLushort *s; 00354 const GLushort *t; 00355 00356 newwidth = width / 2; 00357 newheight = height / 2; 00358 delta = width * components; 00359 s = dataout; 00360 t = datain; 00361 00362 /* Piece o' cake! */ 00363 for (i = 0; i < newheight; i++) { 00364 for (j = 0; j < newwidth; j++) { 00365 for (k = 0; k < components; k++) { 00366 s[0] = (t[0] + t[components] + t[delta] + 00367 t[delta+components] + 2) / 4; 00368 s++; t++; 00369 } 00370 t += components; 00371 } 00372 t += delta; 00373 } 00374 } 00375 00376 static void halveImage_ubyte(GLint components, GLuint width, GLuint height, 00377 const GLubyte *datain, GLubyte *dataout, 00378 GLint element_size, GLint ysize, GLint group_size) 00379 { 00380 int i, j, k; 00381 int newwidth, newheight; 00382 GLubyte *s; 00383 const char *t; 00384 00385 /* handle case where there is only 1 column/row */ 00386 if (width == 1 || height == 1) { 00387 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 00388 halve1Dimage_ubyte(components,width,height,datain,dataout, 00389 element_size,ysize,group_size); 00390 return; 00391 } 00392 00393 newwidth = width / 2; 00394 newheight = height / 2; 00395 s = dataout; 00396 t = (const char *)datain; 00397 00398 /* Piece o' cake! */ 00399 for (i = 0; i < newheight; i++) { 00400 for (j = 0; j < newwidth; j++) { 00401 for (k = 0; k < components; k++) { 00402 s[0] = (*(const GLubyte*)t + 00403 *(const GLubyte*)(t+group_size) + 00404 *(const GLubyte*)(t+ysize) + 00405 *(const GLubyte*)(t+ysize+group_size) + 2) / 4; 00406 s++; t += element_size; 00407 } 00408 t += group_size; 00409 } 00410 t += ysize; 00411 } 00412 } 00413 00414 /* */ 00415 static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height, 00416 const GLubyte *dataIn, GLubyte *dataOut, 00417 GLint element_size, GLint ysize, 00418 GLint group_size) 00419 { 00420 GLint halfWidth= width / 2; 00421 GLint halfHeight= height / 2; 00422 const char *src= (const char *) dataIn; 00423 GLubyte *dest= dataOut; 00424 int jj; 00425 00426 assert(width == 1 || height == 1); /* must be 1D */ 00427 assert(width != height); /* can't be square */ 00428 00429 if (height == 1) { /* 1 row */ 00430 assert(width != 1); /* widthxheight can't be 1x1 */ 00431 halfHeight= 1; 00432 00433 for (jj= 0; jj< halfWidth; jj++) { 00434 int kk; 00435 for (kk= 0; kk< components; kk++) { 00436 *dest= (*(const GLubyte*)src + 00437 *(const GLubyte*)(src+group_size)) / 2; 00438 00439 src+= element_size; 00440 dest++; 00441 } 00442 src+= group_size; /* skip to next 2 */ 00443 } 00444 { 00445 int padBytes= ysize - (width*group_size); 00446 src+= padBytes; /* for assertion only */ 00447 } 00448 } 00449 else if (width == 1) { /* 1 column */ 00450 int padBytes= ysize - (width * group_size); 00451 assert(height != 1); /* widthxheight can't be 1x1 */ 00452 halfWidth= 1; 00453 /* one vertical column with possible pad bytes per row */ 00454 /* average two at a time */ 00455 00456 for (jj= 0; jj< halfHeight; jj++) { 00457 int kk; 00458 for (kk= 0; kk< components; kk++) { 00459 *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2; 00460 00461 src+= element_size; 00462 dest++; 00463 } 00464 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 00465 src+= ysize; 00466 } 00467 } 00468 00469 assert(src == &((const char *)dataIn)[ysize*height]); 00470 assert((char *)dest == &((char *)dataOut) 00471 [components * element_size * halfWidth * halfHeight]); 00472 } /* halve1Dimage_ubyte() */ 00473 00474 static void halveImage_byte(GLint components, GLuint width, GLuint height, 00475 const GLbyte *datain, GLbyte *dataout, 00476 GLint element_size, 00477 GLint ysize, GLint group_size) 00478 { 00479 int i, j, k; 00480 int newwidth, newheight; 00481 GLbyte *s; 00482 const char *t; 00483 00484 /* handle case where there is only 1 column/row */ 00485 if (width == 1 || height == 1) { 00486 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 00487 halve1Dimage_byte(components,width,height,datain,dataout, 00488 element_size,ysize,group_size); 00489 return; 00490 } 00491 00492 newwidth = width / 2; 00493 newheight = height / 2; 00494 s = dataout; 00495 t = (const char *)datain; 00496 00497 /* Piece o' cake! */ 00498 for (i = 0; i < newheight; i++) { 00499 for (j = 0; j < newwidth; j++) { 00500 for (k = 0; k < components; k++) { 00501 s[0] = (*(const GLbyte*)t + 00502 *(const GLbyte*)(t+group_size) + 00503 *(const GLbyte*)(t+ysize) + 00504 *(const GLbyte*)(t+ysize+group_size) + 2) / 4; 00505 s++; t += element_size; 00506 } 00507 t += group_size; 00508 } 00509 t += ysize; 00510 } 00511 } 00512 00513 static void halve1Dimage_byte(GLint components, GLuint width, GLuint height, 00514 const GLbyte *dataIn, GLbyte *dataOut, 00515 GLint element_size,GLint ysize, GLint group_size) 00516 { 00517 GLint halfWidth= width / 2; 00518 GLint halfHeight= height / 2; 00519 const char *src= (const char *) dataIn; 00520 GLbyte *dest= dataOut; 00521 int jj; 00522 00523 assert(width == 1 || height == 1); /* must be 1D */ 00524 assert(width != height); /* can't be square */ 00525 00526 if (height == 1) { /* 1 row */ 00527 assert(width != 1); /* widthxheight can't be 1x1 */ 00528 halfHeight= 1; 00529 00530 for (jj= 0; jj< halfWidth; jj++) { 00531 int kk; 00532 for (kk= 0; kk< components; kk++) { 00533 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2; 00534 00535 src+= element_size; 00536 dest++; 00537 } 00538 src+= group_size; /* skip to next 2 */ 00539 } 00540 { 00541 int padBytes= ysize - (width*group_size); 00542 src+= padBytes; /* for assertion only */ 00543 } 00544 } 00545 else if (width == 1) { /* 1 column */ 00546 int padBytes= ysize - (width * group_size); 00547 assert(height != 1); /* widthxheight can't be 1x1 */ 00548 halfWidth= 1; 00549 /* one vertical column with possible pad bytes per row */ 00550 /* average two at a time */ 00551 00552 for (jj= 0; jj< halfHeight; jj++) { 00553 int kk; 00554 for (kk= 0; kk< components; kk++) { 00555 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2; 00556 00557 src+= element_size; 00558 dest++; 00559 } 00560 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 00561 src+= ysize; 00562 } 00563 00564 assert(src == &((const char *)dataIn)[ysize*height]); 00565 } 00566 00567 assert((char *)dest == &((char *)dataOut) 00568 [components * element_size * halfWidth * halfHeight]); 00569 } /* halve1Dimage_byte() */ 00570 00571 static void halveImage_ushort(GLint components, GLuint width, GLuint height, 00572 const GLushort *datain, GLushort *dataout, 00573 GLint element_size, GLint ysize, GLint group_size, 00574 GLint myswap_bytes) 00575 { 00576 int i, j, k; 00577 int newwidth, newheight; 00578 GLushort *s; 00579 const char *t; 00580 00581 /* handle case where there is only 1 column/row */ 00582 if (width == 1 || height == 1) { 00583 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 00584 halve1Dimage_ushort(components,width,height,datain,dataout, 00585 element_size,ysize,group_size, myswap_bytes); 00586 return; 00587 } 00588 00589 newwidth = width / 2; 00590 newheight = height / 2; 00591 s = dataout; 00592 t = (const char *)datain; 00593 00594 /* Piece o' cake! */ 00595 if (!myswap_bytes) 00596 for (i = 0; i < newheight; i++) { 00597 for (j = 0; j < newwidth; j++) { 00598 for (k = 0; k < components; k++) { 00599 s[0] = (*(const GLushort*)t + 00600 *(const GLushort*)(t+group_size) + 00601 *(const GLushort*)(t+ysize) + 00602 *(const GLushort*)(t+ysize+group_size) + 2) / 4; 00603 s++; t += element_size; 00604 } 00605 t += group_size; 00606 } 00607 t += ysize; 00608 } 00609 else 00610 for (i = 0; i < newheight; i++) { 00611 for (j = 0; j < newwidth; j++) { 00612 for (k = 0; k < components; k++) { 00613 s[0] = (__GLU_SWAP_2_BYTES(t) + 00614 __GLU_SWAP_2_BYTES(t+group_size) + 00615 __GLU_SWAP_2_BYTES(t+ysize) + 00616 __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4; 00617 s++; t += element_size; 00618 } 00619 t += group_size; 00620 } 00621 t += ysize; 00622 } 00623 } 00624 00625 static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height, 00626 const GLushort *dataIn, GLushort *dataOut, 00627 GLint element_size, GLint ysize, 00628 GLint group_size, GLint myswap_bytes) 00629 { 00630 GLint halfWidth= width / 2; 00631 GLint halfHeight= height / 2; 00632 const char *src= (const char *) dataIn; 00633 GLushort *dest= dataOut; 00634 int jj; 00635 00636 assert(width == 1 || height == 1); /* must be 1D */ 00637 assert(width != height); /* can't be square */ 00638 00639 if (height == 1) { /* 1 row */ 00640 assert(width != 1); /* widthxheight can't be 1x1 */ 00641 halfHeight= 1; 00642 00643 for (jj= 0; jj< halfWidth; jj++) { 00644 int kk; 00645 for (kk= 0; kk< components; kk++) { 00646 #define BOX2 2 00647 GLushort ushort[BOX2]; 00648 if (myswap_bytes) { 00649 ushort[0]= __GLU_SWAP_2_BYTES(src); 00650 ushort[1]= __GLU_SWAP_2_BYTES(src+group_size); 00651 } 00652 else { 00653 ushort[0]= *(const GLushort*)src; 00654 ushort[1]= *(const GLushort*)(src+group_size); 00655 } 00656 00657 *dest= (ushort[0] + ushort[1]) / 2; 00658 src+= element_size; 00659 dest++; 00660 } 00661 src+= group_size; /* skip to next 2 */ 00662 } 00663 { 00664 int padBytes= ysize - (width*group_size); 00665 src+= padBytes; /* for assertion only */ 00666 } 00667 } 00668 else if (width == 1) { /* 1 column */ 00669 int padBytes= ysize - (width * group_size); 00670 assert(height != 1); /* widthxheight can't be 1x1 */ 00671 halfWidth= 1; 00672 /* one vertical column with possible pad bytes per row */ 00673 /* average two at a time */ 00674 00675 for (jj= 0; jj< halfHeight; jj++) { 00676 int kk; 00677 for (kk= 0; kk< components; kk++) { 00678 #define BOX2 2 00679 GLushort ushort[BOX2]; 00680 if (myswap_bytes) { 00681 ushort[0]= __GLU_SWAP_2_BYTES(src); 00682 ushort[1]= __GLU_SWAP_2_BYTES(src+ysize); 00683 } 00684 else { 00685 ushort[0]= *(const GLushort*)src; 00686 ushort[1]= *(const GLushort*)(src+ysize); 00687 } 00688 *dest= (ushort[0] + ushort[1]) / 2; 00689 00690 src+= element_size; 00691 dest++; 00692 } 00693 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 00694 src+= ysize; 00695 } 00696 00697 assert(src == &((const char *)dataIn)[ysize*height]); 00698 } 00699 00700 assert((char *)dest == &((char *)dataOut) 00701 [components * element_size * halfWidth * halfHeight]); 00702 00703 } /* halve1Dimage_ushort() */ 00704 00705 00706 static void halveImage_short(GLint components, GLuint width, GLuint height, 00707 const GLshort *datain, GLshort *dataout, 00708 GLint element_size, GLint ysize, GLint group_size, 00709 GLint myswap_bytes) 00710 { 00711 int i, j, k; 00712 int newwidth, newheight; 00713 GLshort *s; 00714 const char *t; 00715 00716 /* handle case where there is only 1 column/row */ 00717 if (width == 1 || height == 1) { 00718 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 00719 halve1Dimage_short(components,width,height,datain,dataout, 00720 element_size,ysize,group_size, myswap_bytes); 00721 return; 00722 } 00723 00724 newwidth = width / 2; 00725 newheight = height / 2; 00726 s = dataout; 00727 t = (const char *)datain; 00728 00729 /* Piece o' cake! */ 00730 if (!myswap_bytes) 00731 for (i = 0; i < newheight; i++) { 00732 for (j = 0; j < newwidth; j++) { 00733 for (k = 0; k < components; k++) { 00734 s[0] = (*(const GLshort*)t + 00735 *(const GLshort*)(t+group_size) + 00736 *(const GLshort*)(t+ysize) + 00737 *(const GLshort*)(t+ysize+group_size) + 2) / 4; 00738 s++; t += element_size; 00739 } 00740 t += group_size; 00741 } 00742 t += ysize; 00743 } 00744 else 00745 for (i = 0; i < newheight; i++) { 00746 for (j = 0; j < newwidth; j++) { 00747 for (k = 0; k < components; k++) { 00748 GLushort b; 00749 GLint buf; 00750 b = __GLU_SWAP_2_BYTES(t); 00751 buf = *(const GLshort*)&b; 00752 b = __GLU_SWAP_2_BYTES(t+group_size); 00753 buf += *(const GLshort*)&b; 00754 b = __GLU_SWAP_2_BYTES(t+ysize); 00755 buf += *(const GLshort*)&b; 00756 b = __GLU_SWAP_2_BYTES(t+ysize+group_size); 00757 buf += *(const GLshort*)&b; 00758 s[0] = (GLshort)((buf+2)/4); 00759 s++; t += element_size; 00760 } 00761 t += group_size; 00762 } 00763 t += ysize; 00764 } 00765 } 00766 00767 static void halve1Dimage_short(GLint components, GLuint width, GLuint height, 00768 const GLshort *dataIn, GLshort *dataOut, 00769 GLint element_size, GLint ysize, 00770 GLint group_size, GLint myswap_bytes) 00771 { 00772 GLint halfWidth= width / 2; 00773 GLint halfHeight= height / 2; 00774 const char *src= (const char *) dataIn; 00775 GLshort *dest= dataOut; 00776 int jj; 00777 00778 assert(width == 1 || height == 1); /* must be 1D */ 00779 assert(width != height); /* can't be square */ 00780 00781 if (height == 1) { /* 1 row */ 00782 assert(width != 1); /* widthxheight can't be 1x1 */ 00783 halfHeight= 1; 00784 00785 for (jj= 0; jj< halfWidth; jj++) { 00786 int kk; 00787 for (kk= 0; kk< components; kk++) { 00788 #define BOX2 2 00789 GLshort sshort[BOX2]; 00790 if (myswap_bytes) { 00791 sshort[0]= __GLU_SWAP_2_BYTES(src); 00792 sshort[1]= __GLU_SWAP_2_BYTES(src+group_size); 00793 } 00794 else { 00795 sshort[0]= *(const GLshort*)src; 00796 sshort[1]= *(const GLshort*)(src+group_size); 00797 } 00798 00799 *dest= (sshort[0] + sshort[1]) / 2; 00800 src+= element_size; 00801 dest++; 00802 } 00803 src+= group_size; /* skip to next 2 */ 00804 } 00805 { 00806 int padBytes= ysize - (width*group_size); 00807 src+= padBytes; /* for assertion only */ 00808 } 00809 } 00810 else if (width == 1) { /* 1 column */ 00811 int padBytes= ysize - (width * group_size); 00812 assert(height != 1); /* widthxheight can't be 1x1 */ 00813 halfWidth= 1; 00814 /* one vertical column with possible pad bytes per row */ 00815 /* average two at a time */ 00816 00817 for (jj= 0; jj< halfHeight; jj++) { 00818 int kk; 00819 for (kk= 0; kk< components; kk++) { 00820 #define BOX2 2 00821 GLshort sshort[BOX2]; 00822 if (myswap_bytes) { 00823 sshort[0]= __GLU_SWAP_2_BYTES(src); 00824 sshort[1]= __GLU_SWAP_2_BYTES(src+ysize); 00825 } 00826 else { 00827 sshort[0]= *(const GLshort*)src; 00828 sshort[1]= *(const GLshort*)(src+ysize); 00829 } 00830 *dest= (sshort[0] + sshort[1]) / 2; 00831 00832 src+= element_size; 00833 dest++; 00834 } 00835 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 00836 src+= ysize; 00837 } 00838 00839 assert(src == &((const char *)dataIn)[ysize*height]); 00840 } 00841 00842 assert((char *)dest == &((char *)dataOut) 00843 [components * element_size * halfWidth * halfHeight]); 00844 00845 } /* halve1Dimage_short() */ 00846 00847 00848 static void halveImage_uint(GLint components, GLuint width, GLuint height, 00849 const GLuint *datain, GLuint *dataout, 00850 GLint element_size, GLint ysize, GLint group_size, 00851 GLint myswap_bytes) 00852 { 00853 int i, j, k; 00854 int newwidth, newheight; 00855 GLuint *s; 00856 const char *t; 00857 00858 /* handle case where there is only 1 column/row */ 00859 if (width == 1 || height == 1) { 00860 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 00861 halve1Dimage_uint(components,width,height,datain,dataout, 00862 element_size,ysize,group_size, myswap_bytes); 00863 return; 00864 } 00865 00866 newwidth = width / 2; 00867 newheight = height / 2; 00868 s = dataout; 00869 t = (const char *)datain; 00870 00871 /* Piece o' cake! */ 00872 if (!myswap_bytes) 00873 for (i = 0; i < newheight; i++) { 00874 for (j = 0; j < newwidth; j++) { 00875 for (k = 0; k < components; k++) { 00876 /* need to cast to double to hold large unsigned ints */ 00877 s[0] = ((double)*(const GLuint*)t + 00878 (double)*(const GLuint*)(t+group_size) + 00879 (double)*(const GLuint*)(t+ysize) + 00880 (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5; 00881 s++; t += element_size; 00882 00883 } 00884 t += group_size; 00885 } 00886 t += ysize; 00887 } 00888 else 00889 for (i = 0; i < newheight; i++) { 00890 for (j = 0; j < newwidth; j++) { 00891 for (k = 0; k < components; k++) { 00892 /* need to cast to double to hold large unsigned ints */ 00893 GLdouble buf; 00894 buf = (GLdouble)__GLU_SWAP_4_BYTES(t) + 00895 (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) + 00896 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) + 00897 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size); 00898 s[0] = (GLuint)(buf/4 + 0.5); 00899 00900 s++; t += element_size; 00901 } 00902 t += group_size; 00903 } 00904 t += ysize; 00905 } 00906 } 00907 00908 /* */ 00909 static void halve1Dimage_uint(GLint components, GLuint width, GLuint height, 00910 const GLuint *dataIn, GLuint *dataOut, 00911 GLint element_size, GLint ysize, 00912 GLint group_size, GLint myswap_bytes) 00913 { 00914 GLint halfWidth= width / 2; 00915 GLint halfHeight= height / 2; 00916 const char *src= (const char *) dataIn; 00917 GLuint *dest= dataOut; 00918 int jj; 00919 00920 assert(width == 1 || height == 1); /* must be 1D */ 00921 assert(width != height); /* can't be square */ 00922 00923 if (height == 1) { /* 1 row */ 00924 assert(width != 1); /* widthxheight can't be 1x1 */ 00925 halfHeight= 1; 00926 00927 for (jj= 0; jj< halfWidth; jj++) { 00928 int kk; 00929 for (kk= 0; kk< components; kk++) { 00930 #define BOX2 2 00931 GLuint uint[BOX2]; 00932 if (myswap_bytes) { 00933 uint[0]= __GLU_SWAP_4_BYTES(src); 00934 uint[1]= __GLU_SWAP_4_BYTES(src+group_size); 00935 } 00936 else { 00937 uint[0]= *(const GLuint*)src; 00938 uint[1]= *(const GLuint*)(src+group_size); 00939 } 00940 *dest= ((double)uint[0]+(double)uint[1])/2.0; 00941 00942 src+= element_size; 00943 dest++; 00944 } 00945 src+= group_size; /* skip to next 2 */ 00946 } 00947 { 00948 int padBytes= ysize - (width*group_size); 00949 src+= padBytes; /* for assertion only */ 00950 } 00951 } 00952 else if (width == 1) { /* 1 column */ 00953 int padBytes= ysize - (width * group_size); 00954 assert(height != 1); /* widthxheight can't be 1x1 */ 00955 halfWidth= 1; 00956 /* one vertical column with possible pad bytes per row */ 00957 /* average two at a time */ 00958 00959 for (jj= 0; jj< halfHeight; jj++) { 00960 int kk; 00961 for (kk= 0; kk< components; kk++) { 00962 #define BOX2 2 00963 GLuint uint[BOX2]; 00964 if (myswap_bytes) { 00965 uint[0]= __GLU_SWAP_4_BYTES(src); 00966 uint[1]= __GLU_SWAP_4_BYTES(src+ysize); 00967 } 00968 else { 00969 uint[0]= *(const GLuint*)src; 00970 uint[1]= *(const GLuint*)(src+ysize); 00971 } 00972 *dest= ((double)uint[0]+(double)uint[1])/2.0; 00973 00974 src+= element_size; 00975 dest++; 00976 } 00977 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 00978 src+= ysize; 00979 } 00980 00981 assert(src == &((const char *)dataIn)[ysize*height]); 00982 } 00983 00984 assert((char *)dest == &((char *)dataOut) 00985 [components * element_size * halfWidth * halfHeight]); 00986 00987 } /* halve1Dimage_uint() */ 00988 00989 static void halveImage_int(GLint components, GLuint width, GLuint height, 00990 const GLint *datain, GLint *dataout, GLint element_size, 00991 GLint ysize, GLint group_size, GLint myswap_bytes) 00992 { 00993 int i, j, k; 00994 int newwidth, newheight; 00995 GLint *s; 00996 const char *t; 00997 00998 /* handle case where there is only 1 column/row */ 00999 if (width == 1 || height == 1) { 01000 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 01001 halve1Dimage_int(components,width,height,datain,dataout, 01002 element_size,ysize,group_size, myswap_bytes); 01003 return; 01004 } 01005 01006 newwidth = width / 2; 01007 newheight = height / 2; 01008 s = dataout; 01009 t = (const char *)datain; 01010 01011 /* Piece o' cake! */ 01012 if (!myswap_bytes) 01013 for (i = 0; i < newheight; i++) { 01014 for (j = 0; j < newwidth; j++) { 01015 for (k = 0; k < components; k++) { 01016 s[0] = ((float)*(const GLint*)t + 01017 (float)*(const GLint*)(t+group_size) + 01018 (float)*(const GLint*)(t+ysize) + 01019 (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5; 01020 s++; t += element_size; 01021 } 01022 t += group_size; 01023 } 01024 t += ysize; 01025 } 01026 else 01027 for (i = 0; i < newheight; i++) { 01028 for (j = 0; j < newwidth; j++) { 01029 for (k = 0; k < components; k++) { 01030 GLuint b; 01031 GLfloat buf; 01032 b = __GLU_SWAP_4_BYTES(t); 01033 buf = *(GLint*)&b; 01034 b = __GLU_SWAP_4_BYTES(t+group_size); 01035 buf += *(GLint*)&b; 01036 b = __GLU_SWAP_4_BYTES(t+ysize); 01037 buf += *(GLint*)&b; 01038 b = __GLU_SWAP_4_BYTES(t+ysize+group_size); 01039 buf += *(GLint*)&b; 01040 s[0] = (GLint)(buf/4 + 0.5); 01041 01042 s++; t += element_size; 01043 } 01044 t += group_size; 01045 } 01046 t += ysize; 01047 } 01048 } 01049 01050 /* */ 01051 static void halve1Dimage_int(GLint components, GLuint width, GLuint height, 01052 const GLint *dataIn, GLint *dataOut, 01053 GLint element_size, GLint ysize, 01054 GLint group_size, GLint myswap_bytes) 01055 { 01056 GLint halfWidth= width / 2; 01057 GLint halfHeight= height / 2; 01058 const char *src= (const char *) dataIn; 01059 GLint *dest= dataOut; 01060 int jj; 01061 01062 assert(width == 1 || height == 1); /* must be 1D */ 01063 assert(width != height); /* can't be square */ 01064 01065 if (height == 1) { /* 1 row */ 01066 assert(width != 1); /* widthxheight can't be 1x1 */ 01067 halfHeight= 1; 01068 01069 for (jj= 0; jj< halfWidth; jj++) { 01070 int kk; 01071 for (kk= 0; kk< components; kk++) { 01072 #define BOX2 2 01073 GLuint uint[BOX2]; 01074 if (myswap_bytes) { 01075 uint[0]= __GLU_SWAP_4_BYTES(src); 01076 uint[1]= __GLU_SWAP_4_BYTES(src+group_size); 01077 } 01078 else { 01079 uint[0]= *(const GLuint*)src; 01080 uint[1]= *(const GLuint*)(src+group_size); 01081 } 01082 *dest= ((float)uint[0]+(float)uint[1])/2.0; 01083 01084 src+= element_size; 01085 dest++; 01086 } 01087 src+= group_size; /* skip to next 2 */ 01088 } 01089 { 01090 int padBytes= ysize - (width*group_size); 01091 src+= padBytes; /* for assertion only */ 01092 } 01093 } 01094 else if (width == 1) { /* 1 column */ 01095 int padBytes= ysize - (width * group_size); 01096 assert(height != 1); /* widthxheight can't be 1x1 */ 01097 halfWidth= 1; 01098 /* one vertical column with possible pad bytes per row */ 01099 /* average two at a time */ 01100 01101 for (jj= 0; jj< halfHeight; jj++) { 01102 int kk; 01103 for (kk= 0; kk< components; kk++) { 01104 #define BOX2 2 01105 GLuint uint[BOX2]; 01106 if (myswap_bytes) { 01107 uint[0]= __GLU_SWAP_4_BYTES(src); 01108 uint[1]= __GLU_SWAP_4_BYTES(src+ysize); 01109 } 01110 else { 01111 uint[0]= *(const GLuint*)src; 01112 uint[1]= *(const GLuint*)(src+ysize); 01113 } 01114 *dest= ((float)uint[0]+(float)uint[1])/2.0; 01115 01116 src+= element_size; 01117 dest++; 01118 } 01119 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 01120 src+= ysize; 01121 } 01122 01123 assert(src == &((const char *)dataIn)[ysize*height]); 01124 } 01125 01126 assert((char *)dest == &((char *)dataOut) 01127 [components * element_size * halfWidth * halfHeight]); 01128 01129 } /* halve1Dimage_int() */ 01130 01131 01132 static void halveImage_float(GLint components, GLuint width, GLuint height, 01133 const GLfloat *datain, GLfloat *dataout, 01134 GLint element_size, GLint ysize, GLint group_size, 01135 GLint myswap_bytes) 01136 { 01137 int i, j, k; 01138 int newwidth, newheight; 01139 GLfloat *s; 01140 const char *t; 01141 01142 /* handle case where there is only 1 column/row */ 01143 if (width == 1 || height == 1) { 01144 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ 01145 halve1Dimage_float(components,width,height,datain,dataout, 01146 element_size,ysize,group_size, myswap_bytes); 01147 return; 01148 } 01149 01150 newwidth = width / 2; 01151 newheight = height / 2; 01152 s = dataout; 01153 t = (const char *)datain; 01154 01155 /* Piece o' cake! */ 01156 if (!myswap_bytes) 01157 for (i = 0; i < newheight; i++) { 01158 for (j = 0; j < newwidth; j++) { 01159 for (k = 0; k < components; k++) { 01160 s[0] = (*(const GLfloat*)t + 01161 *(const GLfloat*)(t+group_size) + 01162 *(const GLfloat*)(t+ysize) + 01163 *(const GLfloat*)(t+ysize+group_size)) / 4; 01164 s++; t += element_size; 01165 } 01166 t += group_size; 01167 } 01168 t += ysize; 01169 } 01170 else 01171 for (i = 0; i < newheight; i++) { 01172 for (j = 0; j < newwidth; j++) { 01173 for (k = 0; k < components; k++) { 01174 GLuint b; 01175 b = __GLU_SWAP_4_BYTES(t); 01176 s[0] = *(GLfloat*)&b; 01177 b = __GLU_SWAP_4_BYTES(t+group_size); 01178 s[0] += *(GLfloat*)&b; 01179 b = __GLU_SWAP_4_BYTES(t+ysize); 01180 s[0] += *(GLfloat*)&b; 01181 b = __GLU_SWAP_4_BYTES(t+ysize+group_size); 01182 s[0] += *(GLfloat*)&b; 01183 s[0] /= 4; 01184 s++; t += element_size; 01185 } 01186 t += group_size; 01187 } 01188 t += ysize; 01189 } 01190 } 01191 01192 /* */ 01193 static void halve1Dimage_float(GLint components, GLuint width, GLuint height, 01194 const GLfloat *dataIn, GLfloat *dataOut, 01195 GLint element_size, GLint ysize, 01196 GLint group_size, GLint myswap_bytes) 01197 { 01198 GLint halfWidth= width / 2; 01199 GLint halfHeight= height / 2; 01200 const char *src= (const char *) dataIn; 01201 GLfloat *dest= dataOut; 01202 int jj; 01203 01204 assert(width == 1 || height == 1); /* must be 1D */ 01205 assert(width != height); /* can't be square */ 01206 01207 if (height == 1) { /* 1 row */ 01208 assert(width != 1); /* widthxheight can't be 1x1 */ 01209 halfHeight= 1; 01210 01211 for (jj= 0; jj< halfWidth; jj++) { 01212 int kk; 01213 for (kk= 0; kk< components; kk++) { 01214 #define BOX2 2 01215 GLfloat sfloat[BOX2]; 01216 if (myswap_bytes) { 01217 sfloat[0]= __GLU_SWAP_4_BYTES(src); 01218 sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size); 01219 } 01220 else { 01221 sfloat[0]= *(const GLfloat*)src; 01222 sfloat[1]= *(const GLfloat*)(src+group_size); 01223 } 01224 01225 *dest= (sfloat[0] + sfloat[1]) / 2.0; 01226 src+= element_size; 01227 dest++; 01228 } 01229 src+= group_size; /* skip to next 2 */ 01230 } 01231 { 01232 int padBytes= ysize - (width*group_size); 01233 src+= padBytes; /* for assertion only */ 01234 } 01235 } 01236 else if (width == 1) { /* 1 column */ 01237 int padBytes= ysize - (width * group_size); 01238 assert(height != 1); /* widthxheight can't be 1x1 */ 01239 halfWidth= 1; 01240 /* one vertical column with possible pad bytes per row */ 01241 /* average two at a time */ 01242 01243 for (jj= 0; jj< halfHeight; jj++) { 01244 int kk; 01245 for (kk= 0; kk< components; kk++) { 01246 #define BOX2 2 01247 GLfloat sfloat[BOX2]; 01248 if (myswap_bytes) { 01249 sfloat[0]= __GLU_SWAP_4_BYTES(src); 01250 sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize); 01251 } 01252 else { 01253 sfloat[0]= *(const GLfloat*)src; 01254 sfloat[1]= *(const GLfloat*)(src+ysize); 01255 } 01256 *dest= (sfloat[0] + sfloat[1]) / 2.0; 01257 01258 src+= element_size; 01259 dest++; 01260 } 01261 src+= padBytes; /* add pad bytes, if any, to get to end to row */ 01262 src+= ysize; /* skip to odd row */ 01263 } 01264 } 01265 01266 assert(src == &((const char *)dataIn)[ysize*height]); 01267 assert((char *)dest == &((char *)dataOut) 01268 [components * element_size * halfWidth * halfHeight]); 01269 } /* halve1Dimage_float() */ 01270 01271 static void scale_internal(GLint components, GLint widthin, GLint heightin, 01272 const GLushort *datain, 01273 GLint widthout, GLint heightout, 01274 GLushort *dataout) 01275 { 01276 float x, lowx, highx, convx, halfconvx; 01277 float y, lowy, highy, convy, halfconvy; 01278 float xpercent,ypercent; 01279 float percent; 01280 /* Max components in a format is 4, so... */ 01281 float totals[4]; 01282 float area; 01283 int i,j,k,yint,xint,xindex,yindex; 01284 int temp; 01285 01286 if (widthin == widthout*2 && heightin == heightout*2) { 01287 halveImage(components, widthin, heightin, datain, dataout); 01288 return; 01289 } 01290 convy = (float) heightin/heightout; 01291 convx = (float) widthin/widthout; 01292 halfconvx = convx/2; 01293 halfconvy = convy/2; 01294 for (i = 0; i < heightout; i++) { 01295 y = convy * (i+0.5); 01296 if (heightin > heightout) { 01297 highy = y + halfconvy; 01298 lowy = y - halfconvy; 01299 } else { 01300 highy = y + 0.5; 01301 lowy = y - 0.5; 01302 } 01303 for (j = 0; j < widthout; j++) { 01304 x = convx * (j+0.5); 01305 if (widthin > widthout) { 01306 highx = x + halfconvx; 01307 lowx = x - halfconvx; 01308 } else { 01309 highx = x + 0.5; 01310 lowx = x - 0.5; 01311 } 01312 01313 /* 01314 ** Ok, now apply box filter to box that goes from (lowx, lowy) 01315 ** to (highx, highy) on input data into this pixel on output 01316 ** data. 01317 */ 01318 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 01319 area = 0.0; 01320 01321 y = lowy; 01322 yint = floor(y); 01323 while (y < highy) { 01324 yindex = (yint + heightin) % heightin; 01325 if (highy < yint+1) { 01326 ypercent = highy - y; 01327 } else { 01328 ypercent = yint+1 - y; 01329 } 01330 01331 x = lowx; 01332 xint = floor(x); 01333 01334 while (x < highx) { 01335 xindex = (xint + widthin) % widthin; 01336 if (highx < xint+1) { 01337 xpercent = highx - x; 01338 } else { 01339 xpercent = xint+1 - x; 01340 } 01341 01342 percent = xpercent * ypercent; 01343 area += percent; 01344 temp = (xindex + (yindex * widthin)) * components; 01345 for (k = 0; k < components; k++) { 01346 totals[k] += datain[temp + k] * percent; 01347 } 01348 01349 xint++; 01350 x = xint; 01351 } 01352 yint++; 01353 y = yint; 01354 } 01355 01356 temp = (j + (i * widthout)) * components; 01357 for (k = 0; k < components; k++) { 01358 /* totals[] should be rounded in the case of enlarging an RGB 01359 * ramp when the type is 332 or 4444 01360 */ 01361 dataout[temp + k] = (totals[k]+0.5)/area; 01362 } 01363 } 01364 } 01365 } 01366 01367 static void scale_internal_ubyte(GLint components, GLint widthin, 01368 GLint heightin, const GLubyte *datain, 01369 GLint widthout, GLint heightout, 01370 GLubyte *dataout, GLint element_size, 01371 GLint ysize, GLint group_size) 01372 { 01373 float convx; 01374 float convy; 01375 float percent; 01376 /* Max components in a format is 4, so... */ 01377 float totals[4]; 01378 float area; 01379 int i,j,k,xindex; 01380 01381 const char *temp, *temp0; 01382 const char *temp_index; 01383 int outindex; 01384 01385 int lowx_int, highx_int, lowy_int, highy_int; 01386 float x_percent, y_percent; 01387 float lowx_float, highx_float, lowy_float, highy_float; 01388 float convy_float, convx_float; 01389 int convy_int, convx_int; 01390 int l, m; 01391 const char *left, *right; 01392 01393 if (widthin == widthout*2 && heightin == heightout*2) { 01394 halveImage_ubyte(components, widthin, heightin, 01395 (const GLubyte *)datain, (GLubyte *)dataout, 01396 element_size, ysize, group_size); 01397 return; 01398 } 01399 convy = (float) heightin/heightout; 01400 convx = (float) widthin/widthout; 01401 convy_int = floor(convy); 01402 convy_float = convy - convy_int; 01403 convx_int = floor(convx); 01404 convx_float = convx - convx_int; 01405 01406 area = convx * convy; 01407 01408 lowy_int = 0; 01409 lowy_float = 0; 01410 highy_int = convy_int; 01411 highy_float = convy_float; 01412 01413 for (i = 0; i < heightout; i++) { 01414 lowx_int = 0; 01415 lowx_float = 0; 01416 highx_int = convx_int; 01417 highx_float = convx_float; 01418 01419 for (j = 0; j < widthout; j++) { 01420 01421 /* 01422 ** Ok, now apply box filter to box that goes from (lowx, lowy) 01423 ** to (highx, highy) on input data into this pixel on output 01424 ** data. 01425 */ 01426 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 01427 01428 /* calculate the value for pixels in the 1st row */ 01429 xindex = lowx_int*group_size; 01430 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 01431 01432 y_percent = 1-lowy_float; 01433 temp = (const char *)datain + xindex + lowy_int * ysize; 01434 percent = y_percent * (1-lowx_float); 01435 for (k = 0, temp_index = temp; k < components; 01436 k++, temp_index += element_size) { 01437 totals[k] += (GLubyte)(*(temp_index)) * percent; 01438 } 01439 left = temp; 01440 for(l = lowx_int+1; l < highx_int; l++) { 01441 temp += group_size; 01442 for (k = 0, temp_index = temp; k < components; 01443 k++, temp_index += element_size) { 01444 totals[k] += (GLubyte)(*(temp_index)) * y_percent; 01445 } 01446 } 01447 temp += group_size; 01448 right = temp; 01449 percent = y_percent * highx_float; 01450 for (k = 0, temp_index = temp; k < components; 01451 k++, temp_index += element_size) { 01452 totals[k] += (GLubyte)(*(temp_index)) * percent; 01453 } 01454 01455 /* calculate the value for pixels in the last row */ 01456 y_percent = highy_float; 01457 percent = y_percent * (1-lowx_float); 01458 temp = (const char *)datain + xindex + highy_int * ysize; 01459 for (k = 0, temp_index = temp; k < components; 01460 k++, temp_index += element_size) { 01461 totals[k] += (GLubyte)(*(temp_index)) * percent; 01462 } 01463 for(l = lowx_int+1; l < highx_int; l++) { 01464 temp += group_size; 01465 for (k = 0, temp_index = temp; k < components; 01466 k++, temp_index += element_size) { 01467 totals[k] += (GLubyte)(*(temp_index)) * y_percent; 01468 } 01469 } 01470 temp += group_size; 01471 percent = y_percent * highx_float; 01472 for (k = 0, temp_index = temp; k < components; 01473 k++, temp_index += element_size) { 01474 totals[k] += (GLubyte)(*(temp_index)) * percent; 01475 } 01476 01477 01478 /* calculate the value for pixels in the 1st and last column */ 01479 for(m = lowy_int+1; m < highy_int; m++) { 01480 left += ysize; 01481 right += ysize; 01482 for (k = 0; k < components; 01483 k++, left += element_size, right += element_size) { 01484 totals[k] += (GLubyte)(*(left))*(1-lowx_float) 01485 +(GLubyte)(*(right))*highx_float; 01486 } 01487 } 01488 } else if (highy_int > lowy_int) { 01489 x_percent = highx_float - lowx_float; 01490 percent = (1-lowy_float)*x_percent; 01491 temp = (const char *)datain + xindex + lowy_int*ysize; 01492 for (k = 0, temp_index = temp; k < components; 01493 k++, temp_index += element_size) { 01494 totals[k] += (GLubyte)(*(temp_index)) * percent; 01495 } 01496 for(m = lowy_int+1; m < highy_int; m++) { 01497 temp += ysize; 01498 for (k = 0, temp_index = temp; k < components; 01499 k++, temp_index += element_size) { 01500 totals[k] += (GLubyte)(*(temp_index)) * x_percent; 01501 } 01502 } 01503 percent = x_percent * highy_float; 01504 temp += ysize; 01505 for (k = 0, temp_index = temp; k < components; 01506 k++, temp_index += element_size) { 01507 totals[k] += (GLubyte)(*(temp_index)) * percent; 01508 } 01509 } else if (highx_int > lowx_int) { 01510 y_percent = highy_float - lowy_float; 01511 percent = (1-lowx_float)*y_percent; 01512 temp = (const char *)datain + xindex + lowy_int*ysize; 01513 for (k = 0, temp_index = temp; k < components; 01514 k++, temp_index += element_size) { 01515 totals[k] += (GLubyte)(*(temp_index)) * percent; 01516 } 01517 for (l = lowx_int+1; l < highx_int; l++) { 01518 temp += group_size; 01519 for (k = 0, temp_index = temp; k < components; 01520 k++, temp_index += element_size) { 01521 totals[k] += (GLubyte)(*(temp_index)) * y_percent; 01522 } 01523 } 01524 temp += group_size; 01525 percent = y_percent * highx_float; 01526 for (k = 0, temp_index = temp; k < components; 01527 k++, temp_index += element_size) { 01528 totals[k] += (GLubyte)(*(temp_index)) * percent; 01529 } 01530 } else { 01531 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 01532 temp = (const char *)datain + xindex + lowy_int * ysize; 01533 for (k = 0, temp_index = temp; k < components; 01534 k++, temp_index += element_size) { 01535 totals[k] += (GLubyte)(*(temp_index)) * percent; 01536 } 01537 } 01538 01539 01540 01541 /* this is for the pixels in the body */ 01542 temp0 = (const char *)datain + xindex + group_size + 01543 (lowy_int+1)*ysize; 01544 for (m = lowy_int+1; m < highy_int; m++) { 01545 temp = temp0; 01546 for(l = lowx_int+1; l < highx_int; l++) { 01547 for (k = 0, temp_index = temp; k < components; 01548 k++, temp_index += element_size) { 01549 totals[k] += (GLubyte)(*(temp_index)); 01550 } 01551 temp += group_size; 01552 } 01553 temp0 += ysize; 01554 } 01555 01556 outindex = (j + (i * widthout)) * components; 01557 for (k = 0; k < components; k++) { 01558 dataout[outindex + k] = totals[k]/area; 01559 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 01560 } 01561 lowx_int = highx_int; 01562 lowx_float = highx_float; 01563 highx_int += convx_int; 01564 highx_float += convx_float; 01565 if(highx_float > 1) { 01566 highx_float -= 1.0; 01567 highx_int++; 01568 } 01569 } 01570 lowy_int = highy_int; 01571 lowy_float = highy_float; 01572 highy_int += convy_int; 01573 highy_float += convy_float; 01574 if(highy_float > 1) { 01575 highy_float -= 1.0; 01576 highy_int++; 01577 } 01578 } 01579 } 01580 01581 static void scale_internal_byte(GLint components, GLint widthin, 01582 GLint heightin, const GLbyte *datain, 01583 GLint widthout, GLint heightout, 01584 GLbyte *dataout, GLint element_size, 01585 GLint ysize, GLint group_size) 01586 { 01587 float convx; 01588 float convy; 01589 float percent; 01590 /* Max components in a format is 4, so... */ 01591 float totals[4]; 01592 float area; 01593 int i,j,k,xindex; 01594 01595 const char *temp, *temp0; 01596 const char *temp_index; 01597 int outindex; 01598 01599 int lowx_int, highx_int, lowy_int, highy_int; 01600 float x_percent, y_percent; 01601 float lowx_float, highx_float, lowy_float, highy_float; 01602 float convy_float, convx_float; 01603 int convy_int, convx_int; 01604 int l, m; 01605 const char *left, *right; 01606 01607 if (widthin == widthout*2 && heightin == heightout*2) { 01608 halveImage_byte(components, widthin, heightin, 01609 (const GLbyte *)datain, (GLbyte *)dataout, 01610 element_size, ysize, group_size); 01611 return; 01612 } 01613 convy = (float) heightin/heightout; 01614 convx = (float) widthin/widthout; 01615 convy_int = floor(convy); 01616 convy_float = convy - convy_int; 01617 convx_int = floor(convx); 01618 convx_float = convx - convx_int; 01619 01620 area = convx * convy; 01621 01622 lowy_int = 0; 01623 lowy_float = 0; 01624 highy_int = convy_int; 01625 highy_float = convy_float; 01626 01627 for (i = 0; i < heightout; i++) { 01628 lowx_int = 0; 01629 lowx_float = 0; 01630 highx_int = convx_int; 01631 highx_float = convx_float; 01632 01633 for (j = 0; j < widthout; j++) { 01634 01635 /* 01636 ** Ok, now apply box filter to box that goes from (lowx, lowy) 01637 ** to (highx, highy) on input data into this pixel on output 01638 ** data. 01639 */ 01640 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 01641 01642 /* calculate the value for pixels in the 1st row */ 01643 xindex = lowx_int*group_size; 01644 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 01645 01646 y_percent = 1-lowy_float; 01647 temp = (const char *)datain + xindex + lowy_int * ysize; 01648 percent = y_percent * (1-lowx_float); 01649 for (k = 0, temp_index = temp; k < components; 01650 k++, temp_index += element_size) { 01651 totals[k] += (GLbyte)(*(temp_index)) * percent; 01652 } 01653 left = temp; 01654 for(l = lowx_int+1; l < highx_int; l++) { 01655 temp += group_size; 01656 for (k = 0, temp_index = temp; k < components; 01657 k++, temp_index += element_size) { 01658 totals[k] += (GLbyte)(*(temp_index)) * y_percent; 01659 } 01660 } 01661 temp += group_size; 01662 right = temp; 01663 percent = y_percent * highx_float; 01664 for (k = 0, temp_index = temp; k < components; 01665 k++, temp_index += element_size) { 01666 totals[k] += (GLbyte)(*(temp_index)) * percent; 01667 } 01668 01669 /* calculate the value for pixels in the last row */ 01670 y_percent = highy_float; 01671 percent = y_percent * (1-lowx_float); 01672 temp = (const char *)datain + xindex + highy_int * ysize; 01673 for (k = 0, temp_index = temp; k < components; 01674 k++, temp_index += element_size) { 01675 totals[k] += (GLbyte)(*(temp_index)) * percent; 01676 } 01677 for(l = lowx_int+1; l < highx_int; l++) { 01678 temp += group_size; 01679 for (k = 0, temp_index = temp; k < components; 01680 k++, temp_index += element_size) { 01681 totals[k] += (GLbyte)(*(temp_index)) * y_percent; 01682 } 01683 } 01684 temp += group_size; 01685 percent = y_percent * highx_float; 01686 for (k = 0, temp_index = temp; k < components; 01687 k++, temp_index += element_size) { 01688 totals[k] += (GLbyte)(*(temp_index)) * percent; 01689 } 01690 01691 01692 /* calculate the value for pixels in the 1st and last column */ 01693 for(m = lowy_int+1; m < highy_int; m++) { 01694 left += ysize; 01695 right += ysize; 01696 for (k = 0; k < components; 01697 k++, left += element_size, right += element_size) { 01698 totals[k] += (GLbyte)(*(left))*(1-lowx_float) 01699 +(GLbyte)(*(right))*highx_float; 01700 } 01701 } 01702 } else if (highy_int > lowy_int) { 01703 x_percent = highx_float - lowx_float; 01704 percent = (1-lowy_float)*x_percent; 01705 temp = (const char *)datain + xindex + lowy_int*ysize; 01706 for (k = 0, temp_index = temp; k < components; 01707 k++, temp_index += element_size) { 01708 totals[k] += (GLbyte)(*(temp_index)) * percent; 01709 } 01710 for(m = lowy_int+1; m < highy_int; m++) { 01711 temp += ysize; 01712 for (k = 0, temp_index = temp; k < components; 01713 k++, temp_index += element_size) { 01714 totals[k] += (GLbyte)(*(temp_index)) * x_percent; 01715 } 01716 } 01717 percent = x_percent * highy_float; 01718 temp += ysize; 01719 for (k = 0, temp_index = temp; k < components; 01720 k++, temp_index += element_size) { 01721 totals[k] += (GLbyte)(*(temp_index)) * percent; 01722 } 01723 } else if (highx_int > lowx_int) { 01724 y_percent = highy_float - lowy_float; 01725 percent = (1-lowx_float)*y_percent; 01726 temp = (const char *)datain + xindex + lowy_int*ysize; 01727 for (k = 0, temp_index = temp; k < components; 01728 k++, temp_index += element_size) { 01729 totals[k] += (GLbyte)(*(temp_index)) * percent; 01730 } 01731 for (l = lowx_int+1; l < highx_int; l++) { 01732 temp += group_size; 01733 for (k = 0, temp_index = temp; k < components; 01734 k++, temp_index += element_size) { 01735 totals[k] += (GLbyte)(*(temp_index)) * y_percent; 01736 } 01737 } 01738 temp += group_size; 01739 percent = y_percent * highx_float; 01740 for (k = 0, temp_index = temp; k < components; 01741 k++, temp_index += element_size) { 01742 totals[k] += (GLbyte)(*(temp_index)) * percent; 01743 } 01744 } else { 01745 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 01746 temp = (const char *)datain + xindex + lowy_int * ysize; 01747 for (k = 0, temp_index = temp; k < components; 01748 k++, temp_index += element_size) { 01749 totals[k] += (GLbyte)(*(temp_index)) * percent; 01750 } 01751 } 01752 01753 01754 01755 /* this is for the pixels in the body */ 01756 temp0 = (const char *)datain + xindex + group_size + 01757 (lowy_int+1)*ysize; 01758 for (m = lowy_int+1; m < highy_int; m++) { 01759 temp = temp0; 01760 for(l = lowx_int+1; l < highx_int; l++) { 01761 for (k = 0, temp_index = temp; k < components; 01762 k++, temp_index += element_size) { 01763 totals[k] += (GLbyte)(*(temp_index)); 01764 } 01765 temp += group_size; 01766 } 01767 temp0 += ysize; 01768 } 01769 01770 outindex = (j + (i * widthout)) * components; 01771 for (k = 0; k < components; k++) { 01772 dataout[outindex + k] = totals[k]/area; 01773 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 01774 } 01775 lowx_int = highx_int; 01776 lowx_float = highx_float; 01777 highx_int += convx_int; 01778 highx_float += convx_float; 01779 if(highx_float > 1) { 01780 highx_float -= 1.0; 01781 highx_int++; 01782 } 01783 } 01784 lowy_int = highy_int; 01785 lowy_float = highy_float; 01786 highy_int += convy_int; 01787 highy_float += convy_float; 01788 if(highy_float > 1) { 01789 highy_float -= 1.0; 01790 highy_int++; 01791 } 01792 } 01793 } 01794 01795 static void scale_internal_ushort(GLint components, GLint widthin, 01796 GLint heightin, const GLushort *datain, 01797 GLint widthout, GLint heightout, 01798 GLushort *dataout, GLint element_size, 01799 GLint ysize, GLint group_size, 01800 GLint myswap_bytes) 01801 { 01802 float convx; 01803 float convy; 01804 float percent; 01805 /* Max components in a format is 4, so... */ 01806 float totals[4]; 01807 float area; 01808 int i,j,k,xindex; 01809 01810 const char *temp, *temp0; 01811 const char *temp_index; 01812 int outindex; 01813 01814 int lowx_int, highx_int, lowy_int, highy_int; 01815 float x_percent, y_percent; 01816 float lowx_float, highx_float, lowy_float, highy_float; 01817 float convy_float, convx_float; 01818 int convy_int, convx_int; 01819 int l, m; 01820 const char *left, *right; 01821 01822 if (widthin == widthout*2 && heightin == heightout*2) { 01823 halveImage_ushort(components, widthin, heightin, 01824 (const GLushort *)datain, (GLushort *)dataout, 01825 element_size, ysize, group_size, myswap_bytes); 01826 return; 01827 } 01828 convy = (float) heightin/heightout; 01829 convx = (float) widthin/widthout; 01830 convy_int = floor(convy); 01831 convy_float = convy - convy_int; 01832 convx_int = floor(convx); 01833 convx_float = convx - convx_int; 01834 01835 area = convx * convy; 01836 01837 lowy_int = 0; 01838 lowy_float = 0; 01839 highy_int = convy_int; 01840 highy_float = convy_float; 01841 01842 for (i = 0; i < heightout; i++) { 01843 lowx_int = 0; 01844 lowx_float = 0; 01845 highx_int = convx_int; 01846 highx_float = convx_float; 01847 01848 for (j = 0; j < widthout; j++) { 01849 /* 01850 ** Ok, now apply box filter to box that goes from (lowx, lowy) 01851 ** to (highx, highy) on input data into this pixel on output 01852 ** data. 01853 */ 01854 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 01855 01856 /* calculate the value for pixels in the 1st row */ 01857 xindex = lowx_int*group_size; 01858 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 01859 01860 y_percent = 1-lowy_float; 01861 temp = (const char *)datain + xindex + lowy_int * ysize; 01862 percent = y_percent * (1-lowx_float); 01863 for (k = 0, temp_index = temp; k < components; 01864 k++, temp_index += element_size) { 01865 if (myswap_bytes) { 01866 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01867 } else { 01868 totals[k] += *(const GLushort*)temp_index * percent; 01869 } 01870 } 01871 left = temp; 01872 for(l = lowx_int+1; l < highx_int; l++) { 01873 temp += group_size; 01874 for (k = 0, temp_index = temp; k < components; 01875 k++, temp_index += element_size) { 01876 if (myswap_bytes) { 01877 totals[k] += 01878 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 01879 } else { 01880 totals[k] += *(const GLushort*)temp_index * y_percent; 01881 } 01882 } 01883 } 01884 temp += group_size; 01885 right = temp; 01886 percent = y_percent * highx_float; 01887 for (k = 0, temp_index = temp; k < components; 01888 k++, temp_index += element_size) { 01889 if (myswap_bytes) { 01890 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01891 } else { 01892 totals[k] += *(const GLushort*)temp_index * percent; 01893 } 01894 } 01895 01896 /* calculate the value for pixels in the last row */ 01897 y_percent = highy_float; 01898 percent = y_percent * (1-lowx_float); 01899 temp = (const char *)datain + xindex + highy_int * ysize; 01900 for (k = 0, temp_index = temp; k < components; 01901 k++, temp_index += element_size) { 01902 if (myswap_bytes) { 01903 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01904 } else { 01905 totals[k] += *(const GLushort*)temp_index * percent; 01906 } 01907 } 01908 for(l = lowx_int+1; l < highx_int; l++) { 01909 temp += group_size; 01910 for (k = 0, temp_index = temp; k < components; 01911 k++, temp_index += element_size) { 01912 if (myswap_bytes) { 01913 totals[k] += 01914 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 01915 } else { 01916 totals[k] += *(const GLushort*)temp_index * y_percent; 01917 } 01918 } 01919 } 01920 temp += group_size; 01921 percent = y_percent * highx_float; 01922 for (k = 0, temp_index = temp; k < components; 01923 k++, temp_index += element_size) { 01924 if (myswap_bytes) { 01925 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01926 } else { 01927 totals[k] += *(const GLushort*)temp_index * percent; 01928 } 01929 } 01930 01931 /* calculate the value for pixels in the 1st and last column */ 01932 for(m = lowy_int+1; m < highy_int; m++) { 01933 left += ysize; 01934 right += ysize; 01935 for (k = 0; k < components; 01936 k++, left += element_size, right += element_size) { 01937 if (myswap_bytes) { 01938 totals[k] += 01939 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + 01940 __GLU_SWAP_2_BYTES(right) * highx_float; 01941 } else { 01942 totals[k] += *(const GLushort*)left * (1-lowx_float) 01943 + *(const GLushort*)right * highx_float; 01944 } 01945 } 01946 } 01947 } else if (highy_int > lowy_int) { 01948 x_percent = highx_float - lowx_float; 01949 percent = (1-lowy_float)*x_percent; 01950 temp = (const char *)datain + xindex + lowy_int*ysize; 01951 for (k = 0, temp_index = temp; k < components; 01952 k++, temp_index += element_size) { 01953 if (myswap_bytes) { 01954 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01955 } else { 01956 totals[k] += *(const GLushort*)temp_index * percent; 01957 } 01958 } 01959 for(m = lowy_int+1; m < highy_int; m++) { 01960 temp += ysize; 01961 for (k = 0, temp_index = temp; k < components; 01962 k++, temp_index += element_size) { 01963 if (myswap_bytes) { 01964 totals[k] += 01965 __GLU_SWAP_2_BYTES(temp_index) * x_percent; 01966 } else { 01967 totals[k] += *(const GLushort*)temp_index * x_percent; 01968 } 01969 } 01970 } 01971 percent = x_percent * highy_float; 01972 temp += ysize; 01973 for (k = 0, temp_index = temp; k < components; 01974 k++, temp_index += element_size) { 01975 if (myswap_bytes) { 01976 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01977 } else { 01978 totals[k] += *(const GLushort*)temp_index * percent; 01979 } 01980 } 01981 } else if (highx_int > lowx_int) { 01982 y_percent = highy_float - lowy_float; 01983 percent = (1-lowx_float)*y_percent; 01984 temp = (const char *)datain + xindex + lowy_int*ysize; 01985 for (k = 0, temp_index = temp; k < components; 01986 k++, temp_index += element_size) { 01987 if (myswap_bytes) { 01988 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 01989 } else { 01990 totals[k] += *(const GLushort*)temp_index * percent; 01991 } 01992 } 01993 for (l = lowx_int+1; l < highx_int; l++) { 01994 temp += group_size; 01995 for (k = 0, temp_index = temp; k < components; 01996 k++, temp_index += element_size) { 01997 if (myswap_bytes) { 01998 totals[k] += 01999 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 02000 } else { 02001 totals[k] += *(const GLushort*)temp_index * y_percent; 02002 } 02003 } 02004 } 02005 temp += group_size; 02006 percent = y_percent * highx_float; 02007 for (k = 0, temp_index = temp; k < components; 02008 k++, temp_index += element_size) { 02009 if (myswap_bytes) { 02010 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 02011 } else { 02012 totals[k] += *(const GLushort*)temp_index * percent; 02013 } 02014 } 02015 } else { 02016 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 02017 temp = (const char *)datain + xindex + lowy_int * ysize; 02018 for (k = 0, temp_index = temp; k < components; 02019 k++, temp_index += element_size) { 02020 if (myswap_bytes) { 02021 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 02022 } else { 02023 totals[k] += *(const GLushort*)temp_index * percent; 02024 } 02025 } 02026 } 02027 02028 /* this is for the pixels in the body */ 02029 temp0 = (const char *)datain + xindex + group_size + 02030 (lowy_int+1)*ysize; 02031 for (m = lowy_int+1; m < highy_int; m++) { 02032 temp = temp0; 02033 for(l = lowx_int+1; l < highx_int; l++) { 02034 for (k = 0, temp_index = temp; k < components; 02035 k++, temp_index += element_size) { 02036 if (myswap_bytes) { 02037 totals[k] += __GLU_SWAP_2_BYTES(temp_index); 02038 } else { 02039 totals[k] += *(const GLushort*)temp_index; 02040 } 02041 } 02042 temp += group_size; 02043 } 02044 temp0 += ysize; 02045 } 02046 02047 outindex = (j + (i * widthout)) * components; 02048 for (k = 0; k < components; k++) { 02049 dataout[outindex + k] = totals[k]/area; 02050 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 02051 } 02052 lowx_int = highx_int; 02053 lowx_float = highx_float; 02054 highx_int += convx_int; 02055 highx_float += convx_float; 02056 if(highx_float > 1) { 02057 highx_float -= 1.0; 02058 highx_int++; 02059 } 02060 } 02061 lowy_int = highy_int; 02062 lowy_float = highy_float; 02063 highy_int += convy_int; 02064 highy_float += convy_float; 02065 if(highy_float > 1) { 02066 highy_float -= 1.0; 02067 highy_int++; 02068 } 02069 } 02070 } 02071 02072 static void scale_internal_short(GLint components, GLint widthin, 02073 GLint heightin, const GLshort *datain, 02074 GLint widthout, GLint heightout, 02075 GLshort *dataout, GLint element_size, 02076 GLint ysize, GLint group_size, 02077 GLint myswap_bytes) 02078 { 02079 float convx; 02080 float convy; 02081 float percent; 02082 /* Max components in a format is 4, so... */ 02083 float totals[4]; 02084 float area; 02085 int i,j,k,xindex; 02086 02087 const char *temp, *temp0; 02088 const char *temp_index; 02089 int outindex; 02090 02091 int lowx_int, highx_int, lowy_int, highy_int; 02092 float x_percent, y_percent; 02093 float lowx_float, highx_float, lowy_float, highy_float; 02094 float convy_float, convx_float; 02095 int convy_int, convx_int; 02096 int l, m; 02097 const char *left, *right; 02098 02099 GLushort swapbuf; /* unsigned buffer */ 02100 02101 if (widthin == widthout*2 && heightin == heightout*2) { 02102 halveImage_short(components, widthin, heightin, 02103 (const GLshort *)datain, (GLshort *)dataout, 02104 element_size, ysize, group_size, myswap_bytes); 02105 return; 02106 } 02107 convy = (float) heightin/heightout; 02108 convx = (float) widthin/widthout; 02109 convy_int = floor(convy); 02110 convy_float = convy - convy_int; 02111 convx_int = floor(convx); 02112 convx_float = convx - convx_int; 02113 02114 area = convx * convy; 02115 02116 lowy_int = 0; 02117 lowy_float = 0; 02118 highy_int = convy_int; 02119 highy_float = convy_float; 02120 02121 for (i = 0; i < heightout; i++) { 02122 lowx_int = 0; 02123 lowx_float = 0; 02124 highx_int = convx_int; 02125 highx_float = convx_float; 02126 02127 for (j = 0; j < widthout; j++) { 02128 /* 02129 ** Ok, now apply box filter to box that goes from (lowx, lowy) 02130 ** to (highx, highy) on input data into this pixel on output 02131 ** data. 02132 */ 02133 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 02134 02135 /* calculate the value for pixels in the 1st row */ 02136 xindex = lowx_int*group_size; 02137 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 02138 02139 y_percent = 1-lowy_float; 02140 temp = (const char *)datain + xindex + lowy_int * ysize; 02141 percent = y_percent * (1-lowx_float); 02142 for (k = 0, temp_index = temp; k < components; 02143 k++, temp_index += element_size) { 02144 if (myswap_bytes) { 02145 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02146 totals[k] += *(const GLshort*)&swapbuf * percent; 02147 } else { 02148 totals[k] += *(const GLshort*)temp_index * percent; 02149 } 02150 } 02151 left = temp; 02152 for(l = lowx_int+1; l < highx_int; l++) { 02153 temp += group_size; 02154 for (k = 0, temp_index = temp; k < components; 02155 k++, temp_index += element_size) { 02156 if (myswap_bytes) { 02157 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02158 totals[k] += *(const GLshort*)&swapbuf * y_percent; 02159 } else { 02160 totals[k] += *(const GLshort*)temp_index * y_percent; 02161 } 02162 } 02163 } 02164 temp += group_size; 02165 right = temp; 02166 percent = y_percent * highx_float; 02167 for (k = 0, temp_index = temp; k < components; 02168 k++, temp_index += element_size) { 02169 if (myswap_bytes) { 02170 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02171 totals[k] += *(const GLshort*)&swapbuf * percent; 02172 } else { 02173 totals[k] += *(const GLshort*)temp_index * percent; 02174 } 02175 } 02176 02177 /* calculate the value for pixels in the last row */ 02178 y_percent = highy_float; 02179 percent = y_percent * (1-lowx_float); 02180 temp = (const char *)datain + xindex + highy_int * ysize; 02181 for (k = 0, temp_index = temp; k < components; 02182 k++, temp_index += element_size) { 02183 if (myswap_bytes) { 02184 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02185 totals[k] += *(const GLshort*)&swapbuf * percent; 02186 } else { 02187 totals[k] += *(const GLshort*)temp_index * percent; 02188 } 02189 } 02190 for(l = lowx_int+1; l < highx_int; l++) { 02191 temp += group_size; 02192 for (k = 0, temp_index = temp; k < components; 02193 k++, temp_index += element_size) { 02194 if (myswap_bytes) { 02195 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02196 totals[k] += *(const GLshort*)&swapbuf * y_percent; 02197 } else { 02198 totals[k] += *(const GLshort*)temp_index * y_percent; 02199 } 02200 } 02201 } 02202 temp += group_size; 02203 percent = y_percent * highx_float; 02204 for (k = 0, temp_index = temp; k < components; 02205 k++, temp_index += element_size) { 02206 if (myswap_bytes) { 02207 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02208 totals[k] += *(const GLshort*)&swapbuf * percent; 02209 } else { 02210 totals[k] += *(const GLshort*)temp_index * percent; 02211 } 02212 } 02213 02214 /* calculate the value for pixels in the 1st and last column */ 02215 for(m = lowy_int+1; m < highy_int; m++) { 02216 left += ysize; 02217 right += ysize; 02218 for (k = 0; k < components; 02219 k++, left += element_size, right += element_size) { 02220 if (myswap_bytes) { 02221 swapbuf = __GLU_SWAP_2_BYTES(left); 02222 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float); 02223 swapbuf = __GLU_SWAP_2_BYTES(right); 02224 totals[k] += *(const GLshort*)&swapbuf * highx_float; 02225 } else { 02226 totals[k] += *(const GLshort*)left * (1-lowx_float) 02227 + *(const GLshort*)right * highx_float; 02228 } 02229 } 02230 } 02231 } else if (highy_int > lowy_int) { 02232 x_percent = highx_float - lowx_float; 02233 percent = (1-lowy_float)*x_percent; 02234 temp = (const char *)datain + xindex + lowy_int*ysize; 02235 for (k = 0, temp_index = temp; k < components; 02236 k++, temp_index += element_size) { 02237 if (myswap_bytes) { 02238 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02239 totals[k] += *(const GLshort*)&swapbuf * percent; 02240 } else { 02241 totals[k] += *(const GLshort*)temp_index * percent; 02242 } 02243 } 02244 for(m = lowy_int+1; m < highy_int; m++) { 02245 temp += ysize; 02246 for (k = 0, temp_index = temp; k < components; 02247 k++, temp_index += element_size) { 02248 if (myswap_bytes) { 02249 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02250 totals[k] += *(const GLshort*)&swapbuf * x_percent; 02251 } else { 02252 totals[k] += *(const GLshort*)temp_index * x_percent; 02253 } 02254 } 02255 } 02256 percent = x_percent * highy_float; 02257 temp += ysize; 02258 for (k = 0, temp_index = temp; k < components; 02259 k++, temp_index += element_size) { 02260 if (myswap_bytes) { 02261 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02262 totals[k] += *(const GLshort*)&swapbuf * percent; 02263 } else { 02264 totals[k] += *(const GLshort*)temp_index * percent; 02265 } 02266 } 02267 } else if (highx_int > lowx_int) { 02268 y_percent = highy_float - lowy_float; 02269 percent = (1-lowx_float)*y_percent; 02270 02271 temp = (const char *)datain + xindex + lowy_int*ysize; 02272 for (k = 0, temp_index = temp; k < components; 02273 k++, temp_index += element_size) { 02274 if (myswap_bytes) { 02275 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02276 totals[k] += *(const GLshort*)&swapbuf * percent; 02277 } else { 02278 totals[k] += *(const GLshort*)temp_index * percent; 02279 } 02280 } 02281 for (l = lowx_int+1; l < highx_int; l++) { 02282 temp += group_size; 02283 for (k = 0, temp_index = temp; k < components; 02284 k++, temp_index += element_size) { 02285 if (myswap_bytes) { 02286 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02287 totals[k] += *(const GLshort*)&swapbuf * y_percent; 02288 } else { 02289 totals[k] += *(const GLshort*)temp_index * y_percent; 02290 } 02291 } 02292 } 02293 temp += group_size; 02294 percent = y_percent * highx_float; 02295 for (k = 0, temp_index = temp; k < components; 02296 k++, temp_index += element_size) { 02297 if (myswap_bytes) { 02298 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02299 totals[k] += *(const GLshort*)&swapbuf * percent; 02300 } else { 02301 totals[k] += *(const GLshort*)temp_index * percent; 02302 } 02303 } 02304 } else { 02305 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 02306 temp = (const char *)datain + xindex + lowy_int * ysize; 02307 for (k = 0, temp_index = temp; k < components; 02308 k++, temp_index += element_size) { 02309 if (myswap_bytes) { 02310 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02311 totals[k] += *(const GLshort*)&swapbuf * percent; 02312 } else { 02313 totals[k] += *(const GLshort*)temp_index * percent; 02314 } 02315 } 02316 } 02317 02318 /* this is for the pixels in the body */ 02319 temp0 = (const char *)datain + xindex + group_size + 02320 (lowy_int+1)*ysize; 02321 for (m = lowy_int+1; m < highy_int; m++) { 02322 temp = temp0; 02323 for(l = lowx_int+1; l < highx_int; l++) { 02324 for (k = 0, temp_index = temp; k < components; 02325 k++, temp_index += element_size) { 02326 if (myswap_bytes) { 02327 swapbuf = __GLU_SWAP_2_BYTES(temp_index); 02328 totals[k] += *(const GLshort*)&swapbuf; 02329 } else { 02330 totals[k] += *(const GLshort*)temp_index; 02331 } 02332 } 02333 temp += group_size; 02334 } 02335 temp0 += ysize; 02336 } 02337 02338 outindex = (j + (i * widthout)) * components; 02339 for (k = 0; k < components; k++) { 02340 dataout[outindex + k] = totals[k]/area; 02341 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 02342 } 02343 lowx_int = highx_int; 02344 lowx_float = highx_float; 02345 highx_int += convx_int; 02346 highx_float += convx_float; 02347 if(highx_float > 1) { 02348 highx_float -= 1.0; 02349 highx_int++; 02350 } 02351 } 02352 lowy_int = highy_int; 02353 lowy_float = highy_float; 02354 highy_int += convy_int; 02355 highy_float += convy_float; 02356 if(highy_float > 1) { 02357 highy_float -= 1.0; 02358 highy_int++; 02359 } 02360 } 02361 } 02362 02363 static void scale_internal_uint(GLint components, GLint widthin, 02364 GLint heightin, const GLuint *datain, 02365 GLint widthout, GLint heightout, 02366 GLuint *dataout, GLint element_size, 02367 GLint ysize, GLint group_size, 02368 GLint myswap_bytes) 02369 { 02370 float convx; 02371 float convy; 02372 float percent; 02373 /* Max components in a format is 4, so... */ 02374 float totals[4]; 02375 float area; 02376 int i,j,k,xindex; 02377 02378 const char *temp, *temp0; 02379 const char *temp_index; 02380 int outindex; 02381 02382 int lowx_int, highx_int, lowy_int, highy_int; 02383 float x_percent, y_percent; 02384 float lowx_float, highx_float, lowy_float, highy_float; 02385 float convy_float, convx_float; 02386 int convy_int, convx_int; 02387 int l, m; 02388 const char *left, *right; 02389 02390 if (widthin == widthout*2 && heightin == heightout*2) { 02391 halveImage_uint(components, widthin, heightin, 02392 (const GLuint *)datain, (GLuint *)dataout, 02393 element_size, ysize, group_size, myswap_bytes); 02394 return; 02395 } 02396 convy = (float) heightin/heightout; 02397 convx = (float) widthin/widthout; 02398 convy_int = floor(convy); 02399 convy_float = convy - convy_int; 02400 convx_int = floor(convx); 02401 convx_float = convx - convx_int; 02402 02403 area = convx * convy; 02404 02405 lowy_int = 0; 02406 lowy_float = 0; 02407 highy_int = convy_int; 02408 highy_float = convy_float; 02409 02410 for (i = 0; i < heightout; i++) { 02411 lowx_int = 0; 02412 lowx_float = 0; 02413 highx_int = convx_int; 02414 highx_float = convx_float; 02415 02416 for (j = 0; j < widthout; j++) { 02417 /* 02418 ** Ok, now apply box filter to box that goes from (lowx, lowy) 02419 ** to (highx, highy) on input data into this pixel on output 02420 ** data. 02421 */ 02422 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 02423 02424 /* calculate the value for pixels in the 1st row */ 02425 xindex = lowx_int*group_size; 02426 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 02427 02428 y_percent = 1-lowy_float; 02429 temp = (const char *)datain + xindex + lowy_int * ysize; 02430 percent = y_percent * (1-lowx_float); 02431 for (k = 0, temp_index = temp; k < components; 02432 k++, temp_index += element_size) { 02433 if (myswap_bytes) { 02434 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02435 } else { 02436 totals[k] += *(const GLuint*)temp_index * percent; 02437 } 02438 } 02439 left = temp; 02440 for(l = lowx_int+1; l < highx_int; l++) { 02441 temp += group_size; 02442 for (k = 0, temp_index = temp; k < components; 02443 k++, temp_index += element_size) { 02444 if (myswap_bytes) { 02445 totals[k] += 02446 __GLU_SWAP_4_BYTES(temp_index) * y_percent; 02447 } else { 02448 totals[k] += *(const GLuint*)temp_index * y_percent; 02449 } 02450 } 02451 } 02452 temp += group_size; 02453 right = temp; 02454 percent = y_percent * highx_float; 02455 for (k = 0, temp_index = temp; k < components; 02456 k++, temp_index += element_size) { 02457 if (myswap_bytes) { 02458 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02459 } else { 02460 totals[k] += *(const GLuint*)temp_index * percent; 02461 } 02462 } 02463 02464 /* calculate the value for pixels in the last row */ 02465 y_percent = highy_float; 02466 percent = y_percent * (1-lowx_float); 02467 temp = (const char *)datain + xindex + highy_int * ysize; 02468 for (k = 0, temp_index = temp; k < components; 02469 k++, temp_index += element_size) { 02470 if (myswap_bytes) { 02471 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02472 } else { 02473 totals[k] += *(const GLuint*)temp_index * percent; 02474 } 02475 } 02476 for(l = lowx_int+1; l < highx_int; l++) { 02477 temp += group_size; 02478 for (k = 0, temp_index = temp; k < components; 02479 k++, temp_index += element_size) { 02480 if (myswap_bytes) { 02481 totals[k] += 02482 __GLU_SWAP_4_BYTES(temp_index) * y_percent; 02483 } else { 02484 totals[k] += *(const GLuint*)temp_index * y_percent; 02485 } 02486 } 02487 } 02488 temp += group_size; 02489 percent = y_percent * highx_float; 02490 for (k = 0, temp_index = temp; k < components; 02491 k++, temp_index += element_size) { 02492 if (myswap_bytes) { 02493 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02494 } else { 02495 totals[k] += *(const GLuint*)temp_index * percent; 02496 } 02497 } 02498 02499 /* calculate the value for pixels in the 1st and last column */ 02500 for(m = lowy_int+1; m < highy_int; m++) { 02501 left += ysize; 02502 right += ysize; 02503 for (k = 0; k < components; 02504 k++, left += element_size, right += element_size) { 02505 if (myswap_bytes) { 02506 totals[k] += 02507 __GLU_SWAP_4_BYTES(left) * (1-lowx_float) 02508 + __GLU_SWAP_4_BYTES(right) * highx_float; 02509 } else { 02510 totals[k] += *(const GLuint*)left * (1-lowx_float) 02511 + *(const GLuint*)right * highx_float; 02512 } 02513 } 02514 } 02515 } else if (highy_int > lowy_int) { 02516 x_percent = highx_float - lowx_float; 02517 percent = (1-lowy_float)*x_percent; 02518 temp = (const char *)datain + xindex + lowy_int*ysize; 02519 for (k = 0, temp_index = temp; k < components; 02520 k++, temp_index += element_size) { 02521 if (myswap_bytes) { 02522 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02523 } else { 02524 totals[k] += *(const GLuint*)temp_index * percent; 02525 } 02526 } 02527 for(m = lowy_int+1; m < highy_int; m++) { 02528 temp += ysize; 02529 for (k = 0, temp_index = temp; k < components; 02530 k++, temp_index += element_size) { 02531 if (myswap_bytes) { 02532 totals[k] += 02533 __GLU_SWAP_4_BYTES(temp_index) * x_percent; 02534 } else { 02535 totals[k] += *(const GLuint*)temp_index * x_percent; 02536 } 02537 } 02538 } 02539 percent = x_percent * highy_float; 02540 temp += ysize; 02541 for (k = 0, temp_index = temp; k < components; 02542 k++, temp_index += element_size) { 02543 if (myswap_bytes) { 02544 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02545 } else { 02546 totals[k] += *(const GLuint*)temp_index * percent; 02547 } 02548 } 02549 } else if (highx_int > lowx_int) { 02550 y_percent = highy_float - lowy_float; 02551 percent = (1-lowx_float)*y_percent; 02552 02553 temp = (const char *)datain + xindex + lowy_int*ysize; 02554 for (k = 0, temp_index = temp; k < components; 02555 k++, temp_index += element_size) { 02556 if (myswap_bytes) { 02557 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02558 } else { 02559 totals[k] += *(const GLuint*)temp_index * percent; 02560 } 02561 } 02562 for (l = lowx_int+1; l < highx_int; l++) { 02563 temp += group_size; 02564 for (k = 0, temp_index = temp; k < components; 02565 k++, temp_index += element_size) { 02566 if (myswap_bytes) { 02567 totals[k] += 02568 __GLU_SWAP_4_BYTES(temp_index) * y_percent; 02569 } else { 02570 totals[k] += *(const GLuint*)temp_index * y_percent; 02571 } 02572 } 02573 } 02574 temp += group_size; 02575 percent = y_percent * highx_float; 02576 for (k = 0, temp_index = temp; k < components; 02577 k++, temp_index += element_size) { 02578 if (myswap_bytes) { 02579 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02580 } else { 02581 totals[k] += *(const GLuint*)temp_index * percent; 02582 } 02583 } 02584 } else { 02585 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 02586 temp = (const char *)datain + xindex + lowy_int * ysize; 02587 for (k = 0, temp_index = temp; k < components; 02588 k++, temp_index += element_size) { 02589 if (myswap_bytes) { 02590 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; 02591 } else { 02592 totals[k] += *(const GLuint*)temp_index * percent; 02593 } 02594 } 02595 } 02596 02597 /* this is for the pixels in the body */ 02598 temp0 = (const char *)datain + xindex + group_size + 02599 (lowy_int+1)*ysize; 02600 for (m = lowy_int+1; m < highy_int; m++) { 02601 temp = temp0; 02602 for(l = lowx_int+1; l < highx_int; l++) { 02603 for (k = 0, temp_index = temp; k < components; 02604 k++, temp_index += element_size) { 02605 if (myswap_bytes) { 02606 totals[k] += __GLU_SWAP_4_BYTES(temp_index); 02607 } else { 02608 totals[k] += *(const GLuint*)temp_index; 02609 } 02610 } 02611 temp += group_size; 02612 } 02613 temp0 += ysize; 02614 } 02615 02616 outindex = (j + (i * widthout)) * components; 02617 for (k = 0; k < components; k++) { 02618 /* clamp at UINT_MAX */ 02619 float value= totals[k]/area; 02620 if (value >= (float) UINT_MAX) { /* need '=' */ 02621 dataout[outindex + k] = UINT_MAX; 02622 } 02623 else dataout[outindex + k] = value; 02624 } 02625 lowx_int = highx_int; 02626 lowx_float = highx_float; 02627 highx_int += convx_int; 02628 highx_float += convx_float; 02629 if(highx_float > 1) { 02630 highx_float -= 1.0; 02631 highx_int++; 02632 } 02633 } 02634 lowy_int = highy_int; 02635 lowy_float = highy_float; 02636 highy_int += convy_int; 02637 highy_float += convy_float; 02638 if(highy_float > 1) { 02639 highy_float -= 1.0; 02640 highy_int++; 02641 } 02642 } 02643 } 02644 02645 02646 02647 static void scale_internal_int(GLint components, GLint widthin, 02648 GLint heightin, const GLint *datain, 02649 GLint widthout, GLint heightout, 02650 GLint *dataout, GLint element_size, 02651 GLint ysize, GLint group_size, 02652 GLint myswap_bytes) 02653 { 02654 float convx; 02655 float convy; 02656 float percent; 02657 /* Max components in a format is 4, so... */ 02658 float totals[4]; 02659 float area; 02660 int i,j,k,xindex; 02661 02662 const char *temp, *temp0; 02663 const char *temp_index; 02664 int outindex; 02665 02666 int lowx_int, highx_int, lowy_int, highy_int; 02667 float x_percent, y_percent; 02668 float lowx_float, highx_float, lowy_float, highy_float; 02669 float convy_float, convx_float; 02670 int convy_int, convx_int; 02671 int l, m; 02672 const char *left, *right; 02673 02674 GLuint swapbuf; /* unsigned buffer */ 02675 02676 if (widthin == widthout*2 && heightin == heightout*2) { 02677 halveImage_int(components, widthin, heightin, 02678 (const GLint *)datain, (GLint *)dataout, 02679 element_size, ysize, group_size, myswap_bytes); 02680 return; 02681 } 02682 convy = (float) heightin/heightout; 02683 convx = (float) widthin/widthout; 02684 convy_int = floor(convy); 02685 convy_float = convy - convy_int; 02686 convx_int = floor(convx); 02687 convx_float = convx - convx_int; 02688 02689 area = convx * convy; 02690 02691 lowy_int = 0; 02692 lowy_float = 0; 02693 highy_int = convy_int; 02694 highy_float = convy_float; 02695 02696 for (i = 0; i < heightout; i++) { 02697 lowx_int = 0; 02698 lowx_float = 0; 02699 highx_int = convx_int; 02700 highx_float = convx_float; 02701 02702 for (j = 0; j < widthout; j++) { 02703 /* 02704 ** Ok, now apply box filter to box that goes from (lowx, lowy) 02705 ** to (highx, highy) on input data into this pixel on output 02706 ** data. 02707 */ 02708 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 02709 02710 /* calculate the value for pixels in the 1st row */ 02711 xindex = lowx_int*group_size; 02712 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 02713 02714 y_percent = 1-lowy_float; 02715 temp = (const char *)datain + xindex + lowy_int * ysize; 02716 percent = y_percent * (1-lowx_float); 02717 for (k = 0, temp_index = temp; k < components; 02718 k++, temp_index += element_size) { 02719 if (myswap_bytes) { 02720 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02721 totals[k] += *(const GLint*)&swapbuf * percent; 02722 } else { 02723 totals[k] += *(const GLint*)temp_index * percent; 02724 } 02725 } 02726 left = temp; 02727 for(l = lowx_int+1; l < highx_int; l++) { 02728 temp += group_size; 02729 for (k = 0, temp_index = temp; k < components; 02730 k++, temp_index += element_size) { 02731 if (myswap_bytes) { 02732 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02733 totals[k] += *(const GLint*)&swapbuf * y_percent; 02734 } else { 02735 totals[k] += *(const GLint*)temp_index * y_percent; 02736 } 02737 } 02738 } 02739 temp += group_size; 02740 right = temp; 02741 percent = y_percent * highx_float; 02742 for (k = 0, temp_index = temp; k < components; 02743 k++, temp_index += element_size) { 02744 if (myswap_bytes) { 02745 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02746 totals[k] += *(const GLint*)&swapbuf * percent; 02747 } else { 02748 totals[k] += *(const GLint*)temp_index * percent; 02749 } 02750 } 02751 02752 /* calculate the value for pixels in the last row */ 02753 y_percent = highy_float; 02754 percent = y_percent * (1-lowx_float); 02755 temp = (const char *)datain + xindex + highy_int * ysize; 02756 for (k = 0, temp_index = temp; k < components; 02757 k++, temp_index += element_size) { 02758 if (myswap_bytes) { 02759 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02760 totals[k] += *(const GLint*)&swapbuf * percent; 02761 } else { 02762 totals[k] += *(const GLint*)temp_index * percent; 02763 } 02764 } 02765 for(l = lowx_int+1; l < highx_int; l++) { 02766 temp += group_size; 02767 for (k = 0, temp_index = temp; k < components; 02768 k++, temp_index += element_size) { 02769 if (myswap_bytes) { 02770 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02771 totals[k] += *(const GLint*)&swapbuf * y_percent; 02772 } else { 02773 totals[k] += *(const GLint*)temp_index * y_percent; 02774 } 02775 } 02776 } 02777 temp += group_size; 02778 percent = y_percent * highx_float; 02779 for (k = 0, temp_index = temp; k < components; 02780 k++, temp_index += element_size) { 02781 if (myswap_bytes) { 02782 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02783 totals[k] += *(const GLint*)&swapbuf * percent; 02784 } else { 02785 totals[k] += *(const GLint*)temp_index * percent; 02786 } 02787 } 02788 02789 /* calculate the value for pixels in the 1st and last column */ 02790 for(m = lowy_int+1; m < highy_int; m++) { 02791 left += ysize; 02792 right += ysize; 02793 for (k = 0; k < components; 02794 k++, left += element_size, right += element_size) { 02795 if (myswap_bytes) { 02796 swapbuf = __GLU_SWAP_4_BYTES(left); 02797 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float); 02798 swapbuf = __GLU_SWAP_4_BYTES(right); 02799 totals[k] += *(const GLint*)&swapbuf * highx_float; 02800 } else { 02801 totals[k] += *(const GLint*)left * (1-lowx_float) 02802 + *(const GLint*)right * highx_float; 02803 } 02804 } 02805 } 02806 } else if (highy_int > lowy_int) { 02807 x_percent = highx_float - lowx_float; 02808 percent = (1-lowy_float)*x_percent; 02809 temp = (const char *)datain + xindex + lowy_int*ysize; 02810 for (k = 0, temp_index = temp; k < components; 02811 k++, temp_index += element_size) { 02812 if (myswap_bytes) { 02813 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02814 totals[k] += *(const GLint*)&swapbuf * percent; 02815 } else { 02816 totals[k] += *(const GLint*)temp_index * percent; 02817 } 02818 } 02819 for(m = lowy_int+1; m < highy_int; m++) { 02820 temp += ysize; 02821 for (k = 0, temp_index = temp; k < components; 02822 k++, temp_index += element_size) { 02823 if (myswap_bytes) { 02824 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02825 totals[k] += *(const GLint*)&swapbuf * x_percent; 02826 } else { 02827 totals[k] += *(const GLint*)temp_index * x_percent; 02828 } 02829 } 02830 } 02831 percent = x_percent * highy_float; 02832 temp += ysize; 02833 for (k = 0, temp_index = temp; k < components; 02834 k++, temp_index += element_size) { 02835 if (myswap_bytes) { 02836 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02837 totals[k] += *(const GLint*)&swapbuf * percent; 02838 } else { 02839 totals[k] += *(const GLint*)temp_index * percent; 02840 } 02841 } 02842 } else if (highx_int > lowx_int) { 02843 y_percent = highy_float - lowy_float; 02844 percent = (1-lowx_float)*y_percent; 02845 02846 temp = (const char *)datain + xindex + lowy_int*ysize; 02847 for (k = 0, temp_index = temp; k < components; 02848 k++, temp_index += element_size) { 02849 if (myswap_bytes) { 02850 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02851 totals[k] += *(const GLint*)&swapbuf * percent; 02852 } else { 02853 totals[k] += *(const GLint*)temp_index * percent; 02854 } 02855 } 02856 for (l = lowx_int+1; l < highx_int; l++) { 02857 temp += group_size; 02858 for (k = 0, temp_index = temp; k < components; 02859 k++, temp_index += element_size) { 02860 if (myswap_bytes) { 02861 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02862 totals[k] += *(const GLint*)&swapbuf * y_percent; 02863 } else { 02864 totals[k] += *(const GLint*)temp_index * y_percent; 02865 } 02866 } 02867 } 02868 temp += group_size; 02869 percent = y_percent * highx_float; 02870 for (k = 0, temp_index = temp; k < components; 02871 k++, temp_index += element_size) { 02872 if (myswap_bytes) { 02873 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02874 totals[k] += *(const GLint*)&swapbuf * percent; 02875 } else { 02876 totals[k] += *(const GLint*)temp_index * percent; 02877 } 02878 } 02879 } else { 02880 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 02881 temp = (const char *)datain + xindex + lowy_int * ysize; 02882 for (k = 0, temp_index = temp; k < components; 02883 k++, temp_index += element_size) { 02884 if (myswap_bytes) { 02885 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02886 totals[k] += *(const GLint*)&swapbuf * percent; 02887 } else { 02888 totals[k] += *(const GLint*)temp_index * percent; 02889 } 02890 } 02891 } 02892 02893 /* this is for the pixels in the body */ 02894 temp0 = (const char *)datain + xindex + group_size + 02895 (lowy_int+1)*ysize; 02896 for (m = lowy_int+1; m < highy_int; m++) { 02897 temp = temp0; 02898 for(l = lowx_int+1; l < highx_int; l++) { 02899 for (k = 0, temp_index = temp; k < components; 02900 k++, temp_index += element_size) { 02901 if (myswap_bytes) { 02902 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 02903 totals[k] += *(const GLint*)&swapbuf; 02904 } else { 02905 totals[k] += *(const GLint*)temp_index; 02906 } 02907 } 02908 temp += group_size; 02909 } 02910 temp0 += ysize; 02911 } 02912 02913 outindex = (j + (i * widthout)) * components; 02914 for (k = 0; k < components; k++) { 02915 dataout[outindex + k] = totals[k]/area; 02916 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 02917 } 02918 lowx_int = highx_int; 02919 lowx_float = highx_float; 02920 highx_int += convx_int; 02921 highx_float += convx_float; 02922 if(highx_float > 1) { 02923 highx_float -= 1.0; 02924 highx_int++; 02925 } 02926 } 02927 lowy_int = highy_int; 02928 lowy_float = highy_float; 02929 highy_int += convy_int; 02930 highy_float += convy_float; 02931 if(highy_float > 1) { 02932 highy_float -= 1.0; 02933 highy_int++; 02934 } 02935 } 02936 } 02937 02938 02939 02940 static void scale_internal_float(GLint components, GLint widthin, 02941 GLint heightin, const GLfloat *datain, 02942 GLint widthout, GLint heightout, 02943 GLfloat *dataout, GLint element_size, 02944 GLint ysize, GLint group_size, 02945 GLint myswap_bytes) 02946 { 02947 float convx; 02948 float convy; 02949 float percent; 02950 /* Max components in a format is 4, so... */ 02951 float totals[4]; 02952 float area; 02953 int i,j,k,xindex; 02954 02955 const char *temp, *temp0; 02956 const char *temp_index; 02957 int outindex; 02958 02959 int lowx_int, highx_int, lowy_int, highy_int; 02960 float x_percent, y_percent; 02961 float lowx_float, highx_float, lowy_float, highy_float; 02962 float convy_float, convx_float; 02963 int convy_int, convx_int; 02964 int l, m; 02965 const char *left, *right; 02966 02967 GLuint swapbuf; /* unsigned buffer */ 02968 02969 if (widthin == widthout*2 && heightin == heightout*2) { 02970 halveImage_float(components, widthin, heightin, 02971 (const GLfloat *)datain, (GLfloat *)dataout, 02972 element_size, ysize, group_size, myswap_bytes); 02973 return; 02974 } 02975 convy = (float) heightin/heightout; 02976 convx = (float) widthin/widthout; 02977 convy_int = floor(convy); 02978 convy_float = convy - convy_int; 02979 convx_int = floor(convx); 02980 convx_float = convx - convx_int; 02981 02982 area = convx * convy; 02983 02984 lowy_int = 0; 02985 lowy_float = 0; 02986 highy_int = convy_int; 02987 highy_float = convy_float; 02988 02989 for (i = 0; i < heightout; i++) { 02990 lowx_int = 0; 02991 lowx_float = 0; 02992 highx_int = convx_int; 02993 highx_float = convx_float; 02994 02995 for (j = 0; j < widthout; j++) { 02996 /* 02997 ** Ok, now apply box filter to box that goes from (lowx, lowy) 02998 ** to (highx, highy) on input data into this pixel on output 02999 ** data. 03000 */ 03001 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 03002 03003 /* calculate the value for pixels in the 1st row */ 03004 xindex = lowx_int*group_size; 03005 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 03006 03007 y_percent = 1-lowy_float; 03008 temp = (const char *)datain + xindex + lowy_int * ysize; 03009 percent = y_percent * (1-lowx_float); 03010 for (k = 0, temp_index = temp; k < components; 03011 k++, temp_index += element_size) { 03012 if (myswap_bytes) { 03013 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03014 totals[k] += *(const GLfloat*)&swapbuf * percent; 03015 } else { 03016 totals[k] += *(const GLfloat*)temp_index * percent; 03017 } 03018 } 03019 left = temp; 03020 for(l = lowx_int+1; l < highx_int; l++) { 03021 temp += group_size; 03022 for (k = 0, temp_index = temp; k < components; 03023 k++, temp_index += element_size) { 03024 if (myswap_bytes) { 03025 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03026 totals[k] += *(const GLfloat*)&swapbuf * y_percent; 03027 } else { 03028 totals[k] += *(const GLfloat*)temp_index * y_percent; 03029 } 03030 } 03031 } 03032 temp += group_size; 03033 right = temp; 03034 percent = y_percent * highx_float; 03035 for (k = 0, temp_index = temp; k < components; 03036 k++, temp_index += element_size) { 03037 if (myswap_bytes) { 03038 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03039 totals[k] += *(const GLfloat*)&swapbuf * percent; 03040 } else { 03041 totals[k] += *(const GLfloat*)temp_index * percent; 03042 } 03043 } 03044 03045 /* calculate the value for pixels in the last row */ 03046 y_percent = highy_float; 03047 percent = y_percent * (1-lowx_float); 03048 temp = (const char *)datain + xindex + highy_int * ysize; 03049 for (k = 0, temp_index = temp; k < components; 03050 k++, temp_index += element_size) { 03051 if (myswap_bytes) { 03052 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03053 totals[k] += *(const GLfloat*)&swapbuf * percent; 03054 } else { 03055 totals[k] += *(const GLfloat*)temp_index * percent; 03056 } 03057 } 03058 for(l = lowx_int+1; l < highx_int; l++) { 03059 temp += group_size; 03060 for (k = 0, temp_index = temp; k < components; 03061 k++, temp_index += element_size) { 03062 if (myswap_bytes) { 03063 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03064 totals[k] += *(const GLfloat*)&swapbuf * y_percent; 03065 } else { 03066 totals[k] += *(const GLfloat*)temp_index * y_percent; 03067 } 03068 } 03069 } 03070 temp += group_size; 03071 percent = y_percent * highx_float; 03072 for (k = 0, temp_index = temp; k < components; 03073 k++, temp_index += element_size) { 03074 if (myswap_bytes) { 03075 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03076 totals[k] += *(const GLfloat*)&swapbuf * percent; 03077 } else { 03078 totals[k] += *(const GLfloat*)temp_index * percent; 03079 } 03080 } 03081 03082 /* calculate the value for pixels in the 1st and last column */ 03083 for(m = lowy_int+1; m < highy_int; m++) { 03084 left += ysize; 03085 right += ysize; 03086 for (k = 0; k < components; 03087 k++, left += element_size, right += element_size) { 03088 if (myswap_bytes) { 03089 swapbuf = __GLU_SWAP_4_BYTES(left); 03090 totals[k] += *(const GLfloat*)&swapbuf * (1-lowx_float); 03091 swapbuf = __GLU_SWAP_4_BYTES(right); 03092 totals[k] += *(const GLfloat*)&swapbuf * highx_float; 03093 } else { 03094 totals[k] += *(const GLfloat*)left * (1-lowx_float) 03095 + *(const GLfloat*)right * highx_float; 03096 } 03097 } 03098 } 03099 } else if (highy_int > lowy_int) { 03100 x_percent = highx_float - lowx_float; 03101 percent = (1-lowy_float)*x_percent; 03102 temp = (const char *)datain + xindex + lowy_int*ysize; 03103 for (k = 0, temp_index = temp; k < components; 03104 k++, temp_index += element_size) { 03105 if (myswap_bytes) { 03106 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03107 totals[k] += *(const GLfloat*)&swapbuf * percent; 03108 } else { 03109 totals[k] += *(const GLfloat*)temp_index * percent; 03110 } 03111 } 03112 for(m = lowy_int+1; m < highy_int; m++) { 03113 temp += ysize; 03114 for (k = 0, temp_index = temp; k < components; 03115 k++, temp_index += element_size) { 03116 if (myswap_bytes) { 03117 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03118 totals[k] += *(const GLfloat*)&swapbuf * x_percent; 03119 } else { 03120 totals[k] += *(const GLfloat*)temp_index * x_percent; 03121 } 03122 } 03123 } 03124 percent = x_percent * highy_float; 03125 temp += ysize; 03126 for (k = 0, temp_index = temp; k < components; 03127 k++, temp_index += element_size) { 03128 if (myswap_bytes) { 03129 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03130 totals[k] += *(const GLfloat*)&swapbuf * percent; 03131 } else { 03132 totals[k] += *(const GLfloat*)temp_index * percent; 03133 } 03134 } 03135 } else if (highx_int > lowx_int) { 03136 y_percent = highy_float - lowy_float; 03137 percent = (1-lowx_float)*y_percent; 03138 03139 temp = (const char *)datain + xindex + lowy_int*ysize; 03140 for (k = 0, temp_index = temp; k < components; 03141 k++, temp_index += element_size) { 03142 if (myswap_bytes) { 03143 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03144 totals[k] += *(const GLfloat*)&swapbuf * percent; 03145 } else { 03146 totals[k] += *(const GLfloat*)temp_index * percent; 03147 } 03148 } 03149 for (l = lowx_int+1; l < highx_int; l++) { 03150 temp += group_size; 03151 for (k = 0, temp_index = temp; k < components; 03152 k++, temp_index += element_size) { 03153 if (myswap_bytes) { 03154 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03155 totals[k] += *(const GLfloat*)&swapbuf * y_percent; 03156 } else { 03157 totals[k] += *(const GLfloat*)temp_index * y_percent; 03158 } 03159 } 03160 } 03161 temp += group_size; 03162 percent = y_percent * highx_float; 03163 for (k = 0, temp_index = temp; k < components; 03164 k++, temp_index += element_size) { 03165 if (myswap_bytes) { 03166 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03167 totals[k] += *(const GLfloat*)&swapbuf * percent; 03168 } else { 03169 totals[k] += *(const GLfloat*)temp_index * percent; 03170 } 03171 } 03172 } else { 03173 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 03174 temp = (const char *)datain + xindex + lowy_int * ysize; 03175 for (k = 0, temp_index = temp; k < components; 03176 k++, temp_index += element_size) { 03177 if (myswap_bytes) { 03178 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03179 totals[k] += *(const GLfloat*)&swapbuf * percent; 03180 } else { 03181 totals[k] += *(const GLfloat*)temp_index * percent; 03182 } 03183 } 03184 } 03185 03186 /* this is for the pixels in the body */ 03187 temp0 = (const char *)datain + xindex + group_size + 03188 (lowy_int+1)*ysize; 03189 for (m = lowy_int+1; m < highy_int; m++) { 03190 temp = temp0; 03191 for(l = lowx_int+1; l < highx_int; l++) { 03192 for (k = 0, temp_index = temp; k < components; 03193 k++, temp_index += element_size) { 03194 if (myswap_bytes) { 03195 swapbuf = __GLU_SWAP_4_BYTES(temp_index); 03196 totals[k] += *(const GLfloat*)&swapbuf; 03197 } else { 03198 totals[k] += *(const GLfloat*)temp_index; 03199 } 03200 } 03201 temp += group_size; 03202 } 03203 temp0 += ysize; 03204 } 03205 03206 outindex = (j + (i * widthout)) * components; 03207 for (k = 0; k < components; k++) { 03208 dataout[outindex + k] = totals[k]/area; 03209 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 03210 } 03211 lowx_int = highx_int; 03212 lowx_float = highx_float; 03213 highx_int += convx_int; 03214 highx_float += convx_float; 03215 if(highx_float > 1) { 03216 highx_float -= 1.0; 03217 highx_int++; 03218 } 03219 } 03220 lowy_int = highy_int; 03221 lowy_float = highy_float; 03222 highy_int += convy_int; 03223 highy_float += convy_float; 03224 if(highy_float > 1) { 03225 highy_float -= 1.0; 03226 highy_int++; 03227 } 03228 } 03229 } 03230 03231 static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type) 03232 { 03233 if (!legalFormat(format) || !legalType(type)) { 03234 return GLU_INVALID_ENUM; 03235 } 03236 if (format == GL_STENCIL_INDEX) { 03237 return GLU_INVALID_ENUM; 03238 } 03239 03240 if (!isLegalFormatForPackedPixelType(format, type)) { 03241 return GLU_INVALID_OPERATION; 03242 } 03243 03244 return 0; 03245 } /* checkMipmapArgs() */ 03246 03247 static GLboolean legalFormat(GLenum format) 03248 { 03249 switch(format) { 03250 case GL_COLOR_INDEX: 03251 case GL_STENCIL_INDEX: 03252 case GL_DEPTH_COMPONENT: 03253 case GL_RED: 03254 case GL_GREEN: 03255 case GL_BLUE: 03256 case GL_ALPHA: 03257 case GL_RGB: 03258 case GL_RGBA: 03259 case GL_LUMINANCE: 03260 case GL_LUMINANCE_ALPHA: 03261 case GL_BGR: 03262 case GL_BGRA: 03263 return GL_TRUE; 03264 default: 03265 return GL_FALSE; 03266 } 03267 } 03268 03269 03270 static GLboolean legalType(GLenum type) 03271 { 03272 switch(type) { 03273 case GL_BITMAP: 03274 case GL_BYTE: 03275 case GL_UNSIGNED_BYTE: 03276 case GL_SHORT: 03277 case GL_UNSIGNED_SHORT: 03278 case GL_INT: 03279 case GL_UNSIGNED_INT: 03280 case GL_FLOAT: 03281 case GL_UNSIGNED_BYTE_3_3_2: 03282 case GL_UNSIGNED_BYTE_2_3_3_REV: 03283 case GL_UNSIGNED_SHORT_5_6_5: 03284 case GL_UNSIGNED_SHORT_5_6_5_REV: 03285 case GL_UNSIGNED_SHORT_4_4_4_4: 03286 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 03287 case GL_UNSIGNED_SHORT_5_5_5_1: 03288 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 03289 case GL_UNSIGNED_INT_8_8_8_8: 03290 case GL_UNSIGNED_INT_8_8_8_8_REV: 03291 case GL_UNSIGNED_INT_10_10_10_2: 03292 case GL_UNSIGNED_INT_2_10_10_10_REV: 03293 return GL_TRUE; 03294 default: 03295 return GL_FALSE; 03296 } 03297 } 03298 03299 /* */ 03300 static GLboolean isTypePackedPixel(GLenum type) 03301 { 03302 assert(legalType(type)); 03303 03304 if (type == GL_UNSIGNED_BYTE_3_3_2 || 03305 type == GL_UNSIGNED_BYTE_2_3_3_REV || 03306 type == GL_UNSIGNED_SHORT_5_6_5 || 03307 type == GL_UNSIGNED_SHORT_5_6_5_REV || 03308 type == GL_UNSIGNED_SHORT_4_4_4_4 || 03309 type == GL_UNSIGNED_SHORT_4_4_4_4_REV || 03310 type == GL_UNSIGNED_SHORT_5_5_5_1 || 03311 type == GL_UNSIGNED_SHORT_1_5_5_5_REV || 03312 type == GL_UNSIGNED_INT_8_8_8_8 || 03313 type == GL_UNSIGNED_INT_8_8_8_8_REV || 03314 type == GL_UNSIGNED_INT_10_10_10_2 || 03315 type == GL_UNSIGNED_INT_2_10_10_10_REV) { 03316 return 1; 03317 } 03318 else return 0; 03319 } /* isTypePackedPixel() */ 03320 03321 /* Determines if the packed pixel type is compatible with the format */ 03322 static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type) 03323 { 03324 /* if not a packed pixel type then return true */ 03325 if (!isTypePackedPixel(type)) { 03326 return GL_TRUE; 03327 } 03328 03329 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */ 03330 if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV|| 03331 type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV) 03332 && format != GL_RGB) 03333 return GL_FALSE; 03334 03335 /* 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 & 03336 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT. 03337 */ 03338 if ((type == GL_UNSIGNED_SHORT_4_4_4_4 || 03339 type == GL_UNSIGNED_SHORT_4_4_4_4_REV || 03340 type == GL_UNSIGNED_SHORT_5_5_5_1 || 03341 type == GL_UNSIGNED_SHORT_1_5_5_5_REV || 03342 type == GL_UNSIGNED_INT_8_8_8_8 || 03343 type == GL_UNSIGNED_INT_8_8_8_8_REV || 03344 type == GL_UNSIGNED_INT_10_10_10_2 || 03345 type == GL_UNSIGNED_INT_2_10_10_10_REV) && 03346 (format != GL_RGBA && 03347 format != GL_BGRA)) { 03348 return GL_FALSE; 03349 } 03350 03351 return GL_TRUE; 03352 } /* isLegalFormatForPackedPixelType() */ 03353 03354 static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel, 03355 GLint totalLevels) 03356 { 03357 if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel || 03358 totalLevels < maxLevel) 03359 return GL_FALSE; 03360 else return GL_TRUE; 03361 } /* isLegalLevels() */ 03362 03363 /* Given user requested texture size, determine if it fits. If it 03364 * doesn't then halve both sides and make the determination again 03365 * until it does fit (for IR only). 03366 * Note that proxy textures are not implemented in RE* even though 03367 * they advertise the texture extension. 03368 * Note that proxy textures are implemented but not according to spec in 03369 * IMPACT*. 03370 */ 03371 static void closestFit(GLenum target, GLint width, GLint height, 03372 GLint internalFormat, GLenum format, GLenum type, 03373 GLint *newWidth, GLint *newHeight) 03374 { 03375 /* Use proxy textures if OpenGL version is >= 1.1 */ 03376 if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1) 03377 ) { 03378 GLint widthPowerOf2= nearestPower(width); 03379 GLint heightPowerOf2= nearestPower(height); 03380 GLint proxyWidth; 03381 03382 do { 03383 /* compute level 1 width & height, clamping each at 1 */ 03384 GLint widthAtLevelOne= (widthPowerOf2 > 1) ? 03385 widthPowerOf2 >> 1 : 03386 widthPowerOf2; 03387 GLint heightAtLevelOne= (heightPowerOf2 > 1) ? 03388 heightPowerOf2 >> 1 : 03389 heightPowerOf2; 03390 GLenum proxyTarget; 03391 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0); 03392 03393 /* does width x height at level 1 & all their mipmaps fit? */ 03394 if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { 03395 proxyTarget = GL_PROXY_TEXTURE_2D; 03396 glTexImage2D(proxyTarget, 1, /* must be non-zero */ 03397 internalFormat, 03398 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL); 03399 } else 03400 #if defined(GL_ARB_texture_cube_map) 03401 if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) || 03402 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) || 03403 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) || 03404 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) || 03405 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) || 03406 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 03407 proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB; 03408 glTexImage2D(proxyTarget, 1, /* must be non-zero */ 03409 internalFormat, 03410 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL); 03411 } else 03412 #endif /* GL_ARB_texture_cube_map */ 03413 { 03414 assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D); 03415 proxyTarget = GL_PROXY_TEXTURE_1D; 03416 glTexImage1D(proxyTarget, 1, /* must be non-zero */ 03417 internalFormat,widthAtLevelOne,0,format,type,NULL); 03418 } 03419 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth); 03420 /* does it fit??? */ 03421 if (proxyWidth == 0) { /* nope, so try again with these sizes */ 03422 if (widthPowerOf2 == 1 && heightPowerOf2 == 1) { 03423 /* An 1x1 texture couldn't fit for some reason, so 03424 * break out. This should never happen. But things 03425 * happen. The disadvantage with this if-statement is 03426 * that we will never be aware of when this happens 03427 * since it will silently branch out. 03428 */ 03429 goto noProxyTextures; 03430 } 03431 widthPowerOf2= widthAtLevelOne; 03432 heightPowerOf2= heightAtLevelOne; 03433 } 03434 /* else it does fit */ 03435 } while (proxyWidth == 0); 03436 /* loop must terminate! */ 03437 03438 /* return the width & height at level 0 that fits */ 03439 *newWidth= widthPowerOf2; 03440 *newHeight= heightPowerOf2; 03441 /*printf("Proxy Textures\n");*/ 03442 } /* if gluCheckExtension() */ 03443 else { /* no texture extension, so do this instead */ 03444 GLint maxsize; 03445 03446 noProxyTextures: 03447 03448 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); 03449 /* clamp user's texture sizes to maximum sizes, if necessary */ 03450 *newWidth = nearestPower(width); 03451 if (*newWidth > maxsize) *newWidth = maxsize; 03452 *newHeight = nearestPower(height); 03453 if (*newHeight > maxsize) *newHeight = maxsize; 03454 /*printf("NO proxy textures\n");*/ 03455 } 03456 } /* closestFit() */ 03457 03458 GLint GLAPIENTRY 03459 gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin, 03460 GLenum typein, const void *datain, 03461 GLsizei widthout, GLsizei heightout, GLenum typeout, 03462 void *dataout) 03463 { 03464 int components; 03465 GLushort *beforeImage; 03466 GLushort *afterImage; 03467 PixelStorageModes psm; 03468 03469 if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) { 03470 return 0; 03471 } 03472 if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) { 03473 return GLU_INVALID_VALUE; 03474 } 03475 if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) { 03476 return GLU_INVALID_ENUM; 03477 } 03478 if (!isLegalFormatForPackedPixelType(format, typein)) { 03479 return GLU_INVALID_OPERATION; 03480 } 03481 if (!isLegalFormatForPackedPixelType(format, typeout)) { 03482 return GLU_INVALID_OPERATION; 03483 } 03484 beforeImage = 03485 malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT)); 03486 if (beforeImage == NULL) { 03487 return GLU_OUT_OF_MEMORY; 03488 } 03489 03490 afterImage = 03491 malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT)); 03492 if (afterImage == NULL) { 03493 free(beforeImage); 03494 return GLU_OUT_OF_MEMORY; 03495 } 03496 03497 retrieveStoreModes(&psm); 03498 fill_image(&psm,widthin, heightin, format, typein, is_index(format), 03499 datain, beforeImage); 03500 components = elements_per_group(format, 0); 03501 scale_internal(components, widthin, heightin, beforeImage, 03502 widthout, heightout, afterImage); 03503 empty_image(&psm,widthout, heightout, format, typeout, 03504 is_index(format), afterImage, dataout); 03505 free((GLbyte *) beforeImage); 03506 free((GLbyte *) afterImage); 03507 03508 return 0; 03509 } 03510 03511 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat, 03512 GLsizei width, 03513 GLsizei widthPowerOf2, 03514 GLenum format, GLenum type, 03515 GLint userLevel, GLint baseLevel,GLint maxLevel, 03516 const void *data) 03517 { 03518 GLint newwidth; 03519 GLint level, levels; 03520 GLushort *newImage; 03521 GLint newImage_width; 03522 GLushort *otherImage; 03523 GLushort *imageTemp; 03524 GLint memreq; 03525 GLint cmpts; 03526 PixelStorageModes psm; 03527 03528 assert(checkMipmapArgs(internalFormat,format,type) == 0); 03529 assert(width >= 1); 03530 03531 otherImage = NULL; 03532 03533 newwidth= widthPowerOf2; 03534 levels = computeLog(newwidth); 03535 03536 levels+= userLevel; 03537 03538 retrieveStoreModes(&psm); 03539 newImage = (GLushort *) 03540 malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT)); 03541 newImage_width = width; 03542 if (newImage == NULL) { 03543 return GLU_OUT_OF_MEMORY; 03544 } 03545 fill_image(&psm,width, 1, format, type, is_index(format), 03546 data, newImage); 03547 cmpts = elements_per_group(format,type); 03548 glPixelStorei(GL_UNPACK_ALIGNMENT, 2); 03549 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 03550 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 03551 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 03552 /* 03553 ** If swap_bytes was set, swapping occurred in fill_image. 03554 */ 03555 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 03556 03557 for (level = userLevel; level <= levels; level++) { 03558 if (newImage_width == newwidth) { 03559 /* Use newImage for this level */ 03560 if (baseLevel <= level && level <= maxLevel) { 03561 glTexImage1D(target, level, internalFormat, newImage_width, 03562 0, format, GL_UNSIGNED_SHORT, (void *) newImage); 03563 } 03564 } else { 03565 if (otherImage == NULL) { 03566 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT); 03567 otherImage = (GLushort *) malloc(memreq); 03568 if (otherImage == NULL) { 03569 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 03570 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 03571 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); 03572 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 03573 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 03574 return GLU_OUT_OF_MEMORY; 03575 } 03576 } 03577 scale_internal(cmpts, newImage_width, 1, newImage, 03578 newwidth, 1, otherImage); 03579 /* Swap newImage and otherImage */ 03580 imageTemp = otherImage; 03581 otherImage = newImage; 03582 newImage = imageTemp; 03583 03584 newImage_width = newwidth; 03585 if (baseLevel <= level && level <= maxLevel) { 03586 glTexImage1D(target, level, internalFormat, newImage_width, 03587 0, format, GL_UNSIGNED_SHORT, (void *) newImage); 03588 } 03589 } 03590 if (newwidth > 1) newwidth /= 2; 03591 } 03592 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 03593 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 03594 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 03595 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 03596 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 03597 03598 free((GLbyte *) newImage); 03599 if (otherImage) { 03600 free((GLbyte *) otherImage); 03601 } 03602 return 0; 03603 } 03604 03605 GLint GLAPIENTRY 03606 gluBuild1DMipmapLevels(GLenum target, GLint internalFormat, 03607 GLsizei width, 03608 GLenum format, GLenum type, 03609 GLint userLevel, GLint baseLevel, GLint maxLevel, 03610 const void *data) 03611 { 03612 int levels; 03613 03614 int rc= checkMipmapArgs(internalFormat,format,type); 03615 if (rc != 0) return rc; 03616 03617 if (width < 1) { 03618 return GLU_INVALID_VALUE; 03619 } 03620 03621 levels = computeLog(width); 03622 03623 levels+= userLevel; 03624 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) 03625 return GLU_INVALID_VALUE; 03626 03627 return gluBuild1DMipmapLevelsCore(target, internalFormat, 03628 width, 03629 width,format, type, 03630 userLevel, baseLevel, maxLevel, 03631 data); 03632 } /* gluBuild1DMipmapLevels() */ 03633 03634 GLint GLAPIENTRY 03635 gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width, 03636 GLenum format, GLenum type, 03637 const void *data) 03638 { 03639 GLint widthPowerOf2; 03640 int levels; 03641 GLint dummy; 03642 03643 int rc= checkMipmapArgs(internalFormat,format,type); 03644 if (rc != 0) return rc; 03645 03646 if (width < 1) { 03647 return GLU_INVALID_VALUE; 03648 } 03649 03650 closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy); 03651 levels = computeLog(widthPowerOf2); 03652 03653 return gluBuild1DMipmapLevelsCore(target,internalFormat, 03654 width, 03655 widthPowerOf2, 03656 format,type,0,0,levels,data); 03657 } 03658 03659 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat, 03660 GLint width, GLint height, GLenum format, 03661 GLenum type, const void *data) 03662 { 03663 GLint newwidth, newheight; 03664 GLint level, levels; 03665 GLushort *newImage; 03666 GLint newImage_width; 03667 GLint newImage_height; 03668 GLushort *otherImage; 03669 GLushort *imageTemp; 03670 GLint memreq; 03671 GLint cmpts; 03672 PixelStorageModes psm; 03673 03674 retrieveStoreModes(&psm); 03675 03676 #if 0 03677 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); 03678 newwidth = nearestPower(width); 03679 if (newwidth > maxsize) newwidth = maxsize; 03680 newheight = nearestPower(height); 03681 if (newheight > maxsize) newheight = maxsize; 03682 #else 03683 closestFit(target,width,height,internalFormat,format,type, 03684 &newwidth,&newheight); 03685 #endif 03686 levels = computeLog(newwidth); 03687 level = computeLog(newheight); 03688 if (level > levels) levels=level; 03689 03690 otherImage = NULL; 03691 newImage = (GLushort *) 03692 malloc(image_size(width, height, format, GL_UNSIGNED_SHORT)); 03693 newImage_width = width; 03694 newImage_height = height; 03695 if (newImage == NULL) { 03696 return GLU_OUT_OF_MEMORY; 03697 } 03698 03699 fill_image(&psm,width, height, format, type, is_index(format), 03700 data, newImage); 03701 03702 cmpts = elements_per_group(format,type); 03703 glPixelStorei(GL_UNPACK_ALIGNMENT, 2); 03704 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 03705 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 03706 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 03707 /* 03708 ** If swap_bytes was set, swapping occurred in fill_image. 03709 */ 03710 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 03711 03712 for (level = 0; level <= levels; level++) { 03713 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */ 03714 glTexImage2D(target, level, internalFormat, newImage_width, 03715 newImage_height, 0, format, GL_UNSIGNED_SHORT, 03716 (void *) newImage); 03717 } else { 03718 if (otherImage == NULL) { 03719 memreq = 03720 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT); 03721 otherImage = (GLushort *) malloc(memreq); 03722 if (otherImage == NULL) { 03723 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 03724 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 03725 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); 03726 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 03727 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 03728 return GLU_OUT_OF_MEMORY; 03729 } 03730 } 03731 scale_internal(cmpts, newImage_width, newImage_height, newImage, 03732 newwidth, newheight, otherImage); 03733 /* Swap newImage and otherImage */ 03734 imageTemp = otherImage; 03735 otherImage = newImage; 03736 newImage = imageTemp; 03737 03738 newImage_width = newwidth; 03739 newImage_height = newheight; 03740 glTexImage2D(target, level, internalFormat, newImage_width, 03741 newImage_height, 0, format, GL_UNSIGNED_SHORT, 03742 (void *) newImage); 03743 } 03744 if (newwidth > 1) newwidth /= 2; 03745 if (newheight > 1) newheight /= 2; 03746 } 03747 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 03748 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 03749 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 03750 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 03751 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 03752 03753 free((GLbyte *) newImage); 03754 if (otherImage) { 03755 free((GLbyte *) otherImage); 03756 } 03757 return 0; 03758 } 03759 03760 /* To make swapping images less error prone */ 03761 #define __GLU_INIT_SWAP_IMAGE void *tmpImage 03762 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage; 03763 03764 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, 03765 GLsizei width, GLsizei height, 03766 GLsizei widthPowerOf2, 03767 GLsizei heightPowerOf2, 03768 GLenum format, GLenum type, 03769 GLint userLevel, 03770 GLint baseLevel,GLint maxLevel, 03771 const void *data) 03772 { 03773 GLint newwidth, newheight; 03774 GLint level, levels; 03775 const void *usersImage; /* passed from user. Don't touch! */ 03776 void *srcImage, *dstImage; /* scratch area to build mipmapped images */ 03777 __GLU_INIT_SWAP_IMAGE; 03778 GLint memreq; 03779 GLint cmpts; 03780 03781 GLint myswap_bytes, groups_per_line, element_size, group_size; 03782 GLint rowsize, padding; 03783 PixelStorageModes psm; 03784 03785 assert(checkMipmapArgs(internalFormat,format,type) == 0); 03786 assert(width >= 1 && height >= 1); 03787 03788 if(type == GL_BITMAP) { 03789 return bitmapBuild2DMipmaps(target, internalFormat, width, height, 03790 format, type, data); 03791 } 03792 03793 srcImage = dstImage = NULL; 03794 03795 newwidth= widthPowerOf2; 03796 newheight= heightPowerOf2; 03797 levels = computeLog(newwidth); 03798 level = computeLog(newheight); 03799 if (level > levels) levels=level; 03800 03801 levels+= userLevel; 03802 03803 retrieveStoreModes(&psm); 03804 myswap_bytes = psm.unpack_swap_bytes; 03805 cmpts = elements_per_group(format,type); 03806 if (psm.unpack_row_length > 0) { 03807 groups_per_line = psm.unpack_row_length; 03808 } else { 03809 groups_per_line = width; 03810 } 03811 03812 element_size = bytes_per_element(type); 03813 group_size = element_size * cmpts; 03814 if (element_size == 1) myswap_bytes = 0; 03815 03816 rowsize = groups_per_line * group_size; 03817 padding = (rowsize % psm.unpack_alignment); 03818 if (padding) { 03819 rowsize += psm.unpack_alignment - padding; 03820 } 03821 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize + 03822 psm.unpack_skip_pixels * group_size; 03823 03824 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 03825 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 03826 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 03827 03828 level = userLevel; 03829 03830 /* already power-of-two square */ 03831 if (width == newwidth && height == newheight) { 03832 /* Use usersImage for level userLevel */ 03833 if (baseLevel <= level && level <= maxLevel) { 03834 glTexImage2D(target, level, internalFormat, width, 03835 height, 0, format, type, 03836 usersImage); 03837 } 03838 if(levels == 0) { /* we're done. clean up and return */ 03839 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 03840 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 03841 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 03842 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 03843 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 03844 return 0; 03845 } 03846 { 03847 int nextWidth= newwidth/2; 03848 int nextHeight= newheight/2; 03849 03850 /* clamp to 1 */ 03851 if (nextWidth < 1) nextWidth= 1; 03852 if (nextHeight < 1) nextHeight= 1; 03853 memreq = image_size(nextWidth, nextHeight, format, type); 03854 } 03855 03856 switch(type) { 03857 case GL_UNSIGNED_BYTE: 03858 dstImage = (GLubyte *)malloc(memreq); 03859 break; 03860 case GL_BYTE: 03861 dstImage = (GLbyte *)malloc(memreq); 03862 break; 03863 case GL_UNSIGNED_SHORT: 03864 dstImage = (GLushort *)malloc(memreq); 03865 break; 03866 case GL_SHORT: 03867 dstImage = (GLshort *)malloc(memreq); 03868 break; 03869 case GL_UNSIGNED_INT: 03870 dstImage = (GLuint *)malloc(memreq); 03871 break; 03872 case GL_INT: 03873 dstImage = (GLint *)malloc(memreq); 03874 break; 03875 case GL_FLOAT: 03876 dstImage = (GLfloat *)malloc(memreq); 03877 break; 03878 case GL_UNSIGNED_BYTE_3_3_2: 03879 case GL_UNSIGNED_BYTE_2_3_3_REV: 03880 dstImage = (GLubyte *)malloc(memreq); 03881 break; 03882 case GL_UNSIGNED_SHORT_5_6_5: 03883 case GL_UNSIGNED_SHORT_5_6_5_REV: 03884 case GL_UNSIGNED_SHORT_4_4_4_4: 03885 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 03886 case GL_UNSIGNED_SHORT_5_5_5_1: 03887 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 03888 dstImage = (GLushort *)malloc(memreq); 03889 break; 03890 case GL_UNSIGNED_INT_8_8_8_8: 03891 case GL_UNSIGNED_INT_8_8_8_8_REV: 03892 case GL_UNSIGNED_INT_10_10_10_2: 03893 case GL_UNSIGNED_INT_2_10_10_10_REV: 03894 dstImage = (GLuint *)malloc(memreq); 03895 break; 03896 default: 03897 return GLU_INVALID_ENUM; 03898 } 03899 if (dstImage == NULL) { 03900 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 03901 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 03902 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 03903 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 03904 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 03905 return GLU_OUT_OF_MEMORY; 03906 } 03907 else 03908 switch(type) { 03909 case GL_UNSIGNED_BYTE: 03910 halveImage_ubyte(cmpts, width, height, 03911 (const GLubyte *)usersImage, (GLubyte *)dstImage, 03912 element_size, rowsize, group_size); 03913 break; 03914 case GL_BYTE: 03915 halveImage_byte(cmpts, width, height, 03916 (const GLbyte *)usersImage, (GLbyte *)dstImage, 03917 element_size, rowsize, group_size); 03918 break; 03919 case GL_UNSIGNED_SHORT: 03920 halveImage_ushort(cmpts, width, height, 03921 (const GLushort *)usersImage, (GLushort *)dstImage, 03922 element_size, rowsize, group_size, myswap_bytes); 03923 break; 03924 case GL_SHORT: 03925 halveImage_short(cmpts, width, height, 03926 (const GLshort *)usersImage, (GLshort *)dstImage, 03927 element_size, rowsize, group_size, myswap_bytes); 03928 break; 03929 case GL_UNSIGNED_INT: 03930 halveImage_uint(cmpts, width, height, 03931 (const GLuint *)usersImage, (GLuint *)dstImage, 03932 element_size, rowsize, group_size, myswap_bytes); 03933 break; 03934 case GL_INT: 03935 halveImage_int(cmpts, width, height, 03936 (const GLint *)usersImage, (GLint *)dstImage, 03937 element_size, rowsize, group_size, myswap_bytes); 03938 break; 03939 case GL_FLOAT: 03940 halveImage_float(cmpts, width, height, 03941 (const GLfloat *)usersImage, (GLfloat *)dstImage, 03942 element_size, rowsize, group_size, myswap_bytes); 03943 break; 03944 case GL_UNSIGNED_BYTE_3_3_2: 03945 assert(format == GL_RGB); 03946 halveImagePackedPixel(3,extract332,shove332, 03947 width,height,usersImage,dstImage, 03948 element_size,rowsize,myswap_bytes); 03949 break; 03950 case GL_UNSIGNED_BYTE_2_3_3_REV: 03951 assert(format == GL_RGB); 03952 halveImagePackedPixel(3,extract233rev,shove233rev, 03953 width,height,usersImage,dstImage, 03954 element_size,rowsize,myswap_bytes); 03955 break; 03956 case GL_UNSIGNED_SHORT_5_6_5: 03957 halveImagePackedPixel(3,extract565,shove565, 03958 width,height,usersImage,dstImage, 03959 element_size,rowsize,myswap_bytes); 03960 break; 03961 case GL_UNSIGNED_SHORT_5_6_5_REV: 03962 halveImagePackedPixel(3,extract565rev,shove565rev, 03963 width,height,usersImage,dstImage, 03964 element_size,rowsize,myswap_bytes); 03965 break; 03966 case GL_UNSIGNED_SHORT_4_4_4_4: 03967 halveImagePackedPixel(4,extract4444,shove4444, 03968 width,height,usersImage,dstImage, 03969 element_size,rowsize,myswap_bytes); 03970 break; 03971 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 03972 halveImagePackedPixel(4,extract4444rev,shove4444rev, 03973 width,height,usersImage,dstImage, 03974 element_size,rowsize,myswap_bytes); 03975 break; 03976 case GL_UNSIGNED_SHORT_5_5_5_1: 03977 halveImagePackedPixel(4,extract5551,shove5551, 03978 width,height,usersImage,dstImage, 03979 element_size,rowsize,myswap_bytes); 03980 break; 03981 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 03982 halveImagePackedPixel(4,extract1555rev,shove1555rev, 03983 width,height,usersImage,dstImage, 03984 element_size,rowsize,myswap_bytes); 03985 break; 03986 case GL_UNSIGNED_INT_8_8_8_8: 03987 halveImagePackedPixel(4,extract8888,shove8888, 03988 width,height,usersImage,dstImage, 03989 element_size,rowsize,myswap_bytes); 03990 break; 03991 case GL_UNSIGNED_INT_8_8_8_8_REV: 03992 halveImagePackedPixel(4,extract8888rev,shove8888rev, 03993 width,height,usersImage,dstImage, 03994 element_size,rowsize,myswap_bytes); 03995 break; 03996 case GL_UNSIGNED_INT_10_10_10_2: 03997 halveImagePackedPixel(4,extract1010102,shove1010102, 03998 width,height,usersImage,dstImage, 03999 element_size,rowsize,myswap_bytes); 04000 break; 04001 case GL_UNSIGNED_INT_2_10_10_10_REV: 04002 halveImagePackedPixel(4,extract2101010rev,shove2101010rev, 04003 width,height,usersImage,dstImage, 04004 element_size,rowsize,myswap_bytes); 04005 break; 04006 default: 04007 assert(0); 04008 break; 04009 } 04010 newwidth = width/2; 04011 newheight = height/2; 04012 /* clamp to 1 */ 04013 if (newwidth < 1) newwidth= 1; 04014 if (newheight < 1) newheight= 1; 04015 04016 myswap_bytes = 0; 04017 rowsize = newwidth * group_size; 04018 memreq = image_size(newwidth, newheight, format, type); 04019 /* Swap srcImage and dstImage */ 04020 __GLU_SWAP_IMAGE(srcImage,dstImage); 04021 switch(type) { 04022 case GL_UNSIGNED_BYTE: 04023 dstImage = (GLubyte *)malloc(memreq); 04024 break; 04025 case GL_BYTE: 04026 dstImage = (GLbyte *)malloc(memreq); 04027 break; 04028 case GL_UNSIGNED_SHORT: 04029 dstImage = (GLushort *)malloc(memreq); 04030 break; 04031 case GL_SHORT: 04032 dstImage = (GLshort *)malloc(memreq); 04033 break; 04034 case GL_UNSIGNED_INT: 04035 dstImage = (GLuint *)malloc(memreq); 04036 break; 04037 case GL_INT: 04038 dstImage = (GLint *)malloc(memreq); 04039 break; 04040 case GL_FLOAT: 04041 dstImage = (GLfloat *)malloc(memreq); 04042 break; 04043 case GL_UNSIGNED_BYTE_3_3_2: 04044 case GL_UNSIGNED_BYTE_2_3_3_REV: 04045 dstImage = (GLubyte *)malloc(memreq); 04046 break; 04047 case GL_UNSIGNED_SHORT_5_6_5: 04048 case GL_UNSIGNED_SHORT_5_6_5_REV: 04049 case GL_UNSIGNED_SHORT_4_4_4_4: 04050 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04051 case GL_UNSIGNED_SHORT_5_5_5_1: 04052 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04053 dstImage = (GLushort *)malloc(memreq); 04054 break; 04055 case GL_UNSIGNED_INT_8_8_8_8: 04056 case GL_UNSIGNED_INT_8_8_8_8_REV: 04057 case GL_UNSIGNED_INT_10_10_10_2: 04058 case GL_UNSIGNED_INT_2_10_10_10_REV: 04059 dstImage = (GLuint *)malloc(memreq); 04060 break; 04061 default: 04062 return GLU_INVALID_ENUM; 04063 } 04064 if (dstImage == NULL) { 04065 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 04066 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 04067 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 04068 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 04069 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 04070 return GLU_OUT_OF_MEMORY; 04071 } 04072 /* level userLevel+1 is in srcImage; level userLevel already saved */ 04073 level = userLevel+1; 04074 } else { /* user's image is *not* nice power-of-2 sized square */ 04075 memreq = image_size(newwidth, newheight, format, type); 04076 switch(type) { 04077 case GL_UNSIGNED_BYTE: 04078 dstImage = (GLubyte *)malloc(memreq); 04079 break; 04080 case GL_BYTE: 04081 dstImage = (GLbyte *)malloc(memreq); 04082 break; 04083 case GL_UNSIGNED_SHORT: 04084 dstImage = (GLushort *)malloc(memreq); 04085 break; 04086 case GL_SHORT: 04087 dstImage = (GLshort *)malloc(memreq); 04088 break; 04089 case GL_UNSIGNED_INT: 04090 dstImage = (GLuint *)malloc(memreq); 04091 break; 04092 case GL_INT: 04093 dstImage = (GLint *)malloc(memreq); 04094 break; 04095 case GL_FLOAT: 04096 dstImage = (GLfloat *)malloc(memreq); 04097 break; 04098 case GL_UNSIGNED_BYTE_3_3_2: 04099 case GL_UNSIGNED_BYTE_2_3_3_REV: 04100 dstImage = (GLubyte *)malloc(memreq); 04101 break; 04102 case GL_UNSIGNED_SHORT_5_6_5: 04103 case GL_UNSIGNED_SHORT_5_6_5_REV: 04104 case GL_UNSIGNED_SHORT_4_4_4_4: 04105 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04106 case GL_UNSIGNED_SHORT_5_5_5_1: 04107 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04108 dstImage = (GLushort *)malloc(memreq); 04109 break; 04110 case GL_UNSIGNED_INT_8_8_8_8: 04111 case GL_UNSIGNED_INT_8_8_8_8_REV: 04112 case GL_UNSIGNED_INT_10_10_10_2: 04113 case GL_UNSIGNED_INT_2_10_10_10_REV: 04114 dstImage = (GLuint *)malloc(memreq); 04115 break; 04116 default: 04117 return GLU_INVALID_ENUM; 04118 } 04119 04120 if (dstImage == NULL) { 04121 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 04122 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 04123 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 04124 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 04125 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 04126 return GLU_OUT_OF_MEMORY; 04127 } 04128 04129 switch(type) { 04130 case GL_UNSIGNED_BYTE: 04131 scale_internal_ubyte(cmpts, width, height, 04132 (const GLubyte *)usersImage, newwidth, newheight, 04133 (GLubyte *)dstImage, element_size, 04134 rowsize, group_size); 04135 break; 04136 case GL_BYTE: 04137 scale_internal_byte(cmpts, width, height, 04138 (const GLbyte *)usersImage, newwidth, newheight, 04139 (GLbyte *)dstImage, element_size, 04140 rowsize, group_size); 04141 break; 04142 case GL_UNSIGNED_SHORT: 04143 scale_internal_ushort(cmpts, width, height, 04144 (const GLushort *)usersImage, newwidth, newheight, 04145 (GLushort *)dstImage, element_size, 04146 rowsize, group_size, myswap_bytes); 04147 break; 04148 case GL_SHORT: 04149 scale_internal_short(cmpts, width, height, 04150 (const GLshort *)usersImage, newwidth, newheight, 04151 (GLshort *)dstImage, element_size, 04152 rowsize, group_size, myswap_bytes); 04153 break; 04154 case GL_UNSIGNED_INT: 04155 scale_internal_uint(cmpts, width, height, 04156 (const GLuint *)usersImage, newwidth, newheight, 04157 (GLuint *)dstImage, element_size, 04158 rowsize, group_size, myswap_bytes); 04159 break; 04160 case GL_INT: 04161 scale_internal_int(cmpts, width, height, 04162 (const GLint *)usersImage, newwidth, newheight, 04163 (GLint *)dstImage, element_size, 04164 rowsize, group_size, myswap_bytes); 04165 break; 04166 case GL_FLOAT: 04167 scale_internal_float(cmpts, width, height, 04168 (const GLfloat *)usersImage, newwidth, newheight, 04169 (GLfloat *)dstImage, element_size, 04170 rowsize, group_size, myswap_bytes); 04171 break; 04172 case GL_UNSIGNED_BYTE_3_3_2: 04173 scaleInternalPackedPixel(3,extract332,shove332, 04174 width, height,usersImage, 04175 newwidth,newheight,(void *)dstImage, 04176 element_size,rowsize,myswap_bytes); 04177 break; 04178 case GL_UNSIGNED_BYTE_2_3_3_REV: 04179 scaleInternalPackedPixel(3,extract233rev,shove233rev, 04180 width, height,usersImage, 04181 newwidth,newheight,(void *)dstImage, 04182 element_size,rowsize,myswap_bytes); 04183 break; 04184 case GL_UNSIGNED_SHORT_5_6_5: 04185 scaleInternalPackedPixel(3,extract565,shove565, 04186 width, height,usersImage, 04187 newwidth,newheight,(void *)dstImage, 04188 element_size,rowsize,myswap_bytes); 04189 break; 04190 case GL_UNSIGNED_SHORT_5_6_5_REV: 04191 scaleInternalPackedPixel(3,extract565rev,shove565rev, 04192 width, height,usersImage, 04193 newwidth,newheight,(void *)dstImage, 04194 element_size,rowsize,myswap_bytes); 04195 break; 04196 case GL_UNSIGNED_SHORT_4_4_4_4: 04197 scaleInternalPackedPixel(4,extract4444,shove4444, 04198 width, height,usersImage, 04199 newwidth,newheight,(void *)dstImage, 04200 element_size,rowsize,myswap_bytes); 04201 break; 04202 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04203 scaleInternalPackedPixel(4,extract4444rev,shove4444rev, 04204 width, height,usersImage, 04205 newwidth,newheight,(void *)dstImage, 04206 element_size,rowsize,myswap_bytes); 04207 break; 04208 case GL_UNSIGNED_SHORT_5_5_5_1: 04209 scaleInternalPackedPixel(4,extract5551,shove5551, 04210 width, height,usersImage, 04211 newwidth,newheight,(void *)dstImage, 04212 element_size,rowsize,myswap_bytes); 04213 break; 04214 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04215 scaleInternalPackedPixel(4,extract1555rev,shove1555rev, 04216 width, height,usersImage, 04217 newwidth,newheight,(void *)dstImage, 04218 element_size,rowsize,myswap_bytes); 04219 break; 04220 case GL_UNSIGNED_INT_8_8_8_8: 04221 scaleInternalPackedPixel(4,extract8888,shove8888, 04222 width, height,usersImage, 04223 newwidth,newheight,(void *)dstImage, 04224 element_size,rowsize,myswap_bytes); 04225 break; 04226 case GL_UNSIGNED_INT_8_8_8_8_REV: 04227 scaleInternalPackedPixel(4,extract8888rev,shove8888rev, 04228 width, height,usersImage, 04229 newwidth,newheight,(void *)dstImage, 04230 element_size,rowsize,myswap_bytes); 04231 break; 04232 case GL_UNSIGNED_INT_10_10_10_2: 04233 scaleInternalPackedPixel(4,extract1010102,shove1010102, 04234 width, height,usersImage, 04235 newwidth,newheight,(void *)dstImage, 04236 element_size,rowsize,myswap_bytes); 04237 break; 04238 case GL_UNSIGNED_INT_2_10_10_10_REV: 04239 scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev, 04240 width, height,usersImage, 04241 newwidth,newheight,(void *)dstImage, 04242 element_size,rowsize,myswap_bytes); 04243 break; 04244 default: 04245 assert(0); 04246 break; 04247 } 04248 myswap_bytes = 0; 04249 rowsize = newwidth * group_size; 04250 /* Swap dstImage and srcImage */ 04251 __GLU_SWAP_IMAGE(srcImage,dstImage); 04252 04253 if(levels != 0) { /* use as little memory as possible */ 04254 { 04255 int nextWidth= newwidth/2; 04256 int nextHeight= newheight/2; 04257 if (nextWidth < 1) nextWidth= 1; 04258 if (nextHeight < 1) nextHeight= 1; 04259 04260 memreq = image_size(nextWidth, nextHeight, format, type); 04261 } 04262 04263 switch(type) { 04264 case GL_UNSIGNED_BYTE: 04265 dstImage = (GLubyte *)malloc(memreq); 04266 break; 04267 case GL_BYTE: 04268 dstImage = (GLbyte *)malloc(memreq); 04269 break; 04270 case GL_UNSIGNED_SHORT: 04271 dstImage = (GLushort *)malloc(memreq); 04272 break; 04273 case GL_SHORT: 04274 dstImage = (GLshort *)malloc(memreq); 04275 break; 04276 case GL_UNSIGNED_INT: 04277 dstImage = (GLuint *)malloc(memreq); 04278 break; 04279 case GL_INT: 04280 dstImage = (GLint *)malloc(memreq); 04281 break; 04282 case GL_FLOAT: 04283 dstImage = (GLfloat *)malloc(memreq); 04284 break; 04285 case GL_UNSIGNED_BYTE_3_3_2: 04286 case GL_UNSIGNED_BYTE_2_3_3_REV: 04287 dstImage = (GLubyte *)malloc(memreq); 04288 break; 04289 case GL_UNSIGNED_SHORT_5_6_5: 04290 case GL_UNSIGNED_SHORT_5_6_5_REV: 04291 case GL_UNSIGNED_SHORT_4_4_4_4: 04292 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04293 case GL_UNSIGNED_SHORT_5_5_5_1: 04294 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04295 dstImage = (GLushort *)malloc(memreq); 04296 break; 04297 case GL_UNSIGNED_INT_8_8_8_8: 04298 case GL_UNSIGNED_INT_8_8_8_8_REV: 04299 case GL_UNSIGNED_INT_10_10_10_2: 04300 case GL_UNSIGNED_INT_2_10_10_10_REV: 04301 dstImage = (GLuint *)malloc(memreq); 04302 break; 04303 default: 04304 return GLU_INVALID_ENUM; 04305 } 04306 if (dstImage == NULL) { 04307 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 04308 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 04309 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 04310 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 04311 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 04312 return GLU_OUT_OF_MEMORY; 04313 } 04314 } 04315 /* level userLevel is in srcImage; nothing saved yet */ 04316 level = userLevel; 04317 } 04318 04319 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 04320 if (baseLevel <= level && level <= maxLevel) { 04321 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, 04322 format, type, (void *)srcImage); 04323 } 04324 04325 level++; /* update current level for the loop */ 04326 for (; level <= levels; level++) { 04327 switch(type) { 04328 case GL_UNSIGNED_BYTE: 04329 halveImage_ubyte(cmpts, newwidth, newheight, 04330 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size, 04331 rowsize, group_size); 04332 break; 04333 case GL_BYTE: 04334 halveImage_byte(cmpts, newwidth, newheight, 04335 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size, 04336 rowsize, group_size); 04337 break; 04338 case GL_UNSIGNED_SHORT: 04339 halveImage_ushort(cmpts, newwidth, newheight, 04340 (GLushort *)srcImage, (GLushort *)dstImage, element_size, 04341 rowsize, group_size, myswap_bytes); 04342 break; 04343 case GL_SHORT: 04344 halveImage_short(cmpts, newwidth, newheight, 04345 (GLshort *)srcImage, (GLshort *)dstImage, element_size, 04346 rowsize, group_size, myswap_bytes); 04347 break; 04348 case GL_UNSIGNED_INT: 04349 halveImage_uint(cmpts, newwidth, newheight, 04350 (GLuint *)srcImage, (GLuint *)dstImage, element_size, 04351 rowsize, group_size, myswap_bytes); 04352 break; 04353 case GL_INT: 04354 halveImage_int(cmpts, newwidth, newheight, 04355 (GLint *)srcImage, (GLint *)dstImage, element_size, 04356 rowsize, group_size, myswap_bytes); 04357 break; 04358 case GL_FLOAT: 04359 halveImage_float(cmpts, newwidth, newheight, 04360 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size, 04361 rowsize, group_size, myswap_bytes); 04362 break; 04363 case GL_UNSIGNED_BYTE_3_3_2: 04364 halveImagePackedPixel(3,extract332,shove332, 04365 newwidth,newheight, 04366 srcImage,dstImage,element_size,rowsize, 04367 myswap_bytes); 04368 break; 04369 case GL_UNSIGNED_BYTE_2_3_3_REV: 04370 halveImagePackedPixel(3,extract233rev,shove233rev, 04371 newwidth,newheight, 04372 srcImage,dstImage,element_size,rowsize, 04373 myswap_bytes); 04374 break; 04375 case GL_UNSIGNED_SHORT_5_6_5: 04376 halveImagePackedPixel(3,extract565,shove565, 04377 newwidth,newheight, 04378 srcImage,dstImage,element_size,rowsize, 04379 myswap_bytes); 04380 break; 04381 case GL_UNSIGNED_SHORT_5_6_5_REV: 04382 halveImagePackedPixel(3,extract565rev,shove565rev, 04383 newwidth,newheight, 04384 srcImage,dstImage,element_size,rowsize, 04385 myswap_bytes); 04386 break; 04387 case GL_UNSIGNED_SHORT_4_4_4_4: 04388 halveImagePackedPixel(4,extract4444,shove4444, 04389 newwidth,newheight, 04390 srcImage,dstImage,element_size,rowsize, 04391 myswap_bytes); 04392 break; 04393 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04394 halveImagePackedPixel(4,extract4444rev,shove4444rev, 04395 newwidth,newheight, 04396 srcImage,dstImage,element_size,rowsize, 04397 myswap_bytes); 04398 break; 04399 case GL_UNSIGNED_SHORT_5_5_5_1: 04400 halveImagePackedPixel(4,extract5551,shove5551, 04401 newwidth,newheight, 04402 srcImage,dstImage,element_size,rowsize, 04403 myswap_bytes); 04404 break; 04405 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04406 halveImagePackedPixel(4,extract1555rev,shove1555rev, 04407 newwidth,newheight, 04408 srcImage,dstImage,element_size,rowsize, 04409 myswap_bytes); 04410 break; 04411 case GL_UNSIGNED_INT_8_8_8_8: 04412 halveImagePackedPixel(4,extract8888,shove8888, 04413 newwidth,newheight, 04414 srcImage,dstImage,element_size,rowsize, 04415 myswap_bytes); 04416 break; 04417 case GL_UNSIGNED_INT_8_8_8_8_REV: 04418 halveImagePackedPixel(4,extract8888rev,shove8888rev, 04419 newwidth,newheight, 04420 srcImage,dstImage,element_size,rowsize, 04421 myswap_bytes); 04422 break; 04423 case GL_UNSIGNED_INT_10_10_10_2: 04424 halveImagePackedPixel(4,extract1010102,shove1010102, 04425 newwidth,newheight, 04426 srcImage,dstImage,element_size,rowsize, 04427 myswap_bytes); 04428 break; 04429 case GL_UNSIGNED_INT_2_10_10_10_REV: 04430 halveImagePackedPixel(4,extract2101010rev,shove2101010rev, 04431 newwidth,newheight, 04432 srcImage,dstImage,element_size,rowsize, 04433 myswap_bytes); 04434 break; 04435 default: 04436 assert(0); 04437 break; 04438 } 04439 04440 __GLU_SWAP_IMAGE(srcImage,dstImage); 04441 04442 if (newwidth > 1) { newwidth /= 2; rowsize /= 2;} 04443 if (newheight > 1) newheight /= 2; 04444 { 04445 /* compute amount to pad per row, if any */ 04446 int rowPad= rowsize % psm.unpack_alignment; 04447 04448 /* should row be padded? */ 04449 if (rowPad == 0) { /* nope, row should not be padded */ 04450 /* call tex image with srcImage untouched since it's not padded */ 04451 if (baseLevel <= level && level <= maxLevel) { 04452 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, 04453 format, type, (void *) srcImage); 04454 } 04455 } 04456 else { /* yes, row should be padded */ 04457 /* compute length of new row in bytes, including padding */ 04458 int newRowLength= rowsize + psm.unpack_alignment - rowPad; 04459 int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */ 04460 04461 /* allocate new image for mipmap of size newRowLength x newheight */ 04462 void *newMipmapImage= malloc((size_t) (newRowLength*newheight)); 04463 if (newMipmapImage == NULL) { 04464 /* out of memory so return */ 04465 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 04466 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 04467 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 04468 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 04469 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 04470 return GLU_OUT_OF_MEMORY; 04471 } 04472 04473 /* copy image from srcImage into newMipmapImage by rows */ 04474 for (ii= 0, 04475 dstTrav= (unsigned char *) newMipmapImage, 04476 srcTrav= (unsigned char *) srcImage; 04477 ii< newheight; 04478 ii++, 04479 dstTrav+= newRowLength, /* make sure the correct distance... */ 04480 srcTrav+= rowsize) { /* ...is skipped */ 04481 memcpy(dstTrav,srcTrav,rowsize); 04482 /* note that the pad bytes are not visited and will contain 04483 * garbage, which is ok. 04484 */ 04485 } 04486 04487 /* ...and use this new image for mipmapping instead */ 04488 if (baseLevel <= level && level <= maxLevel) { 04489 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, 04490 format, type, newMipmapImage); 04491 } 04492 free(newMipmapImage); /* don't forget to free it! */ 04493 } /* else */ 04494 } 04495 } /* for level */ 04496 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 04497 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 04498 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 04499 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 04500 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 04501 04502 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ 04503 if (dstImage) { /* if it's non-rectangular and only 1 level */ 04504 free(dstImage); 04505 } 04506 return 0; 04507 } /* gluBuild2DMipmapLevelsCore() */ 04508 04509 GLint GLAPIENTRY 04510 gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, 04511 GLsizei width, GLsizei height, 04512 GLenum format, GLenum type, 04513 GLint userLevel, GLint baseLevel, GLint maxLevel, 04514 const void *data) 04515 { 04516 int level, levels; 04517 04518 int rc= checkMipmapArgs(internalFormat,format,type); 04519 if (rc != 0) return rc; 04520 04521 if (width < 1 || height < 1) { 04522 return GLU_INVALID_VALUE; 04523 } 04524 04525 levels = computeLog(width); 04526 level = computeLog(height); 04527 if (level > levels) levels=level; 04528 04529 levels+= userLevel; 04530 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) 04531 return GLU_INVALID_VALUE; 04532 04533 return gluBuild2DMipmapLevelsCore(target, internalFormat, 04534 width, height, 04535 width, height, 04536 format, type, 04537 userLevel, baseLevel, maxLevel, 04538 data); 04539 } /* gluBuild2DMipmapLevels() */ 04540 04541 GLint GLAPIENTRY 04542 gluBuild2DMipmaps(GLenum target, GLint internalFormat, 04543 GLsizei width, GLsizei height, 04544 GLenum format, GLenum type, 04545 const void *data) 04546 { 04547 GLint widthPowerOf2, heightPowerOf2; 04548 int level, levels; 04549 04550 int rc= checkMipmapArgs(internalFormat,format,type); 04551 if (rc != 0) return rc; 04552 04553 if (width < 1 || height < 1) { 04554 return GLU_INVALID_VALUE; 04555 } 04556 04557 closestFit(target,width,height,internalFormat,format,type, 04558 &widthPowerOf2,&heightPowerOf2); 04559 04560 levels = computeLog(widthPowerOf2); 04561 level = computeLog(heightPowerOf2); 04562 if (level > levels) levels=level; 04563 04564 return gluBuild2DMipmapLevelsCore(target,internalFormat, 04565 width, height, 04566 widthPowerOf2,heightPowerOf2, 04567 format,type, 04568 0,0,levels,data); 04569 } /* gluBuild2DMipmaps() */ 04570 04571 #if 0 04572 /* 04573 ** This routine is for the limited case in which 04574 ** type == GL_UNSIGNED_BYTE && format != index && 04575 ** unpack_alignment = 1 && unpack_swap_bytes == false 04576 ** 04577 ** so all of the work data can be kept as ubytes instead of shorts. 04578 */ 04579 static int fastBuild2DMipmaps(const PixelStorageModes *psm, 04580 GLenum target, GLint components, GLint width, 04581 GLint height, GLenum format, 04582 GLenum type, void *data) 04583 { 04584 GLint newwidth, newheight; 04585 GLint level, levels; 04586 GLubyte *newImage; 04587 GLint newImage_width; 04588 GLint newImage_height; 04589 GLubyte *otherImage; 04590 GLubyte *imageTemp; 04591 GLint memreq; 04592 GLint cmpts; 04593 04594 04595 #if 0 04596 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); 04597 newwidth = nearestPower(width); 04598 if (newwidth > maxsize) newwidth = maxsize; 04599 newheight = nearestPower(height); 04600 if (newheight > maxsize) newheight = maxsize; 04601 #else 04602 closestFit(target,width,height,components,format,type, 04603 &newwidth,&newheight); 04604 #endif 04605 levels = computeLog(newwidth); 04606 level = computeLog(newheight); 04607 if (level > levels) levels=level; 04608 04609 cmpts = elements_per_group(format,type); 04610 04611 otherImage = NULL; 04616 if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) { 04617 newImage = (GLubyte *)data; 04618 newImage_width = width; 04619 newImage_height = height; 04620 } else { 04621 GLint rowsize; 04622 GLint groups_per_line; 04623 GLint elements_per_line; 04624 const GLubyte *start; 04625 const GLubyte *iter; 04626 GLubyte *iter2; 04627 GLint i, j; 04628 04629 newImage = (GLubyte *) 04630 malloc(image_size(width, height, format, GL_UNSIGNED_BYTE)); 04631 newImage_width = width; 04632 newImage_height = height; 04633 if (newImage == NULL) { 04634 return GLU_OUT_OF_MEMORY; 04635 } 04636 04637 /* 04638 ** Abbreviated version of fill_image for this restricted case. 04639 */ 04640 if (psm->unpack_row_length > 0) { 04641 groups_per_line = psm->unpack_row_length; 04642 } else { 04643 groups_per_line = width; 04644 } 04645 rowsize = groups_per_line * cmpts; 04646 elements_per_line = width * cmpts; 04647 start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize + 04648 psm->unpack_skip_pixels * cmpts; 04649 iter2 = newImage; 04650 04651 for (i = 0; i < height; i++) { 04652 iter = start; 04653 for (j = 0; j < elements_per_line; j++) { 04654 *iter2 = *iter; 04655 iter++; 04656 iter2++; 04657 } 04658 start += rowsize; 04659 } 04660 } 04661 04662 04663 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 04664 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 04665 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 04666 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 04667 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 04668 04669 for (level = 0; level <= levels; level++) { 04670 if (newImage_width == newwidth && newImage_height == newheight) { 04671 /* Use newImage for this level */ 04672 glTexImage2D(target, level, components, newImage_width, 04673 newImage_height, 0, format, GL_UNSIGNED_BYTE, 04674 (void *) newImage); 04675 } else { 04676 if (otherImage == NULL) { 04677 memreq = 04678 image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE); 04679 otherImage = (GLubyte *) malloc(memreq); 04680 if (otherImage == NULL) { 04681 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment); 04682 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows); 04683 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels); 04684 glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length); 04685 glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes); 04686 return GLU_OUT_OF_MEMORY; 04687 } 04688 } 04689 /* 04690 scale_internal_ubyte(cmpts, newImage_width, newImage_height, 04691 newImage, newwidth, newheight, otherImage); 04692 */ 04693 /* Swap newImage and otherImage */ 04694 imageTemp = otherImage; 04695 otherImage = newImage; 04696 newImage = imageTemp; 04697 04698 newImage_width = newwidth; 04699 newImage_height = newheight; 04700 glTexImage2D(target, level, components, newImage_width, 04701 newImage_height, 0, format, GL_UNSIGNED_BYTE, 04702 (void *) newImage); 04703 } 04704 if (newwidth > 1) newwidth /= 2; 04705 if (newheight > 1) newheight /= 2; 04706 } 04707 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment); 04708 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows); 04709 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels); 04710 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length); 04711 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes); 04712 04713 if (newImage != (const GLubyte *)data) { 04714 free((GLbyte *) newImage); 04715 } 04716 if (otherImage && otherImage != (const GLubyte *)data) { 04717 free((GLbyte *) otherImage); 04718 } 04719 return 0; 04720 } 04721 #endif 04722 04723 /* 04724 * Utility Routines 04725 */ 04726 static GLint elements_per_group(GLenum format, GLenum type) 04727 { 04728 /* 04729 * Return the number of elements per group of a specified format 04730 */ 04731 04732 /* If the type is packedpixels then answer is 1 (ignore format) */ 04733 if (type == GL_UNSIGNED_BYTE_3_3_2 || 04734 type == GL_UNSIGNED_BYTE_2_3_3_REV || 04735 type == GL_UNSIGNED_SHORT_5_6_5 || 04736 type == GL_UNSIGNED_SHORT_5_6_5_REV || 04737 type == GL_UNSIGNED_SHORT_4_4_4_4 || 04738 type == GL_UNSIGNED_SHORT_4_4_4_4_REV || 04739 type == GL_UNSIGNED_SHORT_5_5_5_1 || 04740 type == GL_UNSIGNED_SHORT_1_5_5_5_REV || 04741 type == GL_UNSIGNED_INT_8_8_8_8 || 04742 type == GL_UNSIGNED_INT_8_8_8_8_REV || 04743 type == GL_UNSIGNED_INT_10_10_10_2 || 04744 type == GL_UNSIGNED_INT_2_10_10_10_REV) { 04745 return 1; 04746 } 04747 04748 /* Types are not packed pixels, so get elements per group */ 04749 switch(format) { 04750 case GL_RGB: 04751 case GL_BGR: 04752 return 3; 04753 case GL_LUMINANCE_ALPHA: 04754 return 2; 04755 case GL_RGBA: 04756 case GL_BGRA: 04757 return 4; 04758 default: 04759 return 1; 04760 } 04761 } 04762 04763 static GLfloat bytes_per_element(GLenum type) 04764 { 04765 /* 04766 * Return the number of bytes per element, based on the element type 04767 */ 04768 switch(type) { 04769 case GL_BITMAP: 04770 return 1.0 / 8.0; 04771 case GL_UNSIGNED_SHORT: 04772 return(sizeof(GLushort)); 04773 case GL_SHORT: 04774 return(sizeof(GLshort)); 04775 case GL_UNSIGNED_BYTE: 04776 return(sizeof(GLubyte)); 04777 case GL_BYTE: 04778 return(sizeof(GLbyte)); 04779 case GL_INT: 04780 return(sizeof(GLint)); 04781 case GL_UNSIGNED_INT: 04782 return(sizeof(GLuint)); 04783 case GL_FLOAT: 04784 return(sizeof(GLfloat)); 04785 case GL_UNSIGNED_BYTE_3_3_2: 04786 case GL_UNSIGNED_BYTE_2_3_3_REV: 04787 return(sizeof(GLubyte)); 04788 case GL_UNSIGNED_SHORT_5_6_5: 04789 case GL_UNSIGNED_SHORT_5_6_5_REV: 04790 case GL_UNSIGNED_SHORT_4_4_4_4: 04791 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04792 case GL_UNSIGNED_SHORT_5_5_5_1: 04793 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04794 return(sizeof(GLushort)); 04795 case GL_UNSIGNED_INT_8_8_8_8: 04796 case GL_UNSIGNED_INT_8_8_8_8_REV: 04797 case GL_UNSIGNED_INT_10_10_10_2: 04798 case GL_UNSIGNED_INT_2_10_10_10_REV: 04799 return(sizeof(GLuint)); 04800 default: 04801 return 4; 04802 } 04803 } 04804 04805 static GLint is_index(GLenum format) 04806 { 04807 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX; 04808 } 04809 04810 /* 04811 ** Compute memory required for internal packed array of data of given type 04812 ** and format. 04813 */ 04814 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type) 04815 { 04816 int bytes_per_row; 04817 int components; 04818 04819 assert(width > 0); 04820 assert(height > 0); 04821 components = elements_per_group(format,type); 04822 if (type == GL_BITMAP) { 04823 bytes_per_row = (width + 7) / 8; 04824 } else { 04825 bytes_per_row = bytes_per_element(type) * width; 04826 } 04827 return bytes_per_row * height * components; 04828 } 04829 04830 /* 04831 ** Extract array from user's data applying all pixel store modes. 04832 ** The internal format used is an array of unsigned shorts. 04833 */ 04834 static void fill_image(const PixelStorageModes *psm, 04835 GLint width, GLint height, GLenum format, 04836 GLenum type, GLboolean index_format, 04837 const void *userdata, GLushort *newimage) 04838 { 04839 GLint components; 04840 GLint element_size; 04841 GLint rowsize; 04842 GLint padding; 04843 GLint groups_per_line; 04844 GLint group_size; 04845 GLint elements_per_line; 04846 const GLubyte *start; 04847 const GLubyte *iter = NULL; 04848 GLushort *iter2; 04849 GLint i, j, k; 04850 GLint myswap_bytes; 04851 04852 myswap_bytes = psm->unpack_swap_bytes; 04853 components = elements_per_group(format,type); 04854 if (psm->unpack_row_length > 0) { 04855 groups_per_line = psm->unpack_row_length; 04856 } else { 04857 groups_per_line = width; 04858 } 04859 04860 /* All formats except GL_BITMAP fall out trivially */ 04861 if (type == GL_BITMAP) { 04862 GLint bit_offset; 04863 GLint current_bit; 04864 04865 rowsize = (groups_per_line * components + 7) / 8; 04866 padding = (rowsize % psm->unpack_alignment); 04867 if (padding) { 04868 rowsize += psm->unpack_alignment - padding; 04869 } 04870 04871 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + 04872 (psm->unpack_skip_pixels * components / 8); 04873 elements_per_line = width * components; 04874 iter2 = newimage; 04875 for (i = 0; i < height; i++) { 04876 iter = start; 04877 bit_offset = (psm->unpack_skip_pixels * components) % 8; 04878 for (j = 0; j < elements_per_line; j++) { 04879 /* Retrieve bit */ 04880 if (psm->unpack_lsb_first) { 04881 current_bit = iter[0] & (1 << bit_offset); 04882 } else { 04883 current_bit = iter[0] & (1 << (7 - bit_offset)); 04884 } 04885 if (current_bit) { 04886 if (index_format) { 04887 *iter2 = 1; 04888 } else { 04889 *iter2 = 65535; 04890 } 04891 } else { 04892 *iter2 = 0; 04893 } 04894 bit_offset++; 04895 if (bit_offset == 8) { 04896 bit_offset = 0; 04897 iter++; 04898 } 04899 iter2++; 04900 } 04901 start += rowsize; 04902 } 04903 } else { 04904 element_size = bytes_per_element(type); 04905 group_size = element_size * components; 04906 if (element_size == 1) myswap_bytes = 0; 04907 04908 rowsize = groups_per_line * group_size; 04909 padding = (rowsize % psm->unpack_alignment); 04910 if (padding) { 04911 rowsize += psm->unpack_alignment - padding; 04912 } 04913 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + 04914 psm->unpack_skip_pixels * group_size; 04915 elements_per_line = width * components; 04916 04917 iter2 = newimage; 04918 for (i = 0; i < height; i++) { 04919 iter = start; 04920 for (j = 0; j < elements_per_line; j++) { 04921 Type_Widget widget; 04922 float extractComponents[4]; 04923 04924 switch(type) { 04925 case GL_UNSIGNED_BYTE_3_3_2: 04926 extract332(0,iter,extractComponents); 04927 for (k = 0; k < 3; k++) { 04928 *iter2++ = (GLushort)(extractComponents[k]*65535); 04929 } 04930 break; 04931 case GL_UNSIGNED_BYTE_2_3_3_REV: 04932 extract233rev(0,iter,extractComponents); 04933 for (k = 0; k < 3; k++) { 04934 *iter2++ = (GLushort)(extractComponents[k]*65535); 04935 } 04936 break; 04937 case GL_UNSIGNED_BYTE: 04938 if (index_format) { 04939 *iter2++ = *iter; 04940 } else { 04941 *iter2++ = (*iter) * 257; 04942 } 04943 break; 04944 case GL_BYTE: 04945 if (index_format) { 04946 *iter2++ = *((const GLbyte *) iter); 04947 } else { 04948 /* rough approx */ 04949 *iter2++ = (*((const GLbyte *) iter)) * 516; 04950 } 04951 break; 04952 case GL_UNSIGNED_SHORT_5_6_5: 04953 extract565(myswap_bytes,iter,extractComponents); 04954 for (k = 0; k < 3; k++) { 04955 *iter2++ = (GLushort)(extractComponents[k]*65535); 04956 } 04957 break; 04958 case GL_UNSIGNED_SHORT_5_6_5_REV: 04959 extract565rev(myswap_bytes,iter,extractComponents); 04960 for (k = 0; k < 3; k++) { 04961 *iter2++ = (GLushort)(extractComponents[k]*65535); 04962 } 04963 break; 04964 case GL_UNSIGNED_SHORT_4_4_4_4: 04965 extract4444(myswap_bytes,iter,extractComponents); 04966 for (k = 0; k < 4; k++) { 04967 *iter2++ = (GLushort)(extractComponents[k]*65535); 04968 } 04969 break; 04970 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 04971 extract4444rev(myswap_bytes,iter,extractComponents); 04972 for (k = 0; k < 4; k++) { 04973 *iter2++ = (GLushort)(extractComponents[k]*65535); 04974 } 04975 break; 04976 case GL_UNSIGNED_SHORT_5_5_5_1: 04977 extract5551(myswap_bytes,iter,extractComponents); 04978 for (k = 0; k < 4; k++) { 04979 *iter2++ = (GLushort)(extractComponents[k]*65535); 04980 } 04981 break; 04982 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 04983 extract1555rev(myswap_bytes,iter,extractComponents); 04984 for (k = 0; k < 4; k++) { 04985 *iter2++ = (GLushort)(extractComponents[k]*65535); 04986 } 04987 break; 04988 case GL_UNSIGNED_SHORT: 04989 case GL_SHORT: 04990 if (myswap_bytes) { 04991 widget.ub[0] = iter[1]; 04992 widget.ub[1] = iter[0]; 04993 } else { 04994 widget.ub[0] = iter[0]; 04995 widget.ub[1] = iter[1]; 04996 } 04997 if (type == GL_SHORT) { 04998 if (index_format) { 04999 *iter2++ = widget.s[0]; 05000 } else { 05001 /* rough approx */ 05002 *iter2++ = widget.s[0]*2; 05003 } 05004 } else { 05005 *iter2++ = widget.us[0]; 05006 } 05007 break; 05008 case GL_UNSIGNED_INT_8_8_8_8: 05009 extract8888(myswap_bytes,iter,extractComponents); 05010 for (k = 0; k < 4; k++) { 05011 *iter2++ = (GLushort)(extractComponents[k]*65535); 05012 } 05013 break; 05014 case GL_UNSIGNED_INT_8_8_8_8_REV: 05015 extract8888rev(myswap_bytes,iter,extractComponents); 05016 for (k = 0; k < 4; k++) { 05017 *iter2++ = (GLushort)(extractComponents[k]*65535); 05018 } 05019 break; 05020 case GL_UNSIGNED_INT_10_10_10_2: 05021 extract1010102(myswap_bytes,iter,extractComponents); 05022 for (k = 0; k < 4; k++) { 05023 *iter2++ = (GLushort)(extractComponents[k]*65535); 05024 } 05025 break; 05026 case GL_UNSIGNED_INT_2_10_10_10_REV: 05027 extract2101010rev(myswap_bytes,iter,extractComponents); 05028 for (k = 0; k < 4; k++) { 05029 *iter2++ = (GLushort)(extractComponents[k]*65535); 05030 } 05031 break; 05032 case GL_INT: 05033 case GL_UNSIGNED_INT: 05034 case GL_FLOAT: 05035 if (myswap_bytes) { 05036 widget.ub[0] = iter[3]; 05037 widget.ub[1] = iter[2]; 05038 widget.ub[2] = iter[1]; 05039 widget.ub[3] = iter[0]; 05040 } else { 05041 widget.ub[0] = iter[0]; 05042 widget.ub[1] = iter[1]; 05043 widget.ub[2] = iter[2]; 05044 widget.ub[3] = iter[3]; 05045 } 05046 if (type == GL_FLOAT) { 05047 if (index_format) { 05048 *iter2++ = widget.f; 05049 } else { 05050 *iter2++ = 65535 * widget.f; 05051 } 05052 } else if (type == GL_UNSIGNED_INT) { 05053 if (index_format) { 05054 *iter2++ = widget.ui; 05055 } else { 05056 *iter2++ = widget.ui >> 16; 05057 } 05058 } else { 05059 if (index_format) { 05060 *iter2++ = widget.i; 05061 } else { 05062 *iter2++ = widget.i >> 15; 05063 } 05064 } 05065 break; 05066 } 05067 iter += element_size; 05068 } /* for j */ 05069 start += rowsize; 05070 #if 1 05071 /* want 'iter' pointing at start, not within, row for assertion 05072 * purposes 05073 */ 05074 iter= start; 05075 #endif 05076 } /* for i */ 05077 05078 /* iterators should be one byte past end */ 05079 if (!isTypePackedPixel(type)) { 05080 assert(iter2 == &newimage[width*height*components]); 05081 } 05082 else { 05083 assert(iter2 == &newimage[width*height* 05084 elements_per_group(format,0)]); 05085 } 05086 assert( iter == &((const GLubyte *)userdata)[rowsize*height + 05087 psm->unpack_skip_rows * rowsize + 05088 psm->unpack_skip_pixels * group_size] ); 05089 05090 } /* else */ 05091 } /* fill_image() */ 05092 05093 /* 05094 ** Insert array into user's data applying all pixel store modes. 05095 ** The internal format is an array of unsigned shorts. 05096 ** empty_image() because it is the opposite of fill_image(). 05097 */ 05098 static void empty_image(const PixelStorageModes *psm, 05099 GLint width, GLint height, GLenum format, 05100 GLenum type, GLboolean index_format, 05101 const GLushort *oldimage, void *userdata) 05102 { 05103 GLint components; 05104 GLint element_size; 05105 GLint rowsize; 05106 GLint padding; 05107 GLint groups_per_line; 05108 GLint group_size; 05109 GLint elements_per_line; 05110 GLubyte *start; 05111 GLubyte *iter = NULL; 05112 const GLushort *iter2; 05113 GLint i, j, k; 05114 GLint myswap_bytes; 05115 05116 myswap_bytes = psm->pack_swap_bytes; 05117 components = elements_per_group(format,type); 05118 if (psm->pack_row_length > 0) { 05119 groups_per_line = psm->pack_row_length; 05120 } else { 05121 groups_per_line = width; 05122 } 05123 05124 /* All formats except GL_BITMAP fall out trivially */ 05125 if (type == GL_BITMAP) { 05126 GLint bit_offset; 05127 GLint current_bit; 05128 05129 rowsize = (groups_per_line * components + 7) / 8; 05130 padding = (rowsize % psm->pack_alignment); 05131 if (padding) { 05132 rowsize += psm->pack_alignment - padding; 05133 } 05134 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + 05135 (psm->pack_skip_pixels * components / 8); 05136 elements_per_line = width * components; 05137 iter2 = oldimage; 05138 for (i = 0; i < height; i++) { 05139 iter = start; 05140 bit_offset = (psm->pack_skip_pixels * components) % 8; 05141 for (j = 0; j < elements_per_line; j++) { 05142 if (index_format) { 05143 current_bit = iter2[0] & 1; 05144 } else { 05145 if (iter2[0] > 32767) { 05146 current_bit = 1; 05147 } else { 05148 current_bit = 0; 05149 } 05150 } 05151 05152 if (current_bit) { 05153 if (psm->pack_lsb_first) { 05154 *iter |= (1 << bit_offset); 05155 } else { 05156 *iter |= (1 << (7 - bit_offset)); 05157 } 05158 } else { 05159 if (psm->pack_lsb_first) { 05160 *iter &= ~(1 << bit_offset); 05161 } else { 05162 *iter &= ~(1 << (7 - bit_offset)); 05163 } 05164 } 05165 05166 bit_offset++; 05167 if (bit_offset == 8) { 05168 bit_offset = 0; 05169 iter++; 05170 } 05171 iter2++; 05172 } 05173 start += rowsize; 05174 } 05175 } else { 05176 float shoveComponents[4]; 05177 05178 element_size = bytes_per_element(type); 05179 group_size = element_size * components; 05180 if (element_size == 1) myswap_bytes = 0; 05181 05182 rowsize = groups_per_line * group_size; 05183 padding = (rowsize % psm->pack_alignment); 05184 if (padding) { 05185 rowsize += psm->pack_alignment - padding; 05186 } 05187 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + 05188 psm->pack_skip_pixels * group_size; 05189 elements_per_line = width * components; 05190 05191 iter2 = oldimage; 05192 for (i = 0; i < height; i++) { 05193 iter = start; 05194 for (j = 0; j < elements_per_line; j++) { 05195 Type_Widget widget; 05196 05197 switch(type) { 05198 case GL_UNSIGNED_BYTE_3_3_2: 05199 for (k = 0; k < 3; k++) { 05200 shoveComponents[k]= *iter2++ / 65535.0; 05201 } 05202 shove332(shoveComponents,0,(void *)iter); 05203 break; 05204 case GL_UNSIGNED_BYTE_2_3_3_REV: 05205 for (k = 0; k < 3; k++) { 05206 shoveComponents[k]= *iter2++ / 65535.0; 05207 } 05208 shove233rev(shoveComponents,0,(void *)iter); 05209 break; 05210 case GL_UNSIGNED_BYTE: 05211 if (index_format) { 05212 *iter = *iter2++; 05213 } else { 05214 *iter = *iter2++ >> 8; 05215 } 05216 break; 05217 case GL_BYTE: 05218 if (index_format) { 05219 *((GLbyte *) iter) = *iter2++; 05220 } else { 05221 *((GLbyte *) iter) = *iter2++ >> 9; 05222 } 05223 break; 05224 case GL_UNSIGNED_SHORT_5_6_5: 05225 for (k = 0; k < 3; k++) { 05226 shoveComponents[k]= *iter2++ / 65535.0; 05227 } 05228 shove565(shoveComponents,0,(void *)&widget.us[0]); 05229 if (myswap_bytes) { 05230 iter[0] = widget.ub[1]; 05231 iter[1] = widget.ub[0]; 05232 } 05233 else { 05234 *(GLushort *)iter = widget.us[0]; 05235 } 05236 break; 05237 case GL_UNSIGNED_SHORT_5_6_5_REV: 05238 for (k = 0; k < 3; k++) { 05239 shoveComponents[k]= *iter2++ / 65535.0; 05240 } 05241 shove565rev(shoveComponents,0,(void *)&widget.us[0]); 05242 if (myswap_bytes) { 05243 iter[0] = widget.ub[1]; 05244 iter[1] = widget.ub[0]; 05245 } 05246 else { 05247 *(GLushort *)iter = widget.us[0]; 05248 } 05249 break; 05250 case GL_UNSIGNED_SHORT_4_4_4_4: 05251 for (k = 0; k < 4; k++) { 05252 shoveComponents[k]= *iter2++ / 65535.0; 05253 } 05254 shove4444(shoveComponents,0,(void *)&widget.us[0]); 05255 if (myswap_bytes) { 05256 iter[0] = widget.ub[1]; 05257 iter[1] = widget.ub[0]; 05258 } else { 05259 *(GLushort *)iter = widget.us[0]; 05260 } 05261 break; 05262 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 05263 for (k = 0; k < 4; k++) { 05264 shoveComponents[k]= *iter2++ / 65535.0; 05265 } 05266 shove4444rev(shoveComponents,0,(void *)&widget.us[0]); 05267 if (myswap_bytes) { 05268 iter[0] = widget.ub[1]; 05269 iter[1] = widget.ub[0]; 05270 } else { 05271 *(GLushort *)iter = widget.us[0]; 05272 } 05273 break; 05274 case GL_UNSIGNED_SHORT_5_5_5_1: 05275 for (k = 0; k < 4; k++) { 05276 shoveComponents[k]= *iter2++ / 65535.0; 05277 } 05278 shove5551(shoveComponents,0,(void *)&widget.us[0]); 05279 if (myswap_bytes) { 05280 iter[0] = widget.ub[1]; 05281 iter[1] = widget.ub[0]; 05282 } else { 05283 *(GLushort *)iter = widget.us[0]; 05284 } 05285 break; 05286 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 05287 for (k = 0; k < 4; k++) { 05288 shoveComponents[k]= *iter2++ / 65535.0; 05289 } 05290 shove1555rev(shoveComponents,0,(void *)&widget.us[0]); 05291 if (myswap_bytes) { 05292 iter[0] = widget.ub[1]; 05293 iter[1] = widget.ub[0]; 05294 } else { 05295 *(GLushort *)iter = widget.us[0]; 05296 } 05297 break; 05298 case GL_UNSIGNED_SHORT: 05299 case GL_SHORT: 05300 if (type == GL_SHORT) { 05301 if (index_format) { 05302 widget.s[0] = *iter2++; 05303 } else { 05304 widget.s[0] = *iter2++ >> 1; 05305 } 05306 } else { 05307 widget.us[0] = *iter2++; 05308 } 05309 if (myswap_bytes) { 05310 iter[0] = widget.ub[1]; 05311 iter[1] = widget.ub[0]; 05312 } else { 05313 iter[0] = widget.ub[0]; 05314 iter[1] = widget.ub[1]; 05315 } 05316 break; 05317 case GL_UNSIGNED_INT_8_8_8_8: 05318 for (k = 0; k < 4; k++) { 05319 shoveComponents[k]= *iter2++ / 65535.0; 05320 } 05321 shove8888(shoveComponents,0,(void *)&widget.ui); 05322 if (myswap_bytes) { 05323 iter[3] = widget.ub[0]; 05324 iter[2] = widget.ub[1]; 05325 iter[1] = widget.ub[2]; 05326 iter[0] = widget.ub[3]; 05327 } else { 05328 *(GLuint *)iter= widget.ui; 05329 } 05330 05331 break; 05332 case GL_UNSIGNED_INT_8_8_8_8_REV: 05333 for (k = 0; k < 4; k++) { 05334 shoveComponents[k]= *iter2++ / 65535.0; 05335 } 05336 shove8888rev(shoveComponents,0,(void *)&widget.ui); 05337 if (myswap_bytes) { 05338 iter[3] = widget.ub[0]; 05339 iter[2] = widget.ub[1]; 05340 iter[1] = widget.ub[2]; 05341 iter[0] = widget.ub[3]; 05342 } else { 05343 *(GLuint *)iter= widget.ui; 05344 } 05345 break; 05346 case GL_UNSIGNED_INT_10_10_10_2: 05347 for (k = 0; k < 4; k++) { 05348 shoveComponents[k]= *iter2++ / 65535.0; 05349 } 05350 shove1010102(shoveComponents,0,(void *)&widget.ui); 05351 if (myswap_bytes) { 05352 iter[3] = widget.ub[0]; 05353 iter[2] = widget.ub[1]; 05354 iter[1] = widget.ub[2]; 05355 iter[0] = widget.ub[3]; 05356 } else { 05357 *(GLuint *)iter= widget.ui; 05358 } 05359 break; 05360 case GL_UNSIGNED_INT_2_10_10_10_REV: 05361 for (k = 0; k < 4; k++) { 05362 shoveComponents[k]= *iter2++ / 65535.0; 05363 } 05364 shove2101010rev(shoveComponents,0,(void *)&widget.ui); 05365 if (myswap_bytes) { 05366 iter[3] = widget.ub[0]; 05367 iter[2] = widget.ub[1]; 05368 iter[1] = widget.ub[2]; 05369 iter[0] = widget.ub[3]; 05370 } else { 05371 *(GLuint *)iter= widget.ui; 05372 } 05373 break; 05374 case GL_INT: 05375 case GL_UNSIGNED_INT: 05376 case GL_FLOAT: 05377 if (type == GL_FLOAT) { 05378 if (index_format) { 05379 widget.f = *iter2++; 05380 } else { 05381 widget.f = *iter2++ / (float) 65535.0; 05382 } 05383 } else if (type == GL_UNSIGNED_INT) { 05384 if (index_format) { 05385 widget.ui = *iter2++; 05386 } else { 05387 widget.ui = (unsigned int) *iter2++ * 65537; 05388 } 05389 } else { 05390 if (index_format) { 05391 widget.i = *iter2++; 05392 } else { 05393 widget.i = ((unsigned int) *iter2++ * 65537)/2; 05394 } 05395 } 05396 if (myswap_bytes) { 05397 iter[3] = widget.ub[0]; 05398 iter[2] = widget.ub[1]; 05399 iter[1] = widget.ub[2]; 05400 iter[0] = widget.ub[3]; 05401 } else { 05402 iter[0] = widget.ub[0]; 05403 iter[1] = widget.ub[1]; 05404 iter[2] = widget.ub[2]; 05405 iter[3] = widget.ub[3]; 05406 } 05407 break; 05408 } 05409 iter += element_size; 05410 } /* for j */ 05411 start += rowsize; 05412 #if 1 05413 /* want 'iter' pointing at start, not within, row for assertion 05414 * purposes 05415 */ 05416 iter= start; 05417 #endif 05418 } /* for i */ 05419 05420 /* iterators should be one byte past end */ 05421 if (!isTypePackedPixel(type)) { 05422 assert(iter2 == &oldimage[width*height*components]); 05423 } 05424 else { 05425 assert(iter2 == &oldimage[width*height* 05426 elements_per_group(format,0)]); 05427 } 05428 assert( iter == &((GLubyte *)userdata)[rowsize*height + 05429 psm->pack_skip_rows * rowsize + 05430 psm->pack_skip_pixels * group_size] ); 05431 05432 } /* else */ 05433 } /* empty_image() */ 05434 05435 /*-------------------------------------------------------------------------- 05436 * Decimation of packed pixel types 05437 *-------------------------------------------------------------------------- 05438 */ 05439 static void extract332(int isSwap, 05440 const void *packedPixel, GLfloat extractComponents[]) 05441 { 05442 GLubyte ubyte= *(const GLubyte *)packedPixel; 05443 05444 isSwap= isSwap; /* turn off warnings */ 05445 05446 /* 11100000 == 0xe0 */ 05447 /* 00011100 == 0x1c */ 05448 /* 00000011 == 0x03 */ 05449 05450 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0; 05451 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */ 05452 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */ 05453 } /* extract332() */ 05454 05455 static void shove332(const GLfloat shoveComponents[], 05456 int index, void *packedPixel) 05457 { 05458 /* 11100000 == 0xe0 */ 05459 /* 00011100 == 0x1c */ 05460 /* 00000011 == 0x03 */ 05461 05462 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05463 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05464 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05465 05466 /* due to limited precision, need to round before shoving */ 05467 ((GLubyte *)packedPixel)[index] = 05468 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0; 05469 ((GLubyte *)packedPixel)[index] |= 05470 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c; 05471 ((GLubyte *)packedPixel)[index] |= 05472 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03; 05473 } /* shove332() */ 05474 05475 static void extract233rev(int isSwap, 05476 const void *packedPixel, GLfloat extractComponents[]) 05477 { 05478 GLubyte ubyte= *(const GLubyte *)packedPixel; 05479 05480 isSwap= isSwap; /* turn off warnings */ 05481 05482 /* 0000,0111 == 0x07 */ 05483 /* 0011,1000 == 0x38 */ 05484 /* 1100,0000 == 0xC0 */ 05485 05486 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0; 05487 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0; 05488 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0; 05489 } /* extract233rev() */ 05490 05491 static void shove233rev(const GLfloat shoveComponents[], 05492 int index, void *packedPixel) 05493 { 05494 /* 0000,0111 == 0x07 */ 05495 /* 0011,1000 == 0x38 */ 05496 /* 1100,0000 == 0xC0 */ 05497 05498 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05499 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05500 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05501 05502 /* due to limited precision, need to round before shoving */ 05503 ((GLubyte *)packedPixel)[index] = 05504 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07; 05505 ((GLubyte *)packedPixel)[index]|= 05506 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38; 05507 ((GLubyte *)packedPixel)[index]|= 05508 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0; 05509 } /* shove233rev() */ 05510 05511 static void extract565(int isSwap, 05512 const void *packedPixel, GLfloat extractComponents[]) 05513 { 05514 GLushort ushort= *(const GLushort *)packedPixel; 05515 05516 if (isSwap) { 05517 ushort= __GLU_SWAP_2_BYTES(packedPixel); 05518 } 05519 else { 05520 ushort= *(const GLushort *)packedPixel; 05521 } 05522 05523 /* 11111000,00000000 == 0xf800 */ 05524 /* 00000111,11100000 == 0x07e0 */ 05525 /* 00000000,00011111 == 0x001f */ 05526 05527 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ 05528 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/ 05529 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0; 05530 } /* extract565() */ 05531 05532 static void shove565(const GLfloat shoveComponents[], 05533 int index,void *packedPixel) 05534 { 05535 /* 11111000,00000000 == 0xf800 */ 05536 /* 00000111,11100000 == 0x07e0 */ 05537 /* 00000000,00011111 == 0x001f */ 05538 05539 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05540 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05541 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05542 05543 /* due to limited precision, need to round before shoving */ 05544 ((GLushort *)packedPixel)[index] = 05545 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; 05546 ((GLushort *)packedPixel)[index]|= 05547 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0; 05548 ((GLushort *)packedPixel)[index]|= 05549 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f; 05550 } /* shove565() */ 05551 05552 static void extract565rev(int isSwap, 05553 const void *packedPixel, GLfloat extractComponents[]) 05554 { 05555 GLushort ushort= *(const GLushort *)packedPixel; 05556 05557 if (isSwap) { 05558 ushort= __GLU_SWAP_2_BYTES(packedPixel); 05559 } 05560 else { 05561 ushort= *(const GLushort *)packedPixel; 05562 } 05563 05564 /* 00000000,00011111 == 0x001f */ 05565 /* 00000111,11100000 == 0x07e0 */ 05566 /* 11111000,00000000 == 0xf800 */ 05567 05568 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; 05569 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0; 05570 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0; 05571 } /* extract565rev() */ 05572 05573 static void shove565rev(const GLfloat shoveComponents[], 05574 int index,void *packedPixel) 05575 { 05576 /* 00000000,00011111 == 0x001f */ 05577 /* 00000111,11100000 == 0x07e0 */ 05578 /* 11111000,00000000 == 0xf800 */ 05579 05580 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05581 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05582 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05583 05584 /* due to limited precision, need to round before shoving */ 05585 ((GLushort *)packedPixel)[index] = 05586 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F; 05587 ((GLushort *)packedPixel)[index]|= 05588 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0; 05589 ((GLushort *)packedPixel)[index]|= 05590 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800; 05591 } /* shove565rev() */ 05592 05593 static void extract4444(int isSwap,const void *packedPixel, 05594 GLfloat extractComponents[]) 05595 { 05596 GLushort ushort; 05597 05598 if (isSwap) { 05599 ushort= __GLU_SWAP_2_BYTES(packedPixel); 05600 } 05601 else { 05602 ushort= *(const GLushort *)packedPixel; 05603 } 05604 05605 /* 11110000,00000000 == 0xf000 */ 05606 /* 00001111,00000000 == 0x0f00 */ 05607 /* 00000000,11110000 == 0x00f0 */ 05608 /* 00000000,00001111 == 0x000f */ 05609 05610 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */ 05611 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0; 05612 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0; 05613 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0; 05614 } /* extract4444() */ 05615 05616 static void shove4444(const GLfloat shoveComponents[], 05617 int index,void *packedPixel) 05618 { 05619 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05620 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05621 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05622 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05623 05624 /* due to limited precision, need to round before shoving */ 05625 ((GLushort *)packedPixel)[index] = 05626 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000; 05627 ((GLushort *)packedPixel)[index]|= 05628 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00; 05629 ((GLushort *)packedPixel)[index]|= 05630 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0; 05631 ((GLushort *)packedPixel)[index]|= 05632 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f; 05633 } /* shove4444() */ 05634 05635 static void extract4444rev(int isSwap,const void *packedPixel, 05636 GLfloat extractComponents[]) 05637 { 05638 GLushort ushort; 05639 05640 if (isSwap) { 05641 ushort= __GLU_SWAP_2_BYTES(packedPixel); 05642 } 05643 else { 05644 ushort= *(const GLushort *)packedPixel; 05645 } 05646 05647 /* 00000000,00001111 == 0x000f */ 05648 /* 00000000,11110000 == 0x00f0 */ 05649 /* 00001111,00000000 == 0x0f00 */ 05650 /* 11110000,00000000 == 0xf000 */ 05651 05652 /* 15 = 2^4-1 */ 05653 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0; 05654 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0; 05655 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0; 05656 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0; 05657 } /* extract4444rev() */ 05658 05659 static void shove4444rev(const GLfloat shoveComponents[], 05660 int index,void *packedPixel) 05661 { 05662 /* 00000000,00001111 == 0x000f */ 05663 /* 00000000,11110000 == 0x00f0 */ 05664 /* 00001111,00000000 == 0x0f00 */ 05665 /* 11110000,00000000 == 0xf000 */ 05666 05667 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05668 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05669 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05670 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05671 05672 /* due to limited precision, need to round before shoving */ 05673 ((GLushort *)packedPixel)[index] = 05674 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F; 05675 ((GLushort *)packedPixel)[index]|= 05676 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0; 05677 ((GLushort *)packedPixel)[index]|= 05678 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00; 05679 ((GLushort *)packedPixel)[index]|= 05680 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000; 05681 } /* shove4444rev() */ 05682 05683 static void extract5551(int isSwap,const void *packedPixel, 05684 GLfloat extractComponents[]) 05685 { 05686 GLushort ushort; 05687 05688 if (isSwap) { 05689 ushort= __GLU_SWAP_2_BYTES(packedPixel); 05690 } 05691 else { 05692 ushort= *(const GLushort *)packedPixel; 05693 } 05694 05695 /* 11111000,00000000 == 0xf800 */ 05696 /* 00000111,11000000 == 0x07c0 */ 05697 /* 00000000,00111110 == 0x003e */ 05698 /* 00000000,00000001 == 0x0001 */ 05699 05700 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ 05701 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0; 05702 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0; 05703 extractComponents[3]=(float)((ushort & 0x0001) ); 05704 } /* extract5551() */ 05705 05706 static void shove5551(const GLfloat shoveComponents[], 05707 int index,void *packedPixel) 05708 { 05709 /* 11111000,00000000 == 0xf800 */ 05710 /* 00000111,11000000 == 0x07c0 */ 05711 /* 00000000,00111110 == 0x003e */ 05712 /* 00000000,00000001 == 0x0001 */ 05713 05714 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05715 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05716 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05717 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05718 05719 /* due to limited precision, need to round before shoving */ 05720 ((GLushort *)packedPixel)[index] = 05721 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; 05722 ((GLushort *)packedPixel)[index]|= 05723 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0; 05724 ((GLushort *)packedPixel)[index]|= 05725 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e; 05726 ((GLushort *)packedPixel)[index]|= 05727 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001; 05728 } /* shove5551() */ 05729 05730 static void extract1555rev(int isSwap,const void *packedPixel, 05731 GLfloat extractComponents[]) 05732 { 05733 GLushort ushort; 05734 05735 if (isSwap) { 05736 ushort= __GLU_SWAP_2_BYTES(packedPixel); 05737 } 05738 else { 05739 ushort= *(const GLushort *)packedPixel; 05740 } 05741 05742 /* 00000000,00011111 == 0x001F */ 05743 /* 00000011,11100000 == 0x03E0 */ 05744 /* 01111100,00000000 == 0x7C00 */ 05745 /* 10000000,00000000 == 0x8000 */ 05746 05747 /* 31 = 2^5-1 */ 05748 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; 05749 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0; 05750 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0; 05751 extractComponents[3]= (float)((ushort & 0x8000) >> 15); 05752 } /* extract1555rev() */ 05753 05754 static void shove1555rev(const GLfloat shoveComponents[], 05755 int index,void *packedPixel) 05756 { 05757 /* 00000000,00011111 == 0x001F */ 05758 /* 00000011,11100000 == 0x03E0 */ 05759 /* 01111100,00000000 == 0x7C00 */ 05760 /* 10000000,00000000 == 0x8000 */ 05761 05762 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05763 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05764 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05765 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05766 05767 /* due to limited precision, need to round before shoving */ 05768 ((GLushort *)packedPixel)[index] = 05769 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F; 05770 ((GLushort *)packedPixel)[index]|= 05771 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0; 05772 ((GLushort *)packedPixel)[index]|= 05773 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00; 05774 ((GLushort *)packedPixel)[index]|= 05775 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000; 05776 } /* shove1555rev() */ 05777 05778 static void extract8888(int isSwap, 05779 const void *packedPixel, GLfloat extractComponents[]) 05780 { 05781 GLuint uint; 05782 05783 if (isSwap) { 05784 uint= __GLU_SWAP_4_BYTES(packedPixel); 05785 } 05786 else { 05787 uint= *(const GLuint *)packedPixel; 05788 } 05789 05790 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 05791 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 05792 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 05793 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 05794 05795 /* 255 = 2^8-1 */ 05796 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0; 05797 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0; 05798 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0; 05799 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0; 05800 } /* extract8888() */ 05801 05802 static void shove8888(const GLfloat shoveComponents[], 05803 int index,void *packedPixel) 05804 { 05805 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 05806 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 05807 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 05808 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 05809 05810 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05811 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05812 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05813 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05814 05815 /* due to limited precision, need to round before shoving */ 05816 ((GLuint *)packedPixel)[index] = 05817 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000; 05818 ((GLuint *)packedPixel)[index]|= 05819 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000; 05820 ((GLuint *)packedPixel)[index]|= 05821 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00; 05822 ((GLuint *)packedPixel)[index]|= 05823 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff; 05824 } /* shove8888() */ 05825 05826 static void extract8888rev(int isSwap, 05827 const void *packedPixel,GLfloat extractComponents[]) 05828 { 05829 GLuint uint; 05830 05831 if (isSwap) { 05832 uint= __GLU_SWAP_4_BYTES(packedPixel); 05833 } 05834 else { 05835 uint= *(const GLuint *)packedPixel; 05836 } 05837 05838 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 05839 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 05840 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 05841 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 05842 05843 /* 255 = 2^8-1 */ 05844 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0; 05845 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0; 05846 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0; 05847 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0; 05848 } /* extract8888rev() */ 05849 05850 static void shove8888rev(const GLfloat shoveComponents[], 05851 int index,void *packedPixel) 05852 { 05853 /* 00000000,00000000,00000000,11111111 == 0x000000ff */ 05854 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ 05855 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ 05856 /* 11111111,00000000,00000000,00000000 == 0xff000000 */ 05857 05858 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05859 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05860 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05861 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05862 05863 /* due to limited precision, need to round before shoving */ 05864 ((GLuint *)packedPixel)[index] = 05865 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF; 05866 ((GLuint *)packedPixel)[index]|= 05867 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00; 05868 ((GLuint *)packedPixel)[index]|= 05869 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000; 05870 ((GLuint *)packedPixel)[index]|= 05871 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000; 05872 } /* shove8888rev() */ 05873 05874 static void extract1010102(int isSwap, 05875 const void *packedPixel,GLfloat extractComponents[]) 05876 { 05877 GLuint uint; 05878 05879 if (isSwap) { 05880 uint= __GLU_SWAP_4_BYTES(packedPixel); 05881 } 05882 else { 05883 uint= *(const GLuint *)packedPixel; 05884 } 05885 05886 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ 05887 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ 05888 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ 05889 /* 00000000,00000000,00000000,00000011 == 0x00000003 */ 05890 05891 /* 1023 = 2^10-1 */ 05892 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0; 05893 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0; 05894 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0; 05895 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0; 05896 } /* extract1010102() */ 05897 05898 static void shove1010102(const GLfloat shoveComponents[], 05899 int index,void *packedPixel) 05900 { 05901 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ 05902 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ 05903 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ 05904 /* 00000000,00000000,00000000,00000011 == 0x00000003 */ 05905 05906 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05907 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05908 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05909 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05910 05911 /* due to limited precision, need to round before shoving */ 05912 ((GLuint *)packedPixel)[index] = 05913 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000; 05914 ((GLuint *)packedPixel)[index]|= 05915 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000; 05916 ((GLuint *)packedPixel)[index]|= 05917 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc; 05918 ((GLuint *)packedPixel)[index]|= 05919 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003; 05920 } /* shove1010102() */ 05921 05922 static void extract2101010rev(int isSwap, 05923 const void *packedPixel, 05924 GLfloat extractComponents[]) 05925 { 05926 GLuint uint; 05927 05928 if (isSwap) { 05929 uint= __GLU_SWAP_4_BYTES(packedPixel); 05930 } 05931 else { 05932 uint= *(const GLuint *)packedPixel; 05933 } 05934 05935 /* 00000000,00000000,00000011,11111111 == 0x000003FF */ 05936 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ 05937 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ 05938 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ 05939 05940 /* 1023 = 2^10-1 */ 05941 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0; 05942 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0; 05943 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0; 05944 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0; 05945 /* 3 = 2^2-1 */ 05946 } /* extract2101010rev() */ 05947 05948 static void shove2101010rev(const GLfloat shoveComponents[], 05949 int index,void *packedPixel) 05950 { 05951 /* 00000000,00000000,00000011,11111111 == 0x000003FF */ 05952 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ 05953 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ 05954 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ 05955 05956 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); 05957 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); 05958 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); 05959 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); 05960 05961 /* due to limited precision, need to round before shoving */ 05962 ((GLuint *)packedPixel)[index] = 05963 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF; 05964 ((GLuint *)packedPixel)[index]|= 05965 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00; 05966 ((GLuint *)packedPixel)[index]|= 05967 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000; 05968 ((GLuint *)packedPixel)[index]|= 05969 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000; 05970 } /* shove2101010rev() */ 05971 05972 static void scaleInternalPackedPixel(int components, 05973 void (*extractPackedPixel) 05974 (int, const void *,GLfloat []), 05975 void (*shovePackedPixel) 05976 (const GLfloat [], int, void *), 05977 GLint widthIn,GLint heightIn, 05978 const void *dataIn, 05979 GLint widthOut,GLint heightOut, 05980 void *dataOut, 05981 GLint pixelSizeInBytes, 05982 GLint rowSizeInBytes,GLint isSwap) 05983 { 05984 float convx; 05985 float convy; 05986 float percent; 05987 05988 /* Max components in a format is 4, so... */ 05989 float totals[4]; 05990 float extractTotals[4], extractMoreTotals[4], shoveTotals[4]; 05991 05992 float area; 05993 int i,j,k,xindex; 05994 05995 const char *temp, *temp0; 05996 int outindex = 0; 05997 05998 int lowx_int, highx_int, lowy_int, highy_int; 05999 float x_percent, y_percent; 06000 float lowx_float, highx_float, lowy_float, highy_float; 06001 float convy_float, convx_float; 06002 int convy_int, convx_int; 06003 int l, m; 06004 const char *left, *right; 06005 06006 if (widthIn == widthOut*2 && heightIn == heightOut*2) { 06007 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, 06008 widthIn, heightIn, dataIn, dataOut, 06009 pixelSizeInBytes,rowSizeInBytes,isSwap); 06010 return; 06011 } 06012 convy = (float) heightIn/heightOut; 06013 convx = (float) widthIn/widthOut; 06014 convy_int = floor(convy); 06015 convy_float = convy - convy_int; 06016 convx_int = floor(convx); 06017 convx_float = convx - convx_int; 06018 06019 area = convx * convy; 06020 06021 lowy_int = 0; 06022 lowy_float = 0; 06023 highy_int = convy_int; 06024 highy_float = convy_float; 06025 06026 for (i = 0; i < heightOut; i++) { 06027 lowx_int = 0; 06028 lowx_float = 0; 06029 highx_int = convx_int; 06030 highx_float = convx_float; 06031 06032 for (j = 0; j < widthOut; j++) { 06033 /* 06034 ** Ok, now apply box filter to box that goes from (lowx, lowy) 06035 ** to (highx, highy) on input data into this pixel on output 06036 ** data. 06037 */ 06038 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 06039 06040 /* calculate the value for pixels in the 1st row */ 06041 xindex = lowx_int*pixelSizeInBytes; 06042 if((highy_int>lowy_int) && (highx_int>lowx_int)) { 06043 06044 y_percent = 1-lowy_float; 06045 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; 06046 percent = y_percent * (1-lowx_float); 06047 #if 0 06048 for (k = 0, temp_index = temp; k < components; 06049 k++, temp_index += element_size) { 06050 if (myswap_bytes) { 06051 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06052 } else { 06053 totals[k] += *(const GLushort*)temp_index * percent; 06054 } 06055 } 06056 #else 06057 (*extractPackedPixel)(isSwap,temp,extractTotals); 06058 for (k = 0; k < components; k++) { 06059 totals[k]+= extractTotals[k] * percent; 06060 } 06061 #endif 06062 left = temp; 06063 for(l = lowx_int+1; l < highx_int; l++) { 06064 temp += pixelSizeInBytes; 06065 #if 0 06066 for (k = 0, temp_index = temp; k < components; 06067 k++, temp_index += element_size) { 06068 if (myswap_bytes) { 06069 totals[k] += 06070 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 06071 } else { 06072 totals[k] += *(const GLushort*)temp_index * y_percent; 06073 } 06074 } 06075 #else 06076 (*extractPackedPixel)(isSwap,temp,extractTotals); 06077 for (k = 0; k < components; k++) { 06078 totals[k]+= extractTotals[k] * y_percent; 06079 } 06080 #endif 06081 } 06082 temp += pixelSizeInBytes; 06083 right = temp; 06084 percent = y_percent * highx_float; 06085 #if 0 06086 for (k = 0, temp_index = temp; k < components; 06087 k++, temp_index += element_size) { 06088 if (myswap_bytes) { 06089 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06090 } else { 06091 totals[k] += *(const GLushort*)temp_index * percent; 06092 } 06093 } 06094 #else 06095 (*extractPackedPixel)(isSwap,temp,extractTotals); 06096 for (k = 0; k < components; k++) { 06097 totals[k]+= extractTotals[k] * percent; 06098 } 06099 #endif 06100 06101 /* calculate the value for pixels in the last row */ 06102 06103 y_percent = highy_float; 06104 percent = y_percent * (1-lowx_float); 06105 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes; 06106 #if 0 06107 for (k = 0, temp_index = temp; k < components; 06108 k++, temp_index += element_size) { 06109 if (myswap_bytes) { 06110 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06111 } else { 06112 totals[k] += *(const GLushort*)temp_index * percent; 06113 } 06114 } 06115 #else 06116 (*extractPackedPixel)(isSwap,temp,extractTotals); 06117 for (k = 0; k < components; k++) { 06118 totals[k]+= extractTotals[k] * percent; 06119 } 06120 #endif 06121 for(l = lowx_int+1; l < highx_int; l++) { 06122 temp += pixelSizeInBytes; 06123 #if 0 06124 for (k = 0, temp_index = temp; k < components; 06125 k++, temp_index += element_size) { 06126 if (myswap_bytes) { 06127 totals[k] += 06128 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 06129 } else { 06130 totals[k] += *(const GLushort*)temp_index * y_percent; 06131 } 06132 } 06133 #else 06134 (*extractPackedPixel)(isSwap,temp,extractTotals); 06135 for (k = 0; k < components; k++) { 06136 totals[k]+= extractTotals[k] * y_percent; 06137 } 06138 #endif 06139 06140 } 06141 temp += pixelSizeInBytes; 06142 percent = y_percent * highx_float; 06143 #if 0 06144 for (k = 0, temp_index = temp; k < components; 06145 k++, temp_index += element_size) { 06146 if (myswap_bytes) { 06147 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06148 } else { 06149 totals[k] += *(const GLushort*)temp_index * percent; 06150 } 06151 } 06152 #else 06153 (*extractPackedPixel)(isSwap,temp,extractTotals); 06154 for (k = 0; k < components; k++) { 06155 totals[k]+= extractTotals[k] * percent; 06156 } 06157 #endif 06158 06159 /* calculate the value for pixels in the 1st and last column */ 06160 for(m = lowy_int+1; m < highy_int; m++) { 06161 left += rowSizeInBytes; 06162 right += rowSizeInBytes; 06163 #if 0 06164 for (k = 0; k < components; 06165 k++, left += element_size, right += element_size) { 06166 if (myswap_bytes) { 06167 totals[k] += 06168 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + 06169 __GLU_SWAP_2_BYTES(right) * highx_float; 06170 } else { 06171 totals[k] += *(const GLushort*)left * (1-lowx_float) 06172 + *(const GLushort*)right * highx_float; 06173 } 06174 } 06175 #else 06176 (*extractPackedPixel)(isSwap,left,extractTotals); 06177 (*extractPackedPixel)(isSwap,right,extractMoreTotals); 06178 for (k = 0; k < components; k++) { 06179 totals[k]+= (extractTotals[k]*(1-lowx_float) + 06180 extractMoreTotals[k]*highx_float); 06181 } 06182 #endif 06183 } 06184 } else if (highy_int > lowy_int) { 06185 x_percent = highx_float - lowx_float; 06186 percent = (1-lowy_float)*x_percent; 06187 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; 06188 #if 0 06189 for (k = 0, temp_index = temp; k < components; 06190 k++, temp_index += element_size) { 06191 if (myswap_bytes) { 06192 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06193 } else { 06194 totals[k] += *(const GLushort*)temp_index * percent; 06195 } 06196 } 06197 #else 06198 (*extractPackedPixel)(isSwap,temp,extractTotals); 06199 for (k = 0; k < components; k++) { 06200 totals[k]+= extractTotals[k] * percent; 06201 } 06202 #endif 06203 for(m = lowy_int+1; m < highy_int; m++) { 06204 temp += rowSizeInBytes; 06205 #if 0 06206 for (k = 0, temp_index = temp; k < components; 06207 k++, temp_index += element_size) { 06208 if (myswap_bytes) { 06209 totals[k] += 06210 __GLU_SWAP_2_BYTES(temp_index) * x_percent; 06211 } else { 06212 totals[k] += *(const GLushort*)temp_index * x_percent; 06213 } 06214 } 06215 #else 06216 (*extractPackedPixel)(isSwap,temp,extractTotals); 06217 for (k = 0; k < components; k++) { 06218 totals[k]+= extractTotals[k] * x_percent; 06219 } 06220 #endif 06221 } 06222 percent = x_percent * highy_float; 06223 temp += rowSizeInBytes; 06224 #if 0 06225 for (k = 0, temp_index = temp; k < components; 06226 k++, temp_index += element_size) { 06227 if (myswap_bytes) { 06228 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06229 } else { 06230 totals[k] += *(const GLushort*)temp_index * percent; 06231 } 06232 } 06233 #else 06234 (*extractPackedPixel)(isSwap,temp,extractTotals); 06235 for (k = 0; k < components; k++) { 06236 totals[k]+= extractTotals[k] * percent; 06237 } 06238 #endif 06239 } else if (highx_int > lowx_int) { 06240 y_percent = highy_float - lowy_float; 06241 percent = (1-lowx_float)*y_percent; 06242 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; 06243 #if 0 06244 for (k = 0, temp_index = temp; k < components; 06245 k++, temp_index += element_size) { 06246 if (myswap_bytes) { 06247 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06248 } else { 06249 totals[k] += *(const GLushort*)temp_index * percent; 06250 } 06251 } 06252 #else 06253 (*extractPackedPixel)(isSwap,temp,extractTotals); 06254 for (k = 0; k < components; k++) { 06255 totals[k]+= extractTotals[k] * percent; 06256 } 06257 #endif 06258 for (l = lowx_int+1; l < highx_int; l++) { 06259 temp += pixelSizeInBytes; 06260 #if 0 06261 for (k = 0, temp_index = temp; k < components; 06262 k++, temp_index += element_size) { 06263 if (myswap_bytes) { 06264 totals[k] += 06265 __GLU_SWAP_2_BYTES(temp_index) * y_percent; 06266 } else { 06267 totals[k] += *(const GLushort*)temp_index * y_percent; 06268 } 06269 } 06270 #else 06271 (*extractPackedPixel)(isSwap,temp,extractTotals); 06272 for (k = 0; k < components; k++) { 06273 totals[k]+= extractTotals[k] * y_percent; 06274 } 06275 #endif 06276 } 06277 temp += pixelSizeInBytes; 06278 percent = y_percent * highx_float; 06279 #if 0 06280 for (k = 0, temp_index = temp; k < components; 06281 k++, temp_index += element_size) { 06282 if (myswap_bytes) { 06283 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06284 } else { 06285 totals[k] += *(const GLushort*)temp_index * percent; 06286 } 06287 } 06288 #else 06289 (*extractPackedPixel)(isSwap,temp,extractTotals); 06290 for (k = 0; k < components; k++) { 06291 totals[k]+= extractTotals[k] * percent; 06292 } 06293 #endif 06294 } else { 06295 percent = (highy_float-lowy_float)*(highx_float-lowx_float); 06296 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; 06297 #if 0 06298 for (k = 0, temp_index = temp; k < components; 06299 k++, temp_index += element_size) { 06300 if (myswap_bytes) { 06301 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; 06302 } else { 06303 totals[k] += *(const GLushort*)temp_index * percent; 06304 } 06305 } 06306 #else 06307 (*extractPackedPixel)(isSwap,temp,extractTotals); 06308 for (k = 0; k < components; k++) { 06309 totals[k]+= extractTotals[k] * percent; 06310 } 06311 #endif 06312 } 06313 06314 /* this is for the pixels in the body */ 06315 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes; 06316 for (m = lowy_int+1; m < highy_int; m++) { 06317 temp = temp0; 06318 for(l = lowx_int+1; l < highx_int; l++) { 06319 #if 0 06320 for (k = 0, temp_index = temp; k < components; 06321 k++, temp_index += element_size) { 06322 if (myswap_bytes) { 06323 totals[k] += __GLU_SWAP_2_BYTES(temp_index); 06324 } else { 06325 totals[k] += *(const GLushort*)temp_index; 06326 } 06327 } 06328 #else 06329 (*extractPackedPixel)(isSwap,temp,extractTotals); 06330 for (k = 0; k < components; k++) { 06331 totals[k]+= extractTotals[k]; 06332 } 06333 #endif 06334 temp += pixelSizeInBytes; 06335 } 06336 temp0 += rowSizeInBytes; 06337 } 06338 06339 outindex = (j + (i * widthOut)); /* * (components == 1) */ 06340 #if 0 06341 for (k = 0; k < components; k++) { 06342 dataout[outindex + k] = totals[k]/area; 06343 /*printf("totals[%d] = %f\n", k, totals[k]);*/ 06344 } 06345 #else 06346 for (k = 0; k < components; k++) { 06347 shoveTotals[k]= totals[k]/area; 06348 } 06349 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut); 06350 #endif 06351 lowx_int = highx_int; 06352 lowx_float = highx_float; 06353 highx_int += convx_int; 06354 highx_float += convx_float; 06355 if(highx_float > 1) { 06356 highx_float -= 1.0; 06357 highx_int++; 06358 } 06359 } 06360 lowy_int = highy_int; 06361 lowy_float = highy_float; 06362 highy_int += convy_int; 06363 highy_float += convy_float; 06364 if(highy_float > 1) { 06365 highy_float -= 1.0; 06366 highy_int++; 06367 } 06368 } 06369 06370 assert(outindex == (widthOut*heightOut - 1)); 06371 } /* scaleInternalPackedPixel() */ 06372 06373 /* rowSizeInBytes is at least the width (in bytes) due to padding on 06374 * inputs; not always equal. Output NEVER has row padding. 06375 */ 06376 static void halveImagePackedPixel(int components, 06377 void (*extractPackedPixel) 06378 (int, const void *,GLfloat []), 06379 void (*shovePackedPixel) 06380 (const GLfloat [],int, void *), 06381 GLint width, GLint height, 06382 const void *dataIn, void *dataOut, 06383 GLint pixelSizeInBytes, 06384 GLint rowSizeInBytes, GLint isSwap) 06385 { 06386 /* handle case where there is only 1 column/row */ 06387 if (width == 1 || height == 1) { 06388 assert(!(width == 1 && height == 1)); /* can't be 1x1 */ 06389 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel, 06390 width,height,dataIn,dataOut,pixelSizeInBytes, 06391 rowSizeInBytes,isSwap); 06392 return; 06393 } 06394 06395 { 06396 int ii, jj; 06397 06398 int halfWidth= width / 2; 06399 int halfHeight= height / 2; 06400 const char *src= (const char *) dataIn; 06401 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); 06402 int outIndex= 0; 06403 06404 for (ii= 0; ii< halfHeight; ii++) { 06405 for (jj= 0; jj< halfWidth; jj++) { 06406 #define BOX4 4 06407 float totals[4]; /* 4 is maximum components */ 06408 float extractTotals[BOX4][4]; /* 4 is maximum components */ 06409 int cc; 06410 06411 (*extractPackedPixel)(isSwap,src, 06412 &extractTotals[0][0]); 06413 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 06414 &extractTotals[1][0]); 06415 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 06416 &extractTotals[2][0]); 06417 (*extractPackedPixel)(isSwap, 06418 (src+rowSizeInBytes+pixelSizeInBytes), 06419 &extractTotals[3][0]); 06420 for (cc = 0; cc < components; cc++) { 06421 int kk; 06422 06423 /* grab 4 pixels to average */ 06424 totals[cc]= 0.0; 06425 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 06426 * extractTotals[2][RED]+extractTotals[3][RED]; 06427 * totals[RED]/= 4.0; 06428 */ 06429 for (kk = 0; kk < BOX4; kk++) { 06430 totals[cc]+= extractTotals[kk][cc]; 06431 } 06432 totals[cc]/= (float)BOX4; 06433 } 06434 (*shovePackedPixel)(totals,outIndex,dataOut); 06435 06436 outIndex++; 06437 /* skip over to next square of 4 */ 06438 src+= pixelSizeInBytes + pixelSizeInBytes; 06439 } 06440 /* skip past pad bytes, if any, to get to next row */ 06441 src+= padBytes; 06442 06443 /* src is at beginning of a row here, but it's the second row of 06444 * the square block of 4 pixels that we just worked on so we 06445 * need to go one more row. 06446 * i.e., 06447 * OO... 06448 * here -->OO... 06449 * but want -->OO... 06450 * OO... 06451 * ... 06452 */ 06453 src+= rowSizeInBytes; 06454 } 06455 06456 /* both pointers must reach one byte after the end */ 06457 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); 06458 assert(outIndex == halfWidth * halfHeight); 06459 } 06460 } /* halveImagePackedPixel() */ 06461 06462 static void halve1DimagePackedPixel(int components, 06463 void (*extractPackedPixel) 06464 (int, const void *,GLfloat []), 06465 void (*shovePackedPixel) 06466 (const GLfloat [],int, void *), 06467 GLint width, GLint height, 06468 const void *dataIn, void *dataOut, 06469 GLint pixelSizeInBytes, 06470 GLint rowSizeInBytes, GLint isSwap) 06471 { 06472 int halfWidth= width / 2; 06473 int halfHeight= height / 2; 06474 const char *src= (const char *) dataIn; 06475 int jj; 06476 06477 assert(width == 1 || height == 1); /* must be 1D */ 06478 assert(width != height); /* can't be square */ 06479 06480 if (height == 1) { /* 1 row */ 06481 int outIndex= 0; 06482 06483 assert(width != 1); /* widthxheight can't be 1x1 */ 06484 halfHeight= 1; 06485 06486 /* one horizontal row with possible pad bytes */ 06487 06488 for (jj= 0; jj< halfWidth; jj++) { 06489 #define BOX2 2 06490 float totals[4]; /* 4 is maximum components */ 06491 float extractTotals[BOX2][4]; /* 4 is maximum components */ 06492 int cc; 06493 06494 /* average two at a time, instead of four */ 06495 (*extractPackedPixel)(isSwap,src, 06496 &extractTotals[0][0]); 06497 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 06498 &extractTotals[1][0]); 06499 for (cc = 0; cc < components; cc++) { 06500 int kk; 06501 06502 /* grab 2 pixels to average */ 06503 totals[cc]= 0.0; 06504 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 06505 * totals[RED]/= 2.0; 06506 */ 06507 for (kk = 0; kk < BOX2; kk++) { 06508 totals[cc]+= extractTotals[kk][cc]; 06509 } 06510 totals[cc]/= (float)BOX2; 06511 } 06512 (*shovePackedPixel)(totals,outIndex,dataOut); 06513 06514 outIndex++; 06515 /* skip over to next group of 2 */ 06516 src+= pixelSizeInBytes + pixelSizeInBytes; 06517 } 06518 06519 { 06520 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); 06521 src+= padBytes; /* for assertion only */ 06522 } 06523 assert(src == &((const char *)dataIn)[rowSizeInBytes]); 06524 assert(outIndex == halfWidth * halfHeight); 06525 } 06526 else if (width == 1) { /* 1 column */ 06527 int outIndex= 0; 06528 06529 assert(height != 1); /* widthxheight can't be 1x1 */ 06530 halfWidth= 1; 06531 /* one vertical column with possible pad bytes per row */ 06532 /* average two at a time */ 06533 06534 for (jj= 0; jj< halfHeight; jj++) { 06535 #define BOX2 2 06536 float totals[4]; /* 4 is maximum components */ 06537 float extractTotals[BOX2][4]; /* 4 is maximum components */ 06538 int cc; 06539 06540 /* average two at a time, instead of four */ 06541 (*extractPackedPixel)(isSwap,src, 06542 &extractTotals[0][0]); 06543 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 06544 &extractTotals[1][0]); 06545 for (cc = 0; cc < components; cc++) { 06546 int kk; 06547 06548 /* grab 2 pixels to average */ 06549 totals[cc]= 0.0; 06550 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 06551 * totals[RED]/= 2.0; 06552 */ 06553 for (kk = 0; kk < BOX2; kk++) { 06554 totals[cc]+= extractTotals[kk][cc]; 06555 } 06556 totals[cc]/= (float)BOX2; 06557 } 06558 (*shovePackedPixel)(totals,outIndex,dataOut); 06559 06560 outIndex++; 06561 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */ 06562 } 06563 06564 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); 06565 assert(outIndex == halfWidth * halfHeight); 06566 } 06567 } /* halve1DimagePackedPixel() */ 06568 06569 /*===========================================================================*/ 06570 06571 #ifdef RESOLVE_3D_TEXTURE_SUPPORT 06572 /* 06573 * This section ensures that GLU 1.3 will load and run on 06574 * a GL 1.1 implementation. It dynamically resolves the 06575 * call to glTexImage3D() which might not be available. 06576 * Or is it might be supported as an extension. 06577 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>. 06578 */ 06579 06580 typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level, 06581 GLenum internalFormat, 06582 GLsizei width, GLsizei height, 06583 GLsizei depth, GLint border, 06584 GLenum format, GLenum type, 06585 const GLvoid *pixels ); 06586 06587 static TexImage3Dproc pTexImage3D; 06588 06589 #ifndef WIN32 06590 # include <dlfcn.h> 06591 # include <sys/types.h> 06592 #else 06593 # include <windows.h> 06594 PROC WINAPI wglGetProcAddress(LPCSTR); 06595 #endif 06596 06597 static void gluTexImage3D( GLenum target, GLint level, 06598 GLenum internalFormat, 06599 GLsizei width, GLsizei height, 06600 GLsizei depth, GLint border, 06601 GLenum format, GLenum type, 06602 const GLvoid *pixels ) 06603 { 06604 if (!pTexImage3D) { 06605 #ifdef WIN32 06606 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D"); 06607 if (!pTexImage3D) 06608 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT"); 06609 #else 06610 void *libHandle = dlopen("libgl.so", RTLD_LAZY); 06611 pTexImage3D = (TexImage3Dproc) dlsym(libHandle, "glTexImage3D" ); 06612 if (!pTexImage3D) 06613 pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT"); 06614 dlclose(libHandle); 06615 #endif 06616 } 06617 06618 /* Now call glTexImage3D */ 06619 if (pTexImage3D) 06620 pTexImage3D(target, level, internalFormat, width, height, 06621 depth, border, format, type, pixels); 06622 } 06623 06624 #else 06625 06626 /* Only bind to a GL 1.2 implementation: */ 06627 #define gluTexImage3D glTexImage3D 06628 06629 #endif 06630 06631 static GLint imageSize3D(GLint width, GLint height, GLint depth, 06632 GLenum format, GLenum type) 06633 { 06634 int components= elements_per_group(format,type); 06635 int bytes_per_row= bytes_per_element(type) * width; 06636 06637 assert(width > 0 && height > 0 && depth > 0); 06638 assert(type != GL_BITMAP); 06639 06640 return bytes_per_row * height * depth * components; 06641 } /* imageSize3D() */ 06642 06643 static void fillImage3D(const PixelStorageModes *psm, 06644 GLint width, GLint height, GLint depth, GLenum format, 06645 GLenum type, GLboolean indexFormat, 06646 const void *userImage, GLushort *newImage) 06647 { 06648 int myswapBytes; 06649 int components; 06650 int groupsPerLine; 06651 int elementSize; 06652 int groupSize; 06653 int rowSize; 06654 int padding; 06655 int elementsPerLine; 06656 int rowsPerImage; 06657 int imageSize; 06658 const GLubyte *start, *rowStart, *iter = NULL; 06659 GLushort *iter2; 06660 int ww, hh, dd, k; 06661 06662 myswapBytes= psm->unpack_swap_bytes; 06663 components= elements_per_group(format,type); 06664 if (psm->unpack_row_length > 0) { 06665 groupsPerLine= psm->unpack_row_length; 06666 } 06667 else { 06668 groupsPerLine= width; 06669 } 06670 elementSize= bytes_per_element(type); 06671 groupSize= elementSize * components; 06672 if (elementSize == 1) myswapBytes= 0; 06673 06674 /* 3dstuff begin */ 06675 if (psm->unpack_image_height > 0) { 06676 rowsPerImage= psm->unpack_image_height; 06677 } 06678 else { 06679 rowsPerImage= height; 06680 } 06681 /* 3dstuff end */ 06682 06683 rowSize= groupsPerLine * groupSize; 06684 padding= rowSize % psm->unpack_alignment; 06685 if (padding) { 06686 rowSize+= psm->unpack_alignment - padding; 06687 } 06688 06689 imageSize= rowsPerImage * rowSize; /* 3dstuff */ 06690 06691 start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize + 06692 psm->unpack_skip_pixels * groupSize + 06693 /*3dstuff*/ 06694 psm->unpack_skip_images * imageSize; 06695 elementsPerLine = width * components; 06696 06697 iter2= newImage; 06698 for (dd= 0; dd < depth; dd++) { 06699 rowStart= start; 06700 06701 for (hh= 0; hh < height; hh++) { 06702 iter= rowStart; 06703 06704 for (ww= 0; ww < elementsPerLine; ww++) { 06705 Type_Widget widget; 06706 float extractComponents[4]; 06707 06708 switch(type) { 06709 case GL_UNSIGNED_BYTE: 06710 if (indexFormat) { 06711 *iter2++ = *iter; 06712 } else { 06713 *iter2++ = (*iter) * 257; 06714 } 06715 break; 06716 case GL_BYTE: 06717 if (indexFormat) { 06718 *iter2++ = *((const GLbyte *) iter); 06719 } else { 06720 /* rough approx */ 06721 *iter2++ = (*((const GLbyte *) iter)) * 516; 06722 } 06723 break; 06724 case GL_UNSIGNED_BYTE_3_3_2: 06725 extract332(0,iter,extractComponents); 06726 for (k = 0; k < 3; k++) { 06727 *iter2++ = (GLushort)(extractComponents[k]*65535); 06728 } 06729 break; 06730 case GL_UNSIGNED_BYTE_2_3_3_REV: 06731 extract233rev(0,iter,extractComponents); 06732 for (k = 0; k < 3; k++) { 06733 *iter2++ = (GLushort)(extractComponents[k]*65535); 06734 } 06735 break; 06736 case GL_UNSIGNED_SHORT_5_6_5: 06737 extract565(myswapBytes,iter,extractComponents); 06738 for (k = 0; k < 3; k++) { 06739 *iter2++ = (GLushort)(extractComponents[k]*65535); 06740 } 06741 break; 06742 case GL_UNSIGNED_SHORT_5_6_5_REV: 06743 extract565rev(myswapBytes,iter,extractComponents); 06744 for (k = 0; k < 3; k++) { 06745 *iter2++ = (GLushort)(extractComponents[k]*65535); 06746 } 06747 break; 06748 case GL_UNSIGNED_SHORT_4_4_4_4: 06749 extract4444(myswapBytes,iter,extractComponents); 06750 for (k = 0; k < 4; k++) { 06751 *iter2++ = (GLushort)(extractComponents[k]*65535); 06752 } 06753 break; 06754 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 06755 extract4444rev(myswapBytes,iter,extractComponents); 06756 for (k = 0; k < 4; k++) { 06757 *iter2++ = (GLushort)(extractComponents[k]*65535); 06758 } 06759 break; 06760 case GL_UNSIGNED_SHORT_5_5_5_1: 06761 extract5551(myswapBytes,iter,extractComponents); 06762 for (k = 0; k < 4; k++) { 06763 *iter2++ = (GLushort)(extractComponents[k]*65535); 06764 } 06765 break; 06766 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 06767 extract1555rev(myswapBytes,iter,extractComponents); 06768 for (k = 0; k < 4; k++) { 06769 *iter2++ = (GLushort)(extractComponents[k]*65535); 06770 } 06771 break; 06772 case GL_UNSIGNED_SHORT: 06773 case GL_SHORT: 06774 if (myswapBytes) { 06775 widget.ub[0] = iter[1]; 06776 widget.ub[1] = iter[0]; 06777 } else { 06778 widget.ub[0] = iter[0]; 06779 widget.ub[1] = iter[1]; 06780 } 06781 if (type == GL_SHORT) { 06782 if (indexFormat) { 06783 *iter2++ = widget.s[0]; 06784 } else { 06785 /* rough approx */ 06786 *iter2++ = widget.s[0]*2; 06787 } 06788 } else { 06789 *iter2++ = widget.us[0]; 06790 } 06791 break; 06792 case GL_UNSIGNED_INT_8_8_8_8: 06793 extract8888(myswapBytes,iter,extractComponents); 06794 for (k = 0; k < 4; k++) { 06795 *iter2++ = (GLushort)(extractComponents[k]*65535); 06796 } 06797 break; 06798 case GL_UNSIGNED_INT_8_8_8_8_REV: 06799 extract8888rev(myswapBytes,iter,extractComponents); 06800 for (k = 0; k < 4; k++) { 06801 *iter2++ = (GLushort)(extractComponents[k]*65535); 06802 } 06803 break; 06804 case GL_UNSIGNED_INT_10_10_10_2: 06805 extract1010102(myswapBytes,iter,extractComponents); 06806 for (k = 0; k < 4; k++) { 06807 *iter2++ = (GLushort)(extractComponents[k]*65535); 06808 } 06809 break; 06810 case GL_UNSIGNED_INT_2_10_10_10_REV: 06811 extract2101010rev(myswapBytes,iter,extractComponents); 06812 for (k = 0; k < 4; k++) { 06813 *iter2++ = (GLushort)(extractComponents[k]*65535); 06814 } 06815 break; 06816 case GL_INT: 06817 case GL_UNSIGNED_INT: 06818 case GL_FLOAT: 06819 if (myswapBytes) { 06820 widget.ub[0] = iter[3]; 06821 widget.ub[1] = iter[2]; 06822 widget.ub[2] = iter[1]; 06823 widget.ub[3] = iter[0]; 06824 } else { 06825 widget.ub[0] = iter[0]; 06826 widget.ub[1] = iter[1]; 06827 widget.ub[2] = iter[2]; 06828 widget.ub[3] = iter[3]; 06829 } 06830 if (type == GL_FLOAT) { 06831 if (indexFormat) { 06832 *iter2++ = widget.f; 06833 } else { 06834 *iter2++ = 65535 * widget.f; 06835 } 06836 } else if (type == GL_UNSIGNED_INT) { 06837 if (indexFormat) { 06838 *iter2++ = widget.ui; 06839 } else { 06840 *iter2++ = widget.ui >> 16; 06841 } 06842 } else { 06843 if (indexFormat) { 06844 *iter2++ = widget.i; 06845 } else { 06846 *iter2++ = widget.i >> 15; 06847 } 06848 } 06849 break; 06850 default: 06851 assert(0); 06852 } 06853 06854 iter+= elementSize; 06855 } /* for ww */ 06856 rowStart+= rowSize; 06857 06858 iter= rowStart; /* for assertion purposes */ 06859 } /* for hh */ 06860 06861 start+= imageSize; 06862 } /* for dd */ 06863 06864 /* iterators should be one byte past end */ 06865 if (!isTypePackedPixel(type)) { 06866 assert(iter2 == &newImage[width*height*depth*components]); 06867 } 06868 else { 06869 assert(iter2 == &newImage[width*height*depth* 06870 elements_per_group(format,0)]); 06871 } 06872 assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth + 06873 psm->unpack_skip_rows * rowSize + 06874 psm->unpack_skip_pixels * groupSize + 06875 /*3dstuff*/ 06876 psm->unpack_skip_images * imageSize] ); 06877 } /* fillImage3D () */ 06878 06879 static void scaleInternal3D(GLint components, 06880 GLint widthIn, GLint heightIn, GLint depthIn, 06881 const GLushort *dataIn, 06882 GLint widthOut, GLint heightOut, GLint depthOut, 06883 GLushort *dataOut) 06884 { 06885 float x, lowx, highx, convx, halfconvx; 06886 float y, lowy, highy, convy, halfconvy; 06887 float z, lowz, highz, convz, halfconvz; 06888 float xpercent,ypercent,zpercent; 06889 float percent; 06890 /* Max components in a format is 4, so... */ 06891 float totals[4]; 06892 float volume; 06893 int i,j,d,k,zint,yint,xint,xindex,yindex,zindex; 06894 int temp; 06895 06896 convz = (float) depthIn/depthOut; 06897 convy = (float) heightIn/heightOut; 06898 convx = (float) widthIn/widthOut; 06899 halfconvx = convx/2; 06900 halfconvy = convy/2; 06901 halfconvz = convz/2; 06902 for (d = 0; d < depthOut; d++) { 06903 z = convz * (d+0.5); 06904 if (depthIn > depthOut) { 06905 highz = z + halfconvz; 06906 lowz = z - halfconvz; 06907 } else { 06908 highz = z + 0.5; 06909 lowz = z - 0.5; 06910 } 06911 for (i = 0; i < heightOut; i++) { 06912 y = convy * (i+0.5); 06913 if (heightIn > heightOut) { 06914 highy = y + halfconvy; 06915 lowy = y - halfconvy; 06916 } else { 06917 highy = y + 0.5; 06918 lowy = y - 0.5; 06919 } 06920 for (j = 0; j < widthOut; j++) { 06921 x = convx * (j+0.5); 06922 if (widthIn > widthOut) { 06923 highx = x + halfconvx; 06924 lowx = x - halfconvx; 06925 } else { 06926 highx = x + 0.5; 06927 lowx = x - 0.5; 06928 } 06929 06930 /* 06931 ** Ok, now apply box filter to box that goes from (lowx, lowy, 06932 ** lowz) to (highx, highy, highz) on input data into this pixel 06933 ** on output data. 06934 */ 06935 totals[0] = totals[1] = totals[2] = totals[3] = 0.0; 06936 volume = 0.0; 06937 06938 z = lowz; 06939 zint = floor(z); 06940 while (z < highz) { 06941 zindex = (zint + depthIn) % depthIn; 06942 if (highz < zint+1) { 06943 zpercent = highz - z; 06944 } else { 06945 zpercent = zint+1 - z; 06946 } 06947 06948 y = lowy; 06949 yint = floor(y); 06950 while (y < highy) { 06951 yindex = (yint + heightIn) % heightIn; 06952 if (highy < yint+1) { 06953 ypercent = highy - y; 06954 } else { 06955 ypercent = yint+1 - y; 06956 } 06957 06958 x = lowx; 06959 xint = floor(x); 06960 06961 while (x < highx) { 06962 xindex = (xint + widthIn) % widthIn; 06963 if (highx < xint+1) { 06964 xpercent = highx - x; 06965 } else { 06966 xpercent = xint+1 - x; 06967 } 06968 06969 percent = xpercent * ypercent * zpercent; 06970 volume += percent; 06971 06972 temp = (xindex + (yindex*widthIn) + 06973 (zindex*widthIn*heightIn)) * components; 06974 for (k = 0; k < components; k++) { 06975 assert(0 <= (temp+k) && 06976 (temp+k) < 06977 (widthIn*heightIn*depthIn*components)); 06978 totals[k] += dataIn[temp + k] * percent; 06979 } 06980 06981 xint++; 06982 x = xint; 06983 } /* while x */ 06984 06985 yint++; 06986 y = yint; 06987 } /* while y */ 06988 06989 zint++; 06990 z = zint; 06991 } /* while z */ 06992 06993 temp = (j + (i * widthOut) + 06994 (d*widthOut*heightOut)) * components; 06995 for (k = 0; k < components; k++) { 06996 /* totals[] should be rounded in the case of enlarging an 06997 * RGB ramp when the type is 332 or 4444 06998 */ 06999 assert(0 <= (temp+k) && 07000 (temp+k) < (widthOut*heightOut*depthOut*components)); 07001 dataOut[temp + k] = (totals[k]+0.5)/volume; 07002 } 07003 } /* for j */ 07004 } /* for i */ 07005 } /* for d */ 07006 } /* scaleInternal3D() */ 07007 07008 static void emptyImage3D(const PixelStorageModes *psm, 07009 GLint width, GLint height, GLint depth, 07010 GLenum format, GLenum type, GLboolean indexFormat, 07011 const GLushort *oldImage, void *userImage) 07012 { 07013 int myswapBytes; 07014 int components; 07015 int groupsPerLine; 07016 int elementSize; 07017 int groupSize; 07018 int rowSize; 07019 int padding; 07020 GLubyte *start, *rowStart, *iter=NULL; 07021 int elementsPerLine; 07022 const GLushort *iter2; 07023 int ii, jj, dd, k; 07024 int rowsPerImage; 07025 int imageSize; 07026 07027 myswapBytes= psm->pack_swap_bytes; 07028 components = elements_per_group(format,type); 07029 if (psm->pack_row_length > 0) { 07030 groupsPerLine = psm->pack_row_length; 07031 } 07032 else { 07033 groupsPerLine = width; 07034 } 07035 07036 elementSize= bytes_per_element(type); 07037 groupSize= elementSize * components; 07038 if (elementSize == 1) myswapBytes= 0; 07039 07040 /* 3dstuff begin */ 07041 if (psm->pack_image_height > 0) { 07042 rowsPerImage= psm->pack_image_height; 07043 } 07044 else { 07045 rowsPerImage= height; 07046 } 07047 07048 /* 3dstuff end */ 07049 07050 rowSize = groupsPerLine * groupSize; 07051 padding = rowSize % psm->pack_alignment; 07052 if (padding) { 07053 rowSize+= psm->pack_alignment - padding; 07054 } 07055 07056 imageSize= rowsPerImage * rowSize; /* 3dstuff */ 07057 07058 start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize + 07059 psm->pack_skip_pixels * groupSize + 07060 /*3dstuff*/ 07061 psm->pack_skip_images * imageSize; 07062 elementsPerLine= width * components; 07063 07064 iter2 = oldImage; 07065 for (dd= 0; dd < depth; dd++) { 07066 rowStart= start; 07067 07068 for (ii= 0; ii< height; ii++) { 07069 iter = rowStart; 07070 07071 for (jj = 0; jj < elementsPerLine; jj++) { 07072 Type_Widget widget; 07073 float shoveComponents[4]; 07074 07075 switch(type){ 07076 case GL_UNSIGNED_BYTE: 07077 if (indexFormat) { 07078 *iter = *iter2++; 07079 } else { 07080 *iter = *iter2++ >> 8; 07081 } 07082 break; 07083 case GL_BYTE: 07084 if (indexFormat) { 07085 *((GLbyte *) iter) = *iter2++; 07086 } else { 07087 *((GLbyte *) iter) = *iter2++ >> 9; 07088 } 07089 break; 07090 case GL_UNSIGNED_BYTE_3_3_2: 07091 for (k = 0; k < 3; k++) { 07092 shoveComponents[k]= *iter2++ / 65535.0; 07093 } 07094 shove332(shoveComponents,0,(void *)iter); 07095 break; 07096 case GL_UNSIGNED_BYTE_2_3_3_REV: 07097 for (k = 0; k < 3; k++) { 07098 shoveComponents[k]= *iter2++ / 65535.0; 07099 } 07100 shove233rev(shoveComponents,0,(void *)iter); 07101 break; 07102 case GL_UNSIGNED_SHORT_5_6_5: 07103 for (k = 0; k < 3; k++) { 07104 shoveComponents[k]= *iter2++ / 65535.0; 07105 } 07106 shove565(shoveComponents,0,(void *)&widget.us[0]); 07107 if (myswapBytes) { 07108 iter[0] = widget.ub[1]; 07109 iter[1] = widget.ub[0]; 07110 } 07111 else { 07112 *(GLushort *)iter = widget.us[0]; 07113 } 07114 break; 07115 case GL_UNSIGNED_SHORT_5_6_5_REV: 07116 for (k = 0; k < 3; k++) { 07117 shoveComponents[k]= *iter2++ / 65535.0; 07118 } 07119 shove565rev(shoveComponents,0,(void *)&widget.us[0]); 07120 if (myswapBytes) { 07121 iter[0] = widget.ub[1]; 07122 iter[1] = widget.ub[0]; 07123 } 07124 else { 07125 *(GLushort *)iter = widget.us[0]; 07126 } 07127 break; 07128 case GL_UNSIGNED_SHORT_4_4_4_4: 07129 for (k = 0; k < 4; k++) { 07130 shoveComponents[k]= *iter2++ / 65535.0; 07131 } 07132 shove4444(shoveComponents,0,(void *)&widget.us[0]); 07133 if (myswapBytes) { 07134 iter[0] = widget.ub[1]; 07135 iter[1] = widget.ub[0]; 07136 } else { 07137 *(GLushort *)iter = widget.us[0]; 07138 } 07139 break; 07140 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 07141 for (k = 0; k < 4; k++) { 07142 shoveComponents[k]= *iter2++ / 65535.0; 07143 } 07144 shove4444rev(shoveComponents,0,(void *)&widget.us[0]); 07145 if (myswapBytes) { 07146 iter[0] = widget.ub[1]; 07147 iter[1] = widget.ub[0]; 07148 } else { 07149 *(GLushort *)iter = widget.us[0]; 07150 } 07151 break; 07152 case GL_UNSIGNED_SHORT_5_5_5_1: 07153 for (k = 0; k < 4; k++) { 07154 shoveComponents[k]= *iter2++ / 65535.0; 07155 } 07156 shove5551(shoveComponents,0,(void *)&widget.us[0]); 07157 if (myswapBytes) { 07158 iter[0] = widget.ub[1]; 07159 iter[1] = widget.ub[0]; 07160 } else { 07161 *(GLushort *)iter = widget.us[0]; 07162 } 07163 break; 07164 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 07165 for (k = 0; k < 4; k++) { 07166 shoveComponents[k]= *iter2++ / 65535.0; 07167 } 07168 shove1555rev(shoveComponents,0,(void *)&widget.us[0]); 07169 if (myswapBytes) { 07170 iter[0] = widget.ub[1]; 07171 iter[1] = widget.ub[0]; 07172 } else { 07173 *(GLushort *)iter = widget.us[0]; 07174 } 07175 break; 07176 case GL_UNSIGNED_SHORT: 07177 case GL_SHORT: 07178 if (type == GL_SHORT) { 07179 if (indexFormat) { 07180 widget.s[0] = *iter2++; 07181 } else { 07182 widget.s[0] = *iter2++ >> 1; 07183 } 07184 } else { 07185 widget.us[0] = *iter2++; 07186 } 07187 if (myswapBytes) { 07188 iter[0] = widget.ub[1]; 07189 iter[1] = widget.ub[0]; 07190 } else { 07191 iter[0] = widget.ub[0]; 07192 iter[1] = widget.ub[1]; 07193 } 07194 break; 07195 case GL_UNSIGNED_INT_8_8_8_8: 07196 for (k = 0; k < 4; k++) { 07197 shoveComponents[k]= *iter2++ / 65535.0; 07198 } 07199 shove8888(shoveComponents,0,(void *)&widget.ui); 07200 if (myswapBytes) { 07201 iter[3] = widget.ub[0]; 07202 iter[2] = widget.ub[1]; 07203 iter[1] = widget.ub[2]; 07204 iter[0] = widget.ub[3]; 07205 } else { 07206 *(GLuint *)iter= widget.ui; 07207 } 07208 break; 07209 case GL_UNSIGNED_INT_8_8_8_8_REV: 07210 for (k = 0; k < 4; k++) { 07211 shoveComponents[k]= *iter2++ / 65535.0; 07212 } 07213 shove8888rev(shoveComponents,0,(void *)&widget.ui); 07214 if (myswapBytes) { 07215 iter[3] = widget.ub[0]; 07216 iter[2] = widget.ub[1]; 07217 iter[1] = widget.ub[2]; 07218 iter[0] = widget.ub[3]; 07219 } else { 07220 *(GLuint *)iter= widget.ui; 07221 } 07222 break; 07223 case GL_UNSIGNED_INT_10_10_10_2: 07224 for (k = 0; k < 4; k++) { 07225 shoveComponents[k]= *iter2++ / 65535.0; 07226 } 07227 shove1010102(shoveComponents,0,(void *)&widget.ui); 07228 if (myswapBytes) { 07229 iter[3] = widget.ub[0]; 07230 iter[2] = widget.ub[1]; 07231 iter[1] = widget.ub[2]; 07232 iter[0] = widget.ub[3]; 07233 } else { 07234 *(GLuint *)iter= widget.ui; 07235 } 07236 break; 07237 case GL_UNSIGNED_INT_2_10_10_10_REV: 07238 for (k = 0; k < 4; k++) { 07239 shoveComponents[k]= *iter2++ / 65535.0; 07240 } 07241 shove2101010rev(shoveComponents,0,(void *)&widget.ui); 07242 if (myswapBytes) { 07243 iter[3] = widget.ub[0]; 07244 iter[2] = widget.ub[1]; 07245 iter[1] = widget.ub[2]; 07246 iter[0] = widget.ub[3]; 07247 } else { 07248 *(GLuint *)iter= widget.ui; 07249 } 07250 break; 07251 case GL_INT: 07252 case GL_UNSIGNED_INT: 07253 case GL_FLOAT: 07254 if (type == GL_FLOAT) { 07255 if (indexFormat) { 07256 widget.f = *iter2++; 07257 } else { 07258 widget.f = *iter2++ / (float) 65535.0; 07259 } 07260 } else if (type == GL_UNSIGNED_INT) { 07261 if (indexFormat) { 07262 widget.ui = *iter2++; 07263 } else { 07264 widget.ui = (unsigned int) *iter2++ * 65537; 07265 } 07266 } else { 07267 if (indexFormat) { 07268 widget.i = *iter2++; 07269 } else { 07270 widget.i = ((unsigned int) *iter2++ * 65537)/2; 07271 } 07272 } 07273 if (myswapBytes) { 07274 iter[3] = widget.ub[0]; 07275 iter[2] = widget.ub[1]; 07276 iter[1] = widget.ub[2]; 07277 iter[0] = widget.ub[3]; 07278 } else { 07279 iter[0] = widget.ub[0]; 07280 iter[1] = widget.ub[1]; 07281 iter[2] = widget.ub[2]; 07282 iter[3] = widget.ub[3]; 07283 } 07284 break; 07285 default: 07286 assert(0); 07287 } 07288 07289 iter+= elementSize; 07290 } /* for jj */ 07291 07292 rowStart+= rowSize; 07293 } /* for ii */ 07294 07295 start+= imageSize; 07296 } /* for dd */ 07297 07298 /* iterators should be one byte past end */ 07299 if (!isTypePackedPixel(type)) { 07300 assert(iter2 == &oldImage[width*height*depth*components]); 07301 } 07302 else { 07303 assert(iter2 == &oldImage[width*height*depth* 07304 elements_per_group(format,0)]); 07305 } 07306 assert( iter == &((GLubyte *)userImage)[rowSize*height*depth + 07307 psm->unpack_skip_rows * rowSize + 07308 psm->unpack_skip_pixels * groupSize + 07309 /*3dstuff*/ 07310 psm->unpack_skip_images * imageSize] ); 07311 } /* emptyImage3D() */ 07312 07313 static 07314 int gluScaleImage3D(GLenum format, 07315 GLint widthIn, GLint heightIn, GLint depthIn, 07316 GLenum typeIn, const void *dataIn, 07317 GLint widthOut, GLint heightOut, GLint depthOut, 07318 GLenum typeOut, void *dataOut) 07319 { 07320 int components; 07321 GLushort *beforeImage, *afterImage; 07322 PixelStorageModes psm; 07323 07324 if (widthIn == 0 || heightIn == 0 || depthIn == 0 || 07325 widthOut == 0 || heightOut == 0 || depthOut == 0) { 07326 return 0; 07327 } 07328 07329 if (widthIn < 0 || heightIn < 0 || depthIn < 0 || 07330 widthOut < 0 || heightOut < 0 || depthOut < 0) { 07331 return GLU_INVALID_VALUE; 07332 } 07333 07334 if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) || 07335 typeIn == GL_BITMAP || typeOut == GL_BITMAP) { 07336 return GLU_INVALID_ENUM; 07337 } 07338 if (!isLegalFormatForPackedPixelType(format, typeIn)) { 07339 return GLU_INVALID_OPERATION; 07340 } 07341 if (!isLegalFormatForPackedPixelType(format, typeOut)) { 07342 return GLU_INVALID_OPERATION; 07343 } 07344 07345 beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format, 07346 GL_UNSIGNED_SHORT)); 07347 if (beforeImage == NULL) { 07348 return GLU_OUT_OF_MEMORY; 07349 } 07350 07351 afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format, 07352 GL_UNSIGNED_SHORT)); 07353 if (afterImage == NULL) { 07354 free(beforeImage); 07355 return GLU_OUT_OF_MEMORY; 07356 } 07357 retrieveStoreModes3D(&psm); 07358 07359 fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format), 07360 dataIn, beforeImage); 07361 components = elements_per_group(format,0); 07362 scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage, 07363 widthOut,heightOut,depthOut,afterImage); 07364 emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut, 07365 is_index(format),afterImage, dataOut); 07366 free((void *) beforeImage); 07367 free((void *) afterImage); 07368 07369 return 0; 07370 } /* gluScaleImage3D() */ 07371 07372 07373 static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth, 07374 GLint internalFormat, GLenum format, GLenum type, 07375 GLint *newWidth, GLint *newHeight, GLint *newDepth) 07376 { 07377 GLint widthPowerOf2= nearestPower(width); 07378 GLint heightPowerOf2= nearestPower(height); 07379 GLint depthPowerOf2= nearestPower(depth); 07380 GLint proxyWidth ; 07381 07382 do { 07383 /* compute level 1 width & height & depth, clamping each at 1 */ 07384 GLint widthAtLevelOne= (widthPowerOf2 > 1) ? 07385 widthPowerOf2 >> 1 : 07386 widthPowerOf2; 07387 GLint heightAtLevelOne= (heightPowerOf2 > 1) ? 07388 heightPowerOf2 >> 1 : 07389 heightPowerOf2; 07390 GLint depthAtLevelOne= (depthPowerOf2 > 1) ? 07391 depthPowerOf2 >> 1 : 07392 depthPowerOf2; 07393 GLenum proxyTarget = 0; 07394 assert(widthAtLevelOne > 0); 07395 assert(heightAtLevelOne > 0); 07396 assert(depthAtLevelOne > 0); 07397 07398 /* does width x height x depth at level 1 & all their mipmaps fit? */ 07399 if (target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D) { 07400 proxyTarget = GL_PROXY_TEXTURE_3D; 07401 gluTexImage3D(proxyTarget, 1, /* must be non-zero */ 07402 internalFormat, 07403 widthAtLevelOne,heightAtLevelOne,depthAtLevelOne, 07404 0,format,type,NULL); 07405 } 07406 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth); 07407 /* does it fit??? */ 07408 if (proxyWidth == 0) { /* nope, so try again with these sizes */ 07409 if (widthPowerOf2 == 1 && heightPowerOf2 == 1 && 07410 depthPowerOf2 == 1) { 07411 *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */ 07412 return; 07413 } 07414 widthPowerOf2= widthAtLevelOne; 07415 heightPowerOf2= heightAtLevelOne; 07416 depthPowerOf2= depthAtLevelOne; 07417 } 07418 /* else it does fit */ 07419 } while (proxyWidth == 0); 07420 /* loop must terminate! */ 07421 07422 /* return the width & height at level 0 that fits */ 07423 *newWidth= widthPowerOf2; 07424 *newHeight= heightPowerOf2; 07425 *newDepth= depthPowerOf2; 07426 /*printf("Proxy Textures\n");*/ 07427 } /* closestFit3D() */ 07428 07429 static void halveImagePackedPixelSlice(int components, 07430 void (*extractPackedPixel) 07431 (int, const void *,GLfloat []), 07432 void (*shovePackedPixel) 07433 (const GLfloat [],int, void *), 07434 GLint width, GLint height, GLint depth, 07435 const void *dataIn, void *dataOut, 07436 GLint pixelSizeInBytes, 07437 GLint rowSizeInBytes, 07438 GLint imageSizeInBytes, 07439 GLint isSwap) 07440 { 07441 int ii, jj; 07442 int halfWidth= width / 2; 07443 int halfHeight= height / 2; 07444 int halfDepth= depth / 2; 07445 const char *src= (const char *)dataIn; 07446 int outIndex= 0; 07447 07448 assert((width == 1 || height == 1) && depth >= 2); 07449 07450 if (width == height) { /* a 1-pixel column viewed from top */ 07451 assert(width == 1 && height == 1); 07452 assert(depth >= 2); 07453 07454 for (ii= 0; ii< halfDepth; ii++) { 07455 float totals[4]; 07456 float extractTotals[BOX2][4]; 07457 int cc; 07458 07459 (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]); 07460 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 07461 &extractTotals[1][0]); 07462 for (cc = 0; cc < components; cc++) { 07463 int kk; 07464 07465 /* average 2 pixels since only a column */ 07466 totals[cc]= 0.0; 07467 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 07468 * totals[RED]/= 2.0; 07469 */ 07470 for (kk = 0; kk < BOX2; kk++) { 07471 totals[cc]+= extractTotals[kk][cc]; 07472 } 07473 totals[cc]/= (float)BOX2; 07474 } /* for cc */ 07475 07476 (*shovePackedPixel)(totals,outIndex,dataOut); 07477 outIndex++; 07478 /* skip over to next group of 2 */ 07479 src+= imageSizeInBytes + imageSizeInBytes; 07480 } /* for ii */ 07481 } 07482 else if (height == 1) { /* horizontal slice viewed from top */ 07483 assert(width != 1); 07484 07485 for (ii= 0; ii< halfDepth; ii++) { 07486 for (jj= 0; jj< halfWidth; jj++) { 07487 float totals[4]; 07488 float extractTotals[BOX4][4]; 07489 int cc; 07490 07491 (*extractPackedPixel)(isSwap,src, 07492 &extractTotals[0][0]); 07493 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 07494 &extractTotals[1][0]); 07495 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 07496 &extractTotals[2][0]); 07497 (*extractPackedPixel)(isSwap, 07498 (src+imageSizeInBytes+pixelSizeInBytes), 07499 &extractTotals[3][0]); 07500 for (cc = 0; cc < components; cc++) { 07501 int kk; 07502 07503 /* grab 4 pixels to average */ 07504 totals[cc]= 0.0; 07505 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 07506 * extractTotals[2][RED]+extractTotals[3][RED]; 07507 * totals[RED]/= 4.0; 07508 */ 07509 for (kk = 0; kk < BOX4; kk++) { 07510 totals[cc]+= extractTotals[kk][cc]; 07511 } 07512 totals[cc]/= (float)BOX4; 07513 } 07514 (*shovePackedPixel)(totals,outIndex,dataOut); 07515 07516 outIndex++; 07517 /* skip over to next horizontal square of 4 */ 07518 src+= imageSizeInBytes + imageSizeInBytes; 07519 } 07520 } 07521 07522 /* assert() */ 07523 } 07524 else if (width == 1) { /* vertical slice viewed from top */ 07525 assert(height != 1); 07526 07527 for (ii= 0; ii< halfDepth; ii++) { 07528 for (jj= 0; jj< halfHeight; jj++) { 07529 float totals[4]; 07530 float extractTotals[BOX4][4]; 07531 int cc; 07532 07533 (*extractPackedPixel)(isSwap,src, 07534 &extractTotals[0][0]); 07535 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 07536 &extractTotals[1][0]); 07537 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 07538 &extractTotals[2][0]); 07539 (*extractPackedPixel)(isSwap, 07540 (src+imageSizeInBytes+rowSizeInBytes), 07541 &extractTotals[3][0]); 07542 for (cc = 0; cc < components; cc++) { 07543 int kk; 07544 07545 /* grab 4 pixels to average */ 07546 totals[cc]= 0.0; 07547 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 07548 * extractTotals[2][RED]+extractTotals[3][RED]; 07549 * totals[RED]/= 4.0; 07550 */ 07551 for (kk = 0; kk < BOX4; kk++) { 07552 totals[cc]+= extractTotals[kk][cc]; 07553 } 07554 totals[cc]/= (float)BOX4; 07555 } 07556 (*shovePackedPixel)(totals,outIndex,dataOut); 07557 07558 outIndex++; 07559 07560 /* skip over to next vertical square of 4 */ 07561 src+= imageSizeInBytes + imageSizeInBytes; 07562 } 07563 } 07564 /* assert() */ 07565 } 07566 07567 } /* halveImagePackedPixelSlice() */ 07568 07569 static void halveImagePackedPixel3D(int components, 07570 void (*extractPackedPixel) 07571 (int, const void *,GLfloat []), 07572 void (*shovePackedPixel) 07573 (const GLfloat [],int, void *), 07574 GLint width, GLint height, GLint depth, 07575 const void *dataIn, void *dataOut, 07576 GLint pixelSizeInBytes, 07577 GLint rowSizeInBytes, 07578 GLint imageSizeInBytes, 07579 GLint isSwap) 07580 { 07581 if (depth == 1) { 07582 assert(1 <= width && 1 <= height); 07583 07584 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, 07585 width,height,dataIn,dataOut,pixelSizeInBytes, 07586 rowSizeInBytes,isSwap); 07587 return; 07588 } 07589 /* a horizontal or vertical slice viewed from top */ 07590 else if (width == 1 || height == 1) { 07591 assert(1 <= depth); 07592 07593 halveImagePackedPixelSlice(components, 07594 extractPackedPixel,shovePackedPixel, 07595 width, height, depth, dataIn, dataOut, 07596 pixelSizeInBytes, rowSizeInBytes, 07597 imageSizeInBytes, isSwap); 07598 return; 07599 } 07600 { 07601 int ii, jj, dd; 07602 07603 int halfWidth= width / 2; 07604 int halfHeight= height / 2; 07605 int halfDepth= depth / 2; 07606 const char *src= (const char *) dataIn; 07607 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); 07608 int outIndex= 0; 07609 07610 for (dd= 0; dd < halfDepth; dd++) { 07611 for (ii= 0; ii< halfHeight; ii++) { 07612 for (jj= 0; jj< halfWidth; jj++) { 07613 #define BOX8 8 07614 float totals[4]; /* 4 is maximum components */ 07615 float extractTotals[BOX8][4]; /* 4 is maximum components */ 07616 int cc; 07617 07618 (*extractPackedPixel)(isSwap,src, 07619 &extractTotals[0][0]); 07620 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), 07621 &extractTotals[1][0]); 07622 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), 07623 &extractTotals[2][0]); 07624 (*extractPackedPixel)(isSwap, 07625 (src+rowSizeInBytes+pixelSizeInBytes), 07626 &extractTotals[3][0]); 07627 07628 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), 07629 &extractTotals[4][0]); 07630 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes), 07631 &extractTotals[5][0]); 07632 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes), 07633 &extractTotals[6][0]); 07634 (*extractPackedPixel)(isSwap, 07635 (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes), 07636 &extractTotals[7][0]); 07637 for (cc = 0; cc < components; cc++) { 07638 int kk; 07639 07640 /* grab 8 pixels to average */ 07641 totals[cc]= 0.0; 07642 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 07643 * extractTotals[2][RED]+extractTotals[3][RED]+ 07644 * extractTotals[4][RED]+extractTotals[5][RED]+ 07645 * extractTotals[6][RED]+extractTotals[7][RED]; 07646 * totals[RED]/= 8.0; 07647 */ 07648 for (kk = 0; kk < BOX8; kk++) { 07649 totals[cc]+= extractTotals[kk][cc]; 07650 } 07651 totals[cc]/= (float)BOX8; 07652 } 07653 (*shovePackedPixel)(totals,outIndex,dataOut); 07654 07655 outIndex++; 07656 /* skip over to next square of 4 */ 07657 src+= pixelSizeInBytes + pixelSizeInBytes; 07658 } 07659 /* skip past pad bytes, if any, to get to next row */ 07660 src+= padBytes; 07661 07662 /* src is at beginning of a row here, but it's the second row of 07663 * the square block of 4 pixels that we just worked on so we 07664 * need to go one more row. 07665 * i.e., 07666 * OO... 07667 * here -->OO... 07668 * but want -->OO... 07669 * OO... 07670 * ... 07671 */ 07672 src+= rowSizeInBytes; 07673 } 07674 07675 src+= imageSizeInBytes; 07676 } /* for dd */ 07677 07678 /* both pointers must reach one byte after the end */ 07679 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 07680 assert(outIndex == halfWidth * halfHeight * halfDepth); 07681 } /* for dd */ 07682 07683 } /* halveImagePackedPixel3D() */ 07684 07685 static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat, 07686 GLsizei width, 07687 GLsizei height, 07688 GLsizei depth, 07689 GLsizei widthPowerOf2, 07690 GLsizei heightPowerOf2, 07691 GLsizei depthPowerOf2, 07692 GLenum format, GLenum type, 07693 GLint userLevel, 07694 GLint baseLevel,GLint maxLevel, 07695 const void *data) 07696 { 07697 GLint newWidth, newHeight, newDepth; 07698 GLint level, levels; 07699 const void *usersImage; 07700 void *srcImage, *dstImage; 07701 __GLU_INIT_SWAP_IMAGE; 07702 GLint memReq; 07703 GLint cmpts; 07704 07705 GLint myswapBytes, groupsPerLine, elementSize, groupSize; 07706 GLint rowsPerImage, imageSize; 07707 GLint rowSize, padding; 07708 PixelStorageModes psm; 07709 07710 assert(checkMipmapArgs(internalFormat,format,type) == 0); 07711 assert(width >= 1 && height >= 1 && depth >= 1); 07712 assert(type != GL_BITMAP); 07713 07714 srcImage = dstImage = NULL; 07715 07716 newWidth= widthPowerOf2; 07717 newHeight= heightPowerOf2; 07718 newDepth= depthPowerOf2; 07719 levels = computeLog(newWidth); 07720 level = computeLog(newHeight); 07721 if (level > levels) levels=level; 07722 level = computeLog(newDepth); 07723 if (level > levels) levels=level; 07724 07725 levels+= userLevel; 07726 07727 retrieveStoreModes3D(&psm); 07728 myswapBytes = psm.unpack_swap_bytes; 07729 cmpts = elements_per_group(format,type); 07730 if (psm.unpack_row_length > 0) { 07731 groupsPerLine = psm.unpack_row_length; 07732 } else { 07733 groupsPerLine = width; 07734 } 07735 07736 elementSize = bytes_per_element(type); 07737 groupSize = elementSize * cmpts; 07738 if (elementSize == 1) myswapBytes = 0; 07739 07740 /* 3dstuff begin */ 07741 if (psm.unpack_image_height > 0) { 07742 rowsPerImage= psm.unpack_image_height; 07743 } 07744 else { 07745 rowsPerImage= height; 07746 } 07747 07748 /* 3dstuff end */ 07749 rowSize = groupsPerLine * groupSize; 07750 padding = (rowSize % psm.unpack_alignment); 07751 if (padding) { 07752 rowSize += psm.unpack_alignment - padding; 07753 } 07754 07755 imageSize= rowsPerImage * rowSize; /* 3dstuff */ 07756 07757 usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize + 07758 psm.unpack_skip_pixels * groupSize + 07759 /* 3dstuff */ 07760 psm.unpack_skip_images * imageSize; 07761 07762 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 07763 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 07764 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 07765 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); 07766 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); 07767 07768 level = userLevel; 07769 07770 if (width == newWidth && height == newHeight && depth == newDepth) { 07771 /* Use usersImage for level userLevel */ 07772 if (baseLevel <= level && level <= maxLevel) { 07773 gluTexImage3D(target, level, internalFormat, width, 07774 height, depth, 0, format, type, 07775 usersImage); 07776 } 07777 if(levels == 0) { /* we're done. clean up and return */ 07778 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 07779 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 07780 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 07781 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 07782 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 07783 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 07784 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 07785 return 0; 07786 } 07787 { 07788 int nextWidth= newWidth/2; 07789 int nextHeight= newHeight/2; 07790 int nextDepth= newDepth/2; 07791 07792 /* clamp to 1 */ 07793 if (nextWidth < 1) nextWidth= 1; 07794 if (nextHeight < 1) nextHeight= 1; 07795 if (nextDepth < 1) nextDepth= 1; 07796 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); 07797 } 07798 switch(type) { 07799 case GL_UNSIGNED_BYTE: 07800 dstImage = (GLubyte *)malloc(memReq); 07801 break; 07802 case GL_BYTE: 07803 dstImage = (GLbyte *)malloc(memReq); 07804 break; 07805 case GL_UNSIGNED_SHORT: 07806 dstImage = (GLushort *)malloc(memReq); 07807 break; 07808 case GL_SHORT: 07809 dstImage = (GLshort *)malloc(memReq); 07810 break; 07811 case GL_UNSIGNED_INT: 07812 dstImage = (GLuint *)malloc(memReq); 07813 break; 07814 case GL_INT: 07815 dstImage = (GLint *)malloc(memReq); 07816 break; 07817 case GL_FLOAT: 07818 dstImage = (GLfloat *)malloc(memReq); 07819 break; 07820 case GL_UNSIGNED_BYTE_3_3_2: 07821 case GL_UNSIGNED_BYTE_2_3_3_REV: 07822 dstImage = (GLubyte *)malloc(memReq); 07823 break; 07824 case GL_UNSIGNED_SHORT_5_6_5: 07825 case GL_UNSIGNED_SHORT_5_6_5_REV: 07826 case GL_UNSIGNED_SHORT_4_4_4_4: 07827 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 07828 case GL_UNSIGNED_SHORT_5_5_5_1: 07829 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 07830 dstImage = (GLushort *)malloc(memReq); 07831 break; 07832 case GL_UNSIGNED_INT_8_8_8_8: 07833 case GL_UNSIGNED_INT_8_8_8_8_REV: 07834 case GL_UNSIGNED_INT_10_10_10_2: 07835 case GL_UNSIGNED_INT_2_10_10_10_REV: 07836 dstImage = (GLuint *)malloc(memReq); 07837 break; 07838 default: 07839 return GLU_INVALID_ENUM; /* assertion */ 07840 } 07841 if (dstImage == NULL) { 07842 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 07843 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 07844 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 07845 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 07846 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 07847 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 07848 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 07849 return GLU_OUT_OF_MEMORY; 07850 } 07851 else 07852 switch(type) { 07853 case GL_UNSIGNED_BYTE: 07854 if (depth > 1) { 07855 halveImage3D(cmpts,extractUbyte,shoveUbyte, 07856 width,height,depth, 07857 usersImage,dstImage,elementSize,groupSize,rowSize, 07858 imageSize,myswapBytes); 07859 } 07860 else { 07861 halveImage_ubyte(cmpts,width,height,usersImage,dstImage, 07862 elementSize,rowSize,groupSize); 07863 } 07864 break; 07865 case GL_BYTE: 07866 if (depth > 1) { 07867 halveImage3D(cmpts,extractSbyte,shoveSbyte, 07868 width,height,depth, 07869 usersImage,dstImage,elementSize,groupSize,rowSize, 07870 imageSize,myswapBytes); 07871 } 07872 else { 07873 halveImage_byte(cmpts,width,height,usersImage,dstImage, 07874 elementSize,rowSize,groupSize); 07875 } 07876 break; 07877 case GL_UNSIGNED_SHORT: 07878 if (depth > 1) { 07879 halveImage3D(cmpts,extractUshort,shoveUshort, 07880 width,height,depth, 07881 usersImage,dstImage,elementSize,groupSize,rowSize, 07882 imageSize,myswapBytes); 07883 } 07884 else { 07885 halveImage_ushort(cmpts,width,height,usersImage,dstImage, 07886 elementSize,rowSize,groupSize,myswapBytes); 07887 } 07888 break; 07889 case GL_SHORT: 07890 if (depth > 1) { 07891 halveImage3D(cmpts,extractSshort,shoveSshort, 07892 width,height,depth, 07893 usersImage,dstImage,elementSize,groupSize,rowSize, 07894 imageSize,myswapBytes); 07895 } 07896 else { 07897 halveImage_short(cmpts,width,height,usersImage,dstImage, 07898 elementSize,rowSize,groupSize,myswapBytes); 07899 } 07900 break; 07901 case GL_UNSIGNED_INT: 07902 if (depth > 1) { 07903 halveImage3D(cmpts,extractUint,shoveUint, 07904 width,height,depth, 07905 usersImage,dstImage,elementSize,groupSize,rowSize, 07906 imageSize,myswapBytes); 07907 } 07908 else { 07909 halveImage_uint(cmpts,width,height,usersImage,dstImage, 07910 elementSize,rowSize,groupSize,myswapBytes); 07911 } 07912 break; 07913 case GL_INT: 07914 if (depth > 1) { 07915 halveImage3D(cmpts,extractSint,shoveSint, 07916 width,height,depth, 07917 usersImage,dstImage,elementSize,groupSize,rowSize, 07918 imageSize,myswapBytes); 07919 } 07920 else { 07921 halveImage_int(cmpts,width,height,usersImage,dstImage, 07922 elementSize,rowSize,groupSize,myswapBytes); 07923 } 07924 break; 07925 case GL_FLOAT: 07926 if (depth > 1 ) { 07927 halveImage3D(cmpts,extractFloat,shoveFloat, 07928 width,height,depth, 07929 usersImage,dstImage,elementSize,groupSize,rowSize, 07930 imageSize,myswapBytes); 07931 } 07932 else { 07933 halveImage_float(cmpts,width,height,usersImage,dstImage, 07934 elementSize,rowSize,groupSize,myswapBytes); 07935 } 07936 break; 07937 case GL_UNSIGNED_BYTE_3_3_2: 07938 assert(format == GL_RGB); 07939 halveImagePackedPixel3D(3,extract332,shove332, 07940 width,height,depth,usersImage,dstImage, 07941 elementSize,rowSize,imageSize,myswapBytes); 07942 break; 07943 case GL_UNSIGNED_BYTE_2_3_3_REV: 07944 assert(format == GL_RGB); 07945 halveImagePackedPixel3D(3,extract233rev,shove233rev, 07946 width,height,depth,usersImage,dstImage, 07947 elementSize,rowSize,imageSize,myswapBytes); 07948 break; 07949 case GL_UNSIGNED_SHORT_5_6_5: 07950 halveImagePackedPixel3D(3,extract565,shove565, 07951 width,height,depth,usersImage,dstImage, 07952 elementSize,rowSize,imageSize,myswapBytes); 07953 break; 07954 case GL_UNSIGNED_SHORT_5_6_5_REV: 07955 halveImagePackedPixel3D(3,extract565rev,shove565rev, 07956 width,height,depth,usersImage,dstImage, 07957 elementSize,rowSize,imageSize,myswapBytes); 07958 break; 07959 case GL_UNSIGNED_SHORT_4_4_4_4: 07960 halveImagePackedPixel3D(4,extract4444,shove4444, 07961 width,height,depth,usersImage,dstImage, 07962 elementSize,rowSize,imageSize,myswapBytes); 07963 break; 07964 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 07965 halveImagePackedPixel3D(4,extract4444rev,shove4444rev, 07966 width,height,depth,usersImage,dstImage, 07967 elementSize,rowSize,imageSize,myswapBytes); 07968 break; 07969 case GL_UNSIGNED_SHORT_5_5_5_1: 07970 halveImagePackedPixel3D(4,extract5551,shove5551, 07971 width,height,depth,usersImage,dstImage, 07972 elementSize,rowSize,imageSize,myswapBytes); 07973 break; 07974 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 07975 halveImagePackedPixel3D(4,extract1555rev,shove1555rev, 07976 width,height,depth,usersImage,dstImage, 07977 elementSize,rowSize,imageSize,myswapBytes); 07978 break; 07979 case GL_UNSIGNED_INT_8_8_8_8: 07980 halveImagePackedPixel3D(4,extract8888,shove8888, 07981 width,height,depth,usersImage,dstImage, 07982 elementSize,rowSize,imageSize,myswapBytes); 07983 break; 07984 case GL_UNSIGNED_INT_8_8_8_8_REV: 07985 halveImagePackedPixel3D(4,extract8888rev,shove8888rev, 07986 width,height,depth,usersImage,dstImage, 07987 elementSize,rowSize,imageSize,myswapBytes); 07988 break; 07989 case GL_UNSIGNED_INT_10_10_10_2: 07990 halveImagePackedPixel3D(4,extract1010102,shove1010102, 07991 width,height,depth,usersImage,dstImage, 07992 elementSize,rowSize,imageSize,myswapBytes); 07993 break; 07994 case GL_UNSIGNED_INT_2_10_10_10_REV: 07995 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, 07996 width,height,depth,usersImage,dstImage, 07997 elementSize,rowSize,imageSize,myswapBytes); 07998 break; 07999 default: 08000 assert(0); 08001 break; 08002 } 08003 newWidth = width/2; 08004 newHeight = height/2; 08005 newDepth = depth/2; 08006 /* clamp to 1 */ 08007 if (newWidth < 1) newWidth= 1; 08008 if (newHeight < 1) newHeight= 1; 08009 if (newDepth < 1) newDepth= 1; 08010 08011 myswapBytes = 0; 08012 rowSize = newWidth * groupSize; 08013 imageSize= rowSize * newHeight; /* 3dstuff */ 08014 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); 08015 /* Swap srcImage and dstImage */ 08016 __GLU_SWAP_IMAGE(srcImage,dstImage); 08017 switch(type) { 08018 case GL_UNSIGNED_BYTE: 08019 dstImage = (GLubyte *)malloc(memReq); 08020 break; 08021 case GL_BYTE: 08022 dstImage = (GLbyte *)malloc(memReq); 08023 break; 08024 case GL_UNSIGNED_SHORT: 08025 dstImage = (GLushort *)malloc(memReq); 08026 break; 08027 case GL_SHORT: 08028 dstImage = (GLshort *)malloc(memReq); 08029 break; 08030 case GL_UNSIGNED_INT: 08031 dstImage = (GLuint *)malloc(memReq); 08032 break; 08033 case GL_INT: 08034 dstImage = (GLint *)malloc(memReq); 08035 break; 08036 case GL_FLOAT: 08037 dstImage = (GLfloat *)malloc(memReq); 08038 break; 08039 case GL_UNSIGNED_BYTE_3_3_2: 08040 case GL_UNSIGNED_BYTE_2_3_3_REV: 08041 dstImage = (GLubyte *)malloc(memReq); 08042 break; 08043 case GL_UNSIGNED_SHORT_5_6_5: 08044 case GL_UNSIGNED_SHORT_5_6_5_REV: 08045 case GL_UNSIGNED_SHORT_4_4_4_4: 08046 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 08047 case GL_UNSIGNED_SHORT_5_5_5_1: 08048 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 08049 dstImage = (GLushort *)malloc(memReq); 08050 break; 08051 case GL_UNSIGNED_INT_8_8_8_8: 08052 case GL_UNSIGNED_INT_8_8_8_8_REV: 08053 case GL_UNSIGNED_INT_10_10_10_2: 08054 case GL_UNSIGNED_INT_2_10_10_10_REV: 08055 dstImage = (GLuint *)malloc(memReq); 08056 break; 08057 default: 08058 return GLU_INVALID_ENUM; /* assertion */ 08059 } 08060 if (dstImage == NULL) { 08061 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 08062 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 08063 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 08064 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 08065 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 08066 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 08067 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 08068 return GLU_OUT_OF_MEMORY; 08069 } 08070 /* level userLevel+1 is in srcImage; level userLevel already saved */ 08071 level = userLevel+1; 08072 } else {/* user's image is *not* nice power-of-2 sized square */ 08073 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); 08074 switch(type) { 08075 case GL_UNSIGNED_BYTE: 08076 dstImage = (GLubyte *)malloc(memReq); 08077 break; 08078 case GL_BYTE: 08079 dstImage = (GLbyte *)malloc(memReq); 08080 break; 08081 case GL_UNSIGNED_SHORT: 08082 dstImage = (GLushort *)malloc(memReq); 08083 break; 08084 case GL_SHORT: 08085 dstImage = (GLshort *)malloc(memReq); 08086 break; 08087 case GL_UNSIGNED_INT: 08088 dstImage = (GLuint *)malloc(memReq); 08089 break; 08090 case GL_INT: 08091 dstImage = (GLint *)malloc(memReq); 08092 break; 08093 case GL_FLOAT: 08094 dstImage = (GLfloat *)malloc(memReq); 08095 break; 08096 case GL_UNSIGNED_BYTE_3_3_2: 08097 case GL_UNSIGNED_BYTE_2_3_3_REV: 08098 dstImage = (GLubyte *)malloc(memReq); 08099 break; 08100 case GL_UNSIGNED_SHORT_5_6_5: 08101 case GL_UNSIGNED_SHORT_5_6_5_REV: 08102 case GL_UNSIGNED_SHORT_4_4_4_4: 08103 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 08104 case GL_UNSIGNED_SHORT_5_5_5_1: 08105 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 08106 dstImage = (GLushort *)malloc(memReq); 08107 break; 08108 case GL_UNSIGNED_INT_8_8_8_8: 08109 case GL_UNSIGNED_INT_8_8_8_8_REV: 08110 case GL_UNSIGNED_INT_10_10_10_2: 08111 case GL_UNSIGNED_INT_2_10_10_10_REV: 08112 dstImage = (GLuint *)malloc(memReq); 08113 break; 08114 default: 08115 return GLU_INVALID_ENUM; /* assertion */ 08116 } 08117 08118 if (dstImage == NULL) { 08119 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 08120 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 08121 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 08122 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 08123 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 08124 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 08125 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 08126 return GLU_OUT_OF_MEMORY; 08127 } 08128 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n", 08129 width,height,depth,newWidth,newHeight,newDepth);*/ 08130 08131 gluScaleImage3D(format, width, height, depth, type, usersImage, 08132 newWidth, newHeight, newDepth, type, dstImage); 08133 08134 myswapBytes = 0; 08135 rowSize = newWidth * groupSize; 08136 imageSize = rowSize * newHeight; /* 3dstuff */ 08137 /* Swap dstImage and srcImage */ 08138 __GLU_SWAP_IMAGE(srcImage,dstImage); 08139 08140 if(levels != 0) { /* use as little memory as possible */ 08141 { 08142 int nextWidth= newWidth/2; 08143 int nextHeight= newHeight/2; 08144 int nextDepth= newDepth/2; 08145 if (nextWidth < 1) nextWidth= 1; 08146 if (nextHeight < 1) nextHeight= 1; 08147 if (nextDepth < 1) nextDepth= 1; 08148 08149 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); 08150 } 08151 switch(type) { 08152 case GL_UNSIGNED_BYTE: 08153 dstImage = (GLubyte *)malloc(memReq); 08154 break; 08155 case GL_BYTE: 08156 dstImage = (GLbyte *)malloc(memReq); 08157 break; 08158 case GL_UNSIGNED_SHORT: 08159 dstImage = (GLushort *)malloc(memReq); 08160 break; 08161 case GL_SHORT: 08162 dstImage = (GLshort *)malloc(memReq); 08163 break; 08164 case GL_UNSIGNED_INT: 08165 dstImage = (GLuint *)malloc(memReq); 08166 break; 08167 case GL_INT: 08168 dstImage = (GLint *)malloc(memReq); 08169 break; 08170 case GL_FLOAT: 08171 dstImage = (GLfloat *)malloc(memReq); 08172 break; 08173 case GL_UNSIGNED_BYTE_3_3_2: 08174 case GL_UNSIGNED_BYTE_2_3_3_REV: 08175 dstImage = (GLubyte *)malloc(memReq); 08176 break; 08177 case GL_UNSIGNED_SHORT_5_6_5: 08178 case GL_UNSIGNED_SHORT_5_6_5_REV: 08179 case GL_UNSIGNED_SHORT_4_4_4_4: 08180 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 08181 case GL_UNSIGNED_SHORT_5_5_5_1: 08182 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 08183 dstImage = (GLushort *)malloc(memReq); 08184 break; 08185 case GL_UNSIGNED_INT_8_8_8_8: 08186 case GL_UNSIGNED_INT_8_8_8_8_REV: 08187 case GL_UNSIGNED_INT_10_10_10_2: 08188 case GL_UNSIGNED_INT_2_10_10_10_REV: 08189 dstImage = (GLuint *)malloc(memReq); 08190 break; 08191 default: 08192 return GLU_INVALID_ENUM; /* assertion */ 08193 } 08194 if (dstImage == NULL) { 08195 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 08196 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 08197 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 08198 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 08199 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 08200 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 08201 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 08202 return GLU_OUT_OF_MEMORY; 08203 } 08204 } 08205 /* level userLevel is in srcImage; nothing saved yet */ 08206 level = userLevel; 08207 } 08208 08209 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 08210 if (baseLevel <= level && level <= maxLevel) { 08211 gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth, 08212 0,format, type, (void *)srcImage); 08213 } 08214 level++; /* update current level for the loop */ 08215 for (; level <= levels; level++) { 08216 switch(type) { 08217 case GL_UNSIGNED_BYTE: 08218 if (newDepth > 1) { 08219 halveImage3D(cmpts,extractUbyte,shoveUbyte, 08220 newWidth,newHeight,newDepth, 08221 srcImage,dstImage,elementSize,groupSize,rowSize, 08222 imageSize,myswapBytes); 08223 } 08224 else { 08225 halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage, 08226 elementSize,rowSize,groupSize); 08227 } 08228 break; 08229 case GL_BYTE: 08230 if (newDepth > 1) { 08231 halveImage3D(cmpts,extractSbyte,shoveSbyte, 08232 newWidth,newHeight,newDepth, 08233 srcImage,dstImage,elementSize,groupSize,rowSize, 08234 imageSize,myswapBytes); 08235 } 08236 else { 08237 halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage, 08238 elementSize,rowSize,groupSize); 08239 } 08240 break; 08241 case GL_UNSIGNED_SHORT: 08242 if (newDepth > 1) { 08243 halveImage3D(cmpts,extractUshort,shoveUshort, 08244 newWidth,newHeight,newDepth, 08245 srcImage,dstImage,elementSize,groupSize,rowSize, 08246 imageSize,myswapBytes); 08247 } 08248 else { 08249 halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage, 08250 elementSize,rowSize,groupSize,myswapBytes); 08251 } 08252 break; 08253 case GL_SHORT: 08254 if (newDepth > 1) { 08255 halveImage3D(cmpts,extractSshort,shoveSshort, 08256 newWidth,newHeight,newDepth, 08257 srcImage,dstImage,elementSize,groupSize,rowSize, 08258 imageSize,myswapBytes); 08259 } 08260 else { 08261 halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage, 08262 elementSize,rowSize,groupSize,myswapBytes); 08263 } 08264 break; 08265 case GL_UNSIGNED_INT: 08266 if (newDepth > 1) { 08267 halveImage3D(cmpts,extractUint,shoveUint, 08268 newWidth,newHeight,newDepth, 08269 srcImage,dstImage,elementSize,groupSize,rowSize, 08270 imageSize,myswapBytes); 08271 } 08272 else { 08273 halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage, 08274 elementSize,rowSize,groupSize,myswapBytes); 08275 } 08276 break; 08277 case GL_INT: 08278 if (newDepth > 1) { 08279 halveImage3D(cmpts,extractSint,shoveSint, 08280 newWidth,newHeight,newDepth, 08281 srcImage,dstImage,elementSize,groupSize,rowSize, 08282 imageSize,myswapBytes); 08283 } 08284 else { 08285 halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage, 08286 elementSize,rowSize,groupSize,myswapBytes); 08287 } 08288 break; 08289 case GL_FLOAT: 08290 if (newDepth > 1) { 08291 halveImage3D(cmpts,extractFloat,shoveFloat, 08292 newWidth,newHeight,newDepth, 08293 srcImage,dstImage,elementSize,groupSize,rowSize, 08294 imageSize,myswapBytes); 08295 } 08296 else { 08297 halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage, 08298 elementSize,rowSize,groupSize,myswapBytes); 08299 } 08300 break; 08301 case GL_UNSIGNED_BYTE_3_3_2: 08302 halveImagePackedPixel3D(3,extract332,shove332, 08303 newWidth,newHeight,newDepth, 08304 srcImage,dstImage,elementSize,rowSize, 08305 imageSize,myswapBytes); 08306 break; 08307 case GL_UNSIGNED_BYTE_2_3_3_REV: 08308 halveImagePackedPixel3D(3,extract233rev,shove233rev, 08309 newWidth,newHeight,newDepth, 08310 srcImage,dstImage,elementSize,rowSize, 08311 imageSize,myswapBytes); 08312 break; 08313 case GL_UNSIGNED_SHORT_5_6_5: 08314 halveImagePackedPixel3D(3,extract565,shove565, 08315 newWidth,newHeight,newDepth, 08316 srcImage,dstImage,elementSize,rowSize, 08317 imageSize,myswapBytes); 08318 break; 08319 case GL_UNSIGNED_SHORT_5_6_5_REV: 08320 halveImagePackedPixel3D(3,extract565rev,shove565rev, 08321 newWidth,newHeight,newDepth, 08322 srcImage,dstImage,elementSize,rowSize, 08323 imageSize,myswapBytes); 08324 break; 08325 case GL_UNSIGNED_SHORT_4_4_4_4: 08326 halveImagePackedPixel3D(4,extract4444,shove4444, 08327 newWidth,newHeight,newDepth, 08328 srcImage,dstImage,elementSize,rowSize, 08329 imageSize,myswapBytes); 08330 break; 08331 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 08332 halveImagePackedPixel3D(4,extract4444rev,shove4444rev, 08333 newWidth,newHeight,newDepth, 08334 srcImage,dstImage,elementSize,rowSize, 08335 imageSize,myswapBytes); 08336 break; 08337 case GL_UNSIGNED_SHORT_5_5_5_1: 08338 halveImagePackedPixel3D(4,extract5551,shove5551, 08339 newWidth,newHeight,newDepth, 08340 srcImage,dstImage,elementSize,rowSize, 08341 imageSize,myswapBytes); 08342 break; 08343 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 08344 halveImagePackedPixel3D(4,extract1555rev,shove1555rev, 08345 newWidth,newHeight,newDepth, 08346 srcImage,dstImage,elementSize,rowSize, 08347 imageSize,myswapBytes); 08348 break; 08349 case GL_UNSIGNED_INT_8_8_8_8: 08350 halveImagePackedPixel3D(4,extract8888,shove8888, 08351 newWidth,newHeight,newDepth, 08352 srcImage,dstImage,elementSize,rowSize, 08353 imageSize,myswapBytes); 08354 break; 08355 case GL_UNSIGNED_INT_8_8_8_8_REV: 08356 halveImagePackedPixel3D(4,extract8888rev,shove8888rev, 08357 newWidth,newHeight,newDepth, 08358 srcImage,dstImage,elementSize,rowSize, 08359 imageSize,myswapBytes); 08360 break; 08361 case GL_UNSIGNED_INT_10_10_10_2: 08362 halveImagePackedPixel3D(4,extract1010102,shove1010102, 08363 newWidth,newHeight,newDepth, 08364 srcImage,dstImage,elementSize,rowSize, 08365 imageSize,myswapBytes); 08366 break; 08367 case GL_UNSIGNED_INT_2_10_10_10_REV: 08368 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, 08369 newWidth,newHeight,newDepth, 08370 srcImage,dstImage,elementSize,rowSize, 08371 imageSize,myswapBytes); 08372 break; 08373 default: 08374 assert(0); 08375 break; 08376 } 08377 08378 __GLU_SWAP_IMAGE(srcImage,dstImage); 08379 08380 if (newWidth > 1) { newWidth /= 2; rowSize /= 2;} 08381 if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; } 08382 if (newDepth > 1) newDepth /= 2; 08383 { 08384 /* call tex image with srcImage untouched since it's not padded */ 08385 if (baseLevel <= level && level <= maxLevel) { 08386 gluTexImage3D(target, level, internalFormat, newWidth, newHeight, 08387 newDepth,0, format, type, (void *) srcImage); 08388 } 08389 } 08390 } /* for level */ 08391 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); 08392 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); 08393 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); 08394 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); 08395 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); 08396 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); 08397 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); 08398 08399 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ 08400 if (dstImage) { /* if it's non-rectangular and only 1 level */ 08401 free(dstImage); 08402 } 08403 return 0; 08404 } /* gluBuild3DMipmapLevelsCore() */ 08405 08406 GLint GLAPIENTRY 08407 gluBuild3DMipmapLevels(GLenum target, GLint internalFormat, 08408 GLsizei width, GLsizei height, GLsizei depth, 08409 GLenum format, GLenum type, 08410 GLint userLevel, GLint baseLevel, GLint maxLevel, 08411 const void *data) 08412 { 08413 int level, levels; 08414 08415 int rc= checkMipmapArgs(internalFormat,format,type); 08416 if (rc != 0) return rc; 08417 08418 if (width < 1 || height < 1 || depth < 1) { 08419 return GLU_INVALID_VALUE; 08420 } 08421 08422 if(type == GL_BITMAP) { 08423 return GLU_INVALID_ENUM; 08424 } 08425 08426 levels = computeLog(width); 08427 level = computeLog(height); 08428 if (level > levels) levels=level; 08429 level = computeLog(depth); 08430 if (level > levels) levels=level; 08431 08432 levels+= userLevel; 08433 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) 08434 return GLU_INVALID_VALUE; 08435 08436 return gluBuild3DMipmapLevelsCore(target, internalFormat, 08437 width, height, depth, 08438 width, height, depth, 08439 format, type, 08440 userLevel, baseLevel, maxLevel, 08441 data); 08442 } /* gluBuild3DMipmapLevels() */ 08443 08444 GLint GLAPIENTRY 08445 gluBuild3DMipmaps(GLenum target, GLint internalFormat, 08446 GLsizei width, GLsizei height, GLsizei depth, 08447 GLenum format, GLenum type, const void *data) 08448 { 08449 GLint widthPowerOf2, heightPowerOf2, depthPowerOf2; 08450 int level, levels; 08451 08452 int rc= checkMipmapArgs(internalFormat,format,type); 08453 if (rc != 0) return rc; 08454 08455 if (width < 1 || height < 1 || depth < 1) { 08456 return GLU_INVALID_VALUE; 08457 } 08458 08459 if(type == GL_BITMAP) { 08460 return GLU_INVALID_ENUM; 08461 } 08462 08463 closestFit3D(target,width,height,depth,internalFormat,format,type, 08464 &widthPowerOf2,&heightPowerOf2,&depthPowerOf2); 08465 08466 levels = computeLog(widthPowerOf2); 08467 level = computeLog(heightPowerOf2); 08468 if (level > levels) levels=level; 08469 level = computeLog(depthPowerOf2); 08470 if (level > levels) levels=level; 08471 08472 return gluBuild3DMipmapLevelsCore(target, internalFormat, 08473 width, height, depth, 08474 widthPowerOf2, heightPowerOf2, 08475 depthPowerOf2, 08476 format, type, 0, 0, levels, 08477 data); 08478 } /* gluBuild3DMipmaps() */ 08479 08480 static GLdouble extractUbyte(int isSwap, const void *ubyte) 08481 { 08482 isSwap= isSwap; /* turn off warnings */ 08483 08484 return (GLdouble)(*((const GLubyte *)ubyte)); 08485 } /* extractUbyte() */ 08486 08487 static void shoveUbyte(GLdouble value, int index, void *data) 08488 { 08489 assert(0.0 <= value && value < 256.0); 08490 08491 ((GLubyte *)data)[index]= (GLubyte)value; 08492 } /* shoveUbyte() */ 08493 08494 static GLdouble extractSbyte(int isSwap, const void *sbyte) 08495 { 08496 isSwap= isSwap; /* turn off warnings */ 08497 08498 return (GLdouble)(*((const GLbyte *)sbyte)); 08499 } /* extractSbyte() */ 08500 08501 static void shoveSbyte(GLdouble value, int index, void *data) 08502 { 08503 ((GLbyte *)data)[index]= (GLbyte)value; 08504 } /* shoveSbyte() */ 08505 08506 static GLdouble extractUshort(int isSwap, const void *uitem) 08507 { 08508 GLushort ushort; 08509 08510 if (isSwap) { 08511 ushort= __GLU_SWAP_2_BYTES(uitem); 08512 } 08513 else { 08514 ushort= *(const GLushort *)uitem; 08515 } 08516 08517 return (GLdouble)ushort; 08518 } /* extractUshort() */ 08519 08520 static void shoveUshort(GLdouble value, int index, void *data) 08521 { 08522 assert(0.0 <= value && value < 65536.0); 08523 08524 ((GLushort *)data)[index]= (GLushort)value; 08525 } /* shoveUshort() */ 08526 08527 static GLdouble extractSshort(int isSwap, const void *sitem) 08528 { 08529 GLshort sshort; 08530 08531 if (isSwap) { 08532 sshort= __GLU_SWAP_2_BYTES(sitem); 08533 } 08534 else { 08535 sshort= *(const GLshort *)sitem; 08536 } 08537 08538 return (GLdouble)sshort; 08539 } /* extractSshort() */ 08540 08541 static void shoveSshort(GLdouble value, int index, void *data) 08542 { 08543 assert(0.0 <= value && value < 32768.0); 08544 08545 ((GLshort *)data)[index]= (GLshort)value; 08546 } /* shoveSshort() */ 08547 08548 static GLdouble extractUint(int isSwap, const void *uitem) 08549 { 08550 GLuint uint; 08551 08552 if (isSwap) { 08553 uint= __GLU_SWAP_4_BYTES(uitem); 08554 } 08555 else { 08556 uint= *(const GLuint *)uitem; 08557 } 08558 08559 assert(uint <= 0xffffffff); 08560 08561 return (GLdouble)uint; 08562 } /* extractUint() */ 08563 08564 static void shoveUint(GLdouble value, int index, void *data) 08565 { 08566 assert(0.0 <= value && value <= (GLdouble) UINT_MAX); 08567 08568 ((GLuint *)data)[index]= (GLuint)value; 08569 } /* shoveUint() */ 08570 08571 static GLdouble extractSint(int isSwap, const void *sitem) 08572 { 08573 GLint sint; 08574 08575 if (isSwap) { 08576 sint= __GLU_SWAP_4_BYTES(sitem); 08577 } 08578 else { 08579 sint= *(const GLint *)sitem; 08580 } 08581 08582 assert(sint <= 0x7fffffff); 08583 08584 return (GLdouble)sint; 08585 } /* extractSint() */ 08586 08587 static void shoveSint(GLdouble value, int index, void *data) 08588 { 08589 assert(0.0 <= value && value <= (GLdouble) INT_MAX); 08590 08591 ((GLint *)data)[index]= (GLint)value; 08592 } /* shoveSint() */ 08593 08594 static GLdouble extractFloat(int isSwap, const void *item) 08595 { 08596 GLfloat ffloat; 08597 08598 if (isSwap) { 08599 ffloat= __GLU_SWAP_4_BYTES(item); 08600 } 08601 else { 08602 ffloat= *(const GLfloat *)item; 08603 } 08604 08605 assert(ffloat <= 1.0); 08606 08607 return (GLdouble)ffloat; 08608 } /* extractFloat() */ 08609 08610 static void shoveFloat(GLdouble value, int index, void *data) 08611 { 08612 assert(0.0 <= value && value <= 1.0); 08613 08614 ((GLfloat *)data)[index]= value; 08615 } /* shoveFloat() */ 08616 08617 static void halveImageSlice(int components, 08618 GLdouble (*extract)(int, const void *), 08619 void (*shove)(GLdouble, int, void *), 08620 GLint width, GLint height, GLint depth, 08621 const void *dataIn, void *dataOut, 08622 GLint elementSizeInBytes, 08623 GLint groupSizeInBytes, 08624 GLint rowSizeInBytes, 08625 GLint imageSizeInBytes, 08626 GLint isSwap) 08627 { 08628 int ii, jj; 08629 int halfWidth= width / 2; 08630 int halfHeight= height / 2; 08631 int halfDepth= depth / 2; 08632 const char *src= (const char *)dataIn; 08633 int padBytes= rowSizeInBytes - (width * groupSizeInBytes); 08634 int outIndex= 0; 08635 08636 assert((width == 1 || height == 1) && depth >= 2); 08637 08638 if (width == height) { /* a 1-pixel column viewed from top */ 08639 /* printf("1-column\n");*/ 08640 assert(width == 1 && height == 1); 08641 assert(depth >= 2); 08642 08643 for (ii= 0; ii< halfDepth; ii++) { 08644 int cc; 08645 08646 for (cc = 0; cc < components; cc++) { 08647 double totals[4]; 08648 double extractTotals[BOX2][4]; 08649 int kk; 08650 08651 extractTotals[0][cc]= (*extract)(isSwap,src); 08652 extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes)); 08653 08654 /* average 2 pixels since only a column */ 08655 totals[cc]= 0.0; 08656 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; 08657 * totals[RED]/= 2.0; 08658 */ 08659 for (kk = 0; kk < BOX2; kk++) { 08660 totals[cc]+= extractTotals[kk][cc]; 08661 } 08662 totals[cc]/= (double)BOX2; 08663 08664 (*shove)(totals[cc],outIndex,dataOut); 08665 outIndex++; 08666 src+= elementSizeInBytes; 08667 } /* for cc */ 08668 08669 /* skip over to next group of 2 */ 08670 src+= rowSizeInBytes; 08671 } /* for ii */ 08672 08673 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 08674 assert(outIndex == halfDepth * components); 08675 } 08676 else if (height == 1) { /* horizontal slice viewed from top */ 08677 /* printf("horizontal slice\n"); */ 08678 assert(width != 1); 08679 08680 for (ii= 0; ii< halfDepth; ii++) { 08681 for (jj= 0; jj< halfWidth; jj++) { 08682 int cc; 08683 08684 for (cc = 0; cc < components; cc++) { 08685 int kk; 08686 double totals[4]; 08687 double extractTotals[BOX4][4]; 08688 08689 extractTotals[0][cc]=(*extract)(isSwap,src); 08690 extractTotals[1][cc]=(*extract)(isSwap, 08691 (src+groupSizeInBytes)); 08692 extractTotals[2][cc]=(*extract)(isSwap, 08693 (src+imageSizeInBytes)); 08694 extractTotals[3][cc]=(*extract)(isSwap, 08695 (src+imageSizeInBytes+groupSizeInBytes)); 08696 08697 /* grab 4 pixels to average */ 08698 totals[cc]= 0.0; 08699 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 08700 * extractTotals[2][RED]+extractTotals[3][RED]; 08701 * totals[RED]/= 4.0; 08702 */ 08703 for (kk = 0; kk < BOX4; kk++) { 08704 totals[cc]+= extractTotals[kk][cc]; 08705 } 08706 totals[cc]/= (double)BOX4; 08707 08708 (*shove)(totals[cc],outIndex,dataOut); 08709 outIndex++; 08710 08711 src+= elementSizeInBytes; 08712 } /* for cc */ 08713 08714 /* skip over to next horizontal square of 4 */ 08715 src+= groupSizeInBytes; 08716 } /* for jj */ 08717 src+= padBytes; 08718 08719 src+= rowSizeInBytes; 08720 } /* for ii */ 08721 08722 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 08723 assert(outIndex == halfWidth * halfDepth * components); 08724 } 08725 else if (width == 1) { /* vertical slice viewed from top */ 08726 /* printf("vertical slice\n"); */ 08727 assert(height != 1); 08728 08729 for (ii= 0; ii< halfDepth; ii++) { 08730 for (jj= 0; jj< halfHeight; jj++) { 08731 int cc; 08732 08733 for (cc = 0; cc < components; cc++) { 08734 int kk; 08735 double totals[4]; 08736 double extractTotals[BOX4][4]; 08737 08738 extractTotals[0][cc]=(*extract)(isSwap,src); 08739 extractTotals[1][cc]=(*extract)(isSwap, 08740 (src+rowSizeInBytes)); 08741 extractTotals[2][cc]=(*extract)(isSwap, 08742 (src+imageSizeInBytes)); 08743 extractTotals[3][cc]=(*extract)(isSwap, 08744 (src+imageSizeInBytes+rowSizeInBytes)); 08745 08746 /* grab 4 pixels to average */ 08747 totals[cc]= 0.0; 08748 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 08749 * extractTotals[2][RED]+extractTotals[3][RED]; 08750 * totals[RED]/= 4.0; 08751 */ 08752 for (kk = 0; kk < BOX4; kk++) { 08753 totals[cc]+= extractTotals[kk][cc]; 08754 } 08755 totals[cc]/= (double)BOX4; 08756 08757 (*shove)(totals[cc],outIndex,dataOut); 08758 outIndex++; 08759 08760 src+= elementSizeInBytes; 08761 } /* for cc */ 08762 src+= padBytes; 08763 08764 /* skip over to next vertical square of 4 */ 08765 src+= rowSizeInBytes; 08766 } /* for jj */ 08767 08768 src+= imageSizeInBytes; 08769 } /* for ii */ 08770 08771 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 08772 assert(outIndex == halfHeight * halfDepth * components); 08773 } 08774 08775 } /* halveImageSlice() */ 08776 08777 static void halveImage3D(int components, 08778 GLdouble (*extract)(int, const void *), 08779 void (*shove)(GLdouble, int, void *), 08780 GLint width, GLint height, GLint depth, 08781 const void *dataIn, void *dataOut, 08782 GLint elementSizeInBytes, 08783 GLint groupSizeInBytes, 08784 GLint rowSizeInBytes, 08785 GLint imageSizeInBytes, 08786 GLint isSwap) 08787 { 08788 assert(depth > 1); 08789 08790 /* a horizontal/vertical/one-column slice viewed from top */ 08791 if (width == 1 || height == 1) { 08792 assert(1 <= depth); 08793 08794 halveImageSlice(components,extract,shove, width, height, depth, 08795 dataIn, dataOut, elementSizeInBytes, groupSizeInBytes, 08796 rowSizeInBytes, imageSizeInBytes, isSwap); 08797 return; 08798 } 08799 { 08800 int ii, jj, dd; 08801 08802 int halfWidth= width / 2; 08803 int halfHeight= height / 2; 08804 int halfDepth= depth / 2; 08805 const char *src= (const char *) dataIn; 08806 int padBytes= rowSizeInBytes - (width*groupSizeInBytes); 08807 int outIndex= 0; 08808 08809 for (dd= 0; dd < halfDepth; dd++) { 08810 for (ii= 0; ii< halfHeight; ii++) { 08811 for (jj= 0; jj< halfWidth; jj++) { 08812 int cc; 08813 08814 for (cc= 0; cc < components; cc++) { 08815 int kk; 08816 #define BOX8 8 08817 double totals[4]; /* 4 is maximum components */ 08818 double extractTotals[BOX8][4]; /* 4 is maximum components */ 08819 08820 extractTotals[0][cc]= (*extract)(isSwap,src); 08821 extractTotals[1][cc]= (*extract)(isSwap, 08822 (src+groupSizeInBytes)); 08823 extractTotals[2][cc]= (*extract)(isSwap, 08824 (src+rowSizeInBytes)); 08825 extractTotals[3][cc]= (*extract)(isSwap, 08826 (src+rowSizeInBytes+groupSizeInBytes)); 08827 08828 extractTotals[4][cc]= (*extract)(isSwap, 08829 (src+imageSizeInBytes)); 08830 08831 extractTotals[5][cc]= (*extract)(isSwap, 08832 (src+groupSizeInBytes+imageSizeInBytes)); 08833 extractTotals[6][cc]= (*extract)(isSwap, 08834 (src+rowSizeInBytes+imageSizeInBytes)); 08835 extractTotals[7][cc]= (*extract)(isSwap, 08836 (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes)); 08837 08838 totals[cc]= 0.0; 08839 08840 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ 08841 * extractTotals[2][RED]+extractTotals[3][RED]+ 08842 * extractTotals[4][RED]+extractTotals[5][RED]+ 08843 * extractTotals[6][RED]+extractTotals[7][RED]; 08844 * totals[RED]/= 8.0; 08845 */ 08846 for (kk = 0; kk < BOX8; kk++) { 08847 totals[cc]+= extractTotals[kk][cc]; 08848 } 08849 totals[cc]/= (double)BOX8; 08850 08851 (*shove)(totals[cc],outIndex,dataOut); 08852 08853 outIndex++; 08854 08855 src+= elementSizeInBytes; /* go to next component */ 08856 } /* for cc */ 08857 08858 /* skip over to next square of 4 */ 08859 src+= groupSizeInBytes; 08860 } /* for jj */ 08861 /* skip past pad bytes, if any, to get to next row */ 08862 src+= padBytes; 08863 08864 /* src is at beginning of a row here, but it's the second row of 08865 * the square block of 4 pixels that we just worked on so we 08866 * need to go one more row. 08867 * i.e., 08868 * OO... 08869 * here -->OO... 08870 * but want -->OO... 08871 * OO... 08872 * ... 08873 */ 08874 src+= rowSizeInBytes; 08875 } /* for ii */ 08876 08877 src+= imageSizeInBytes; 08878 } /* for dd */ 08879 08880 /* both pointers must reach one byte after the end */ 08881 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); 08882 assert(outIndex == halfWidth * halfHeight * halfDepth * components); 08883 } 08884 } /* halveImage3D() */ 08885 08886 08887 08888 /*** mipmap.c ***/ 08889 Generated on Wed May 23 2012 04:18:29 for ReactOS by
1.7.6.1
|