replace color table FloatTable boolean with Type enum
[mesa.git] / src / mesa / main / histogram.c
index dddaac39350f509d2ab5caef2f01252c7eeffafc..f390a2dade9174408193fd6977d7285dee3b5b42 100644 (file)
@@ -1,10 +1,9 @@
-/* $Id: histogram.c,v 1.7 2001/02/17 18:41:01 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  5.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  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"),
  */
 
 
-#ifdef PC_HEADER
-#include "all.h"
-#else
 #include "glheader.h"
 #include "colormac.h"
 #include "context.h"
 #include "image.h"
 #include "histogram.h"
-#include "mmath.h"
-#endif
+
+
+/**********************************************************************
+ * 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]++;
+   }
+}
 
 
 /*
@@ -125,7 +185,7 @@ pack_histogram( GLcontext *ctx,
             }                                                  \
             break;                                             \
          default:                                              \
-            gl_problem(ctx, "bad format in pack_histogram");   \
+            _mesa_problem(ctx, "bad format in pack_histogram");        \
       }                                                                \
    }
 
@@ -536,7 +596,7 @@ pack_histogram( GLcontext *ctx,
          }
          break;
       default:
-         gl_problem(ctx, "Bad type in pack_histogram");
+         _mesa_problem(ctx, "Bad type in pack_histogram");
    }
 
 #undef PACK_MACRO
@@ -596,24 +656,30 @@ base_histogram_format( GLenum format )
 }
 
 
-void
+
+/**********************************************************************
+ * API functions
+ */
+
+
+void GLAPIENTRY
 _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmax");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax");
       return;
    }
 
    if (target != GL_MINMAX) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)");
       return;
    }
 
    if (!_mesa_is_legal_format_and_type(format, type)) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)");
       return;
    }
 
@@ -636,7 +702,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
        type != GL_UNSIGNED_INT_8_8_8_8_REV &&
        type != GL_UNSIGNED_INT_10_10_10_2 &&
        type != GL_UNSIGNED_INT_2_10_10_10_REV) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinmax(type)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(type)");
       return;
    }
 
@@ -663,24 +729,24 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
 }
 
 
-void
+void GLAPIENTRY
 _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogram");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram");
       return;
    }
 
    if (target != GL_HISTOGRAM) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)");
       return;
    }
 
    if (!_mesa_is_legal_format_and_type(format, type)) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)");
       return;
    }
 
@@ -703,7 +769,7 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
        type != GL_UNSIGNED_INT_8_8_8_8_REV &&
        type != GL_UNSIGNED_INT_10_10_10_2 &&
        type != GL_UNSIGNED_INT_2_10_10_10_REV) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetHistogram(type)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(type)");
       return;
    }
 
@@ -726,19 +792,19 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
 }
 
 
-void
+void GLAPIENTRY
 _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv");
       return;
    }
 
    if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)");
       return;
    }
 
@@ -768,24 +834,24 @@ _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
          *params = (GLfloat) ctx->Histogram.Sink;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)");
    }
 }
 
 
-void
+void GLAPIENTRY
 _mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv");
       return;
    }
 
    if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)");
       return;
    }
 
@@ -815,23 +881,23 @@ _mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
          *params = (GLint) ctx->Histogram.Sink;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)");
    }
 }
 
 
-void
+void GLAPIENTRY
 _mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv");
       return;
    }
    if (target != GL_MINMAX) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)");
       return;
    }
    if (pname == GL_MINMAX_FORMAT) {
@@ -841,23 +907,23 @@ _mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
       *params = (GLfloat) ctx->MinMax.Sink;
    }
    else {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)");
    }
 }
 
 
-void
+void GLAPIENTRY
 _mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv");
       return;
    }
    if (target != GL_MINMAX) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)");
       return;
    }
    if (pname == GL_MINMAX_FORMAT) {
@@ -867,12 +933,12 @@ _mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
       *params = (GLint) ctx->MinMax.Sink;
    }
    else {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)");
    }
 }
 
 
-void
+void GLAPIENTRY
 _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink)
 {
    GLuint i;
@@ -880,13 +946,13 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glHistogram");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram");
       return;
    }
 
    if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
-      gl_error(ctx, GL_INVALID_ENUM, "glHistogram(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(target)");
       return;
    }
 
@@ -896,9 +962,9 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s
       }
       else {
          if (width < 0)
-            gl_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
+            _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
          else
-            gl_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)");
+            _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)");
          return;
       }
    }
@@ -908,7 +974,7 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s
          error = GL_TRUE;
       }
       else {
-         gl_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
+         _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
          return;
       }
    }
@@ -918,7 +984,7 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s
          error = GL_TRUE;
       }
       else {
-         gl_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)");
          return;
       }
    }
@@ -950,32 +1016,32 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s
       ctx->Histogram.AlphaSize     = 8 * sizeof(GLuint);
       ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint);
    }
-   
+
    ctx->NewState |= _NEW_PIXEL;
 }
 
 
-void
+void GLAPIENTRY
 _mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glMinmax");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax");
       return;
    }
 
    if (target != GL_MINMAX) {
-      gl_error(ctx, GL_INVALID_ENUM, "glMinMax(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(target)");
       return;
    }
 
    if (base_histogram_format(internalFormat) < 0) {
-      gl_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)");
       return;
    }
-   
+
    if (ctx->MinMax.Sink == sink)
       return;
    FLUSH_VERTICES(ctx, _NEW_PIXEL);
@@ -983,20 +1049,20 @@ _mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
 }
 
 
-void
+void GLAPIENTRY
 _mesa_ResetHistogram(GLenum target)
 {
    GLuint i;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glResetHistogram");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram");
       return;
    }
 
    if (target != GL_HISTOGRAM) {
-      gl_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)");
       return;
    }
 
@@ -1011,19 +1077,19 @@ _mesa_ResetHistogram(GLenum target)
 }
 
 
-void
+void GLAPIENTRY
 _mesa_ResetMinmax(GLenum target)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (!ctx->Extensions.EXT_histogram) {
-      gl_error(ctx, GL_INVALID_OPERATION, "glResetMinmax");
+   if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax");
       return;
    }
 
    if (target != GL_MINMAX) {
-      gl_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)");
       return;
    }
 
@@ -1033,3 +1099,38 @@ _mesa_ResetMinmax(GLenum target)
    ctx->MinMax.Min[ACOMP] = 1000;    ctx->MinMax.Max[ACOMP] = -1000;
    ctx->NewState |= _NEW_PIXEL;
 }
+
+
+
+/**********************************************************************/
+/*****                      Initialization                        *****/
+/**********************************************************************/
+
+void _mesa_init_histogram( GLcontext * ctx )
+{
+   int i;
+
+   /* Histogram group */
+   ctx->Histogram.Width = 0;
+   ctx->Histogram.Format = GL_RGBA;
+   ctx->Histogram.Sink = GL_FALSE;
+   ctx->Histogram.RedSize       = 0;
+   ctx->Histogram.GreenSize     = 0;
+   ctx->Histogram.BlueSize      = 0;
+   ctx->Histogram.AlphaSize     = 0;
+   ctx->Histogram.LuminanceSize = 0;
+   for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
+      ctx->Histogram.Count[i][0] = 0;
+      ctx->Histogram.Count[i][1] = 0;
+      ctx->Histogram.Count[i][2] = 0;
+      ctx->Histogram.Count[i][3] = 0;
+   }
+
+   /* Min/Max group */
+   ctx->MinMax.Format = GL_RGBA;
+   ctx->MinMax.Sink = GL_FALSE;
+   ctx->MinMax.Min[RCOMP] = 1000;    ctx->MinMax.Max[RCOMP] = -1000;
+   ctx->MinMax.Min[GCOMP] = 1000;    ctx->MinMax.Max[GCOMP] = -1000;
+   ctx->MinMax.Min[BCOMP] = 1000;    ctx->MinMax.Max[BCOMP] = -1000;
+   ctx->MinMax.Min[ACOMP] = 1000;    ctx->MinMax.Max[ACOMP] = -1000;
+}