📄 mipmap.c
字号:
/* * 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>#include "gluint.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 */ } {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -