Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / main / image.c
index 3b62eb34ed94a958f36e0da35a6968f59f5deb79..d3282d42e99bc8216213cd109908da9f2d01464c 100644 (file)
@@ -34,7 +34,6 @@
 #include "context.h"
 #include "image.h"
 #include "imports.h"
-#include "histogram.h"
 #include "macros.h"
 #include "pixel.h"
 
@@ -1431,6 +1430,68 @@ _mesa_scale_and_bias_depth_uint(const GLcontext *ctx, GLuint n,
 }
 
 
+
+/*
+ * Update the min/max values from an array of fragment colors.
+ */
+static void
+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.
+ */
+static void
+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]++;
+   }
+}
+
+
 /**
  * Apply various pixel transfer operations to an array of RGBA pixels
  * as indicated by the transferOps bitmask
@@ -1486,11 +1547,11 @@ _mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLbitfield transferOps,
    }
    /* update histogram count */
    if (transferOps & IMAGE_HISTOGRAM_BIT) {
-      _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
+      update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
    }
    /* update min/max values */
    if (transferOps & IMAGE_MIN_MAX_BIT) {
-      _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
+      update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
    }
    /* clamping to [0,1] */
    if (transferOps & IMAGE_CLAMP_BIT) {
@@ -1589,7 +1650,7 @@ _mesa_apply_stencil_transfer_ops(const GLcontext *ctx, GLuint n,
       GLuint mask = ctx->PixelMaps.StoS.Size - 1;
       GLuint i;
       for (i = 0; i < n; i++) {
-         stencil[i] = ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
+         stencil[i] = (GLstencil)ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
       }
    }
 }
@@ -1628,7 +1689,7 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
 
    if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
       /* compute luminance values */
-      if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
+      if (transferOps & IMAGE_CLAMP_BIT) {
          for (i = 0; i < n; i++) {
             GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
             luminance[i] = CLAMP(sum, 0.0F, 1.0F);
@@ -4100,7 +4161,7 @@ _mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
          const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
          GLuint i;
          for (i = 0; i < n; i++) {
-            indexes[i] = ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
+            indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
          }
       }
 
@@ -4452,7 +4513,7 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
    if (needClamp) {
       GLuint i;
       for (i = 0; i < n; i++) {
-         depthValues[i] = CLAMP(depthValues[i], 0.0, 1.0);
+         depthValues[i] = (GLfloat)CLAMP(depthValues[i], 0.0, 1.0);
       }
    }
 
@@ -5041,6 +5102,37 @@ _mesa_clip_readpixels(const GLcontext *ctx,
 }
 
 
+/**
+ * Do clipping for a glCopyTexSubImage call.
+ * The framebuffer source region might extend outside the framebuffer
+ * bounds.  Clip the source region against the framebuffer bounds and
+ * adjust the texture/dest position and size accordingly.
+ *
+ * \return GL_FALSE if region is totally clipped, GL_TRUE otherwise.
+ */
+GLboolean
+_mesa_clip_copytexsubimage(const GLcontext *ctx,
+                           GLint *destX, GLint *destY,
+                           GLint *srcX, GLint *srcY,
+                           GLsizei *width, GLsizei *height)
+{
+   const struct gl_framebuffer *fb = ctx->ReadBuffer;
+   const GLint srcX0 = *srcX, srcY0 = *srcY;
+
+   if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height,
+                            srcX, srcY, width, height)) {
+      *destX = *destX + *srcX - srcX0;
+      *destY = *destY + *srcY - srcY0;
+
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+
 /**
  * Clip the rectangle defined by (x, y, width, height) against the bounds
  * specified by [xmin, xmax) and [ymin, ymax).