⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 histogram.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 void
pack_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 + -