image.c

来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,907 行 · 第 1/5 页

C
1,907
字号
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2006  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"/** Compute ceiling of integer quotient of A divided by B. */#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )/** * 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 ){   register 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 ){   register 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 ){   register 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:         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:               return GL_TRUE;            case GL_HALF_FLOAT_ARB:               return ctx->Extensions.ARB_half_float_pixel;            default:               return GL_FALSE;         }      case GL_RED:      case GL_GREEN:      case GL_BLUE:      case GL_ALPHA:#if 0 /* not legal!  see table 3.6 of the 1.5 spec */      case GL_INTENSITY:#endif      case GL_LUMINANCE:      case GL_LUMINANCE_ALPHA:      case GL_DEPTH_COMPONENT:         switch (type) {            case GL_BYTE:            case GL_UNSIGNED_BYTE:            case GL_SHORT:            case GL_UNSIGNED_SHORT:            case GL_INT:            case GL_UNSIGNED_INT:            case GL_FLOAT:               return GL_TRUE;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?