Removed all RCS / CVS tags (Id, Header, Date, etc.) from everything.
[mesa.git] / src / mesa / main / histogram.c
index 80ed72b6dbe9e12bb65a32e7980de39e40357bb2..63b147b00538b7151436252f39597e108713f91a 100644 (file)
@@ -1,10 +1,9 @@
-/* $Id: histogram.c,v 1.5 2000/12/26 05:09:28 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  5.1
  *
- * Copyright (C) 1999-2000  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 )
 }
 
 
+
+/**********************************************************************
+ * API functions
+ */
+
+
 void
 _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;
    }
 
@@ -623,8 +689,20 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
        type != GL_SHORT &&
        type != GL_UNSIGNED_INT &&
        type != GL_INT &&
-       type != GL_FLOAT) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetMinmax(type)");
+       type != GL_FLOAT &&
+       type != GL_UNSIGNED_BYTE_3_3_2 &&
+       type != GL_UNSIGNED_BYTE_2_3_3_REV &&
+       type != GL_UNSIGNED_SHORT_5_6_5 &&
+       type != GL_UNSIGNED_SHORT_5_6_5_REV &&
+       type != GL_UNSIGNED_SHORT_4_4_4_4 &&
+       type != GL_UNSIGNED_SHORT_4_4_4_4_REV &&
+       type != GL_UNSIGNED_SHORT_5_5_5_1 &&
+       type != GL_UNSIGNED_SHORT_1_5_5_5_REV &&
+       type != GL_UNSIGNED_INT_8_8_8_8 &&
+       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) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(type)");
       return;
    }
 
@@ -657,18 +735,18 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
    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;
    }
 
@@ -678,8 +756,20 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
        type != GL_SHORT &&
        type != GL_UNSIGNED_INT &&
        type != GL_INT &&
-       type != GL_FLOAT) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetHistogram(type)");
+       type != GL_FLOAT &&
+       type != GL_UNSIGNED_BYTE_3_3_2 &&
+       type != GL_UNSIGNED_BYTE_2_3_3_REV &&
+       type != GL_UNSIGNED_SHORT_5_6_5 &&
+       type != GL_UNSIGNED_SHORT_5_6_5_REV &&
+       type != GL_UNSIGNED_SHORT_4_4_4_4 &&
+       type != GL_UNSIGNED_SHORT_4_4_4_4_REV &&
+       type != GL_UNSIGNED_SHORT_5_5_5_1 &&
+       type != GL_UNSIGNED_SHORT_1_5_5_5_REV &&
+       type != GL_UNSIGNED_INT_8_8_8_8 &&
+       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) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(type)");
       return;
    }
 
@@ -708,13 +798,13 @@ _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;
    }
 
@@ -744,7 +834,7 @@ _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)");
    }
 }
 
@@ -755,13 +845,13 @@ _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;
    }
 
@@ -791,7 +881,7 @@ _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)");
    }
 }
 
@@ -802,12 +892,12 @@ _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) {
@@ -817,7 +907,7 @@ _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)");
    }
 }
 
@@ -828,12 +918,12 @@ _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) {
@@ -843,7 +933,7 @@ _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)");
    }
 }
 
@@ -856,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;
    }
 
@@ -872,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;
       }
    }
@@ -884,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;
       }
    }
@@ -894,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;
       }
    }
@@ -920,13 +1010,13 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s
       ctx->Histogram.Width = width;
       ctx->Histogram.Format = internalFormat;
       ctx->Histogram.Sink = sink;
-      ctx->Histogram.RedSize       = 0xffffffff;
-      ctx->Histogram.GreenSize     = 0xffffffff;
-      ctx->Histogram.BlueSize      = 0xffffffff;
-      ctx->Histogram.AlphaSize     = 0xffffffff;
-      ctx->Histogram.LuminanceSize = 0xffffffff;
+      ctx->Histogram.RedSize       = 8 * sizeof(GLuint);
+      ctx->Histogram.GreenSize     = 8 * sizeof(GLuint);
+      ctx->Histogram.BlueSize      = 8 * sizeof(GLuint);
+      ctx->Histogram.AlphaSize     = 8 * sizeof(GLuint);
+      ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint);
    }
-   
+
    ctx->NewState |= _NEW_PIXEL;
 }
 
@@ -937,21 +1027,21 @@ _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);
@@ -966,13 +1056,13 @@ _mesa_ResetHistogram(GLenum target)
    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;
    }
 
@@ -993,13 +1083,13 @@ _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;
    }