| /* |
| * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) |
| * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice including the dates of first publication and |
| * either this permission notice or a reference to |
| * http://oss.sgi.com/projects/FreeB/ |
| * shall be included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
| * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * Except as contained in this notice, the name of Silicon Graphics, Inc. |
| * shall not be used in advertising or otherwise to promote the sale, use or |
| * other dealings in this Software without prior written authorization from |
| * Silicon Graphics, Inc. |
| */ |
| |
| #include "config.h" |
| #include "wine/port.h" |
| |
| #include <assert.h> |
| #include <stdarg.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <limits.h> |
| #include <math.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wine/wgl.h" |
| #include "wine/glu.h" |
| |
| #define GLU_INVALID_OPERATION GLU_INVALID_VALUE /* GLU_INVALID_OPERATION is missing on Windows */ |
| |
| typedef union { |
| unsigned char ub[4]; |
| unsigned short us[2]; |
| unsigned int ui; |
| char b[4]; |
| short s[2]; |
| int i; |
| float f; |
| } Type_Widget; |
| |
| /* Pixel storage modes */ |
| typedef struct { |
| GLint pack_alignment; |
| GLint pack_row_length; |
| GLint pack_skip_rows; |
| GLint pack_skip_pixels; |
| GLint pack_lsb_first; |
| GLint pack_swap_bytes; |
| GLint pack_skip_images; |
| GLint pack_image_height; |
| |
| GLint unpack_alignment; |
| GLint unpack_row_length; |
| GLint unpack_skip_rows; |
| GLint unpack_skip_pixels; |
| GLint unpack_lsb_first; |
| GLint unpack_swap_bytes; |
| GLint unpack_skip_images; |
| GLint unpack_image_height; |
| } PixelStorageModes; |
| |
| static int gluBuild1DMipmapLevelsCore(GLenum, GLint, |
| GLsizei, |
| GLsizei, |
| GLenum, GLenum, GLint, GLint, GLint, |
| const void *); |
| static int gluBuild2DMipmapLevelsCore(GLenum, GLint, |
| GLsizei, GLsizei, |
| GLsizei, GLsizei, |
| GLenum, GLenum, GLint, GLint, GLint, |
| const void *); |
| |
| /* |
| * internal function declarations |
| */ |
| static GLfloat bytes_per_element(GLenum type); |
| static GLint elements_per_group(GLenum format, GLenum type); |
| static GLint is_index(GLenum format); |
| static GLint image_size(GLint width, GLint height, GLenum format, GLenum type); |
| static void fill_image(const PixelStorageModes *, |
| GLint width, GLint height, GLenum format, |
| GLenum type, GLboolean index_format, |
| const void *userdata, GLushort *newimage); |
| static void empty_image(const PixelStorageModes *, |
| GLint width, GLint height, GLenum format, |
| GLenum type, GLboolean index_format, |
| const GLushort *oldimage, void *userdata); |
| static void scale_internal(GLint components, GLint widthin, GLint heightin, |
| const GLushort *datain, |
| GLint widthout, GLint heightout, |
| GLushort *dataout); |
| |
| static void scale_internal_ubyte(GLint components, GLint widthin, |
| GLint heightin, const GLubyte *datain, |
| GLint widthout, GLint heightout, |
| GLubyte *dataout, GLint element_size, |
| GLint ysize, GLint group_size); |
| static void scale_internal_byte(GLint components, GLint widthin, |
| GLint heightin, const GLbyte *datain, |
| GLint widthout, GLint heightout, |
| GLbyte *dataout, GLint element_size, |
| GLint ysize, GLint group_size); |
| static void scale_internal_ushort(GLint components, GLint widthin, |
| GLint heightin, const GLushort *datain, |
| GLint widthout, GLint heightout, |
| GLushort *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes); |
| static void scale_internal_short(GLint components, GLint widthin, |
| GLint heightin, const GLshort *datain, |
| GLint widthout, GLint heightout, |
| GLshort *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes); |
| static void scale_internal_uint(GLint components, GLint widthin, |
| GLint heightin, const GLuint *datain, |
| GLint widthout, GLint heightout, |
| GLuint *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes); |
| static void scale_internal_int(GLint components, GLint widthin, |
| GLint heightin, const GLint *datain, |
| GLint widthout, GLint heightout, |
| GLint *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes); |
| static void scale_internal_float(GLint components, GLint widthin, |
| GLint heightin, const GLfloat *datain, |
| GLint widthout, GLint heightout, |
| GLfloat *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes); |
| |
| static int checkMipmapArgs(GLenum, GLenum, GLenum); |
| static GLboolean legalFormat(GLenum); |
| static GLboolean legalType(GLenum); |
| static GLboolean isTypePackedPixel(GLenum); |
| static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum); |
| static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum, |
| GLint *, GLint *); |
| |
| /* packedpixel type scale routines */ |
| static void extract332(int,const void *, GLfloat []); |
| static void shove332(const GLfloat [],int ,void *); |
| static void extract233rev(int,const void *, GLfloat []); |
| static void shove233rev(const GLfloat [],int ,void *); |
| static void extract565(int,const void *, GLfloat []); |
| static void shove565(const GLfloat [],int ,void *); |
| static void extract565rev(int,const void *, GLfloat []); |
| static void shove565rev(const GLfloat [],int ,void *); |
| static void extract4444(int,const void *, GLfloat []); |
| static void shove4444(const GLfloat [],int ,void *); |
| static void extract4444rev(int,const void *, GLfloat []); |
| static void shove4444rev(const GLfloat [],int ,void *); |
| static void extract5551(int,const void *, GLfloat []); |
| static void shove5551(const GLfloat [],int ,void *); |
| static void extract1555rev(int,const void *, GLfloat []); |
| static void shove1555rev(const GLfloat [],int ,void *); |
| static void extract8888(int,const void *, GLfloat []); |
| static void shove8888(const GLfloat [],int ,void *); |
| static void extract8888rev(int,const void *, GLfloat []); |
| static void shove8888rev(const GLfloat [],int ,void *); |
| static void extract1010102(int,const void *, GLfloat []); |
| static void shove1010102(const GLfloat [],int ,void *); |
| static void extract2101010rev(int,const void *, GLfloat []); |
| static void shove2101010rev(const GLfloat [],int ,void *); |
| static void scaleInternalPackedPixel(int, |
| void (*)(int, const void *,GLfloat []), |
| void (*)(const GLfloat [],int, void *), |
| GLint,GLint, const void *, |
| GLint,GLint,void *,GLint,GLint,GLint); |
| static void halveImagePackedPixel(int, |
| void (*)(int, const void *,GLfloat []), |
| void (*)(const GLfloat [],int, void *), |
| GLint, GLint, const void *, |
| void *, GLint, GLint, GLint); |
| static void halve1DimagePackedPixel(int, |
| void (*)(int, const void *,GLfloat []), |
| void (*)(const GLfloat [],int, void *), |
| GLint, GLint, const void *, |
| void *, GLint, GLint, GLint); |
| |
| static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *, |
| GLubyte *, GLint, GLint, GLint); |
| static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *, |
| GLint, GLint, GLint); |
| static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *, |
| GLushort *, GLint, GLint, GLint, GLint); |
| static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *, |
| GLint, GLint, GLint, GLint); |
| static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *, |
| GLint, GLint, GLint, GLint); |
| static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *, |
| GLint, GLint, GLint, GLint); |
| static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *, |
| GLint, GLint, GLint, GLint); |
| |
| static void retrieveStoreModes(PixelStorageModes *psm) |
| { |
| glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment); |
| glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length); |
| glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows); |
| glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels); |
| glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first); |
| glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes); |
| |
| glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment); |
| glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length); |
| glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows); |
| glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels); |
| glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first); |
| glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes); |
| } |
| |
| static int computeLog(GLuint value) |
| { |
| int i; |
| |
| i = 0; |
| |
| /* Error! */ |
| if (value == 0) return -1; |
| |
| for (;;) { |
| if (value & 1) { |
| /* Error ! */ |
| if (value != 1) return -1; |
| return i; |
| } |
| value = value >> 1; |
| i++; |
| } |
| } |
| |
| /* |
| ** Compute the nearest power of 2 number. This algorithm is a little |
| ** strange, but it works quite well. |
| */ |
| static int nearestPower(GLuint value) |
| { |
| int i; |
| |
| i = 1; |
| |
| /* Error! */ |
| if (value == 0) return -1; |
| |
| for (;;) { |
| if (value == 1) { |
| return i; |
| } else if (value == 3) { |
| return i*4; |
| } |
| value = value >> 1; |
| i *= 2; |
| } |
| } |
| |
| #define __GLU_SWAP_2_BYTES(s)\ |
| (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) |
| |
| #define __GLU_SWAP_4_BYTES(s)\ |
| (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \ |
| ((GLuint)((const GLubyte*)(s))[2])<<16 | \ |
| ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) |
| |
| static void halveImage(GLint components, GLuint width, GLuint height, |
| const GLushort *datain, GLushort *dataout) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int delta; |
| GLushort *s; |
| const GLushort *t; |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| delta = width * components; |
| s = dataout; |
| t = datain; |
| |
| /* Piece o' cake! */ |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (t[0] + t[components] + t[delta] + |
| t[delta+components] + 2) / 4; |
| s++; t++; |
| } |
| t += components; |
| } |
| t += delta; |
| } |
| } |
| |
| static void halveImage_ubyte(GLint components, GLuint width, GLuint height, |
| const GLubyte *datain, GLubyte *dataout, |
| GLint element_size, GLint ysize, GLint group_size) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLubyte *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_ubyte(components,width,height,datain,dataout, |
| element_size,ysize,group_size); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (*(const GLubyte*)t + |
| *(const GLubyte*)(t+group_size) + |
| *(const GLubyte*)(t+ysize) + |
| *(const GLubyte*)(t+ysize+group_size) + 2) / 4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| /* */ |
| static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height, |
| const GLubyte *dataIn, GLubyte *dataOut, |
| GLint element_size, GLint ysize, |
| GLint group_size) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLubyte *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| *dest= (*(const GLubyte*)src + |
| *(const GLubyte*)(src+group_size)) / 2; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; |
| } |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| } /* halve1Dimage_ubyte() */ |
| |
| static void halveImage_byte(GLint components, GLuint width, GLuint height, |
| const GLbyte *datain, GLbyte *dataout, |
| GLint element_size, |
| GLint ysize, GLint group_size) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLbyte *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_byte(components,width,height,datain,dataout, |
| element_size,ysize,group_size); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (*(const GLbyte*)t + |
| *(const GLbyte*)(t+group_size) + |
| *(const GLbyte*)(t+ysize) + |
| *(const GLbyte*)(t+ysize+group_size) + 2) / 4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| static void halve1Dimage_byte(GLint components, GLuint width, GLuint height, |
| const GLbyte *dataIn, GLbyte *dataOut, |
| GLint element_size,GLint ysize, GLint group_size) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLbyte *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| } |
| |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| } /* halve1Dimage_byte() */ |
| |
| static void halveImage_ushort(GLint components, GLuint width, GLuint height, |
| const GLushort *datain, GLushort *dataout, |
| GLint element_size, GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLushort *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_ushort(components,width,height,datain,dataout, |
| element_size,ysize,group_size, myswap_bytes); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| if (!myswap_bytes) |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (*(const GLushort*)t + |
| *(const GLushort*)(t+group_size) + |
| *(const GLushort*)(t+ysize) + |
| *(const GLushort*)(t+ysize+group_size) + 2) / 4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| else |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (__GLU_SWAP_2_BYTES(t) + |
| __GLU_SWAP_2_BYTES(t+group_size) + |
| __GLU_SWAP_2_BYTES(t+ysize) + |
| __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height, |
| const GLushort *dataIn, GLushort *dataOut, |
| GLint element_size, GLint ysize, |
| GLint group_size, GLint myswap_bytes) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLushort *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLushort ushort[BOX2]; |
| if (myswap_bytes) { |
| ushort[0]= __GLU_SWAP_2_BYTES(src); |
| ushort[1]= __GLU_SWAP_2_BYTES(src+group_size); |
| } |
| else { |
| ushort[0]= *(const GLushort*)src; |
| ushort[1]= *(const GLushort*)(src+group_size); |
| } |
| |
| *dest= (ushort[0] + ushort[1]) / 2; |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLushort ushort[BOX2]; |
| if (myswap_bytes) { |
| ushort[0]= __GLU_SWAP_2_BYTES(src); |
| ushort[1]= __GLU_SWAP_2_BYTES(src+ysize); |
| } |
| else { |
| ushort[0]= *(const GLushort*)src; |
| ushort[1]= *(const GLushort*)(src+ysize); |
| } |
| *dest= (ushort[0] + ushort[1]) / 2; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| } |
| |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| |
| } /* halve1Dimage_ushort() */ |
| |
| |
| static void halveImage_short(GLint components, GLuint width, GLuint height, |
| const GLshort *datain, GLshort *dataout, |
| GLint element_size, GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLshort *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_short(components,width,height,datain,dataout, |
| element_size,ysize,group_size, myswap_bytes); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| if (!myswap_bytes) |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (*(const GLshort*)t + |
| *(const GLshort*)(t+group_size) + |
| *(const GLshort*)(t+ysize) + |
| *(const GLshort*)(t+ysize+group_size) + 2) / 4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| else |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| GLushort b; |
| GLint buf; |
| b = __GLU_SWAP_2_BYTES(t); |
| buf = *(const GLshort*)&b; |
| b = __GLU_SWAP_2_BYTES(t+group_size); |
| buf += *(const GLshort*)&b; |
| b = __GLU_SWAP_2_BYTES(t+ysize); |
| buf += *(const GLshort*)&b; |
| b = __GLU_SWAP_2_BYTES(t+ysize+group_size); |
| buf += *(const GLshort*)&b; |
| s[0] = (GLshort)((buf+2)/4); |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| static void halve1Dimage_short(GLint components, GLuint width, GLuint height, |
| const GLshort *dataIn, GLshort *dataOut, |
| GLint element_size, GLint ysize, |
| GLint group_size, GLint myswap_bytes) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLshort *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLshort sshort[BOX2]; |
| if (myswap_bytes) { |
| sshort[0]= __GLU_SWAP_2_BYTES(src); |
| sshort[1]= __GLU_SWAP_2_BYTES(src+group_size); |
| } |
| else { |
| sshort[0]= *(const GLshort*)src; |
| sshort[1]= *(const GLshort*)(src+group_size); |
| } |
| |
| *dest= (sshort[0] + sshort[1]) / 2; |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLshort sshort[BOX2]; |
| if (myswap_bytes) { |
| sshort[0]= __GLU_SWAP_2_BYTES(src); |
| sshort[1]= __GLU_SWAP_2_BYTES(src+ysize); |
| } |
| else { |
| sshort[0]= *(const GLshort*)src; |
| sshort[1]= *(const GLshort*)(src+ysize); |
| } |
| *dest= (sshort[0] + sshort[1]) / 2; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| } |
| |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| |
| } /* halve1Dimage_short() */ |
| |
| |
| static void halveImage_uint(GLint components, GLuint width, GLuint height, |
| const GLuint *datain, GLuint *dataout, |
| GLint element_size, GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLuint *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_uint(components,width,height,datain,dataout, |
| element_size,ysize,group_size, myswap_bytes); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| if (!myswap_bytes) |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| /* need to cast to double to hold large unsigned ints */ |
| s[0] = ((double)*(const GLuint*)t + |
| (double)*(const GLuint*)(t+group_size) + |
| (double)*(const GLuint*)(t+ysize) + |
| (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5; |
| s++; t += element_size; |
| |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| else |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| /* need to cast to double to hold large unsigned ints */ |
| GLdouble buf; |
| buf = (GLdouble)__GLU_SWAP_4_BYTES(t) + |
| (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) + |
| (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) + |
| (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size); |
| s[0] = (GLuint)(buf/4 + 0.5); |
| |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| /* */ |
| static void halve1Dimage_uint(GLint components, GLuint width, GLuint height, |
| const GLuint *dataIn, GLuint *dataOut, |
| GLint element_size, GLint ysize, |
| GLint group_size, GLint myswap_bytes) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLuint *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLuint uint[BOX2]; |
| if (myswap_bytes) { |
| uint[0]= __GLU_SWAP_4_BYTES(src); |
| uint[1]= __GLU_SWAP_4_BYTES(src+group_size); |
| } |
| else { |
| uint[0]= *(const GLuint*)src; |
| uint[1]= *(const GLuint*)(src+group_size); |
| } |
| *dest= ((double)uint[0]+(double)uint[1])/2.0; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLuint uint[BOX2]; |
| if (myswap_bytes) { |
| uint[0]= __GLU_SWAP_4_BYTES(src); |
| uint[1]= __GLU_SWAP_4_BYTES(src+ysize); |
| } |
| else { |
| uint[0]= *(const GLuint*)src; |
| uint[1]= *(const GLuint*)(src+ysize); |
| } |
| *dest= ((double)uint[0]+(double)uint[1])/2.0; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| } |
| |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| |
| } /* halve1Dimage_uint() */ |
| |
| static void halveImage_int(GLint components, GLuint width, GLuint height, |
| const GLint *datain, GLint *dataout, GLint element_size, |
| GLint ysize, GLint group_size, GLint myswap_bytes) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLint *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_int(components,width,height,datain,dataout, |
| element_size,ysize,group_size, myswap_bytes); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| if (!myswap_bytes) |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = ((float)*(const GLint*)t + |
| (float)*(const GLint*)(t+group_size) + |
| (float)*(const GLint*)(t+ysize) + |
| (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| else |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| GLuint b; |
| GLfloat buf; |
| b = __GLU_SWAP_4_BYTES(t); |
| buf = *(GLint*)&b; |
| b = __GLU_SWAP_4_BYTES(t+group_size); |
| buf += *(GLint*)&b; |
| b = __GLU_SWAP_4_BYTES(t+ysize); |
| buf += *(GLint*)&b; |
| b = __GLU_SWAP_4_BYTES(t+ysize+group_size); |
| buf += *(GLint*)&b; |
| s[0] = (GLint)(buf/4 + 0.5); |
| |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| /* */ |
| static void halve1Dimage_int(GLint components, GLuint width, GLuint height, |
| const GLint *dataIn, GLint *dataOut, |
| GLint element_size, GLint ysize, |
| GLint group_size, GLint myswap_bytes) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLint *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLuint uint[BOX2]; |
| if (myswap_bytes) { |
| uint[0]= __GLU_SWAP_4_BYTES(src); |
| uint[1]= __GLU_SWAP_4_BYTES(src+group_size); |
| } |
| else { |
| uint[0]= *(const GLuint*)src; |
| uint[1]= *(const GLuint*)(src+group_size); |
| } |
| *dest= ((float)uint[0]+(float)uint[1])/2.0; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLuint uint[BOX2]; |
| if (myswap_bytes) { |
| uint[0]= __GLU_SWAP_4_BYTES(src); |
| uint[1]= __GLU_SWAP_4_BYTES(src+ysize); |
| } |
| else { |
| uint[0]= *(const GLuint*)src; |
| uint[1]= *(const GLuint*)(src+ysize); |
| } |
| *dest= ((float)uint[0]+(float)uint[1])/2.0; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| } |
| |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| |
| } /* halve1Dimage_int() */ |
| |
| |
| static void halveImage_float(GLint components, GLuint width, GLuint height, |
| const GLfloat *datain, GLfloat *dataout, |
| GLint element_size, GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| int i, j, k; |
| int newwidth, newheight; |
| int padBytes; |
| GLfloat *s; |
| const char *t; |
| |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
| halve1Dimage_float(components,width,height,datain,dataout, |
| element_size,ysize,group_size, myswap_bytes); |
| return; |
| } |
| |
| newwidth = width / 2; |
| newheight = height / 2; |
| padBytes = ysize - (width*group_size); |
| s = dataout; |
| t = (const char *)datain; |
| |
| /* Piece o' cake! */ |
| if (!myswap_bytes) |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| s[0] = (*(const GLfloat*)t + |
| *(const GLfloat*)(t+group_size) + |
| *(const GLfloat*)(t+ysize) + |
| *(const GLfloat*)(t+ysize+group_size)) / 4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| else |
| for (i = 0; i < newheight; i++) { |
| for (j = 0; j < newwidth; j++) { |
| for (k = 0; k < components; k++) { |
| union { GLuint b; GLfloat f; } swapbuf; |
| swapbuf.b = __GLU_SWAP_4_BYTES(t); |
| s[0] = swapbuf.f; |
| swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size); |
| s[0] += swapbuf.f; |
| swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize); |
| s[0] += swapbuf.f; |
| swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size); |
| s[0] += swapbuf.f; |
| s[0] /= 4; |
| s++; t += element_size; |
| } |
| t += group_size; |
| } |
| t += padBytes; |
| t += ysize; |
| } |
| } |
| |
| /* */ |
| static void halve1Dimage_float(GLint components, GLuint width, GLuint height, |
| const GLfloat *dataIn, GLfloat *dataOut, |
| GLint element_size, GLint ysize, |
| GLint group_size, GLint myswap_bytes) |
| { |
| GLint halfWidth= width / 2; |
| GLint halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| GLfloat *dest= dataOut; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLfloat sfloat[BOX2]; |
| if (myswap_bytes) { |
| sfloat[0]= __GLU_SWAP_4_BYTES(src); |
| sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size); |
| } |
| else { |
| sfloat[0]= *(const GLfloat*)src; |
| sfloat[1]= *(const GLfloat*)(src+group_size); |
| } |
| |
| *dest= (sfloat[0] + sfloat[1]) / 2.0; |
| src+= element_size; |
| dest++; |
| } |
| src+= group_size; /* skip to next 2 */ |
| } |
| { |
| int padBytes= ysize - (width*group_size); |
| src+= padBytes; /* for assertion only */ |
| } |
| } |
| else if (width == 1) { /* 1 column */ |
| int padBytes= ysize - (width * group_size); |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| int kk; |
| for (kk= 0; kk< components; kk++) { |
| #define BOX2 2 |
| GLfloat sfloat[BOX2]; |
| if (myswap_bytes) { |
| sfloat[0]= __GLU_SWAP_4_BYTES(src); |
| sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize); |
| } |
| else { |
| sfloat[0]= *(const GLfloat*)src; |
| sfloat[1]= *(const GLfloat*)(src+ysize); |
| } |
| *dest= (sfloat[0] + sfloat[1]) / 2.0; |
| |
| src+= element_size; |
| dest++; |
| } |
| src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
| src+= ysize; /* skip to odd row */ |
| } |
| } |
| |
| assert(src == &((const char *)dataIn)[ysize*height]); |
| assert((char *)dest == &((char *)dataOut) |
| [components * element_size * halfWidth * halfHeight]); |
| } /* halve1Dimage_float() */ |
| |
| static void scale_internal(GLint components, GLint widthin, GLint heightin, |
| const GLushort *datain, |
| GLint widthout, GLint heightout, |
| GLushort *dataout) |
| { |
| float x, lowx, highx, convx, halfconvx; |
| float y, lowy, highy, convy, halfconvy; |
| float xpercent,ypercent; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,yint,xint,xindex,yindex; |
| int temp; |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage(components, widthin, heightin, datain, dataout); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| halfconvx = convx/2; |
| halfconvy = convy/2; |
| for (i = 0; i < heightout; i++) { |
| y = convy * (i+0.5); |
| if (heightin > heightout) { |
| highy = y + halfconvy; |
| lowy = y - halfconvy; |
| } else { |
| highy = y + 0.5; |
| lowy = y - 0.5; |
| } |
| for (j = 0; j < widthout; j++) { |
| x = convx * (j+0.5); |
| if (widthin > widthout) { |
| highx = x + halfconvx; |
| lowx = x - halfconvx; |
| } else { |
| highx = x + 0.5; |
| lowx = x - 0.5; |
| } |
| |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| area = 0.0; |
| |
| y = lowy; |
| yint = floor(y); |
| while (y < highy) { |
| yindex = (yint + heightin) % heightin; |
| if (highy < yint+1) { |
| ypercent = highy - y; |
| } else { |
| ypercent = yint+1 - y; |
| } |
| |
| x = lowx; |
| xint = floor(x); |
| |
| while (x < highx) { |
| xindex = (xint + widthin) % widthin; |
| if (highx < xint+1) { |
| xpercent = highx - x; |
| } else { |
| xpercent = xint+1 - x; |
| } |
| |
| percent = xpercent * ypercent; |
| area += percent; |
| temp = (xindex + (yindex * widthin)) * components; |
| for (k = 0; k < components; k++) { |
| totals[k] += datain[temp + k] * percent; |
| } |
| |
| xint++; |
| x = xint; |
| } |
| yint++; |
| y = yint; |
| } |
| |
| temp = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| /* totals[] should be rounded in the case of enlarging an RGB |
| * ramp when the type is 332 or 4444 |
| */ |
| dataout[temp + k] = (totals[k]+0.5)/area; |
| } |
| } |
| } |
| } |
| |
| static void scale_internal_ubyte(GLint components, GLint widthin, |
| GLint heightin, const GLubyte *datain, |
| GLint widthout, GLint heightout, |
| GLubyte *dataout, GLint element_size, |
| GLint ysize, GLint group_size) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_ubyte(components, widthin, heightin, |
| (const GLubyte *)datain, (GLubyte *)dataout, |
| element_size, ysize, group_size); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * y_percent; |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * y_percent; |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| totals[k] += (GLubyte)(*(left))*(1-lowx_float) |
| +(GLubyte)(*(right))*highx_float; |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * x_percent; |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * y_percent; |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)) * percent; |
| } |
| } |
| |
| |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLubyte)(*(temp_index)); |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| static void scale_internal_byte(GLint components, GLint widthin, |
| GLint heightin, const GLbyte *datain, |
| GLint widthout, GLint heightout, |
| GLbyte *dataout, GLint element_size, |
| GLint ysize, GLint group_size) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_byte(components, widthin, heightin, |
| (const GLbyte *)datain, (GLbyte *)dataout, |
| element_size, ysize, group_size); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * y_percent; |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * y_percent; |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| totals[k] += (GLbyte)(*(left))*(1-lowx_float) |
| +(GLbyte)(*(right))*highx_float; |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * x_percent; |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * y_percent; |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)) * percent; |
| } |
| } |
| |
| |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| totals[k] += (GLbyte)(*(temp_index)); |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| static void scale_internal_ushort(GLint components, GLint widthin, |
| GLint heightin, const GLushort *datain, |
| GLint widthout, GLint heightout, |
| GLushort *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_ushort(components, widthin, heightin, |
| (const GLushort *)datain, (GLushort *)dataout, |
| element_size, ysize, group_size, myswap_bytes); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + |
| __GLU_SWAP_2_BYTES(right) * highx_float; |
| } else { |
| totals[k] += *(const GLushort*)left * (1-lowx_float) |
| + *(const GLushort*)right * highx_float; |
| } |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * x_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * x_percent; |
| } |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| } |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index); |
| } else { |
| totals[k] += *(const GLushort*)temp_index; |
| } |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| static void scale_internal_short(GLint components, GLint widthin, |
| GLint heightin, const GLshort *datain, |
| GLint widthout, GLint heightout, |
| GLshort *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| GLushort swapbuf; /* unsigned buffer */ |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_short(components, widthin, heightin, |
| (const GLshort *)datain, (GLshort *)dataout, |
| element_size, ysize, group_size, myswap_bytes); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * y_percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * y_percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(left); |
| totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float); |
| swapbuf = __GLU_SWAP_2_BYTES(right); |
| totals[k] += *(const GLshort*)&swapbuf * highx_float; |
| } else { |
| totals[k] += *(const GLshort*)left * (1-lowx_float) |
| + *(const GLshort*)right * highx_float; |
| } |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * x_percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * x_percent; |
| } |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * y_percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLshort*)temp_index * percent; |
| } |
| } |
| } |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
| totals[k] += *(const GLshort*)&swapbuf; |
| } else { |
| totals[k] += *(const GLshort*)temp_index; |
| } |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| static void scale_internal_uint(GLint components, GLint widthin, |
| GLint heightin, const GLuint *datain, |
| GLint widthout, GLint heightout, |
| GLuint *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_uint(components, widthin, heightin, |
| (const GLuint *)datain, (GLuint *)dataout, |
| element_size, ysize, group_size, myswap_bytes); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_4_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_4_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_4_BYTES(left) * (1-lowx_float) |
| + __GLU_SWAP_4_BYTES(right) * highx_float; |
| } else { |
| totals[k] += *(const GLuint*)left * (1-lowx_float) |
| + *(const GLuint*)right * highx_float; |
| } |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_4_BYTES(temp_index) * x_percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * x_percent; |
| } |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_4_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLuint*)temp_index * percent; |
| } |
| } |
| } |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_4_BYTES(temp_index); |
| } else { |
| totals[k] += *(const GLuint*)temp_index; |
| } |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| /* clamp at UINT_MAX */ |
| float value= totals[k]/area; |
| if (value >= (float) UINT_MAX) { /* need '=' */ |
| dataout[outindex + k] = UINT_MAX; |
| } |
| else dataout[outindex + k] = value; |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| |
| |
| static void scale_internal_int(GLint components, GLint widthin, |
| GLint heightin, const GLint *datain, |
| GLint widthout, GLint heightout, |
| GLint *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| GLuint swapbuf; /* unsigned buffer */ |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_int(components, widthin, heightin, |
| (const GLint *)datain, (GLint *)dataout, |
| element_size, ysize, group_size, myswap_bytes); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * y_percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * y_percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(left); |
| totals[k] += *(const GLint*)&swapbuf * (1-lowx_float); |
| swapbuf = __GLU_SWAP_4_BYTES(right); |
| totals[k] += *(const GLint*)&swapbuf * highx_float; |
| } else { |
| totals[k] += *(const GLint*)left * (1-lowx_float) |
| + *(const GLint*)right * highx_float; |
| } |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * x_percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * x_percent; |
| } |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * y_percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf * percent; |
| } else { |
| totals[k] += *(const GLint*)temp_index * percent; |
| } |
| } |
| } |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += *(const GLint*)&swapbuf; |
| } else { |
| totals[k] += *(const GLint*)temp_index; |
| } |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| |
| |
| static void scale_internal_float(GLint components, GLint widthin, |
| GLint heightin, const GLfloat *datain, |
| GLint widthout, GLint heightout, |
| GLfloat *dataout, GLint element_size, |
| GLint ysize, GLint group_size, |
| GLint myswap_bytes) |
| { |
| float convx; |
| float convy; |
| float percent; |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| const char *temp_index; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| union { GLuint b; GLfloat f; } swapbuf; |
| |
| if (widthin == widthout*2 && heightin == heightout*2) { |
| halveImage_float(components, widthin, heightin, |
| (const GLfloat *)datain, (GLfloat *)dataout, |
| element_size, ysize, group_size, myswap_bytes); |
| return; |
| } |
| convy = (float) heightin/heightout; |
| convx = (float) widthin/widthout; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightout; i++) { |
| /* Clamp here to be sure we don't read beyond input buffer. */ |
| if (highy_int >= heightin) |
| highy_int = heightin - 1; |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthout; j++) { |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*group_size; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| percent = y_percent * (1-lowx_float); |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * y_percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| right = temp; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the last row */ |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)datain + xindex + highy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * y_percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += ysize; |
| right += ysize; |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(left); |
| totals[k] += swapbuf.f * (1-lowx_float); |
| swapbuf.b = __GLU_SWAP_4_BYTES(right); |
| totals[k] += swapbuf.f * highx_float; |
| } else { |
| totals[k] += *(const GLfloat*)left * (1-lowx_float) |
| + *(const GLfloat*)right * highx_float; |
| } |
| } |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * x_percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * x_percent; |
| } |
| } |
| } |
| percent = x_percent * highy_float; |
| temp += ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| |
| temp = (const char *)datain + xindex + lowy_int*ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += group_size; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * y_percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * y_percent; |
| } |
| } |
| } |
| temp += group_size; |
| percent = y_percent * highx_float; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)datain + xindex + lowy_int * ysize; |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f * percent; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index * percent; |
| } |
| } |
| } |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)datain + xindex + group_size + |
| (lowy_int+1)*ysize; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
| totals[k] += swapbuf.f; |
| } else { |
| totals[k] += *(const GLfloat*)temp_index; |
| } |
| } |
| temp += group_size; |
| } |
| temp0 += ysize; |
| } |
| |
| outindex = (j + (i * widthout)) * components; |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| } |
| |
| static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type) |
| { |
| if (!legalFormat(format) || !legalType(type)) { |
| return GLU_INVALID_ENUM; |
| } |
| if (format == GL_STENCIL_INDEX) { |
| return GLU_INVALID_ENUM; |
| } |
| |
| if (!isLegalFormatForPackedPixelType(format, type)) { |
| return GLU_INVALID_OPERATION; |
| } |
| |
| return 0; |
| } /* checkMipmapArgs() */ |
| |
| static GLboolean legalFormat(GLenum format) |
| { |
| switch(format) { |
| case GL_COLOR_INDEX: |
| case GL_STENCIL_INDEX: |
| case GL_DEPTH_COMPONENT: |
| case GL_RED: |
| case GL_GREEN: |
| case GL_BLUE: |
| case GL_ALPHA: |
| case GL_RGB: |
| case GL_RGBA: |
| case GL_LUMINANCE: |
| case GL_LUMINANCE_ALPHA: |
| case GL_BGR: |
| case GL_BGRA: |
| return GL_TRUE; |
| default: |
| return GL_FALSE; |
| } |
| } |
| |
| |
| static GLboolean legalType(GLenum type) |
| { |
| switch(type) { |
| case GL_BITMAP: |
| case GL_BYTE: |
| case GL_UNSIGNED_BYTE: |
| case GL_SHORT: |
| case GL_UNSIGNED_SHORT: |
| case GL_INT: |
| case GL_UNSIGNED_INT: |
| case GL_FLOAT: |
| case GL_UNSIGNED_BYTE_3_3_2: |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| case GL_UNSIGNED_SHORT_5_6_5: |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| case GL_UNSIGNED_INT_8_8_8_8: |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| case GL_UNSIGNED_INT_10_10_10_2: |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| return GL_TRUE; |
| default: |
| return GL_FALSE; |
| } |
| } |
| |
| /* */ |
| static GLboolean isTypePackedPixel(GLenum type) |
| { |
| assert(legalType(type)); |
| |
| if (type == GL_UNSIGNED_BYTE_3_3_2 || |
| type == GL_UNSIGNED_BYTE_2_3_3_REV || |
| type == GL_UNSIGNED_SHORT_5_6_5 || |
| type == GL_UNSIGNED_SHORT_5_6_5_REV || |
| type == GL_UNSIGNED_SHORT_4_4_4_4 || |
| type == GL_UNSIGNED_SHORT_4_4_4_4_REV || |
| type == GL_UNSIGNED_SHORT_5_5_5_1 || |
| type == GL_UNSIGNED_SHORT_1_5_5_5_REV || |
| type == GL_UNSIGNED_INT_8_8_8_8 || |
| type == GL_UNSIGNED_INT_8_8_8_8_REV || |
| type == GL_UNSIGNED_INT_10_10_10_2 || |
| type == GL_UNSIGNED_INT_2_10_10_10_REV) { |
| return 1; |
| } |
| else return 0; |
| } /* isTypePackedPixel() */ |
| |
| /* Determines if the packed pixel type is compatible with the format */ |
| static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type) |
| { |
| /* if not a packed pixel type then return true */ |
| if (!isTypePackedPixel(type)) { |
| return GL_TRUE; |
| } |
| |
| /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */ |
| if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV|| |
| type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV) |
| && format != GL_RGB) |
| return GL_FALSE; |
| |
| /* 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 & |
| * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT. |
| */ |
| if ((type == GL_UNSIGNED_SHORT_4_4_4_4 || |
| type == GL_UNSIGNED_SHORT_4_4_4_4_REV || |
| type == GL_UNSIGNED_SHORT_5_5_5_1 || |
| type == GL_UNSIGNED_SHORT_1_5_5_5_REV || |
| type == GL_UNSIGNED_INT_8_8_8_8 || |
| type == GL_UNSIGNED_INT_8_8_8_8_REV || |
| type == GL_UNSIGNED_INT_10_10_10_2 || |
| type == GL_UNSIGNED_INT_2_10_10_10_REV) && |
| (format != GL_RGBA && |
| format != GL_BGRA)) { |
| return GL_FALSE; |
| } |
| |
| return GL_TRUE; |
| } /* isLegalFormatForPackedPixelType() */ |
| |
| /* Given user requested texture size, determine if it fits. If it |
| * doesn't then halve both sides and make the determination again |
| * until it does fit (for IR only). |
| * Note that proxy textures are not implemented in RE* even though |
| * they advertise the texture extension. |
| * Note that proxy textures are implemented but not according to spec in |
| * IMPACT*. |
| */ |
| static void closestFit(GLenum target, GLint width, GLint height, |
| GLint internalFormat, GLenum format, GLenum type, |
| GLint *newWidth, GLint *newHeight) |
| { |
| /* Use proxy textures if OpenGL version is >= 1.1 */ |
| if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1) |
| ) { |
| GLint widthPowerOf2= nearestPower(width); |
| GLint heightPowerOf2= nearestPower(height); |
| GLint proxyWidth; |
| |
| do { |
| /* compute level 1 width & height, clamping each at 1 */ |
| GLint widthAtLevelOne= (widthPowerOf2 > 1) ? |
| widthPowerOf2 >> 1 : |
| widthPowerOf2; |
| GLint heightAtLevelOne= (heightPowerOf2 > 1) ? |
| heightPowerOf2 >> 1 : |
| heightPowerOf2; |
| GLenum proxyTarget; |
| assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0); |
| |
| /* does width x height at level 1 & all their mipmaps fit? */ |
| if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { |
| proxyTarget = GL_PROXY_TEXTURE_2D; |
| glTexImage2D(proxyTarget, 1, /* must be non-zero */ |
| internalFormat, |
| widthAtLevelOne,heightAtLevelOne,0,format,type,NULL); |
| } else |
| if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) || |
| (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) || |
| (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) || |
| (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) || |
| (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) || |
| (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { |
| proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB; |
| glTexImage2D(proxyTarget, 1, /* must be non-zero */ |
| internalFormat, |
| widthAtLevelOne,heightAtLevelOne,0,format,type,NULL); |
| } else |
| { |
| assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D); |
| proxyTarget = GL_PROXY_TEXTURE_1D; |
| glTexImage1D(proxyTarget, 1, /* must be non-zero */ |
| internalFormat,widthAtLevelOne,0,format,type,NULL); |
| } |
| glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth); |
| /* does it fit??? */ |
| if (proxyWidth == 0) { /* nope, so try again with these sizes */ |
| if (widthPowerOf2 == 1 && heightPowerOf2 == 1) { |
| /* An 1x1 texture couldn't fit for some reason, so |
| * break out. This should never happen. But things |
| * happen. The disadvantage with this if-statement is |
| * that we will never be aware of when this happens |
| * since it will silently branch out. |
| */ |
| goto noProxyTextures; |
| } |
| widthPowerOf2= widthAtLevelOne; |
| heightPowerOf2= heightAtLevelOne; |
| } |
| /* else it does fit */ |
| } while (proxyWidth == 0); |
| /* loop must terminate! */ |
| |
| /* return the width & height at level 0 that fits */ |
| *newWidth= widthPowerOf2; |
| *newHeight= heightPowerOf2; |
| /*printf("Proxy Textures\n");*/ |
| } /* if gluCheckExtension() */ |
| else { /* no texture extension, so do this instead */ |
| GLint maxsize; |
| |
| noProxyTextures: |
| |
| glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); |
| /* clamp user's texture sizes to maximum sizes, if necessary */ |
| *newWidth = nearestPower(width); |
| if (*newWidth > maxsize) *newWidth = maxsize; |
| *newHeight = nearestPower(height); |
| if (*newHeight > maxsize) *newHeight = maxsize; |
| /*printf("NO proxy textures\n");*/ |
| } |
| } /* closestFit() */ |
| |
| |
| /*********************************************************************** |
| * gluScaleImage (GLU32.@) |
| */ |
| GLint WINAPI gluScaleImage( GLenum format, GLint widthin, GLint heightin, GLenum typein, const void *datain, |
| GLint widthout, GLint heightout, GLenum typeout, void *dataout ) |
| { |
| int components; |
| GLushort *beforeImage; |
| GLushort *afterImage; |
| PixelStorageModes psm; |
| |
| if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) { |
| return 0; |
| } |
| if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) { |
| return GLU_INVALID_VALUE; |
| } |
| if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) { |
| return GLU_INVALID_ENUM; |
| } |
| if (!isLegalFormatForPackedPixelType(format, typein)) { |
| return GLU_INVALID_OPERATION; |
| } |
| if (!isLegalFormatForPackedPixelType(format, typeout)) { |
| return GLU_INVALID_OPERATION; |
| } |
| beforeImage = |
| HeapAlloc(GetProcessHeap(), 0, image_size(widthin, heightin, format, GL_UNSIGNED_SHORT)); |
| afterImage = |
| HeapAlloc(GetProcessHeap(), 0, image_size(widthout, heightout, format, GL_UNSIGNED_SHORT)); |
| if (beforeImage == NULL || afterImage == NULL) { |
| HeapFree(GetProcessHeap(), 0, beforeImage); |
| HeapFree(GetProcessHeap(), 0, afterImage); |
| return GLU_OUT_OF_MEMORY; |
| } |
| |
| retrieveStoreModes(&psm); |
| fill_image(&psm,widthin, heightin, format, typein, is_index(format), |
| datain, beforeImage); |
| components = elements_per_group(format, 0); |
| scale_internal(components, widthin, heightin, beforeImage, |
| widthout, heightout, afterImage); |
| empty_image(&psm,widthout, heightout, format, typeout, |
| is_index(format), afterImage, dataout); |
| HeapFree(GetProcessHeap(), 0, beforeImage); |
| HeapFree(GetProcessHeap(), 0, afterImage); |
| |
| return 0; |
| } |
| |
| int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat, |
| GLsizei width, |
| GLsizei widthPowerOf2, |
| GLenum format, GLenum type, |
| GLint userLevel, GLint baseLevel,GLint maxLevel, |
| const void *data) |
| { |
| GLint newwidth; |
| GLint level, levels; |
| GLushort *newImage; |
| GLint newImage_width; |
| GLushort *otherImage; |
| GLushort *imageTemp; |
| GLint memreq; |
| GLint cmpts; |
| PixelStorageModes psm; |
| |
| assert(checkMipmapArgs(internalFormat,format,type) == 0); |
| assert(width >= 1); |
| |
| otherImage = NULL; |
| |
| newwidth= widthPowerOf2; |
| levels = computeLog(newwidth); |
| |
| levels+= userLevel; |
| |
| retrieveStoreModes(&psm); |
| newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, 1, format, GL_UNSIGNED_SHORT)); |
| newImage_width = width; |
| if (newImage == NULL) { |
| return GLU_OUT_OF_MEMORY; |
| } |
| fill_image(&psm,width, 1, format, type, is_index(format), |
| data, newImage); |
| cmpts = elements_per_group(format,type); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, 2); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| /* |
| ** If swap_bytes was set, swapping occurred in fill_image. |
| */ |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
| |
| for (level = userLevel; level <= levels; level++) { |
| if (newImage_width == newwidth) { |
| /* Use newImage for this level */ |
| if (baseLevel <= level && level <= maxLevel) { |
| glTexImage1D(target, level, internalFormat, newImage_width, |
| 0, format, GL_UNSIGNED_SHORT, (void *) newImage); |
| } |
| } else { |
| if (otherImage == NULL) { |
| memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT); |
| otherImage = HeapAlloc(GetProcessHeap(), 0, memreq); |
| if (otherImage == NULL) { |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| HeapFree(GetProcessHeap(), 0, newImage); |
| return GLU_OUT_OF_MEMORY; |
| } |
| } |
| scale_internal(cmpts, newImage_width, 1, newImage, |
| newwidth, 1, otherImage); |
| /* Swap newImage and otherImage */ |
| imageTemp = otherImage; |
| otherImage = newImage; |
| newImage = imageTemp; |
| |
| newImage_width = newwidth; |
| if (baseLevel <= level && level <= maxLevel) { |
| glTexImage1D(target, level, internalFormat, newImage_width, |
| 0, format, GL_UNSIGNED_SHORT, (void *) newImage); |
| } |
| } |
| if (newwidth > 1) newwidth /= 2; |
| } |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| |
| HeapFree(GetProcessHeap(), 0, newImage); |
| HeapFree(GetProcessHeap(), 0, otherImage); |
| return 0; |
| } |
| |
| |
| /*********************************************************************** |
| * gluBuild1DMipmaps (GLU32.@) |
| */ |
| GLint WINAPI gluBuild1DMipmaps( GLenum target, GLint internalFormat, GLsizei width, |
| GLenum format, GLenum type, const void *data ) |
| { |
| GLint widthPowerOf2; |
| int levels; |
| GLint dummy; |
| |
| int rc= checkMipmapArgs(internalFormat,format,type); |
| if (rc != 0) return rc; |
| |
| if (width < 1) { |
| return GLU_INVALID_VALUE; |
| } |
| |
| closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy); |
| levels = computeLog(widthPowerOf2); |
| |
| return gluBuild1DMipmapLevelsCore(target,internalFormat, |
| width, |
| widthPowerOf2, |
| format,type,0,0,levels,data); |
| } |
| |
| static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat, |
| GLint width, GLint height, GLenum format, |
| GLenum type, const void *data) |
| { |
| GLint newwidth, newheight; |
| GLint level, levels; |
| GLushort *newImage; |
| GLint newImage_width; |
| GLint newImage_height; |
| GLushort *otherImage; |
| GLushort *imageTemp; |
| GLint memreq; |
| GLint cmpts; |
| PixelStorageModes psm; |
| |
| retrieveStoreModes(&psm); |
| |
| #if 0 |
| glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); |
| newwidth = nearestPower(width); |
| if (newwidth > maxsize) newwidth = maxsize; |
| newheight = nearestPower(height); |
| if (newheight > maxsize) newheight = maxsize; |
| #else |
| closestFit(target,width,height,internalFormat,format,type, |
| &newwidth,&newheight); |
| #endif |
| levels = computeLog(newwidth); |
| level = computeLog(newheight); |
| if (level > levels) levels=level; |
| |
| otherImage = NULL; |
| newImage = HeapAlloc(GetProcessHeap(), 0, image_size(width, height, format, GL_UNSIGNED_SHORT)); |
| newImage_width = width; |
| newImage_height = height; |
| if (newImage == NULL) { |
| return GLU_OUT_OF_MEMORY; |
| } |
| |
| fill_image(&psm,width, height, format, type, is_index(format), |
| data, newImage); |
| |
| cmpts = elements_per_group(format,type); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, 2); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| /* |
| ** If swap_bytes was set, swapping occurred in fill_image. |
| */ |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
| |
| for (level = 0; level <= levels; level++) { |
| if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */ |
| glTexImage2D(target, level, internalFormat, newImage_width, |
| newImage_height, 0, format, GL_UNSIGNED_SHORT, |
| (void *) newImage); |
| } else { |
| if (otherImage == NULL) { |
| memreq = |
| image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT); |
| otherImage = HeapAlloc(GetProcessHeap(), 0, memreq); |
| if (otherImage == NULL) { |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| HeapFree(GetProcessHeap(), 0, newImage); |
| return GLU_OUT_OF_MEMORY; |
| } |
| } |
| scale_internal(cmpts, newImage_width, newImage_height, newImage, |
| newwidth, newheight, otherImage); |
| /* Swap newImage and otherImage */ |
| imageTemp = otherImage; |
| otherImage = newImage; |
| newImage = imageTemp; |
| |
| newImage_width = newwidth; |
| newImage_height = newheight; |
| glTexImage2D(target, level, internalFormat, newImage_width, |
| newImage_height, 0, format, GL_UNSIGNED_SHORT, |
| (void *) newImage); |
| } |
| if (newwidth > 1) newwidth /= 2; |
| if (newheight > 1) newheight /= 2; |
| } |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| |
| HeapFree(GetProcessHeap(), 0, newImage); |
| HeapFree(GetProcessHeap(), 0, otherImage); |
| return 0; |
| } |
| |
| /* To make swapping images less error prone */ |
| #define __GLU_INIT_SWAP_IMAGE void *tmpImage |
| #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage; |
| |
| static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, |
| GLsizei width, GLsizei height, |
| GLsizei widthPowerOf2, |
| GLsizei heightPowerOf2, |
| GLenum format, GLenum type, |
| GLint userLevel, |
| GLint baseLevel,GLint maxLevel, |
| const void *data) |
| { |
| GLint newwidth, newheight; |
| GLint level, levels; |
| const void *usersImage; /* passed from user. Don't touch! */ |
| void *srcImage, *dstImage; /* scratch area to build mipmapped images */ |
| __GLU_INIT_SWAP_IMAGE; |
| GLint memreq; |
| GLint cmpts; |
| |
| GLint myswap_bytes, groups_per_line, element_size, group_size; |
| GLint rowsize, padding; |
| PixelStorageModes psm; |
| |
| assert(checkMipmapArgs(internalFormat,format,type) == 0); |
| assert(width >= 1 && height >= 1); |
| |
| if(type == GL_BITMAP) { |
| return bitmapBuild2DMipmaps(target, internalFormat, width, height, |
| format, type, data); |
| } |
| |
| srcImage = dstImage = NULL; |
| |
| newwidth= widthPowerOf2; |
| newheight= heightPowerOf2; |
| levels = computeLog(newwidth); |
| level = computeLog(newheight); |
| if (level > levels) levels=level; |
| |
| levels+= userLevel; |
| |
| retrieveStoreModes(&psm); |
| myswap_bytes = psm.unpack_swap_bytes; |
| cmpts = elements_per_group(format,type); |
| if (psm.unpack_row_length > 0) { |
| groups_per_line = psm.unpack_row_length; |
| } else { |
| groups_per_line = width; |
| } |
| |
| element_size = bytes_per_element(type); |
| group_size = element_size * cmpts; |
| if (element_size == 1) myswap_bytes = 0; |
| |
| rowsize = groups_per_line * group_size; |
| padding = (rowsize % psm.unpack_alignment); |
| if (padding) { |
| rowsize += psm.unpack_alignment - padding; |
| } |
| usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize + |
| psm.unpack_skip_pixels * group_size; |
| |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| |
| level = userLevel; |
| |
| /* already power-of-two square */ |
| if (width == newwidth && height == newheight) { |
| /* Use usersImage for level userLevel */ |
| if (baseLevel <= level && level <= maxLevel) { |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glTexImage2D(target, level, internalFormat, width, |
| height, 0, format, type, |
| usersImage); |
| } |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| if(levels == 0) { /* we're done. clean up and return */ |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| return 0; |
| } |
| { |
| int nextWidth= newwidth/2; |
| int nextHeight= newheight/2; |
| |
| /* clamp to 1 */ |
| if (nextWidth < 1) nextWidth= 1; |
| if (nextHeight < 1) nextHeight= 1; |
| memreq = image_size(nextWidth, nextHeight, format, type); |
| } |
| |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| case GL_BYTE: |
| case GL_UNSIGNED_SHORT: |
| case GL_SHORT: |
| case GL_UNSIGNED_INT: |
| case GL_INT: |
| case GL_FLOAT: |
| case GL_UNSIGNED_BYTE_3_3_2: |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| case GL_UNSIGNED_SHORT_5_6_5: |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| case GL_UNSIGNED_INT_8_8_8_8: |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| case GL_UNSIGNED_INT_10_10_10_2: |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| dstImage = HeapAlloc(GetProcessHeap(), 0, memreq); |
| break; |
| default: |
| return GLU_INVALID_ENUM; |
| } |
| if (dstImage == NULL) { |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| return GLU_OUT_OF_MEMORY; |
| } |
| else |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| halveImage_ubyte(cmpts, width, height, |
| (const GLubyte *)usersImage, (GLubyte *)dstImage, |
| element_size, rowsize, group_size); |
| break; |
| case GL_BYTE: |
| halveImage_byte(cmpts, width, height, |
| (const GLbyte *)usersImage, (GLbyte *)dstImage, |
| element_size, rowsize, group_size); |
| break; |
| case GL_UNSIGNED_SHORT: |
| halveImage_ushort(cmpts, width, height, |
| (const GLushort *)usersImage, (GLushort *)dstImage, |
| element_size, rowsize, group_size, myswap_bytes); |
| break; |
| case GL_SHORT: |
| halveImage_short(cmpts, width, height, |
| (const GLshort *)usersImage, (GLshort *)dstImage, |
| element_size, rowsize, group_size, myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT: |
| halveImage_uint(cmpts, width, height, |
| (const GLuint *)usersImage, (GLuint *)dstImage, |
| element_size, rowsize, group_size, myswap_bytes); |
| break; |
| case GL_INT: |
| halveImage_int(cmpts, width, height, |
| (const GLint *)usersImage, (GLint *)dstImage, |
| element_size, rowsize, group_size, myswap_bytes); |
| break; |
| case GL_FLOAT: |
| halveImage_float(cmpts, width, height, |
| (const GLfloat *)usersImage, (GLfloat *)dstImage, |
| element_size, rowsize, group_size, myswap_bytes); |
| break; |
| case GL_UNSIGNED_BYTE_3_3_2: |
| assert(format == GL_RGB); |
| halveImagePackedPixel(3,extract332,shove332, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| assert(format == GL_RGB); |
| halveImagePackedPixel(3,extract233rev,shove233rev, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5: |
| halveImagePackedPixel(3,extract565,shove565, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| halveImagePackedPixel(3,extract565rev,shove565rev, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| halveImagePackedPixel(4,extract4444,shove4444, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| halveImagePackedPixel(4,extract4444rev,shove4444rev, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| halveImagePackedPixel(4,extract5551,shove5551, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| halveImagePackedPixel(4,extract1555rev,shove1555rev, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8: |
| halveImagePackedPixel(4,extract8888,shove8888, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| halveImagePackedPixel(4,extract8888rev,shove8888rev, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_10_10_10_2: |
| halveImagePackedPixel(4,extract1010102,shove1010102, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| halveImagePackedPixel(4,extract2101010rev,shove2101010rev, |
| width,height,usersImage,dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| default: |
| assert(0); |
| break; |
| } |
| newwidth = width/2; |
| newheight = height/2; |
| /* clamp to 1 */ |
| if (newwidth < 1) newwidth= 1; |
| if (newheight < 1) newheight= 1; |
| |
| myswap_bytes = 0; |
| rowsize = newwidth * group_size; |
| memreq = image_size(newwidth, newheight, format, type); |
| /* Swap srcImage and dstImage */ |
| __GLU_SWAP_IMAGE(srcImage,dstImage); |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| case GL_BYTE: |
| case GL_UNSIGNED_SHORT: |
| case GL_SHORT: |
| case GL_UNSIGNED_INT: |
| case GL_INT: |
| case GL_FLOAT: |
| case GL_UNSIGNED_BYTE_3_3_2: |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| case GL_UNSIGNED_SHORT_5_6_5: |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| case GL_UNSIGNED_INT_8_8_8_8: |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| case GL_UNSIGNED_INT_10_10_10_2: |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| dstImage = HeapAlloc(GetProcessHeap(), 0, memreq); |
| break; |
| default: |
| return GLU_INVALID_ENUM; |
| } |
| if (dstImage == NULL) { |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| HeapFree(GetProcessHeap(), 0, srcImage); |
| return GLU_OUT_OF_MEMORY; |
| } |
| /* level userLevel+1 is in srcImage; level userLevel already saved */ |
| level = userLevel+1; |
| } else { /* user's image is *not* nice power-of-2 sized square */ |
| memreq = image_size(newwidth, newheight, format, type); |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| case GL_BYTE: |
| case GL_UNSIGNED_SHORT: |
| case GL_SHORT: |
| case GL_UNSIGNED_INT: |
| case GL_INT: |
| case GL_FLOAT: |
| case GL_UNSIGNED_BYTE_3_3_2: |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| case GL_UNSIGNED_SHORT_5_6_5: |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| case GL_UNSIGNED_INT_8_8_8_8: |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| case GL_UNSIGNED_INT_10_10_10_2: |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| dstImage = HeapAlloc(GetProcessHeap(), 0, memreq); |
| break; |
| default: |
| return GLU_INVALID_ENUM; |
| } |
| |
| if (dstImage == NULL) { |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| return GLU_OUT_OF_MEMORY; |
| } |
| |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| scale_internal_ubyte(cmpts, width, height, |
| (const GLubyte *)usersImage, newwidth, newheight, |
| (GLubyte *)dstImage, element_size, |
| rowsize, group_size); |
| break; |
| case GL_BYTE: |
| scale_internal_byte(cmpts, width, height, |
| (const GLbyte *)usersImage, newwidth, newheight, |
| (GLbyte *)dstImage, element_size, |
| rowsize, group_size); |
| break; |
| case GL_UNSIGNED_SHORT: |
| scale_internal_ushort(cmpts, width, height, |
| (const GLushort *)usersImage, newwidth, newheight, |
| (GLushort *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_SHORT: |
| scale_internal_short(cmpts, width, height, |
| (const GLshort *)usersImage, newwidth, newheight, |
| (GLshort *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT: |
| scale_internal_uint(cmpts, width, height, |
| (const GLuint *)usersImage, newwidth, newheight, |
| (GLuint *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_INT: |
| scale_internal_int(cmpts, width, height, |
| (const GLint *)usersImage, newwidth, newheight, |
| (GLint *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_FLOAT: |
| scale_internal_float(cmpts, width, height, |
| (const GLfloat *)usersImage, newwidth, newheight, |
| (GLfloat *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_UNSIGNED_BYTE_3_3_2: |
| scaleInternalPackedPixel(3,extract332,shove332, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| scaleInternalPackedPixel(3,extract233rev,shove233rev, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5: |
| scaleInternalPackedPixel(3,extract565,shove565, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| scaleInternalPackedPixel(3,extract565rev,shove565rev, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| scaleInternalPackedPixel(4,extract4444,shove4444, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| scaleInternalPackedPixel(4,extract4444rev,shove4444rev, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| scaleInternalPackedPixel(4,extract5551,shove5551, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| scaleInternalPackedPixel(4,extract1555rev,shove1555rev, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8: |
| scaleInternalPackedPixel(4,extract8888,shove8888, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| scaleInternalPackedPixel(4,extract8888rev,shove8888rev, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_10_10_10_2: |
| scaleInternalPackedPixel(4,extract1010102,shove1010102, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev, |
| width, height,usersImage, |
| newwidth,newheight,(void *)dstImage, |
| element_size,rowsize,myswap_bytes); |
| break; |
| default: |
| assert(0); |
| break; |
| } |
| myswap_bytes = 0; |
| rowsize = newwidth * group_size; |
| /* Swap dstImage and srcImage */ |
| __GLU_SWAP_IMAGE(srcImage,dstImage); |
| |
| if(levels != 0) { /* use as little memory as possible */ |
| { |
| int nextWidth= newwidth/2; |
| int nextHeight= newheight/2; |
| if (nextWidth < 1) nextWidth= 1; |
| if (nextHeight < 1) nextHeight= 1; |
| |
| memreq = image_size(nextWidth, nextHeight, format, type); |
| } |
| |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| case GL_BYTE: |
| case GL_UNSIGNED_SHORT: |
| case GL_SHORT: |
| case GL_UNSIGNED_INT: |
| case GL_INT: |
| case GL_FLOAT: |
| case GL_UNSIGNED_BYTE_3_3_2: |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| case GL_UNSIGNED_SHORT_5_6_5: |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| case GL_UNSIGNED_INT_8_8_8_8: |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| case GL_UNSIGNED_INT_10_10_10_2: |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| dstImage = (GLuint *)HeapAlloc(GetProcessHeap(), 0, memreq); |
| break; |
| default: |
| return GLU_INVALID_ENUM; |
| } |
| if (dstImage == NULL) { |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| HeapFree(GetProcessHeap(), 0, srcImage); |
| return GLU_OUT_OF_MEMORY; |
| } |
| } |
| /* level userLevel is in srcImage; nothing saved yet */ |
| level = userLevel; |
| } |
| |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
| if (baseLevel <= level && level <= maxLevel) { |
| glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, |
| format, type, (void *)srcImage); |
| } |
| |
| level++; /* update current level for the loop */ |
| for (; level <= levels; level++) { |
| switch(type) { |
| case GL_UNSIGNED_BYTE: |
| halveImage_ubyte(cmpts, newwidth, newheight, |
| (GLubyte *)srcImage, (GLubyte *)dstImage, element_size, |
| rowsize, group_size); |
| break; |
| case GL_BYTE: |
| halveImage_byte(cmpts, newwidth, newheight, |
| (GLbyte *)srcImage, (GLbyte *)dstImage, element_size, |
| rowsize, group_size); |
| break; |
| case GL_UNSIGNED_SHORT: |
| halveImage_ushort(cmpts, newwidth, newheight, |
| (GLushort *)srcImage, (GLushort *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_SHORT: |
| halveImage_short(cmpts, newwidth, newheight, |
| (GLshort *)srcImage, (GLshort *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT: |
| halveImage_uint(cmpts, newwidth, newheight, |
| (GLuint *)srcImage, (GLuint *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_INT: |
| halveImage_int(cmpts, newwidth, newheight, |
| (GLint *)srcImage, (GLint *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_FLOAT: |
| halveImage_float(cmpts, newwidth, newheight, |
| (GLfloat *)srcImage, (GLfloat *)dstImage, element_size, |
| rowsize, group_size, myswap_bytes); |
| break; |
| case GL_UNSIGNED_BYTE_3_3_2: |
| halveImagePackedPixel(3,extract332,shove332, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| halveImagePackedPixel(3,extract233rev,shove233rev, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5: |
| halveImagePackedPixel(3,extract565,shove565, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| halveImagePackedPixel(3,extract565rev,shove565rev, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| halveImagePackedPixel(4,extract4444,shove4444, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| halveImagePackedPixel(4,extract4444rev,shove4444rev, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| halveImagePackedPixel(4,extract5551,shove5551, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| halveImagePackedPixel(4,extract1555rev,shove1555rev, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8: |
| halveImagePackedPixel(4,extract8888,shove8888, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| halveImagePackedPixel(4,extract8888rev,shove8888rev, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_10_10_10_2: |
| halveImagePackedPixel(4,extract1010102,shove1010102, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| halveImagePackedPixel(4,extract2101010rev,shove2101010rev, |
| newwidth,newheight, |
| srcImage,dstImage,element_size,rowsize, |
| myswap_bytes); |
| break; |
| default: |
| assert(0); |
| break; |
| } |
| |
| __GLU_SWAP_IMAGE(srcImage,dstImage); |
| |
| if (newwidth > 1) { newwidth /= 2; rowsize /= 2;} |
| if (newheight > 1) newheight /= 2; |
| { |
| /* compute amount to pad per row, if any */ |
| int rowPad= rowsize % psm.unpack_alignment; |
| |
| /* should row be padded? */ |
| if (rowPad == 0) { /* nope, row should not be padded */ |
| /* call tex image with srcImage untouched since it's not padded */ |
| if (baseLevel <= level && level <= maxLevel) { |
| glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, |
| format, type, (void *) srcImage); |
| } |
| } |
| else { /* yes, row should be padded */ |
| /* compute length of new row in bytes, including padding */ |
| int newRowLength= rowsize + psm.unpack_alignment - rowPad; |
| int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */ |
| |
| /* allocate new image for mipmap of size newRowLength x newheight */ |
| void *newMipmapImage= HeapAlloc(GetProcessHeap(), 0, (size_t) (newRowLength*newheight)); |
| if (newMipmapImage == NULL) { |
| /* out of memory so return */ |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| return GLU_OUT_OF_MEMORY; |
| } |
| |
| /* copy image from srcImage into newMipmapImage by rows */ |
| for (ii= 0, |
| dstTrav= (unsigned char *) newMipmapImage, |
| srcTrav= (unsigned char *) srcImage; |
| ii< newheight; |
| ii++, |
| dstTrav+= newRowLength, /* make sure the correct distance... */ |
| srcTrav+= rowsize) { /* ...is skipped */ |
| memcpy(dstTrav,srcTrav,rowsize); |
| /* note that the pad bytes are not visited and will contain |
| * garbage, which is ok. |
| */ |
| } |
| |
| /* ...and use this new image for mipmapping instead */ |
| if (baseLevel <= level && level <= maxLevel) { |
| glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, |
| format, type, newMipmapImage); |
| } |
| HeapFree(GetProcessHeap(), 0, newMipmapImage); /* don't forget to free it! */ |
| } /* else */ |
| } |
| } /* for level */ |
| glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
| glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
| |
| HeapFree(GetProcessHeap(), 0, srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ |
| HeapFree(GetProcessHeap(), 0, dstImage); |
| return 0; |
| } /* gluBuild2DMipmapLevelsCore() */ |
| |
| |
| /*********************************************************************** |
| * gluBuild2DMipmaps (GLU32.@) |
| */ |
| GLint WINAPI gluBuild2DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, |
| GLenum format, GLenum type, const void *data ) |
| { |
| GLint widthPowerOf2, heightPowerOf2; |
| int level, levels; |
| |
| int rc= checkMipmapArgs(internalFormat,format,type); |
| if (rc != 0) return rc; |
| |
| if (width < 1 || height < 1) { |
| return GLU_INVALID_VALUE; |
| } |
| |
| closestFit(target,width,height,internalFormat,format,type, |
| &widthPowerOf2,&heightPowerOf2); |
| |
| levels = computeLog(widthPowerOf2); |
| level = computeLog(heightPowerOf2); |
| if (level > levels) levels=level; |
| |
| return gluBuild2DMipmapLevelsCore(target,internalFormat, |
| width, height, |
| widthPowerOf2,heightPowerOf2, |
| format,type, |
| 0,0,levels,data); |
| } /* gluBuild2DMipmaps() */ |
| |
| |
| /* |
| * Utility Routines |
| */ |
| static GLint elements_per_group(GLenum format, GLenum type) |
| { |
| /* |
| * Return the number of elements per group of a specified format |
| */ |
| |
| /* If the type is packedpixels then answer is 1 (ignore format) */ |
| if (type == GL_UNSIGNED_BYTE_3_3_2 || |
| type == GL_UNSIGNED_BYTE_2_3_3_REV || |
| type == GL_UNSIGNED_SHORT_5_6_5 || |
| type == GL_UNSIGNED_SHORT_5_6_5_REV || |
| type == GL_UNSIGNED_SHORT_4_4_4_4 || |
| type == GL_UNSIGNED_SHORT_4_4_4_4_REV || |
| type == GL_UNSIGNED_SHORT_5_5_5_1 || |
| type == GL_UNSIGNED_SHORT_1_5_5_5_REV || |
| type == GL_UNSIGNED_INT_8_8_8_8 || |
| type == GL_UNSIGNED_INT_8_8_8_8_REV || |
| type == GL_UNSIGNED_INT_10_10_10_2 || |
| type == GL_UNSIGNED_INT_2_10_10_10_REV) { |
| return 1; |
| } |
| |
| /* Types are not packed pixels, so get elements per group */ |
| switch(format) { |
| case GL_RGB: |
| case GL_BGR: |
| return 3; |
| case GL_LUMINANCE_ALPHA: |
| return 2; |
| case GL_RGBA: |
| case GL_BGRA: |
| return 4; |
| default: |
| return 1; |
| } |
| } |
| |
| static GLfloat bytes_per_element(GLenum type) |
| { |
| /* |
| * Return the number of bytes per element, based on the element type |
| */ |
| switch(type) { |
| case GL_BITMAP: |
| return 1.0 / 8.0; |
| case GL_UNSIGNED_SHORT: |
| return(sizeof(GLushort)); |
| case GL_SHORT: |
| return(sizeof(GLshort)); |
| case GL_UNSIGNED_BYTE: |
| return(sizeof(GLubyte)); |
| case GL_BYTE: |
| return(sizeof(GLbyte)); |
| case GL_INT: |
| return(sizeof(GLint)); |
| case GL_UNSIGNED_INT: |
| return(sizeof(GLuint)); |
| case GL_FLOAT: |
| return(sizeof(GLfloat)); |
| case GL_UNSIGNED_BYTE_3_3_2: |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| return(sizeof(GLubyte)); |
| case GL_UNSIGNED_SHORT_5_6_5: |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| return(sizeof(GLushort)); |
| case GL_UNSIGNED_INT_8_8_8_8: |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| case GL_UNSIGNED_INT_10_10_10_2: |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| return(sizeof(GLuint)); |
| default: |
| return 4; |
| } |
| } |
| |
| static GLint is_index(GLenum format) |
| { |
| return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX; |
| } |
| |
| /* |
| ** Compute memory required for internal packed array of data of given type |
| ** and format. |
| */ |
| static GLint image_size(GLint width, GLint height, GLenum format, GLenum type) |
| { |
| int bytes_per_row; |
| int components; |
| |
| assert(width > 0); |
| assert(height > 0); |
| components = elements_per_group(format,type); |
| if (type == GL_BITMAP) { |
| bytes_per_row = (width + 7) / 8; |
| } else { |
| bytes_per_row = bytes_per_element(type) * width; |
| } |
| return bytes_per_row * height * components; |
| } |
| |
| /* |
| ** Extract array from user's data applying all pixel store modes. |
| ** The internal format used is an array of unsigned shorts. |
| */ |
| static void fill_image(const PixelStorageModes *psm, |
| GLint width, GLint height, GLenum format, |
| GLenum type, GLboolean index_format, |
| const void *userdata, GLushort *newimage) |
| { |
| GLint components; |
| GLint element_size; |
| GLint rowsize; |
| GLint padding; |
| GLint groups_per_line; |
| GLint group_size; |
| GLint elements_per_line; |
| const GLubyte *start; |
| const GLubyte *iter; |
| GLushort *iter2; |
| GLint i, j, k; |
| GLint myswap_bytes; |
| |
| myswap_bytes = psm->unpack_swap_bytes; |
| components = elements_per_group(format,type); |
| if (psm->unpack_row_length > 0) { |
| groups_per_line = psm->unpack_row_length; |
| } else { |
| groups_per_line = width; |
| } |
| |
| /* All formats except GL_BITMAP fall out trivially */ |
| if (type == GL_BITMAP) { |
| GLint bit_offset; |
| GLint current_bit; |
| |
| rowsize = (groups_per_line * components + 7) / 8; |
| padding = (rowsize % psm->unpack_alignment); |
| if (padding) { |
| rowsize += psm->unpack_alignment - padding; |
| } |
| start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + |
| (psm->unpack_skip_pixels * components / 8); |
| elements_per_line = width * components; |
| iter2 = newimage; |
| for (i = 0; i < height; i++) { |
| iter = start; |
| bit_offset = (psm->unpack_skip_pixels * components) % 8; |
| for (j = 0; j < elements_per_line; j++) { |
| /* Retrieve bit */ |
| if (psm->unpack_lsb_first) { |
| current_bit = iter[0] & (1 << bit_offset); |
| } else { |
| current_bit = iter[0] & (1 << (7 - bit_offset)); |
| } |
| if (current_bit) { |
| if (index_format) { |
| *iter2 = 1; |
| } else { |
| *iter2 = 65535; |
| } |
| } else { |
| *iter2 = 0; |
| } |
| bit_offset++; |
| if (bit_offset == 8) { |
| bit_offset = 0; |
| iter++; |
| } |
| iter2++; |
| } |
| start += rowsize; |
| } |
| } else { |
| element_size = bytes_per_element(type); |
| group_size = element_size * components; |
| if (element_size == 1) myswap_bytes = 0; |
| |
| rowsize = groups_per_line * group_size; |
| padding = (rowsize % psm->unpack_alignment); |
| if (padding) { |
| rowsize += psm->unpack_alignment - padding; |
| } |
| start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + |
| psm->unpack_skip_pixels * group_size; |
| elements_per_line = width * components; |
| |
| iter2 = newimage; |
| for (i = 0; i < height; i++) { |
| iter = start; |
| for (j = 0; j < elements_per_line; j++) { |
| Type_Widget widget; |
| float extractComponents[4]; |
| |
| switch(type) { |
| case GL_UNSIGNED_BYTE_3_3_2: |
| extract332(0,iter,extractComponents); |
| for (k = 0; k < 3; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| extract233rev(0,iter,extractComponents); |
| for (k = 0; k < 3; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_BYTE: |
| if (index_format) { |
| *iter2++ = *iter; |
| } else { |
| *iter2++ = (*iter) * 257; |
| } |
| break; |
| case GL_BYTE: |
| if (index_format) { |
| *iter2++ = *((const GLbyte *) iter); |
| } else { |
| /* rough approx */ |
| *iter2++ = (*((const GLbyte *) iter)) * 516; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5: |
| extract565(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 3; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| extract565rev(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 3; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| extract4444(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| extract4444rev(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| extract5551(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| extract1555rev(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_SHORT: |
| case GL_SHORT: |
| if (myswap_bytes) { |
| widget.ub[0] = iter[1]; |
| widget.ub[1] = iter[0]; |
| } else { |
| widget.ub[0] = iter[0]; |
| widget.ub[1] = iter[1]; |
| } |
| if (type == GL_SHORT) { |
| if (index_format) { |
| *iter2++ = widget.s[0]; |
| } else { |
| /* rough approx */ |
| *iter2++ = widget.s[0]*2; |
| } |
| } else { |
| *iter2++ = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8: |
| extract8888(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| extract8888rev(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_INT_10_10_10_2: |
| extract1010102(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| extract2101010rev(myswap_bytes,iter,extractComponents); |
| for (k = 0; k < 4; k++) { |
| *iter2++ = (GLushort)(extractComponents[k]*65535); |
| } |
| break; |
| case GL_INT: |
| case GL_UNSIGNED_INT: |
| case GL_FLOAT: |
| if (myswap_bytes) { |
| widget.ub[0] = iter[3]; |
| widget.ub[1] = iter[2]; |
| widget.ub[2] = iter[1]; |
| widget.ub[3] = iter[0]; |
| } else { |
| widget.ub[0] = iter[0]; |
| widget.ub[1] = iter[1]; |
| widget.ub[2] = iter[2]; |
| widget.ub[3] = iter[3]; |
| } |
| if (type == GL_FLOAT) { |
| if (index_format) { |
| *iter2++ = widget.f; |
| } else { |
| *iter2++ = 65535 * widget.f; |
| } |
| } else if (type == GL_UNSIGNED_INT) { |
| if (index_format) { |
| *iter2++ = widget.ui; |
| } else { |
| *iter2++ = widget.ui >> 16; |
| } |
| } else { |
| if (index_format) { |
| *iter2++ = widget.i; |
| } else { |
| *iter2++ = widget.i >> 15; |
| } |
| } |
| break; |
| } |
| iter += element_size; |
| } /* for j */ |
| start += rowsize; |
| #if 1 |
| /* want 'iter' pointing at start, not within, row for assertion |
| * purposes |
| */ |
| iter= start; |
| #endif |
| } /* for i */ |
| |
| /* iterators should be one byte past end */ |
| if (!isTypePackedPixel(type)) { |
| assert(iter2 == &newimage[width*height*components]); |
| } |
| else { |
| assert(iter2 == &newimage[width*height* |
| elements_per_group(format,0)]); |
| } |
| assert( iter == &((const GLubyte *)userdata)[rowsize*height + |
| psm->unpack_skip_rows * rowsize + |
| psm->unpack_skip_pixels * group_size] ); |
| |
| } /* else */ |
| } /* fill_image() */ |
| |
| /* |
| ** Insert array into user's data applying all pixel store modes. |
| ** The internal format is an array of unsigned shorts. |
| ** empty_image() because it is the opposite of fill_image(). |
| */ |
| static void empty_image(const PixelStorageModes *psm, |
| GLint width, GLint height, GLenum format, |
| GLenum type, GLboolean index_format, |
| const GLushort *oldimage, void *userdata) |
| { |
| GLint components; |
| GLint element_size; |
| GLint rowsize; |
| GLint padding; |
| GLint groups_per_line; |
| GLint group_size; |
| GLint elements_per_line; |
| GLubyte *start; |
| GLubyte *iter; |
| const GLushort *iter2; |
| GLint i, j, k; |
| GLint myswap_bytes; |
| |
| myswap_bytes = psm->pack_swap_bytes; |
| components = elements_per_group(format,type); |
| if (psm->pack_row_length > 0) { |
| groups_per_line = psm->pack_row_length; |
| } else { |
| groups_per_line = width; |
| } |
| |
| /* All formats except GL_BITMAP fall out trivially */ |
| if (type == GL_BITMAP) { |
| GLint bit_offset; |
| GLint current_bit; |
| |
| rowsize = (groups_per_line * components + 7) / 8; |
| padding = (rowsize % psm->pack_alignment); |
| if (padding) { |
| rowsize += psm->pack_alignment - padding; |
| } |
| start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + |
| (psm->pack_skip_pixels * components / 8); |
| elements_per_line = width * components; |
| iter2 = oldimage; |
| for (i = 0; i < height; i++) { |
| iter = start; |
| bit_offset = (psm->pack_skip_pixels * components) % 8; |
| for (j = 0; j < elements_per_line; j++) { |
| if (index_format) { |
| current_bit = iter2[0] & 1; |
| } else { |
| if (iter2[0] > 32767) { |
| current_bit = 1; |
| } else { |
| current_bit = 0; |
| } |
| } |
| |
| if (current_bit) { |
| if (psm->pack_lsb_first) { |
| *iter |= (1 << bit_offset); |
| } else { |
| *iter |= (1 << (7 - bit_offset)); |
| } |
| } else { |
| if (psm->pack_lsb_first) { |
| *iter &= ~(1 << bit_offset); |
| } else { |
| *iter &= ~(1 << (7 - bit_offset)); |
| } |
| } |
| |
| bit_offset++; |
| if (bit_offset == 8) { |
| bit_offset = 0; |
| iter++; |
| } |
| iter2++; |
| } |
| start += rowsize; |
| } |
| } else { |
| float shoveComponents[4]; |
| |
| element_size = bytes_per_element(type); |
| group_size = element_size * components; |
| if (element_size == 1) myswap_bytes = 0; |
| |
| rowsize = groups_per_line * group_size; |
| padding = (rowsize % psm->pack_alignment); |
| if (padding) { |
| rowsize += psm->pack_alignment - padding; |
| } |
| start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + |
| psm->pack_skip_pixels * group_size; |
| elements_per_line = width * components; |
| |
| iter2 = oldimage; |
| for (i = 0; i < height; i++) { |
| iter = start; |
| for (j = 0; j < elements_per_line; j++) { |
| Type_Widget widget; |
| |
| switch(type) { |
| case GL_UNSIGNED_BYTE_3_3_2: |
| for (k = 0; k < 3; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove332(shoveComponents,0,(void *)iter); |
| break; |
| case GL_UNSIGNED_BYTE_2_3_3_REV: |
| for (k = 0; k < 3; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove233rev(shoveComponents,0,(void *)iter); |
| break; |
| case GL_UNSIGNED_BYTE: |
| if (index_format) { |
| *iter = *iter2++; |
| } else { |
| *iter = *iter2++ >> 8; |
| } |
| break; |
| case GL_BYTE: |
| if (index_format) { |
| *((GLbyte *) iter) = *iter2++; |
| } else { |
| *((GLbyte *) iter) = *iter2++ >> 9; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5: |
| for (k = 0; k < 3; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove565(shoveComponents,0,(void *)&widget.us[0]); |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } |
| else { |
| *(GLushort *)iter = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_5_6_5_REV: |
| for (k = 0; k < 3; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove565rev(shoveComponents,0,(void *)&widget.us[0]); |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } |
| else { |
| *(GLushort *)iter = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove4444(shoveComponents,0,(void *)&widget.us[0]); |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } else { |
| *(GLushort *)iter = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove4444rev(shoveComponents,0,(void *)&widget.us[0]); |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } else { |
| *(GLushort *)iter = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove5551(shoveComponents,0,(void *)&widget.us[0]); |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } else { |
| *(GLushort *)iter = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove1555rev(shoveComponents,0,(void *)&widget.us[0]); |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } else { |
| *(GLushort *)iter = widget.us[0]; |
| } |
| break; |
| case GL_UNSIGNED_SHORT: |
| case GL_SHORT: |
| if (type == GL_SHORT) { |
| if (index_format) { |
| widget.s[0] = *iter2++; |
| } else { |
| widget.s[0] = *iter2++ >> 1; |
| } |
| } else { |
| widget.us[0] = *iter2++; |
| } |
| if (myswap_bytes) { |
| iter[0] = widget.ub[1]; |
| iter[1] = widget.ub[0]; |
| } else { |
| iter[0] = widget.ub[0]; |
| iter[1] = widget.ub[1]; |
| } |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove8888(shoveComponents,0,(void *)&widget.ui); |
| if (myswap_bytes) { |
| iter[3] = widget.ub[0]; |
| iter[2] = widget.ub[1]; |
| iter[1] = widget.ub[2]; |
| iter[0] = widget.ub[3]; |
| } else { |
| *(GLuint *)iter= widget.ui; |
| } |
| |
| break; |
| case GL_UNSIGNED_INT_8_8_8_8_REV: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove8888rev(shoveComponents,0,(void *)&widget.ui); |
| if (myswap_bytes) { |
| iter[3] = widget.ub[0]; |
| iter[2] = widget.ub[1]; |
| iter[1] = widget.ub[2]; |
| iter[0] = widget.ub[3]; |
| } else { |
| *(GLuint *)iter= widget.ui; |
| } |
| break; |
| case GL_UNSIGNED_INT_10_10_10_2: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove1010102(shoveComponents,0,(void *)&widget.ui); |
| if (myswap_bytes) { |
| iter[3] = widget.ub[0]; |
| iter[2] = widget.ub[1]; |
| iter[1] = widget.ub[2]; |
| iter[0] = widget.ub[3]; |
| } else { |
| *(GLuint *)iter= widget.ui; |
| } |
| break; |
| case GL_UNSIGNED_INT_2_10_10_10_REV: |
| for (k = 0; k < 4; k++) { |
| shoveComponents[k]= *iter2++ / 65535.0; |
| } |
| shove2101010rev(shoveComponents,0,(void *)&widget.ui); |
| if (myswap_bytes) { |
| iter[3] = widget.ub[0]; |
| iter[2] = widget.ub[1]; |
| iter[1] = widget.ub[2]; |
| iter[0] = widget.ub[3]; |
| } else { |
| *(GLuint *)iter= widget.ui; |
| } |
| break; |
| case GL_INT: |
| case GL_UNSIGNED_INT: |
| case GL_FLOAT: |
| if (type == GL_FLOAT) { |
| if (index_format) { |
| widget.f = *iter2++; |
| } else { |
| widget.f = *iter2++ / (float) 65535.0; |
| } |
| } else if (type == GL_UNSIGNED_INT) { |
| if (index_format) { |
| widget.ui = *iter2++; |
| } else { |
| widget.ui = (unsigned int) *iter2++ * 65537; |
| } |
| } else { |
| if (index_format) { |
| widget.i = *iter2++; |
| } else { |
| widget.i = ((unsigned int) *iter2++ * 65537)/2; |
| } |
| } |
| if (myswap_bytes) { |
| iter[3] = widget.ub[0]; |
| iter[2] = widget.ub[1]; |
| iter[1] = widget.ub[2]; |
| iter[0] = widget.ub[3]; |
| } else { |
| iter[0] = widget.ub[0]; |
| iter[1] = widget.ub[1]; |
| iter[2] = widget.ub[2]; |
| iter[3] = widget.ub[3]; |
| } |
| break; |
| } |
| iter += element_size; |
| } /* for j */ |
| start += rowsize; |
| #if 1 |
| /* want 'iter' pointing at start, not within, row for assertion |
| * purposes |
| */ |
| iter= start; |
| #endif |
| } /* for i */ |
| |
| /* iterators should be one byte past end */ |
| if (!isTypePackedPixel(type)) { |
| assert(iter2 == &oldimage[width*height*components]); |
| } |
| else { |
| assert(iter2 == &oldimage[width*height* |
| elements_per_group(format,0)]); |
| } |
| assert( iter == &((GLubyte *)userdata)[rowsize*height + |
| psm->pack_skip_rows * rowsize + |
| psm->pack_skip_pixels * group_size] ); |
| |
| } /* else */ |
| } /* empty_image() */ |
| |
| /*-------------------------------------------------------------------------- |
| * Decimation of packed pixel types |
| *-------------------------------------------------------------------------- |
| */ |
| static void extract332(int isSwap, |
| const void *packedPixel, GLfloat extractComponents[]) |
| { |
| GLubyte ubyte= *(const GLubyte *)packedPixel; |
| |
| /* 11100000 == 0xe0 */ |
| /* 00011100 == 0x1c */ |
| /* 00000011 == 0x03 */ |
| |
| extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0; |
| extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */ |
| extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */ |
| } /* extract332() */ |
| |
| static void shove332(const GLfloat shoveComponents[], |
| int index, void *packedPixel) |
| { |
| /* 11100000 == 0xe0 */ |
| /* 00011100 == 0x1c */ |
| /* 00000011 == 0x03 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLubyte *)packedPixel)[index] = |
| ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0; |
| ((GLubyte *)packedPixel)[index] |= |
| ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c; |
| ((GLubyte *)packedPixel)[index] |= |
| ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03; |
| } /* shove332() */ |
| |
| static void extract233rev(int isSwap, |
| const void *packedPixel, GLfloat extractComponents[]) |
| { |
| GLubyte ubyte= *(const GLubyte *)packedPixel; |
| |
| /* 0000,0111 == 0x07 */ |
| /* 0011,1000 == 0x38 */ |
| /* 1100,0000 == 0xC0 */ |
| |
| extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0; |
| extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0; |
| extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0; |
| } /* extract233rev() */ |
| |
| static void shove233rev(const GLfloat shoveComponents[], |
| int index, void *packedPixel) |
| { |
| /* 0000,0111 == 0x07 */ |
| /* 0011,1000 == 0x38 */ |
| /* 1100,0000 == 0xC0 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLubyte *)packedPixel)[index] = |
| ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07; |
| ((GLubyte *)packedPixel)[index]|= |
| ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38; |
| ((GLubyte *)packedPixel)[index]|= |
| ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0; |
| } /* shove233rev() */ |
| |
| static void extract565(int isSwap, |
| const void *packedPixel, GLfloat extractComponents[]) |
| { |
| GLushort ushort; |
| |
| if (isSwap) { |
| ushort= __GLU_SWAP_2_BYTES(packedPixel); |
| } |
| else { |
| ushort= *(const GLushort *)packedPixel; |
| } |
| |
| /* 11111000,00000000 == 0xf800 */ |
| /* 00000111,11100000 == 0x07e0 */ |
| /* 00000000,00011111 == 0x001f */ |
| |
| extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ |
| extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/ |
| extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0; |
| } /* extract565() */ |
| |
| static void shove565(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 11111000,00000000 == 0xf800 */ |
| /* 00000111,11100000 == 0x07e0 */ |
| /* 00000000,00011111 == 0x001f */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLushort *)packedPixel)[index] = |
| ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f; |
| } /* shove565() */ |
| |
| static void extract565rev(int isSwap, |
| const void *packedPixel, GLfloat extractComponents[]) |
| { |
| GLushort ushort; |
| |
| if (isSwap) { |
| ushort= __GLU_SWAP_2_BYTES(packedPixel); |
| } |
| else { |
| ushort= *(const GLushort *)packedPixel; |
| } |
| |
| /* 00000000,00011111 == 0x001f */ |
| /* 00000111,11100000 == 0x07e0 */ |
| /* 11111000,00000000 == 0xf800 */ |
| |
| extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; |
| extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0; |
| extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0; |
| } /* extract565rev() */ |
| |
| static void shove565rev(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 00000000,00011111 == 0x001f */ |
| /* 00000111,11100000 == 0x07e0 */ |
| /* 11111000,00000000 == 0xf800 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLushort *)packedPixel)[index] = |
| ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800; |
| } /* shove565rev() */ |
| |
| static void extract4444(int isSwap,const void *packedPixel, |
| GLfloat extractComponents[]) |
| { |
| GLushort ushort; |
| |
| if (isSwap) { |
| ushort= __GLU_SWAP_2_BYTES(packedPixel); |
| } |
| else { |
| ushort= *(const GLushort *)packedPixel; |
| } |
| |
| /* 11110000,00000000 == 0xf000 */ |
| /* 00001111,00000000 == 0x0f00 */ |
| /* 00000000,11110000 == 0x00f0 */ |
| /* 00000000,00001111 == 0x000f */ |
| |
| extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */ |
| extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0; |
| extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0; |
| extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0; |
| } /* extract4444() */ |
| |
| static void shove4444(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLushort *)packedPixel)[index] = |
| ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f; |
| } /* shove4444() */ |
| |
| static void extract4444rev(int isSwap,const void *packedPixel, |
| GLfloat extractComponents[]) |
| { |
| GLushort ushort; |
| |
| if (isSwap) { |
| ushort= __GLU_SWAP_2_BYTES(packedPixel); |
| } |
| else { |
| ushort= *(const GLushort *)packedPixel; |
| } |
| |
| /* 00000000,00001111 == 0x000f */ |
| /* 00000000,11110000 == 0x00f0 */ |
| /* 00001111,00000000 == 0x0f00 */ |
| /* 11110000,00000000 == 0xf000 */ |
| |
| /* 15 = 2^4-1 */ |
| extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0; |
| extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0; |
| extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0; |
| extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0; |
| } /* extract4444rev() */ |
| |
| static void shove4444rev(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 00000000,00001111 == 0x000f */ |
| /* 00000000,11110000 == 0x00f0 */ |
| /* 00001111,00000000 == 0x0f00 */ |
| /* 11110000,00000000 == 0xf000 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLushort *)packedPixel)[index] = |
| ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000; |
| } /* shove4444rev() */ |
| |
| static void extract5551(int isSwap,const void *packedPixel, |
| GLfloat extractComponents[]) |
| { |
| GLushort ushort; |
| |
| if (isSwap) { |
| ushort= __GLU_SWAP_2_BYTES(packedPixel); |
| } |
| else { |
| ushort= *(const GLushort *)packedPixel; |
| } |
| |
| /* 11111000,00000000 == 0xf800 */ |
| /* 00000111,11000000 == 0x07c0 */ |
| /* 00000000,00111110 == 0x003e */ |
| /* 00000000,00000001 == 0x0001 */ |
| |
| extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ |
| extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0; |
| extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0; |
| extractComponents[3]=(float)((ushort & 0x0001) ); |
| } /* extract5551() */ |
| |
| static void shove5551(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 11111000,00000000 == 0xf800 */ |
| /* 00000111,11000000 == 0x07c0 */ |
| /* 00000000,00111110 == 0x003e */ |
| /* 00000000,00000001 == 0x0001 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLushort *)packedPixel)[index] = |
| ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001; |
| } /* shove5551() */ |
| |
| static void extract1555rev(int isSwap,const void *packedPixel, |
| GLfloat extractComponents[]) |
| { |
| GLushort ushort; |
| |
| if (isSwap) { |
| ushort= __GLU_SWAP_2_BYTES(packedPixel); |
| } |
| else { |
| ushort= *(const GLushort *)packedPixel; |
| } |
| |
| /* 00000000,00011111 == 0x001F */ |
| /* 00000011,11100000 == 0x03E0 */ |
| /* 01111100,00000000 == 0x7C00 */ |
| /* 10000000,00000000 == 0x8000 */ |
| |
| /* 31 = 2^5-1 */ |
| extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; |
| extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0; |
| extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0; |
| extractComponents[3]= (float)((ushort & 0x8000) >> 15); |
| } /* extract1555rev() */ |
| |
| static void shove1555rev(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 00000000,00011111 == 0x001F */ |
| /* 00000011,11100000 == 0x03E0 */ |
| /* 01111100,00000000 == 0x7C00 */ |
| /* 10000000,00000000 == 0x8000 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLushort *)packedPixel)[index] = |
| ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00; |
| ((GLushort *)packedPixel)[index]|= |
| ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000; |
| } /* shove1555rev() */ |
| |
| static void extract8888(int isSwap, |
| const void *packedPixel, GLfloat extractComponents[]) |
| { |
| GLuint uint; |
| |
| if (isSwap) { |
| uint= __GLU_SWAP_4_BYTES(packedPixel); |
| } |
| else { |
| uint= *(const GLuint *)packedPixel; |
| } |
| |
| /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
| /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
| /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
| /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
| |
| /* 255 = 2^8-1 */ |
| extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0; |
| extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0; |
| extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0; |
| extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0; |
| } /* extract8888() */ |
| |
| static void shove8888(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
| /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
| /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
| /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLuint *)packedPixel)[index] = |
| ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff; |
| } /* shove8888() */ |
| |
| static void extract8888rev(int isSwap, |
| const void *packedPixel,GLfloat extractComponents[]) |
| { |
| GLuint uint; |
| |
| if (isSwap) { |
| uint= __GLU_SWAP_4_BYTES(packedPixel); |
| } |
| else { |
| uint= *(const GLuint *)packedPixel; |
| } |
| |
| /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
| /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
| /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
| /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
| |
| /* 255 = 2^8-1 */ |
| extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0; |
| extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0; |
| extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0; |
| extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0; |
| } /* extract8888rev() */ |
| |
| static void shove8888rev(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
| /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
| /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
| /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLuint *)packedPixel)[index] = |
| ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000; |
| } /* shove8888rev() */ |
| |
| static void extract1010102(int isSwap, |
| const void *packedPixel,GLfloat extractComponents[]) |
| { |
| GLuint uint; |
| |
| if (isSwap) { |
| uint= __GLU_SWAP_4_BYTES(packedPixel); |
| } |
| else { |
| uint= *(const GLuint *)packedPixel; |
| } |
| |
| /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ |
| /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ |
| /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ |
| /* 00000000,00000000,00000000,00000011 == 0x00000003 */ |
| |
| /* 1023 = 2^10-1 */ |
| extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0; |
| extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0; |
| extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0; |
| extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0; |
| } /* extract1010102() */ |
| |
| static void shove1010102(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ |
| /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ |
| /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ |
| /* 00000000,00000000,00000000,00000011 == 0x00000003 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLuint *)packedPixel)[index] = |
| ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003; |
| } /* shove1010102() */ |
| |
| static void extract2101010rev(int isSwap, |
| const void *packedPixel, |
| GLfloat extractComponents[]) |
| { |
| GLuint uint; |
| |
| if (isSwap) { |
| uint= __GLU_SWAP_4_BYTES(packedPixel); |
| } |
| else { |
| uint= *(const GLuint *)packedPixel; |
| } |
| |
| /* 00000000,00000000,00000011,11111111 == 0x000003FF */ |
| /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ |
| /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ |
| /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ |
| |
| /* 1023 = 2^10-1 */ |
| extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0; |
| extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0; |
| extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0; |
| extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0; |
| /* 3 = 2^2-1 */ |
| } /* extract2101010rev() */ |
| |
| static void shove2101010rev(const GLfloat shoveComponents[], |
| int index,void *packedPixel) |
| { |
| /* 00000000,00000000,00000011,11111111 == 0x000003FF */ |
| /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ |
| /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ |
| /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ |
| |
| assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
| assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
| assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
| assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
| |
| /* due to limited precision, need to round before shoving */ |
| ((GLuint *)packedPixel)[index] = |
| ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000; |
| ((GLuint *)packedPixel)[index]|= |
| ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000; |
| } /* shove2101010rev() */ |
| |
| static void scaleInternalPackedPixel(int components, |
| void (*extractPackedPixel) |
| (int, const void *,GLfloat []), |
| void (*shovePackedPixel) |
| (const GLfloat [], int, void *), |
| GLint widthIn,GLint heightIn, |
| const void *dataIn, |
| GLint widthOut,GLint heightOut, |
| void *dataOut, |
| GLint pixelSizeInBytes, |
| GLint rowSizeInBytes,GLint isSwap) |
| { |
| float convx; |
| float convy; |
| float percent; |
| |
| /* Max components in a format is 4, so... */ |
| float totals[4]; |
| float extractTotals[4], extractMoreTotals[4], shoveTotals[4]; |
| |
| float area; |
| int i,j,k,xindex; |
| |
| const char *temp, *temp0; |
| int outindex; |
| |
| int lowx_int, highx_int, lowy_int, highy_int; |
| float x_percent, y_percent; |
| float lowx_float, highx_float, lowy_float, highy_float; |
| float convy_float, convx_float; |
| int convy_int, convx_int; |
| int l, m; |
| const char *left, *right; |
| |
| if (widthIn == widthOut*2 && heightIn == heightOut*2) { |
| halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, |
| widthIn, heightIn, dataIn, dataOut, |
| pixelSizeInBytes,rowSizeInBytes,isSwap); |
| return; |
| } |
| convy = (float) heightIn/heightOut; |
| convx = (float) widthIn/widthOut; |
| convy_int = floor(convy); |
| convy_float = convy - convy_int; |
| convx_int = floor(convx); |
| convx_float = convx - convx_int; |
| |
| area = convx * convy; |
| |
| lowy_int = 0; |
| lowy_float = 0; |
| highy_int = convy_int; |
| highy_float = convy_float; |
| |
| for (i = 0; i < heightOut; i++) { |
| lowx_int = 0; |
| lowx_float = 0; |
| highx_int = convx_int; |
| highx_float = convx_float; |
| |
| for (j = 0; j < widthOut; j++) { |
| /* |
| ** Ok, now apply box filter to box that goes from (lowx, lowy) |
| ** to (highx, highy) on input data into this pixel on output |
| ** data. |
| */ |
| totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
| |
| /* calculate the value for pixels in the 1st row */ |
| xindex = lowx_int*pixelSizeInBytes; |
| if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
| |
| y_percent = 1-lowy_float; |
| temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; |
| percent = y_percent * (1-lowx_float); |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| left = temp; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += pixelSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * y_percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * y_percent; |
| } |
| #endif |
| } |
| temp += pixelSizeInBytes; |
| right = temp; |
| percent = y_percent * highx_float; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| |
| /* calculate the value for pixels in the last row */ |
| |
| y_percent = highy_float; |
| percent = y_percent * (1-lowx_float); |
| temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| for(l = lowx_int+1; l < highx_int; l++) { |
| temp += pixelSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * y_percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * y_percent; |
| } |
| #endif |
| |
| } |
| temp += pixelSizeInBytes; |
| percent = y_percent * highx_float; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| |
| /* calculate the value for pixels in the 1st and last column */ |
| for(m = lowy_int+1; m < highy_int; m++) { |
| left += rowSizeInBytes; |
| right += rowSizeInBytes; |
| #if 0 |
| for (k = 0; k < components; |
| k++, left += element_size, right += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + |
| __GLU_SWAP_2_BYTES(right) * highx_float; |
| } else { |
| totals[k] += *(const GLushort*)left * (1-lowx_float) |
| + *(const GLushort*)right * highx_float; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,left,extractTotals); |
| (*extractPackedPixel)(isSwap,right,extractMoreTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= (extractTotals[k]*(1-lowx_float) + |
| extractMoreTotals[k]*highx_float); |
| } |
| #endif |
| } |
| } else if (highy_int > lowy_int) { |
| x_percent = highx_float - lowx_float; |
| percent = (1-lowy_float)*x_percent; |
| temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| for(m = lowy_int+1; m < highy_int; m++) { |
| temp += rowSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * x_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * x_percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * x_percent; |
| } |
| #endif |
| } |
| percent = x_percent * highy_float; |
| temp += rowSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| } else if (highx_int > lowx_int) { |
| y_percent = highy_float - lowy_float; |
| percent = (1-lowx_float)*y_percent; |
| temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| for (l = lowx_int+1; l < highx_int; l++) { |
| temp += pixelSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += |
| __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * y_percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * y_percent; |
| } |
| #endif |
| } |
| temp += pixelSizeInBytes; |
| percent = y_percent * highx_float; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| } else { |
| percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
| temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
| } else { |
| totals[k] += *(const GLushort*)temp_index * percent; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k] * percent; |
| } |
| #endif |
| } |
| |
| /* this is for the pixels in the body */ |
| temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes; |
| for (m = lowy_int+1; m < highy_int; m++) { |
| temp = temp0; |
| for(l = lowx_int+1; l < highx_int; l++) { |
| #if 0 |
| for (k = 0, temp_index = temp; k < components; |
| k++, temp_index += element_size) { |
| if (myswap_bytes) { |
| totals[k] += __GLU_SWAP_2_BYTES(temp_index); |
| } else { |
| totals[k] += *(const GLushort*)temp_index; |
| } |
| } |
| #else |
| (*extractPackedPixel)(isSwap,temp,extractTotals); |
| for (k = 0; k < components; k++) { |
| totals[k]+= extractTotals[k]; |
| } |
| #endif |
| temp += pixelSizeInBytes; |
| } |
| temp0 += rowSizeInBytes; |
| } |
| |
| outindex = (j + (i * widthOut)); /* * (components == 1) */ |
| #if 0 |
| for (k = 0; k < components; k++) { |
| dataout[outindex + k] = totals[k]/area; |
| /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
| } |
| #else |
| for (k = 0; k < components; k++) { |
| shoveTotals[k]= totals[k]/area; |
| } |
| (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut); |
| #endif |
| lowx_int = highx_int; |
| lowx_float = highx_float; |
| highx_int += convx_int; |
| highx_float += convx_float; |
| if(highx_float > 1) { |
| highx_float -= 1.0; |
| highx_int++; |
| } |
| } |
| lowy_int = highy_int; |
| lowy_float = highy_float; |
| highy_int += convy_int; |
| highy_float += convy_float; |
| if(highy_float > 1) { |
| highy_float -= 1.0; |
| highy_int++; |
| } |
| } |
| |
| assert(outindex == (widthOut*heightOut - 1)); |
| } /* scaleInternalPackedPixel() */ |
| |
| /* rowSizeInBytes is at least the width (in bytes) due to padding on |
| * inputs; not always equal. Output NEVER has row padding. |
| */ |
| static void halveImagePackedPixel(int components, |
| void (*extractPackedPixel) |
| (int, const void *,GLfloat []), |
| void (*shovePackedPixel) |
| (const GLfloat [],int, void *), |
| GLint width, GLint height, |
| const void *dataIn, void *dataOut, |
| GLint pixelSizeInBytes, |
| GLint rowSizeInBytes, GLint isSwap) |
| { |
| /* handle case where there is only 1 column/row */ |
| if (width == 1 || height == 1) { |
| assert(!(width == 1 && height == 1)); /* can't be 1x1 */ |
| halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel, |
| width,height,dataIn,dataOut,pixelSizeInBytes, |
| rowSizeInBytes,isSwap); |
| return; |
| } |
| |
| { |
| int ii, jj; |
| |
| int halfWidth= width / 2; |
| int halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); |
| int outIndex= 0; |
| |
| for (ii= 0; ii< halfHeight; ii++) { |
| for (jj= 0; jj< halfWidth; jj++) { |
| #define BOX4 4 |
| float totals[4]; /* 4 is maximum components */ |
| float extractTotals[BOX4][4]; /* 4 is maximum components */ |
| int cc; |
| |
| (*extractPackedPixel)(isSwap,src, |
| &extractTotals[0][0]); |
| (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
| &extractTotals[1][0]); |
| (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
| &extractTotals[2][0]); |
| (*extractPackedPixel)(isSwap, |
| (src+rowSizeInBytes+pixelSizeInBytes), |
| &extractTotals[3][0]); |
| for (cc = 0; cc < components; cc++) { |
| int kk; |
| |
| /* grab 4 pixels to average */ |
| totals[cc]= 0.0; |
| /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
| * extractTotals[2][RED]+extractTotals[3][RED]; |
| * totals[RED]/= 4.0; |
| */ |
| for (kk = 0; kk < BOX4; kk++) { |
| totals[cc]+= extractTotals[kk][cc]; |
| } |
| totals[cc]/= (float)BOX4; |
| } |
| (*shovePackedPixel)(totals,outIndex,dataOut); |
| |
| outIndex++; |
| /* skip over to next square of 4 */ |
| src+= pixelSizeInBytes + pixelSizeInBytes; |
| } |
| /* skip past pad bytes, if any, to get to next row */ |
| src+= padBytes; |
| |
| /* src is at beginning of a row here, but it's the second row of |
| * the square block of 4 pixels that we just worked on so we |
| * need to go one more row. |
| * i.e., |
| * OO... |
| * here -->OO... |
| * but want -->OO... |
| * OO... |
| * ... |
| */ |
| src+= rowSizeInBytes; |
| } |
| |
| /* both pointers must reach one byte after the end */ |
| assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); |
| assert(outIndex == halfWidth * halfHeight); |
| } |
| } /* halveImagePackedPixel() */ |
| |
| static void halve1DimagePackedPixel(int components, |
| void (*extractPackedPixel) |
| (int, const void *,GLfloat []), |
| void (*shovePackedPixel) |
| (const GLfloat [],int, void *), |
| GLint width, GLint height, |
| const void *dataIn, void *dataOut, |
| GLint pixelSizeInBytes, |
| GLint rowSizeInBytes, GLint isSwap) |
| { |
| int halfWidth= width / 2; |
| int halfHeight= height / 2; |
| const char *src= (const char *) dataIn; |
| int jj; |
| |
| assert(width == 1 || height == 1); /* must be 1D */ |
| assert(width != height); /* can't be square */ |
| |
| if (height == 1) { /* 1 row */ |
| int outIndex= 0; |
| |
| assert(width != 1); /* widthxheight can't be 1x1 */ |
| halfHeight= 1; |
| |
| /* one horizontal row with possible pad bytes */ |
| |
| for (jj= 0; jj< halfWidth; jj++) { |
| #define BOX2 2 |
| float totals[4]; /* 4 is maximum components */ |
| float extractTotals[BOX2][4]; /* 4 is maximum components */ |
| int cc; |
| |
| /* average two at a time, instead of four */ |
| (*extractPackedPixel)(isSwap,src, |
| &extractTotals[0][0]); |
| (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
| &extractTotals[1][0]); |
| for (cc = 0; cc < components; cc++) { |
| int kk; |
| |
| /* grab 2 pixels to average */ |
| totals[cc]= 0.0; |
| /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; |
| * totals[RED]/= 2.0; |
| */ |
| for (kk = 0; kk < BOX2; kk++) { |
| totals[cc]+= extractTotals[kk][cc]; |
| } |
| totals[cc]/= (float)BOX2; |
| } |
| (*shovePackedPixel)(totals,outIndex,dataOut); |
| |
| outIndex++; |
| /* skip over to next group of 2 */ |
| src+= pixelSizeInBytes + pixelSizeInBytes; |
| } |
| |
| { |
| int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); |
| src+= padBytes; /* for assertion only */ |
| } |
| assert(src == &((const char *)dataIn)[rowSizeInBytes]); |
| assert(outIndex == halfWidth * halfHeight); |
| } |
| else if (width == 1) { /* 1 column */ |
| int outIndex= 0; |
| |
| assert(height != 1); /* widthxheight can't be 1x1 */ |
| halfWidth= 1; |
| /* one vertical column with possible pad bytes per row */ |
| /* average two at a time */ |
| |
| for (jj= 0; jj< halfHeight; jj++) { |
| #define BOX2 2 |
| float totals[4]; /* 4 is maximum components */ |
| float extractTotals[BOX2][4]; /* 4 is maximum components */ |
| int cc; |
| |
| /* average two at a time, instead of four */ |
| (*extractPackedPixel)(isSwap,src, |
| &extractTotals[0][0]); |
| (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
| &extractTotals[1][0]); |
| for (cc = 0; cc < components; cc++) { |
| int kk; |
| |
| /* grab 2 pixels to average */ |
| totals[cc]= 0.0; |
| /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; |
| * totals[RED]/= 2.0; |
| */ |
| for (kk = 0; kk < BOX2; kk++) { |
| totals[cc]+= extractTotals[kk][cc]; |
| } |
| totals[cc]/= (float)BOX2; |
| } |
| (*shovePackedPixel)(totals,outIndex,dataOut); |
| |
| outIndex++; |
| src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */ |
| } |
| |
| assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); |
| assert(outIndex == halfWidth * halfHeight); |
| } |
| } /* halve1DimagePackedPixel() */ |