📄 histogram.c
字号:
/* * Mesa 3-D graphics library * Version: 6.3 * * Copyright (C) 1999-2004 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. */#include "glheader.h"#include "bufferobj.h"#include "colormac.h"#include "context.h"#include "image.h"#include "histogram.h"/********************************************************************** * Internal functions *//* * Update the min/max values from an array of fragment colors. */void_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]){ GLuint i; for (i = 0; i < n; i++) { /* update mins */ if (rgba[i][RCOMP] < ctx->MinMax.Min[RCOMP]) ctx->MinMax.Min[RCOMP] = rgba[i][RCOMP]; if (rgba[i][GCOMP] < ctx->MinMax.Min[GCOMP]) ctx->MinMax.Min[GCOMP] = rgba[i][GCOMP]; if (rgba[i][BCOMP] < ctx->MinMax.Min[BCOMP]) ctx->MinMax.Min[BCOMP] = rgba[i][BCOMP]; if (rgba[i][ACOMP] < ctx->MinMax.Min[ACOMP]) ctx->MinMax.Min[ACOMP] = rgba[i][ACOMP]; /* update maxs */ if (rgba[i][RCOMP] > ctx->MinMax.Max[RCOMP]) ctx->MinMax.Max[RCOMP] = rgba[i][RCOMP]; if (rgba[i][GCOMP] > ctx->MinMax.Max[GCOMP]) ctx->MinMax.Max[GCOMP] = rgba[i][GCOMP]; if (rgba[i][BCOMP] > ctx->MinMax.Max[BCOMP]) ctx->MinMax.Max[BCOMP] = rgba[i][BCOMP]; if (rgba[i][ACOMP] > ctx->MinMax.Max[ACOMP]) ctx->MinMax.Max[ACOMP] = rgba[i][ACOMP]; }}/* * Update the histogram values from an array of fragment colors. */void_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]){ const GLint max = ctx->Histogram.Width - 1; GLfloat w = (GLfloat) max; GLuint i; if (ctx->Histogram.Width == 0) return; for (i = 0; i < n; i++) { GLint ri = IROUND(rgba[i][RCOMP] * w); GLint gi = IROUND(rgba[i][GCOMP] * w); GLint bi = IROUND(rgba[i][BCOMP] * w); GLint ai = IROUND(rgba[i][ACOMP] * w); ri = CLAMP(ri, 0, max); gi = CLAMP(gi, 0, max); bi = CLAMP(bi, 0, max); ai = CLAMP(ai, 0, max); ctx->Histogram.Count[ri][RCOMP]++; ctx->Histogram.Count[gi][GCOMP]++; ctx->Histogram.Count[bi][BCOMP]++; ctx->Histogram.Count[ai][ACOMP]++; }}/* * XXX the packed pixel formats haven't been tested. */static voidpack_histogram( GLcontext *ctx, GLuint n, CONST GLuint rgba[][4], GLenum format, GLenum type, GLvoid *destination, const struct gl_pixelstore_attrib *packing ){ const GLint comps = _mesa_components_in_format(format); GLuint luminance[MAX_WIDTH]; if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { GLuint i; for (i = 0; i < n; i++) { luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; } }#define PACK_MACRO(TYPE) \ { \ GLuint i; \ switch (format) { \ case GL_RED: \ for (i=0;i<n;i++) \ dst[i] = (TYPE) rgba[i][RCOMP]; \ break; \ case GL_GREEN: \ for (i=0;i<n;i++) \ dst[i] = (TYPE) rgba[i][GCOMP]; \ break; \ case GL_BLUE: \ for (i=0;i<n;i++) \ dst[i] = (TYPE) rgba[i][BCOMP]; \ break; \ case GL_ALPHA: \ for (i=0;i<n;i++) \ dst[i] = (TYPE) rgba[i][ACOMP]; \ break; \ case GL_LUMINANCE: \ for (i=0;i<n;i++) \ dst[i] = (TYPE) luminance[i]; \ break; \ case GL_LUMINANCE_ALPHA: \ for (i=0;i<n;i++) { \ dst[i*2+0] = (TYPE) luminance[i]; \ dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \ } \ break; \ case GL_RGB: \ for (i=0;i<n;i++) { \ dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \ dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \ dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \ } \ break; \ case GL_RGBA: \ for (i=0;i<n;i++) { \ dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \ dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \ dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \ dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \ } \ break; \ case GL_BGR: \ for (i=0;i<n;i++) { \ dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \ dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \ dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \ } \ break; \ case GL_BGRA: \ for (i=0;i<n;i++) { \ dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \ dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \ dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \ dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \ } \ break; \ case GL_ABGR_EXT: \ for (i=0;i<n;i++) { \ dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \ dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \ dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \ dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \ } \ break; \ default: \ _mesa_problem(ctx, "bad format in pack_histogram"); \ } \ } switch (type) { case GL_UNSIGNED_BYTE: { GLubyte *dst = (GLubyte *) destination; PACK_MACRO(GLubyte); } break; case GL_BYTE: { GLbyte *dst = (GLbyte *) destination; PACK_MACRO(GLbyte); } break; case GL_UNSIGNED_SHORT: { GLushort *dst = (GLushort *) destination; PACK_MACRO(GLushort); if (packing->SwapBytes) { _mesa_swap2(dst, n * comps); } } break; case GL_SHORT: { GLshort *dst = (GLshort *) destination; PACK_MACRO(GLshort); if (packing->SwapBytes) { _mesa_swap2((GLushort *) dst, n * comps); } } break; case GL_UNSIGNED_INT: { GLuint *dst = (GLuint *) destination; PACK_MACRO(GLuint); if (packing->SwapBytes) { _mesa_swap4(dst, n * comps); } } break; case GL_INT: { GLint *dst = (GLint *) destination; PACK_MACRO(GLint); if (packing->SwapBytes) { _mesa_swap4((GLuint *) dst, n * comps); } } break; case GL_FLOAT: { GLfloat *dst = (GLfloat *) destination; PACK_MACRO(GLfloat); if (packing->SwapBytes) { _mesa_swap4((GLuint *) dst, n * comps); } } break; case GL_HALF_FLOAT_ARB: { /* temporarily store as GLuints */ GLuint temp[4*HISTOGRAM_TABLE_SIZE]; GLhalfARB *dst = (GLhalfARB *) destination; GLuint i; /* get GLuint values */ PACK_MACRO(GLuint); /* convert to GLhalf */ for (i = 0; i < n * comps; i++) { dst[i] = _mesa_float_to_half((GLfloat) temp[i]); } if (packing->SwapBytes) { _mesa_swap2((GLushort *) dst, n * comps); } } break; case GL_UNSIGNED_BYTE_3_3_2: if (format == GL_RGB) { GLubyte *dst = (GLubyte *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][RCOMP] & 0x7) << 5) | ((rgba[i][GCOMP] & 0x7) << 2) | ((rgba[i][BCOMP] & 0x3) ); } } else { GLubyte *dst = (GLubyte *) destination; GLuint i; ASSERT(format == GL_BGR); for (i = 0; i < n; i++) { dst[i] = ((rgba[i][BCOMP] & 0x7) << 5) | ((rgba[i][GCOMP] & 0x7) << 2) | ((rgba[i][RCOMP] & 0x3) ); } } break; case GL_UNSIGNED_BYTE_2_3_3_REV: if (format == GL_RGB) { GLubyte *dst = (GLubyte *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][RCOMP] & 0x3) << 6) | ((rgba[i][GCOMP] & 0x7) << 3) | ((rgba[i][BCOMP] & 0x7) ); } } else { GLubyte *dst = (GLubyte *) destination; GLuint i; ASSERT(format == GL_BGR); for (i = 0; i < n; i++) { dst[i] = ((rgba[i][BCOMP] & 0x3) << 6) | ((rgba[i][GCOMP] & 0x7) << 3) | ((rgba[i][RCOMP] & 0x7) ); } } break; case GL_UNSIGNED_SHORT_5_6_5: if (format == GL_RGB) { GLushort *dst = (GLushort *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) | ((rgba[i][GCOMP] & 0x3f) << 5) | ((rgba[i][BCOMP] & 0x1f) ); } } else { GLushort *dst = (GLushort *) destination; GLuint i; ASSERT(format == GL_BGR); for (i = 0; i < n; i++) { dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) | ((rgba[i][GCOMP] & 0x3f) << 5) | ((rgba[i][RCOMP] & 0x1f) ); } } break; case GL_UNSIGNED_SHORT_5_6_5_REV: if (format == GL_RGB) { GLushort *dst = (GLushort *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) | ((rgba[i][GCOMP] & 0x3f) << 5) | ((rgba[i][RCOMP] & 0x1f) ); } } else { GLushort *dst = (GLushort *) destination; GLuint i; ASSERT(format == GL_BGR); for (i = 0; i < n; i++) { dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) | ((rgba[i][GCOMP] & 0x3f) << 5) | ((rgba[i][BCOMP] & 0x1f) ); } } break; case GL_UNSIGNED_SHORT_4_4_4_4: if (format == GL_RGBA) { GLushort *dst = (GLushort *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][RCOMP] & 0xf) << 12) | ((rgba[i][GCOMP] & 0xf) << 8) | ((rgba[i][BCOMP] & 0xf) << 4) | ((rgba[i][ACOMP] & 0xf) ); } } else if (format == GL_BGRA) { GLushort *dst = (GLushort *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][BCOMP] & 0xf) << 12) | ((rgba[i][GCOMP] & 0xf) << 8) | ((rgba[i][RCOMP] & 0xf) << 4) | ((rgba[i][ACOMP] & 0xf) ); } } else { GLushort *dst = (GLushort *) destination; GLuint i; ASSERT(format == GL_ABGR_EXT); for (i = 0; i < n; i++) { dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) | ((rgba[i][BCOMP] & 0xf) << 8) | ((rgba[i][GCOMP] & 0xf) << 4) | ((rgba[i][RCOMP] & 0xf) ); } } break; case GL_UNSIGNED_SHORT_4_4_4_4_REV: if (format == GL_RGBA) { GLushort *dst = (GLushort *) destination; GLuint i; for (i = 0; i < n; i++) { dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) | ((rgba[i][BCOMP] & 0xf) << 8) | ((rgba[i][GCOMP] & 0xf) << 4) | ((rgba[i][RCOMP] & 0xf) ); } } else if (format == GL_BGRA) { GLushort *dst = (GLushort *) destination;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -