0,0 → 1,8940 |
/* |
* 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 "gluos.h" |
#include <assert.h> |
#include <GL/glu.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <limits.h> /* UINT_MAX */ |
#include <math.h> |
|
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 *); |
static int gluBuild3DMipmapLevelsCore(GLenum, GLint, |
GLsizei, GLsizei, 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 GLboolean isLegalLevels(GLint, GLint, GLint, GLint); |
static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum, |
GLint *, GLint *); |
|
/* all extract/shove routines must return double to handle unsigned ints */ |
static GLdouble extractUbyte(int, const void *); |
static void shoveUbyte(GLdouble, int, void *); |
static GLdouble extractSbyte(int, const void *); |
static void shoveSbyte(GLdouble, int, void *); |
static GLdouble extractUshort(int, const void *); |
static void shoveUshort(GLdouble, int, void *); |
static GLdouble extractSshort(int, const void *); |
static void shoveSshort(GLdouble, int, void *); |
static GLdouble extractUint(int, const void *); |
static void shoveUint(GLdouble, int, void *); |
static GLdouble extractSint(int, const void *); |
static void shoveSint(GLdouble, int, void *); |
static GLdouble extractFloat(int, const void *); |
static void shoveFloat(GLdouble, int, void *); |
static void halveImageSlice(int, GLdouble (*)(int, const void *), |
void (*)(GLdouble, int, void *), |
GLint, GLint, GLint, |
const void *, void *, |
GLint, GLint, GLint, GLint, GLint); |
static void halveImage3D(int, GLdouble (*)(int, const void *), |
void (*)(GLdouble, int, void *), |
GLint, GLint, GLint, |
const void *, void *, |
GLint, GLint, GLint, 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 GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum); |
static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum, |
GLenum, GLboolean, const void *, GLushort *); |
static void emptyImage3D(const PixelStorageModes *, |
GLint, GLint, GLint, GLenum, |
GLenum, GLboolean, |
const GLushort *, void *); |
static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *, |
GLint, GLint, GLint, GLushort *); |
|
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 void retrieveStoreModes3D(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_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images); |
glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height); |
|
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); |
glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images); |
glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height); |
} |
|
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() */ |
|
static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel, |
GLint totalLevels) |
{ |
if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel || |
totalLevels < maxLevel) |
return GL_FALSE; |
else return GL_TRUE; |
} /* isLegalLevels() */ |
|
/* 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 defined(GL_ARB_texture_cube_map) |
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 |
#endif /* GL_ARB_texture_cube_map */ |
{ |
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() */ |
|
GLint GLAPIENTRY |
gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin, |
GLenum typein, const void *datain, |
GLsizei widthout, GLsizei 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 = |
malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT)); |
afterImage = |
malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT)); |
if (beforeImage == NULL || afterImage == NULL) { |
free(beforeImage); |
free(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); |
free((GLbyte *) beforeImage); |
free((GLbyte *) 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 = (GLushort *) |
malloc(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 = (GLushort *) malloc(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); |
free(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); |
|
free((GLbyte *) newImage); |
if (otherImage) { |
free((GLbyte *) otherImage); |
} |
return 0; |
} |
|
GLint GLAPIENTRY |
gluBuild1DMipmapLevels(GLenum target, GLint internalFormat, |
GLsizei width, |
GLenum format, GLenum type, |
GLint userLevel, GLint baseLevel, GLint maxLevel, |
const void *data) |
{ |
int levels; |
|
int rc= checkMipmapArgs(internalFormat,format,type); |
if (rc != 0) return rc; |
|
if (width < 1) { |
return GLU_INVALID_VALUE; |
} |
|
levels = computeLog(width); |
|
levels+= userLevel; |
if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) |
return GLU_INVALID_VALUE; |
|
return gluBuild1DMipmapLevelsCore(target, internalFormat, |
width, |
width,format, type, |
userLevel, baseLevel, maxLevel, |
data); |
} /* gluBuild1DMipmapLevels() */ |
|
GLint GLAPIENTRY |
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 = (GLushort *) |
malloc(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 = (GLushort *) malloc(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); |
free(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); |
|
free((GLbyte *) newImage); |
if (otherImage) { |
free((GLbyte *) 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: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memreq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memreq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memreq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memreq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memreq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memreq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
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: |
dstImage = (GLushort *)malloc(memreq); |
break; |
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 *)malloc(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: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memreq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memreq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memreq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memreq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memreq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memreq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
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: |
dstImage = (GLushort *)malloc(memreq); |
break; |
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 *)malloc(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); |
free(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: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memreq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memreq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memreq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memreq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memreq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memreq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
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: |
dstImage = (GLushort *)malloc(memreq); |
break; |
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 *)malloc(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: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memreq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memreq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memreq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memreq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memreq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memreq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memreq); |
break; |
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: |
dstImage = (GLushort *)malloc(memreq); |
break; |
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 *)malloc(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); |
free(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= malloc((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); |
} |
free(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); |
|
free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ |
if (dstImage) { /* if it's non-rectangular and only 1 level */ |
free(dstImage); |
} |
return 0; |
} /* gluBuild2DMipmapLevelsCore() */ |
|
GLint GLAPIENTRY |
gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, |
GLsizei width, GLsizei height, |
GLenum format, GLenum type, |
GLint userLevel, GLint baseLevel, GLint maxLevel, |
const void *data) |
{ |
int level, levels; |
|
int rc= checkMipmapArgs(internalFormat,format,type); |
if (rc != 0) return rc; |
|
if (width < 1 || height < 1) { |
return GLU_INVALID_VALUE; |
} |
|
levels = computeLog(width); |
level = computeLog(height); |
if (level > levels) levels=level; |
|
levels+= userLevel; |
if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) |
return GLU_INVALID_VALUE; |
|
return gluBuild2DMipmapLevelsCore(target, internalFormat, |
width, height, |
width, height, |
format, type, |
userLevel, baseLevel, maxLevel, |
data); |
} /* gluBuild2DMipmapLevels() */ |
|
GLint GLAPIENTRY |
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() */ |
|
#if 0 |
/* |
** This routine is for the limited case in which |
** type == GL_UNSIGNED_BYTE && format != index && |
** unpack_alignment = 1 && unpack_swap_bytes == false |
** |
** so all of the work data can be kept as ubytes instead of shorts. |
*/ |
static int fastBuild2DMipmaps(const PixelStorageModes *psm, |
GLenum target, GLint components, GLint width, |
GLint height, GLenum format, |
GLenum type, void *data) |
{ |
GLint newwidth, newheight; |
GLint level, levels; |
GLubyte *newImage; |
GLint newImage_width; |
GLint newImage_height; |
GLubyte *otherImage; |
GLubyte *imageTemp; |
GLint memreq; |
GLint cmpts; |
|
|
#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,components,format,type, |
&newwidth,&newheight); |
#endif |
levels = computeLog(newwidth); |
level = computeLog(newheight); |
if (level > levels) levels=level; |
|
cmpts = elements_per_group(format,type); |
|
otherImage = NULL; |
/** |
** No need to copy the user data if its in the packed correctly. |
** Make sure that later routines don't change that data. |
*/ |
if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) { |
newImage = (GLubyte *)data; |
newImage_width = width; |
newImage_height = height; |
} else { |
GLint rowsize; |
GLint groups_per_line; |
GLint elements_per_line; |
const GLubyte *start; |
const GLubyte *iter; |
GLubyte *iter2; |
GLint i, j; |
|
newImage = (GLubyte *) |
malloc(image_size(width, height, format, GL_UNSIGNED_BYTE)); |
newImage_width = width; |
newImage_height = height; |
if (newImage == NULL) { |
return GLU_OUT_OF_MEMORY; |
} |
|
/* |
** Abbreviated version of fill_image for this restricted case. |
*/ |
if (psm->unpack_row_length > 0) { |
groups_per_line = psm->unpack_row_length; |
} else { |
groups_per_line = width; |
} |
rowsize = groups_per_line * cmpts; |
elements_per_line = width * cmpts; |
start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize + |
psm->unpack_skip_pixels * cmpts; |
iter2 = newImage; |
|
for (i = 0; i < height; i++) { |
iter = start; |
for (j = 0; j < elements_per_line; j++) { |
*iter2 = *iter; |
iter++; |
iter2++; |
} |
start += rowsize; |
} |
} |
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
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, components, newImage_width, |
newImage_height, 0, format, GL_UNSIGNED_BYTE, |
(void *) newImage); |
} else { |
if (otherImage == NULL) { |
memreq = |
image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE); |
otherImage = (GLubyte *) malloc(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); |
return GLU_OUT_OF_MEMORY; |
} |
} |
/* |
scale_internal_ubyte(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, components, newImage_width, |
newImage_height, 0, format, GL_UNSIGNED_BYTE, |
(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); |
|
if (newImage != (const GLubyte *)data) { |
free((GLbyte *) newImage); |
} |
if (otherImage && otherImage != (const GLubyte *)data) { |
free((GLbyte *) otherImage); |
} |
return 0; |
} |
#endif |
|
/* |
* 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; |
|
isSwap= isSwap; /* turn off warnings */ |
|
/* 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; |
|
isSwap= isSwap; /* turn off warnings */ |
|
/* 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() */ |
|
/*===========================================================================*/ |
|
#ifdef RESOLVE_3D_TEXTURE_SUPPORT |
/* |
* This section ensures that GLU 1.3 will load and run on |
* a GL 1.1 implementation. It dynamically resolves the |
* call to glTexImage3D() which might not be available. |
* Or is it might be supported as an extension. |
* Contributed by Gerk Huisma <gerk@five-d.demon.nl>. |
*/ |
|
typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level, |
GLenum internalFormat, |
GLsizei width, GLsizei height, |
GLsizei depth, GLint border, |
GLenum format, GLenum type, |
const GLvoid *pixels ); |
|
static TexImage3Dproc pTexImage3D = 0; |
|
#if !defined(_WIN32) && !defined(__WIN32__) |
# include <dlfcn.h> |
# include <sys/types.h> |
#else |
WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); |
#endif |
|
static void gluTexImage3D( GLenum target, GLint level, |
GLenum internalFormat, |
GLsizei width, GLsizei height, |
GLsizei depth, GLint border, |
GLenum format, GLenum type, |
const GLvoid *pixels ) |
{ |
if (!pTexImage3D) { |
#if defined(_WIN32) || defined(__WIN32__) |
pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D"); |
if (!pTexImage3D) |
pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT"); |
#else |
void *libHandle = dlopen("libgl.so", RTLD_LAZY); |
pTexImage3D = TexImage3Dproc) dlsym(libHandle, "glTexImage3D" ); |
if (!pTexImage3D) |
pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT"); |
dlclose(libHandle); |
#endif |
} |
|
/* Now call glTexImage3D */ |
if (pTexImage3D) |
pTexImage3D(target, level, internalFormat, width, height, |
depth, border, format, type, pixels); |
} |
|
#else |
|
/* Only bind to a GL 1.2 implementation: */ |
#define gluTexImage3D glTexImage3D |
|
#endif |
|
static GLint imageSize3D(GLint width, GLint height, GLint depth, |
GLenum format, GLenum type) |
{ |
int components= elements_per_group(format,type); |
int bytes_per_row= bytes_per_element(type) * width; |
|
assert(width > 0 && height > 0 && depth > 0); |
assert(type != GL_BITMAP); |
|
return bytes_per_row * height * depth * components; |
} /* imageSize3D() */ |
|
static void fillImage3D(const PixelStorageModes *psm, |
GLint width, GLint height, GLint depth, GLenum format, |
GLenum type, GLboolean indexFormat, |
const void *userImage, GLushort *newImage) |
{ |
int myswapBytes; |
int components; |
int groupsPerLine; |
int elementSize; |
int groupSize; |
int rowSize; |
int padding; |
int elementsPerLine; |
int rowsPerImage; |
int imageSize; |
const GLubyte *start, *rowStart, *iter; |
GLushort *iter2; |
int ww, hh, dd, k; |
|
myswapBytes= psm->unpack_swap_bytes; |
components= elements_per_group(format,type); |
if (psm->unpack_row_length > 0) { |
groupsPerLine= psm->unpack_row_length; |
} |
else { |
groupsPerLine= width; |
} |
elementSize= bytes_per_element(type); |
groupSize= elementSize * components; |
if (elementSize == 1) myswapBytes= 0; |
|
/* 3dstuff begin */ |
if (psm->unpack_image_height > 0) { |
rowsPerImage= psm->unpack_image_height; |
} |
else { |
rowsPerImage= height; |
} |
/* 3dstuff end */ |
|
rowSize= groupsPerLine * groupSize; |
padding= rowSize % psm->unpack_alignment; |
if (padding) { |
rowSize+= psm->unpack_alignment - padding; |
} |
|
imageSize= rowsPerImage * rowSize; /* 3dstuff */ |
|
start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize + |
psm->unpack_skip_pixels * groupSize + |
/*3dstuff*/ |
psm->unpack_skip_images * imageSize; |
elementsPerLine = width * components; |
|
iter2= newImage; |
for (dd= 0; dd < depth; dd++) { |
rowStart= start; |
|
for (hh= 0; hh < height; hh++) { |
iter= rowStart; |
|
for (ww= 0; ww < elementsPerLine; ww++) { |
Type_Widget widget; |
float extractComponents[4]; |
|
switch(type) { |
case GL_UNSIGNED_BYTE: |
if (indexFormat) { |
*iter2++ = *iter; |
} else { |
*iter2++ = (*iter) * 257; |
} |
break; |
case GL_BYTE: |
if (indexFormat) { |
*iter2++ = *((const GLbyte *) iter); |
} else { |
/* rough approx */ |
*iter2++ = (*((const GLbyte *) iter)) * 516; |
} |
break; |
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_SHORT_5_6_5: |
extract565(myswapBytes,iter,extractComponents); |
for (k = 0; k < 3; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_SHORT_5_6_5_REV: |
extract565rev(myswapBytes,iter,extractComponents); |
for (k = 0; k < 3; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_SHORT_4_4_4_4: |
extract4444(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
extract4444rev(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_SHORT_5_5_5_1: |
extract5551(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
extract1555rev(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_SHORT: |
case GL_SHORT: |
if (myswapBytes) { |
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 (indexFormat) { |
*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(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_INT_8_8_8_8_REV: |
extract8888rev(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_INT_10_10_10_2: |
extract1010102(myswapBytes,iter,extractComponents); |
for (k = 0; k < 4; k++) { |
*iter2++ = (GLushort)(extractComponents[k]*65535); |
} |
break; |
case GL_UNSIGNED_INT_2_10_10_10_REV: |
extract2101010rev(myswapBytes,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 (myswapBytes) { |
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 (indexFormat) { |
*iter2++ = widget.f; |
} else { |
*iter2++ = 65535 * widget.f; |
} |
} else if (type == GL_UNSIGNED_INT) { |
if (indexFormat) { |
*iter2++ = widget.ui; |
} else { |
*iter2++ = widget.ui >> 16; |
} |
} else { |
if (indexFormat) { |
*iter2++ = widget.i; |
} else { |
*iter2++ = widget.i >> 15; |
} |
} |
break; |
default: |
assert(0); |
} |
|
iter+= elementSize; |
} /* for ww */ |
rowStart+= rowSize; |
|
iter= rowStart; /* for assertion purposes */ |
} /* for hh */ |
|
start+= imageSize; |
} /* for dd */ |
|
/* iterators should be one byte past end */ |
if (!isTypePackedPixel(type)) { |
assert(iter2 == &newImage[width*height*depth*components]); |
} |
else { |
assert(iter2 == &newImage[width*height*depth* |
elements_per_group(format,0)]); |
} |
assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth + |
psm->unpack_skip_rows * rowSize + |
psm->unpack_skip_pixels * groupSize + |
/*3dstuff*/ |
psm->unpack_skip_images * imageSize] ); |
} /* fillImage3D () */ |
|
static void scaleInternal3D(GLint components, |
GLint widthIn, GLint heightIn, GLint depthIn, |
const GLushort *dataIn, |
GLint widthOut, GLint heightOut, GLint depthOut, |
GLushort *dataOut) |
{ |
float x, lowx, highx, convx, halfconvx; |
float y, lowy, highy, convy, halfconvy; |
float z, lowz, highz, convz, halfconvz; |
float xpercent,ypercent,zpercent; |
float percent; |
/* Max components in a format is 4, so... */ |
float totals[4]; |
float volume; |
int i,j,d,k,zint,yint,xint,xindex,yindex,zindex; |
int temp; |
|
convz = (float) depthIn/depthOut; |
convy = (float) heightIn/heightOut; |
convx = (float) widthIn/widthOut; |
halfconvx = convx/2; |
halfconvy = convy/2; |
halfconvz = convz/2; |
for (d = 0; d < depthOut; d++) { |
z = convz * (d+0.5); |
if (depthIn > depthOut) { |
highz = z + halfconvz; |
lowz = z - halfconvz; |
} else { |
highz = z + 0.5; |
lowz = z - 0.5; |
} |
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, |
** lowz) to (highx, highy, highz) on input data into this pixel |
** on output data. |
*/ |
totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
volume = 0.0; |
|
z = lowz; |
zint = floor(z); |
while (z < highz) { |
zindex = (zint + depthIn) % depthIn; |
if (highz < zint+1) { |
zpercent = highz - z; |
} else { |
zpercent = zint+1 - z; |
} |
|
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 * zpercent; |
volume += percent; |
|
temp = (xindex + (yindex*widthIn) + |
(zindex*widthIn*heightIn)) * components; |
for (k = 0; k < components; k++) { |
assert(0 <= (temp+k) && |
(temp+k) < |
(widthIn*heightIn*depthIn*components)); |
totals[k] += dataIn[temp + k] * percent; |
} |
|
xint++; |
x = xint; |
} /* while x */ |
|
yint++; |
y = yint; |
} /* while y */ |
|
zint++; |
z = zint; |
} /* while z */ |
|
temp = (j + (i * widthOut) + |
(d*widthOut*heightOut)) * 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 |
*/ |
assert(0 <= (temp+k) && |
(temp+k) < (widthOut*heightOut*depthOut*components)); |
dataOut[temp + k] = (totals[k]+0.5)/volume; |
} |
} /* for j */ |
} /* for i */ |
} /* for d */ |
} /* scaleInternal3D() */ |
|
static void emptyImage3D(const PixelStorageModes *psm, |
GLint width, GLint height, GLint depth, |
GLenum format, GLenum type, GLboolean indexFormat, |
const GLushort *oldImage, void *userImage) |
{ |
int myswapBytes; |
int components; |
int groupsPerLine; |
int elementSize; |
int groupSize; |
int rowSize; |
int padding; |
GLubyte *start, *rowStart, *iter; |
int elementsPerLine; |
const GLushort *iter2; |
int ii, jj, dd, k; |
int rowsPerImage; |
int imageSize; |
|
myswapBytes= psm->pack_swap_bytes; |
components = elements_per_group(format,type); |
if (psm->pack_row_length > 0) { |
groupsPerLine = psm->pack_row_length; |
} |
else { |
groupsPerLine = width; |
} |
|
elementSize= bytes_per_element(type); |
groupSize= elementSize * components; |
if (elementSize == 1) myswapBytes= 0; |
|
/* 3dstuff begin */ |
if (psm->pack_image_height > 0) { |
rowsPerImage= psm->pack_image_height; |
} |
else { |
rowsPerImage= height; |
} |
|
/* 3dstuff end */ |
|
rowSize = groupsPerLine * groupSize; |
padding = rowSize % psm->pack_alignment; |
if (padding) { |
rowSize+= psm->pack_alignment - padding; |
} |
|
imageSize= rowsPerImage * rowSize; /* 3dstuff */ |
|
start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize + |
psm->pack_skip_pixels * groupSize + |
/*3dstuff*/ |
psm->pack_skip_images * imageSize; |
elementsPerLine= width * components; |
|
iter2 = oldImage; |
for (dd= 0; dd < depth; dd++) { |
rowStart= start; |
|
for (ii= 0; ii< height; ii++) { |
iter = rowStart; |
|
for (jj = 0; jj < elementsPerLine; jj++) { |
Type_Widget widget; |
float shoveComponents[4]; |
|
switch(type){ |
case GL_UNSIGNED_BYTE: |
if (indexFormat) { |
*iter = *iter2++; |
} else { |
*iter = *iter2++ >> 8; |
} |
break; |
case GL_BYTE: |
if (indexFormat) { |
*((GLbyte *) iter) = *iter2++; |
} else { |
*((GLbyte *) iter) = *iter2++ >> 9; |
} |
break; |
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_SHORT_5_6_5: |
for (k = 0; k < 3; k++) { |
shoveComponents[k]= *iter2++ / 65535.0; |
} |
shove565(shoveComponents,0,(void *)&widget.us[0]); |
if (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (indexFormat) { |
widget.s[0] = *iter2++; |
} else { |
widget.s[0] = *iter2++ >> 1; |
} |
} else { |
widget.us[0] = *iter2++; |
} |
if (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (myswapBytes) { |
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 (indexFormat) { |
widget.f = *iter2++; |
} else { |
widget.f = *iter2++ / (float) 65535.0; |
} |
} else if (type == GL_UNSIGNED_INT) { |
if (indexFormat) { |
widget.ui = *iter2++; |
} else { |
widget.ui = (unsigned int) *iter2++ * 65537; |
} |
} else { |
if (indexFormat) { |
widget.i = *iter2++; |
} else { |
widget.i = ((unsigned int) *iter2++ * 65537)/2; |
} |
} |
if (myswapBytes) { |
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; |
default: |
assert(0); |
} |
|
iter+= elementSize; |
} /* for jj */ |
|
rowStart+= rowSize; |
} /* for ii */ |
|
start+= imageSize; |
} /* for dd */ |
|
/* iterators should be one byte past end */ |
if (!isTypePackedPixel(type)) { |
assert(iter2 == &oldImage[width*height*depth*components]); |
} |
else { |
assert(iter2 == &oldImage[width*height*depth* |
elements_per_group(format,0)]); |
} |
assert( iter == &((GLubyte *)userImage)[rowSize*height*depth + |
psm->unpack_skip_rows * rowSize + |
psm->unpack_skip_pixels * groupSize + |
/*3dstuff*/ |
psm->unpack_skip_images * imageSize] ); |
} /* emptyImage3D() */ |
|
static |
int gluScaleImage3D(GLenum format, |
GLint widthIn, GLint heightIn, GLint depthIn, |
GLenum typeIn, const void *dataIn, |
GLint widthOut, GLint heightOut, GLint depthOut, |
GLenum typeOut, void *dataOut) |
{ |
int components; |
GLushort *beforeImage, *afterImage; |
PixelStorageModes psm; |
|
if (widthIn == 0 || heightIn == 0 || depthIn == 0 || |
widthOut == 0 || heightOut == 0 || depthOut == 0) { |
return 0; |
} |
|
if (widthIn < 0 || heightIn < 0 || depthIn < 0 || |
widthOut < 0 || heightOut < 0 || depthOut < 0) { |
return GLU_INVALID_VALUE; |
} |
|
if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) || |
typeIn == GL_BITMAP || typeOut == GL_BITMAP) { |
return GLU_INVALID_ENUM; |
} |
if (!isLegalFormatForPackedPixelType(format, typeIn)) { |
return GLU_INVALID_OPERATION; |
} |
if (!isLegalFormatForPackedPixelType(format, typeOut)) { |
return GLU_INVALID_OPERATION; |
} |
|
beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format, |
GL_UNSIGNED_SHORT)); |
afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format, |
GL_UNSIGNED_SHORT)); |
if (beforeImage == NULL || afterImage == NULL) { |
free(beforeImage); |
free(afterImage); |
return GLU_OUT_OF_MEMORY; |
} |
retrieveStoreModes3D(&psm); |
|
fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format), |
dataIn, beforeImage); |
components = elements_per_group(format,0); |
scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage, |
widthOut,heightOut,depthOut,afterImage); |
emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut, |
is_index(format),afterImage, dataOut); |
free((void *) beforeImage); |
free((void *) afterImage); |
|
return 0; |
} /* gluScaleImage3D() */ |
|
|
static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth, |
GLint internalFormat, GLenum format, GLenum type, |
GLint *newWidth, GLint *newHeight, GLint *newDepth) |
{ |
GLint widthPowerOf2= nearestPower(width); |
GLint heightPowerOf2= nearestPower(height); |
GLint depthPowerOf2= nearestPower(depth); |
GLint proxyWidth; |
|
do { |
/* compute level 1 width & height & depth, clamping each at 1 */ |
GLint widthAtLevelOne= (widthPowerOf2 > 1) ? |
widthPowerOf2 >> 1 : |
widthPowerOf2; |
GLint heightAtLevelOne= (heightPowerOf2 > 1) ? |
heightPowerOf2 >> 1 : |
heightPowerOf2; |
GLint depthAtLevelOne= (depthPowerOf2 > 1) ? |
depthPowerOf2 >> 1 : |
depthPowerOf2; |
GLenum proxyTarget = GL_PROXY_TEXTURE_3D; |
assert(widthAtLevelOne > 0); |
assert(heightAtLevelOne > 0); |
assert(depthAtLevelOne > 0); |
|
/* does width x height x depth at level 1 & all their mipmaps fit? */ |
assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D); |
gluTexImage3D(proxyTarget, 1, /* must be non-zero */ |
internalFormat, |
widthAtLevelOne,heightAtLevelOne,depthAtLevelOne, |
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 && |
depthPowerOf2 == 1) { |
*newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */ |
return; |
} |
widthPowerOf2= widthAtLevelOne; |
heightPowerOf2= heightAtLevelOne; |
depthPowerOf2= depthAtLevelOne; |
} |
/* else it does fit */ |
} while (proxyWidth == 0); |
/* loop must terminate! */ |
|
/* return the width & height at level 0 that fits */ |
*newWidth= widthPowerOf2; |
*newHeight= heightPowerOf2; |
*newDepth= depthPowerOf2; |
/*printf("Proxy Textures\n");*/ |
} /* closestFit3D() */ |
|
static void halveImagePackedPixelSlice(int components, |
void (*extractPackedPixel) |
(int, const void *,GLfloat []), |
void (*shovePackedPixel) |
(const GLfloat [],int, void *), |
GLint width, GLint height, GLint depth, |
const void *dataIn, void *dataOut, |
GLint pixelSizeInBytes, |
GLint rowSizeInBytes, |
GLint imageSizeInBytes, |
GLint isSwap) |
{ |
int ii, jj; |
int halfWidth= width / 2; |
int halfHeight= height / 2; |
int halfDepth= depth / 2; |
const char *src= (const char *)dataIn; |
int outIndex= 0; |
|
assert((width == 1 || height == 1) && depth >= 2); |
|
if (width == height) { /* a 1-pixel column viewed from top */ |
assert(width == 1 && height == 1); |
assert(depth >= 2); |
|
for (ii= 0; ii< halfDepth; ii++) { |
float totals[4]; |
float extractTotals[BOX2][4]; |
int cc; |
|
(*extractPackedPixel)(isSwap,src,&extractTotals[0][0]); |
(*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
&extractTotals[1][0]); |
for (cc = 0; cc < components; cc++) { |
int kk; |
|
/* average 2 pixels since only a column */ |
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; |
} /* for cc */ |
|
(*shovePackedPixel)(totals,outIndex,dataOut); |
outIndex++; |
/* skip over to next group of 2 */ |
src+= imageSizeInBytes + imageSizeInBytes; |
} /* for ii */ |
} |
else if (height == 1) { /* horizontal slice viewed from top */ |
assert(width != 1); |
|
for (ii= 0; ii< halfDepth; ii++) { |
for (jj= 0; jj< halfWidth; jj++) { |
float totals[4]; |
float extractTotals[BOX4][4]; |
int cc; |
|
(*extractPackedPixel)(isSwap,src, |
&extractTotals[0][0]); |
(*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
&extractTotals[1][0]); |
(*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
&extractTotals[2][0]); |
(*extractPackedPixel)(isSwap, |
(src+imageSizeInBytes+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 horizontal square of 4 */ |
src+= imageSizeInBytes + imageSizeInBytes; |
} |
} |
|
/* assert() */ |
} |
else if (width == 1) { /* vertical slice viewed from top */ |
assert(height != 1); |
|
for (ii= 0; ii< halfDepth; ii++) { |
for (jj= 0; jj< halfHeight; jj++) { |
float totals[4]; |
float extractTotals[BOX4][4]; |
int cc; |
|
(*extractPackedPixel)(isSwap,src, |
&extractTotals[0][0]); |
(*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
&extractTotals[1][0]); |
(*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
&extractTotals[2][0]); |
(*extractPackedPixel)(isSwap, |
(src+imageSizeInBytes+rowSizeInBytes), |
&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 vertical square of 4 */ |
src+= imageSizeInBytes + imageSizeInBytes; |
} |
} |
/* assert() */ |
} |
|
} /* halveImagePackedPixelSlice() */ |
|
static void halveImagePackedPixel3D(int components, |
void (*extractPackedPixel) |
(int, const void *,GLfloat []), |
void (*shovePackedPixel) |
(const GLfloat [],int, void *), |
GLint width, GLint height, GLint depth, |
const void *dataIn, void *dataOut, |
GLint pixelSizeInBytes, |
GLint rowSizeInBytes, |
GLint imageSizeInBytes, |
GLint isSwap) |
{ |
if (depth == 1) { |
assert(1 <= width && 1 <= height); |
|
halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, |
width,height,dataIn,dataOut,pixelSizeInBytes, |
rowSizeInBytes,isSwap); |
return; |
} |
/* a horizontal or vertical slice viewed from top */ |
else if (width == 1 || height == 1) { |
assert(1 <= depth); |
|
halveImagePackedPixelSlice(components, |
extractPackedPixel,shovePackedPixel, |
width, height, depth, dataIn, dataOut, |
pixelSizeInBytes, rowSizeInBytes, |
imageSizeInBytes, isSwap); |
return; |
} |
{ |
int ii, jj, dd; |
|
int halfWidth= width / 2; |
int halfHeight= height / 2; |
int halfDepth= depth / 2; |
const char *src= (const char *) dataIn; |
int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); |
int outIndex= 0; |
|
for (dd= 0; dd < halfDepth; dd++) { |
for (ii= 0; ii< halfHeight; ii++) { |
for (jj= 0; jj< halfWidth; jj++) { |
#define BOX8 8 |
float totals[4]; /* 4 is maximum components */ |
float extractTotals[BOX8][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]); |
|
(*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
&extractTotals[4][0]); |
(*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes), |
&extractTotals[5][0]); |
(*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes), |
&extractTotals[6][0]); |
(*extractPackedPixel)(isSwap, |
(src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes), |
&extractTotals[7][0]); |
for (cc = 0; cc < components; cc++) { |
int kk; |
|
/* grab 8 pixels to average */ |
totals[cc]= 0.0; |
/* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
* extractTotals[2][RED]+extractTotals[3][RED]+ |
* extractTotals[4][RED]+extractTotals[5][RED]+ |
* extractTotals[6][RED]+extractTotals[7][RED]; |
* totals[RED]/= 8.0; |
*/ |
for (kk = 0; kk < BOX8; kk++) { |
totals[cc]+= extractTotals[kk][cc]; |
} |
totals[cc]/= (float)BOX8; |
} |
(*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; |
} |
|
src+= imageSizeInBytes; |
} /* for dd */ |
|
/* both pointers must reach one byte after the end */ |
assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
assert(outIndex == halfWidth * halfHeight * halfDepth); |
} /* for dd */ |
|
} /* halveImagePackedPixel3D() */ |
|
static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat, |
GLsizei width, |
GLsizei height, |
GLsizei depth, |
GLsizei widthPowerOf2, |
GLsizei heightPowerOf2, |
GLsizei depthPowerOf2, |
GLenum format, GLenum type, |
GLint userLevel, |
GLint baseLevel,GLint maxLevel, |
const void *data) |
{ |
GLint newWidth, newHeight, newDepth; |
GLint level, levels; |
const void *usersImage; |
void *srcImage, *dstImage; |
__GLU_INIT_SWAP_IMAGE; |
GLint memReq; |
GLint cmpts; |
|
GLint myswapBytes, groupsPerLine, elementSize, groupSize; |
GLint rowsPerImage, imageSize; |
GLint rowSize, padding; |
PixelStorageModes psm; |
|
assert(checkMipmapArgs(internalFormat,format,type) == 0); |
assert(width >= 1 && height >= 1 && depth >= 1); |
assert(type != GL_BITMAP); |
|
srcImage = dstImage = NULL; |
|
newWidth= widthPowerOf2; |
newHeight= heightPowerOf2; |
newDepth= depthPowerOf2; |
levels = computeLog(newWidth); |
level = computeLog(newHeight); |
if (level > levels) levels=level; |
level = computeLog(newDepth); |
if (level > levels) levels=level; |
|
levels+= userLevel; |
|
retrieveStoreModes3D(&psm); |
myswapBytes = psm.unpack_swap_bytes; |
cmpts = elements_per_group(format,type); |
if (psm.unpack_row_length > 0) { |
groupsPerLine = psm.unpack_row_length; |
} else { |
groupsPerLine = width; |
} |
|
elementSize = bytes_per_element(type); |
groupSize = elementSize * cmpts; |
if (elementSize == 1) myswapBytes = 0; |
|
/* 3dstuff begin */ |
if (psm.unpack_image_height > 0) { |
rowsPerImage= psm.unpack_image_height; |
} |
else { |
rowsPerImage= height; |
} |
|
/* 3dstuff end */ |
rowSize = groupsPerLine * groupSize; |
padding = (rowSize % psm.unpack_alignment); |
if (padding) { |
rowSize += psm.unpack_alignment - padding; |
} |
|
imageSize= rowsPerImage * rowSize; /* 3dstuff */ |
|
usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize + |
psm.unpack_skip_pixels * groupSize + |
/* 3dstuff */ |
psm.unpack_skip_images * imageSize; |
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); |
|
level = userLevel; |
|
if (width == newWidth && height == newHeight && depth == newDepth) { |
/* Use usersImage for level userLevel */ |
if (baseLevel <= level && level <= maxLevel) { |
gluTexImage3D(target, level, internalFormat, width, |
height, depth, 0, format, type, |
usersImage); |
} |
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); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
return 0; |
} |
{ |
int nextWidth= newWidth/2; |
int nextHeight= newHeight/2; |
int nextDepth= newDepth/2; |
|
/* clamp to 1 */ |
if (nextWidth < 1) nextWidth= 1; |
if (nextHeight < 1) nextHeight= 1; |
if (nextDepth < 1) nextDepth= 1; |
memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); |
} |
switch(type) { |
case GL_UNSIGNED_BYTE: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memReq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memReq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memReq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memReq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memReq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memReq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
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: |
dstImage = (GLushort *)malloc(memReq); |
break; |
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 *)malloc(memReq); |
break; |
default: |
return GLU_INVALID_ENUM; /* assertion */ |
} |
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); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
return GLU_OUT_OF_MEMORY; |
} |
else |
switch(type) { |
case GL_UNSIGNED_BYTE: |
if (depth > 1) { |
halveImage3D(cmpts,extractUbyte,shoveUbyte, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_ubyte(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize); |
} |
break; |
case GL_BYTE: |
if (depth > 1) { |
halveImage3D(cmpts,extractSbyte,shoveSbyte, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_byte(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize); |
} |
break; |
case GL_UNSIGNED_SHORT: |
if (depth > 1) { |
halveImage3D(cmpts,extractUshort,shoveUshort, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_ushort(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_SHORT: |
if (depth > 1) { |
halveImage3D(cmpts,extractSshort,shoveSshort, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_short(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_UNSIGNED_INT: |
if (depth > 1) { |
halveImage3D(cmpts,extractUint,shoveUint, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_uint(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_INT: |
if (depth > 1) { |
halveImage3D(cmpts,extractSint,shoveSint, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_int(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_FLOAT: |
if (depth > 1 ) { |
halveImage3D(cmpts,extractFloat,shoveFloat, |
width,height,depth, |
usersImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_float(cmpts,width,height,usersImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
assert(format == GL_RGB); |
halveImagePackedPixel3D(3,extract332,shove332, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
assert(format == GL_RGB); |
halveImagePackedPixel3D(3,extract233rev,shove233rev, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_5_6_5: |
halveImagePackedPixel3D(3,extract565,shove565, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_5_6_5_REV: |
halveImagePackedPixel3D(3,extract565rev,shove565rev, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_4_4_4_4: |
halveImagePackedPixel3D(4,extract4444,shove4444, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
halveImagePackedPixel3D(4,extract4444rev,shove4444rev, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_5_5_5_1: |
halveImagePackedPixel3D(4,extract5551,shove5551, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
halveImagePackedPixel3D(4,extract1555rev,shove1555rev, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_8_8_8_8: |
halveImagePackedPixel3D(4,extract8888,shove8888, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_8_8_8_8_REV: |
halveImagePackedPixel3D(4,extract8888rev,shove8888rev, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_10_10_10_2: |
halveImagePackedPixel3D(4,extract1010102,shove1010102, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_2_10_10_10_REV: |
halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, |
width,height,depth,usersImage,dstImage, |
elementSize,rowSize,imageSize,myswapBytes); |
break; |
default: |
assert(0); |
break; |
} |
newWidth = width/2; |
newHeight = height/2; |
newDepth = depth/2; |
/* clamp to 1 */ |
if (newWidth < 1) newWidth= 1; |
if (newHeight < 1) newHeight= 1; |
if (newDepth < 1) newDepth= 1; |
|
myswapBytes = 0; |
rowSize = newWidth * groupSize; |
imageSize= rowSize * newHeight; /* 3dstuff */ |
memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); |
/* Swap srcImage and dstImage */ |
__GLU_SWAP_IMAGE(srcImage,dstImage); |
switch(type) { |
case GL_UNSIGNED_BYTE: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memReq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memReq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memReq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memReq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memReq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memReq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
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: |
dstImage = (GLushort *)malloc(memReq); |
break; |
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 *)malloc(memReq); |
break; |
default: |
return GLU_INVALID_ENUM; /* assertion */ |
} |
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); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
free(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 = imageSize3D(newWidth, newHeight, newDepth, format, type); |
switch(type) { |
case GL_UNSIGNED_BYTE: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memReq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memReq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memReq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memReq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memReq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memReq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
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: |
dstImage = (GLushort *)malloc(memReq); |
break; |
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 *)malloc(memReq); |
break; |
default: |
return GLU_INVALID_ENUM; /* assertion */ |
} |
|
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); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
return GLU_OUT_OF_MEMORY; |
} |
/*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n", |
width,height,depth,newWidth,newHeight,newDepth);*/ |
|
gluScaleImage3D(format, width, height, depth, type, usersImage, |
newWidth, newHeight, newDepth, type, dstImage); |
|
myswapBytes = 0; |
rowSize = newWidth * groupSize; |
imageSize = rowSize * newHeight; /* 3dstuff */ |
/* 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; |
int nextDepth= newDepth/2; |
if (nextWidth < 1) nextWidth= 1; |
if (nextHeight < 1) nextHeight= 1; |
if (nextDepth < 1) nextDepth= 1; |
|
memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); |
} |
switch(type) { |
case GL_UNSIGNED_BYTE: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
case GL_BYTE: |
dstImage = (GLbyte *)malloc(memReq); |
break; |
case GL_UNSIGNED_SHORT: |
dstImage = (GLushort *)malloc(memReq); |
break; |
case GL_SHORT: |
dstImage = (GLshort *)malloc(memReq); |
break; |
case GL_UNSIGNED_INT: |
dstImage = (GLuint *)malloc(memReq); |
break; |
case GL_INT: |
dstImage = (GLint *)malloc(memReq); |
break; |
case GL_FLOAT: |
dstImage = (GLfloat *)malloc(memReq); |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
dstImage = (GLubyte *)malloc(memReq); |
break; |
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: |
dstImage = (GLushort *)malloc(memReq); |
break; |
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 *)malloc(memReq); |
break; |
default: |
return GLU_INVALID_ENUM; /* assertion */ |
} |
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); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
free(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) { |
gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth, |
0,format, type, (void *)srcImage); |
} |
level++; /* update current level for the loop */ |
for (; level <= levels; level++) { |
switch(type) { |
case GL_UNSIGNED_BYTE: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractUbyte,shoveUbyte, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize); |
} |
break; |
case GL_BYTE: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractSbyte,shoveSbyte, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize); |
} |
break; |
case GL_UNSIGNED_SHORT: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractUshort,shoveUshort, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_SHORT: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractSshort,shoveSshort, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_UNSIGNED_INT: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractUint,shoveUint, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_INT: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractSint,shoveSint, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_FLOAT: |
if (newDepth > 1) { |
halveImage3D(cmpts,extractFloat,shoveFloat, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,groupSize,rowSize, |
imageSize,myswapBytes); |
} |
else { |
halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage, |
elementSize,rowSize,groupSize,myswapBytes); |
} |
break; |
case GL_UNSIGNED_BYTE_3_3_2: |
halveImagePackedPixel3D(3,extract332,shove332, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_BYTE_2_3_3_REV: |
halveImagePackedPixel3D(3,extract233rev,shove233rev, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_5_6_5: |
halveImagePackedPixel3D(3,extract565,shove565, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_5_6_5_REV: |
halveImagePackedPixel3D(3,extract565rev,shove565rev, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_4_4_4_4: |
halveImagePackedPixel3D(4,extract4444,shove4444, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
halveImagePackedPixel3D(4,extract4444rev,shove4444rev, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_5_5_5_1: |
halveImagePackedPixel3D(4,extract5551,shove5551, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
halveImagePackedPixel3D(4,extract1555rev,shove1555rev, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_8_8_8_8: |
halveImagePackedPixel3D(4,extract8888,shove8888, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_8_8_8_8_REV: |
halveImagePackedPixel3D(4,extract8888rev,shove8888rev, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_10_10_10_2: |
halveImagePackedPixel3D(4,extract1010102,shove1010102, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
case GL_UNSIGNED_INT_2_10_10_10_REV: |
halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, |
newWidth,newHeight,newDepth, |
srcImage,dstImage,elementSize,rowSize, |
imageSize,myswapBytes); |
break; |
default: |
assert(0); |
break; |
} |
|
__GLU_SWAP_IMAGE(srcImage,dstImage); |
|
if (newWidth > 1) { newWidth /= 2; rowSize /= 2;} |
if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; } |
if (newDepth > 1) newDepth /= 2; |
{ |
/* call tex image with srcImage untouched since it's not padded */ |
if (baseLevel <= level && level <= maxLevel) { |
gluTexImage3D(target, level, internalFormat, newWidth, newHeight, |
newDepth,0, format, type, (void *) srcImage); |
} |
} |
} /* 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); |
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
|
free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ |
if (dstImage) { /* if it's non-rectangular and only 1 level */ |
free(dstImage); |
} |
return 0; |
} /* gluBuild3DMipmapLevelsCore() */ |
|
GLint GLAPIENTRY |
gluBuild3DMipmapLevels(GLenum target, GLint internalFormat, |
GLsizei width, GLsizei height, GLsizei depth, |
GLenum format, GLenum type, |
GLint userLevel, GLint baseLevel, GLint maxLevel, |
const void *data) |
{ |
int level, levels; |
|
int rc= checkMipmapArgs(internalFormat,format,type); |
if (rc != 0) return rc; |
|
if (width < 1 || height < 1 || depth < 1) { |
return GLU_INVALID_VALUE; |
} |
|
if(type == GL_BITMAP) { |
return GLU_INVALID_ENUM; |
} |
|
levels = computeLog(width); |
level = computeLog(height); |
if (level > levels) levels=level; |
level = computeLog(depth); |
if (level > levels) levels=level; |
|
levels+= userLevel; |
if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) |
return GLU_INVALID_VALUE; |
|
return gluBuild3DMipmapLevelsCore(target, internalFormat, |
width, height, depth, |
width, height, depth, |
format, type, |
userLevel, baseLevel, maxLevel, |
data); |
} /* gluBuild3DMipmapLevels() */ |
|
GLint GLAPIENTRY |
gluBuild3DMipmaps(GLenum target, GLint internalFormat, |
GLsizei width, GLsizei height, GLsizei depth, |
GLenum format, GLenum type, const void *data) |
{ |
GLint widthPowerOf2, heightPowerOf2, depthPowerOf2; |
int level, levels; |
|
int rc= checkMipmapArgs(internalFormat,format,type); |
if (rc != 0) return rc; |
|
if (width < 1 || height < 1 || depth < 1) { |
return GLU_INVALID_VALUE; |
} |
|
if(type == GL_BITMAP) { |
return GLU_INVALID_ENUM; |
} |
|
closestFit3D(target,width,height,depth,internalFormat,format,type, |
&widthPowerOf2,&heightPowerOf2,&depthPowerOf2); |
|
levels = computeLog(widthPowerOf2); |
level = computeLog(heightPowerOf2); |
if (level > levels) levels=level; |
level = computeLog(depthPowerOf2); |
if (level > levels) levels=level; |
|
return gluBuild3DMipmapLevelsCore(target, internalFormat, |
width, height, depth, |
widthPowerOf2, heightPowerOf2, |
depthPowerOf2, |
format, type, 0, 0, levels, |
data); |
} /* gluBuild3DMipmaps() */ |
|
static GLdouble extractUbyte(int isSwap, const void *ubyte) |
{ |
isSwap= isSwap; /* turn off warnings */ |
|
assert(*((const GLubyte *)ubyte) <= 255); |
|
return (GLdouble)(*((const GLubyte *)ubyte)); |
} /* extractUbyte() */ |
|
static void shoveUbyte(GLdouble value, int index, void *data) |
{ |
assert(0.0 <= value && value < 256.0); |
|
((GLubyte *)data)[index]= (GLubyte)value; |
} /* shoveUbyte() */ |
|
static GLdouble extractSbyte(int isSwap, const void *sbyte) |
{ |
isSwap= isSwap; /* turn off warnings */ |
|
assert(*((const GLbyte *)sbyte) <= 127); |
|
return (GLdouble)(*((const GLbyte *)sbyte)); |
} /* extractSbyte() */ |
|
static void shoveSbyte(GLdouble value, int index, void *data) |
{ |
((GLbyte *)data)[index]= (GLbyte)value; |
} /* shoveSbyte() */ |
|
static GLdouble extractUshort(int isSwap, const void *uitem) |
{ |
GLushort ushort; |
|
if (isSwap) { |
ushort= __GLU_SWAP_2_BYTES(uitem); |
} |
else { |
ushort= *(const GLushort *)uitem; |
} |
|
assert(ushort <= 65535); |
|
return (GLdouble)ushort; |
} /* extractUshort() */ |
|
static void shoveUshort(GLdouble value, int index, void *data) |
{ |
assert(0.0 <= value && value < 65536.0); |
|
((GLushort *)data)[index]= (GLushort)value; |
} /* shoveUshort() */ |
|
static GLdouble extractSshort(int isSwap, const void *sitem) |
{ |
GLshort sshort; |
|
if (isSwap) { |
sshort= __GLU_SWAP_2_BYTES(sitem); |
} |
else { |
sshort= *(const GLshort *)sitem; |
} |
|
assert(sshort <= 32767); |
|
return (GLdouble)sshort; |
} /* extractSshort() */ |
|
static void shoveSshort(GLdouble value, int index, void *data) |
{ |
assert(0.0 <= value && value < 32768.0); |
|
((GLshort *)data)[index]= (GLshort)value; |
} /* shoveSshort() */ |
|
static GLdouble extractUint(int isSwap, const void *uitem) |
{ |
GLuint uint; |
|
if (isSwap) { |
uint= __GLU_SWAP_4_BYTES(uitem); |
} |
else { |
uint= *(const GLuint *)uitem; |
} |
|
assert(uint <= 0xffffffff); |
|
return (GLdouble)uint; |
} /* extractUint() */ |
|
static void shoveUint(GLdouble value, int index, void *data) |
{ |
assert(0.0 <= value && value <= (GLdouble) UINT_MAX); |
|
((GLuint *)data)[index]= (GLuint)value; |
} /* shoveUint() */ |
|
static GLdouble extractSint(int isSwap, const void *sitem) |
{ |
GLint sint; |
|
if (isSwap) { |
sint= __GLU_SWAP_4_BYTES(sitem); |
} |
else { |
sint= *(const GLint *)sitem; |
} |
|
assert(sint <= 0x7fffffff); |
|
return (GLdouble)sint; |
} /* extractSint() */ |
|
static void shoveSint(GLdouble value, int index, void *data) |
{ |
assert(0.0 <= value && value <= (GLdouble) INT_MAX); |
|
((GLint *)data)[index]= (GLint)value; |
} /* shoveSint() */ |
|
static GLdouble extractFloat(int isSwap, const void *item) |
{ |
GLfloat ffloat; |
|
if (isSwap) { |
ffloat= __GLU_SWAP_4_BYTES(item); |
} |
else { |
ffloat= *(const GLfloat *)item; |
} |
|
assert(ffloat <= 1.0); |
|
return (GLdouble)ffloat; |
} /* extractFloat() */ |
|
static void shoveFloat(GLdouble value, int index, void *data) |
{ |
assert(0.0 <= value && value <= 1.0); |
|
((GLfloat *)data)[index]= value; |
} /* shoveFloat() */ |
|
static void halveImageSlice(int components, |
GLdouble (*extract)(int, const void *), |
void (*shove)(GLdouble, int, void *), |
GLint width, GLint height, GLint depth, |
const void *dataIn, void *dataOut, |
GLint elementSizeInBytes, |
GLint groupSizeInBytes, |
GLint rowSizeInBytes, |
GLint imageSizeInBytes, |
GLint isSwap) |
{ |
int ii, jj; |
int halfWidth= width / 2; |
int halfHeight= height / 2; |
int halfDepth= depth / 2; |
const char *src= (const char *)dataIn; |
int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes); |
int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); |
int outIndex= 0; |
|
assert((width == 1 || height == 1) && depth >= 2); |
|
if (width == height) { /* a 1-pixel column viewed from top */ |
/* printf("1-column\n");*/ |
assert(width == 1 && height == 1); |
assert(depth >= 2); |
|
for (ii= 0; ii< halfDepth; ii++) { |
int cc; |
|
for (cc = 0; cc < components; cc++) { |
double totals[4]; |
double extractTotals[BOX2][4]; |
int kk; |
|
extractTotals[0][cc]= (*extract)(isSwap,src); |
extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes)); |
|
/* average 2 pixels since only a column */ |
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]/= (double)BOX2; |
|
(*shove)(totals[cc],outIndex,dataOut); |
outIndex++; |
src+= elementSizeInBytes; |
} /* for cc */ |
|
/* skip over to next group of 2 */ |
src+= rowSizeInBytes; |
} /* for ii */ |
|
assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
assert(outIndex == halfDepth * components); |
} |
else if (height == 1) { /* horizontal slice viewed from top */ |
/* printf("horizontal slice\n"); */ |
assert(width != 1); |
|
for (ii= 0; ii< halfDepth; ii++) { |
for (jj= 0; jj< halfWidth; jj++) { |
int cc; |
|
for (cc = 0; cc < components; cc++) { |
int kk; |
double totals[4]; |
double extractTotals[BOX4][4]; |
|
extractTotals[0][cc]=(*extract)(isSwap,src); |
extractTotals[1][cc]=(*extract)(isSwap, |
(src+groupSizeInBytes)); |
extractTotals[2][cc]=(*extract)(isSwap, |
(src+imageSizeInBytes)); |
extractTotals[3][cc]=(*extract)(isSwap, |
(src+imageSizeInBytes+groupSizeInBytes)); |
|
/* 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]/= (double)BOX4; |
|
(*shove)(totals[cc],outIndex,dataOut); |
outIndex++; |
|
src+= elementSizeInBytes; |
} /* for cc */ |
|
/* skip over to next horizontal square of 4 */ |
src+= groupSizeInBytes; |
} /* for jj */ |
src+= rowPadBytes; |
|
src+= rowSizeInBytes; |
} /* for ii */ |
|
assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
assert(outIndex == halfWidth * halfDepth * components); |
} |
else if (width == 1) { /* vertical slice viewed from top */ |
/* printf("vertical slice\n"); */ |
assert(height != 1); |
|
for (ii= 0; ii< halfDepth; ii++) { |
for (jj= 0; jj< halfHeight; jj++) { |
int cc; |
|
for (cc = 0; cc < components; cc++) { |
int kk; |
double totals[4]; |
double extractTotals[BOX4][4]; |
|
extractTotals[0][cc]=(*extract)(isSwap,src); |
extractTotals[1][cc]=(*extract)(isSwap, |
(src+rowSizeInBytes)); |
extractTotals[2][cc]=(*extract)(isSwap, |
(src+imageSizeInBytes)); |
extractTotals[3][cc]=(*extract)(isSwap, |
(src+imageSizeInBytes+rowSizeInBytes)); |
|
/* 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]/= (double)BOX4; |
|
(*shove)(totals[cc],outIndex,dataOut); |
outIndex++; |
|
src+= elementSizeInBytes; |
} /* for cc */ |
src+= rowPadBytes; |
|
/* skip over to next vertical square of 4 */ |
src+= rowSizeInBytes; |
} /* for jj */ |
src+= imagePadBytes; |
|
src+= imageSizeInBytes; |
} /* for ii */ |
|
assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
assert(outIndex == halfHeight * halfDepth * components); |
} |
|
} /* halveImageSlice() */ |
|
static void halveImage3D(int components, |
GLdouble (*extract)(int, const void *), |
void (*shove)(GLdouble, int, void *), |
GLint width, GLint height, GLint depth, |
const void *dataIn, void *dataOut, |
GLint elementSizeInBytes, |
GLint groupSizeInBytes, |
GLint rowSizeInBytes, |
GLint imageSizeInBytes, |
GLint isSwap) |
{ |
assert(depth > 1); |
|
/* a horizontal/vertical/one-column slice viewed from top */ |
if (width == 1 || height == 1) { |
assert(1 <= depth); |
|
halveImageSlice(components,extract,shove, width, height, depth, |
dataIn, dataOut, elementSizeInBytes, groupSizeInBytes, |
rowSizeInBytes, imageSizeInBytes, isSwap); |
return; |
} |
{ |
int ii, jj, dd; |
|
int halfWidth= width / 2; |
int halfHeight= height / 2; |
int halfDepth= depth / 2; |
const char *src= (const char *) dataIn; |
int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes); |
int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); |
int outIndex= 0; |
|
for (dd= 0; dd < halfDepth; dd++) { |
for (ii= 0; ii< halfHeight; ii++) { |
for (jj= 0; jj< halfWidth; jj++) { |
int cc; |
|
for (cc= 0; cc < components; cc++) { |
int kk; |
#define BOX8 8 |
double totals[4]; /* 4 is maximum components */ |
double extractTotals[BOX8][4]; /* 4 is maximum components */ |
|
extractTotals[0][cc]= (*extract)(isSwap,src); |
extractTotals[1][cc]= (*extract)(isSwap, |
(src+groupSizeInBytes)); |
extractTotals[2][cc]= (*extract)(isSwap, |
(src+rowSizeInBytes)); |
extractTotals[3][cc]= (*extract)(isSwap, |
(src+rowSizeInBytes+groupSizeInBytes)); |
|
extractTotals[4][cc]= (*extract)(isSwap, |
(src+imageSizeInBytes)); |
|
extractTotals[5][cc]= (*extract)(isSwap, |
(src+groupSizeInBytes+imageSizeInBytes)); |
extractTotals[6][cc]= (*extract)(isSwap, |
(src+rowSizeInBytes+imageSizeInBytes)); |
extractTotals[7][cc]= (*extract)(isSwap, |
(src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes)); |
|
totals[cc]= 0.0; |
|
/* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
* extractTotals[2][RED]+extractTotals[3][RED]+ |
* extractTotals[4][RED]+extractTotals[5][RED]+ |
* extractTotals[6][RED]+extractTotals[7][RED]; |
* totals[RED]/= 8.0; |
*/ |
for (kk = 0; kk < BOX8; kk++) { |
totals[cc]+= extractTotals[kk][cc]; |
} |
totals[cc]/= (double)BOX8; |
|
(*shove)(totals[cc],outIndex,dataOut); |
|
outIndex++; |
|
src+= elementSizeInBytes; /* go to next component */ |
} /* for cc */ |
|
/* skip over to next square of 4 */ |
src+= groupSizeInBytes; |
} /* for jj */ |
/* skip past pad bytes, if any, to get to next row */ |
src+= rowPadBytes; |
|
/* 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; |
} /* for ii */ |
|
/* skip past pad bytes, if any, to get to next image */ |
src+= imagePadBytes; |
|
src+= imageSizeInBytes; |
} /* for dd */ |
|
/* both pointers must reach one byte after the end */ |
assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
assert(outIndex == halfWidth * halfHeight * halfDepth * components); |
} |
} /* halveImage3D() */ |
|
|
|
/*** mipmap.c ***/ |
|