📄 image.c
字号:
/* * Mesa 3-D graphics library * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul 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 and this permission notice 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 * BRIAN PAUL 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. *//** * \file image.c * Image handling. */#include "glheader.h"#include "colormac.h"#include "context.h"#include "image.h"#include "imports.h"#include "histogram.h"#include "macros.h"#include "pixel.h"/** * NOTE: * Normally, BYTE_TO_FLOAT(0) returns 0.00392 That causes problems when * we later convert the float to a packed integer value (such as for * GL_RGB5_A1) because we'll wind up with a non-zero value. * * We redefine the macros here so zero is handled correctly. */#undef BYTE_TO_FLOAT#define BYTE_TO_FLOAT(B) ((B) == 0 ? 0.0F : ((2.0F * (B) + 1.0F) * (1.0F/255.0F)))#undef SHORT_TO_FLOAT#define SHORT_TO_FLOAT(S) ((S) == 0 ? 0.0F : ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)))/** Compute ceiling of integer quotient of A divided by B. */#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )/** * \return GL_TRUE if type is packed pixel type, GL_FALSE otherwise. */static GLboolean_mesa_type_is_packed(GLenum type){ switch (type) { 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: case GL_UNSIGNED_SHORT_8_8_MESA: case GL_UNSIGNED_SHORT_8_8_REV_MESA: case GL_UNSIGNED_INT_24_8_EXT: return GL_TRUE; } return GL_FALSE;}/** * Flip the 8 bits in each byte of the given array. * * \param p array. * \param n number of bytes. * * \todo try this trick to flip bytes someday: * \code * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); * \endcode */static voidflip_bytes( GLubyte *p, GLuint n ){ GLuint i, a, b; for (i = 0; i < n; i++) { b = (GLuint) p[i]; /* words are often faster than bytes */ a = ((b & 0x01) << 7) | ((b & 0x02) << 5) | ((b & 0x04) << 3) | ((b & 0x08) << 1) | ((b & 0x10) >> 1) | ((b & 0x20) >> 3) | ((b & 0x40) >> 5) | ((b & 0x80) >> 7); p[i] = (GLubyte) a; }}/** * Flip the order of the 2 bytes in each word in the given array. * * \param p array. * \param n number of words. */void_mesa_swap2( GLushort *p, GLuint n ){ GLuint i; for (i = 0; i < n; i++) { p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00); }}/* * Flip the order of the 4 bytes in each word in the given array. */void_mesa_swap4( GLuint *p, GLuint n ){ GLuint i, a, b; for (i = 0; i < n; i++) { b = p[i]; a = (b >> 24) | ((b >> 8) & 0xff00) | ((b << 8) & 0xff0000) | ((b << 24) & 0xff000000); p[i] = a; }}/** * Get the size of a GL data type. * * \param type GL data type. * * \return the size, in bytes, of the given data type, 0 if a GL_BITMAP, or -1 * if an invalid type enum. */GLint_mesa_sizeof_type( GLenum type ){ switch (type) { case GL_BITMAP: return 0; case GL_UNSIGNED_BYTE: return sizeof(GLubyte); case GL_BYTE: return sizeof(GLbyte); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_SHORT: return sizeof(GLshort); case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_INT: return sizeof(GLint); case GL_FLOAT: return sizeof(GLfloat); case GL_HALF_FLOAT_ARB: return sizeof(GLhalfARB); default: return -1; }}/** * Same as _mesa_sizeof_type() but also accepting the packed pixel * format data types. */GLint_mesa_sizeof_packed_type( GLenum type ){ switch (type) { case GL_BITMAP: return 0; case GL_UNSIGNED_BYTE: return sizeof(GLubyte); case GL_BYTE: return sizeof(GLbyte); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_SHORT: return sizeof(GLshort); case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_INT: return sizeof(GLint); case GL_HALF_FLOAT_ARB: return sizeof(GLhalfARB); case GL_FLOAT: return sizeof(GLfloat); case GL_UNSIGNED_BYTE_3_3_2: return sizeof(GLubyte); case GL_UNSIGNED_BYTE_2_3_3_REV: return sizeof(GLubyte); case GL_UNSIGNED_SHORT_5_6_5: return sizeof(GLushort); case GL_UNSIGNED_SHORT_5_6_5_REV: return sizeof(GLushort); case GL_UNSIGNED_SHORT_4_4_4_4: return sizeof(GLushort); case GL_UNSIGNED_SHORT_4_4_4_4_REV: return sizeof(GLushort); case GL_UNSIGNED_SHORT_5_5_5_1: return sizeof(GLushort); case GL_UNSIGNED_SHORT_1_5_5_5_REV: return sizeof(GLushort); case GL_UNSIGNED_INT_8_8_8_8: return sizeof(GLuint); case GL_UNSIGNED_INT_8_8_8_8_REV: return sizeof(GLuint); case GL_UNSIGNED_INT_10_10_10_2: return sizeof(GLuint); case GL_UNSIGNED_INT_2_10_10_10_REV: return sizeof(GLuint); case GL_UNSIGNED_SHORT_8_8_MESA: case GL_UNSIGNED_SHORT_8_8_REV_MESA: return sizeof(GLushort); case GL_UNSIGNED_INT_24_8_EXT: return sizeof(GLuint); default: return -1; }}/** * Get the number of components in a pixel format. * * \param format pixel format. * * \return the number of components in the given format, or -1 if a bad format. */GLint_mesa_components_in_format( GLenum format ){ switch (format) { case GL_COLOR_INDEX: case GL_COLOR_INDEX1_EXT: case GL_COLOR_INDEX2_EXT: case GL_COLOR_INDEX4_EXT: case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT: case GL_STENCIL_INDEX: case GL_DEPTH_COMPONENT: case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: case GL_LUMINANCE: case GL_INTENSITY: return 1; case GL_LUMINANCE_ALPHA: return 2; case GL_RGB: return 3; case GL_RGBA: return 4; case GL_BGR: return 3; case GL_BGRA: return 4; case GL_ABGR_EXT: return 4; case GL_YCBCR_MESA: return 2; case GL_DEPTH_STENCIL_EXT: return 2; default: return -1; }}/** * Get the bytes per pixel of pixel format type pair. * * \param format pixel format. * \param type pixel type. * * \return bytes per pixel, or -1 if a bad format or type was given. */GLint_mesa_bytes_per_pixel( GLenum format, GLenum type ){ GLint comps = _mesa_components_in_format( format ); if (comps < 0) return -1; switch (type) { case GL_BITMAP: return 0; /* special case */ case GL_BYTE: case GL_UNSIGNED_BYTE: return comps * sizeof(GLubyte); case GL_SHORT: case GL_UNSIGNED_SHORT: return comps * sizeof(GLshort); case GL_INT: case GL_UNSIGNED_INT: return comps * sizeof(GLint); case GL_FLOAT: return comps * sizeof(GLfloat); case GL_HALF_FLOAT_ARB: return comps * sizeof(GLhalfARB); case GL_UNSIGNED_BYTE_3_3_2: case GL_UNSIGNED_BYTE_2_3_3_REV: if (format == GL_RGB || format == GL_BGR) return sizeof(GLubyte); else return -1; /* error */ case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5_REV: if (format == GL_RGB || format == GL_BGR) return sizeof(GLushort); else return -1; /* error */ 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: if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT) return sizeof(GLushort); else return -1; 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: if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT) return sizeof(GLuint); else return -1; case GL_UNSIGNED_SHORT_8_8_MESA: case GL_UNSIGNED_SHORT_8_8_REV_MESA: if (format == GL_YCBCR_MESA) return sizeof(GLushort); else return -1; case GL_UNSIGNED_INT_24_8_EXT: if (format == GL_DEPTH_STENCIL_EXT) return sizeof(GLuint); else return -1; default: return -1; }}/** * Test for a legal pixel format and type. * * \param format pixel format. * \param type pixel type. * * \return GL_TRUE if the given pixel format and type are legal, or GL_FALSE * otherwise. */GLboolean_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type ){ switch (format) { case GL_COLOR_INDEX: case GL_STENCIL_INDEX:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -