Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Imaging/libImaging/Histo.c
diff options
context:
space:
mode:
Diffstat (limited to 'Imaging/libImaging/Histo.c')
-rw-r--r--Imaging/libImaging/Histo.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/Imaging/libImaging/Histo.c b/Imaging/libImaging/Histo.c
new file mode 100644
index 0000000..b69b1db
--- /dev/null
+++ b/Imaging/libImaging/Histo.c
@@ -0,0 +1,169 @@
+/*
+ * The Python Imaging Library
+ * $Id: Histo.c 2134 2004-10-06 08:55:20Z fredrik $
+ *
+ * histogram support
+ *
+ * history:
+ * 1995-06-15 fl Created.
+ * 1996-04-05 fl Fixed histogram for multiband images.
+ * 1997-02-23 fl Added mask support
+ * 1998-07-01 fl Added basic 32-bit float/integer support
+ *
+ * Copyright (c) 1997-2003 by Secret Labs AB.
+ * Copyright (c) 1995-2003 by Fredrik Lundh.
+ *
+ * See the README file for information on usage and redistribution.
+ */
+
+
+#include "Imaging.h"
+
+
+/* HISTOGRAM */
+/* --------------------------------------------------------------------
+ * Take a histogram of an image. Returns a histogram object containing
+ * 256 slots per band in the input image.
+ */
+
+void
+ImagingHistogramDelete(ImagingHistogram h)
+{
+ if (h->histogram)
+ free(h->histogram);
+ free(h);
+}
+
+ImagingHistogram
+ImagingHistogramNew(Imaging im)
+{
+ ImagingHistogram h;
+
+ /* Create histogram descriptor */
+ h = calloc(1, sizeof(struct ImagingHistogramInstance));
+ strcpy(h->mode, im->mode);
+ h->bands = im->bands;
+ h->histogram = calloc(im->pixelsize, 256 * sizeof(long));
+
+ return h;
+}
+
+ImagingHistogram
+ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
+{
+ ImagingSectionCookie cookie;
+ int x, y, i;
+ ImagingHistogram h;
+ INT32 imin, imax;
+ FLOAT32 fmin, fmax, scale;
+
+ if (!im)
+ return ImagingError_ModeError();
+
+ if (imMask) {
+ /* Validate mask */
+ if (im->xsize != imMask->xsize || im->ysize != imMask->ysize)
+ return ImagingError_Mismatch();
+ if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0)
+ return ImagingError_ValueError("bad transparency mask");
+ }
+
+ h = ImagingHistogramNew(im);
+
+ if (imMask) {
+ /* mask */
+ if (im->image8) {
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < im->ysize; y++)
+ for (x = 0; x < im->xsize; x++)
+ if (imMask->image8[y][x] != 0)
+ h->histogram[im->image8[y][x]]++;
+ ImagingSectionLeave(&cookie);
+ } else { /* yes, we need the braces. C isn't Python! */
+ if (im->type != IMAGING_TYPE_UINT8)
+ return ImagingError_ModeError();
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < im->ysize; y++) {
+ UINT8* in = (UINT8*) im->image32[y];
+ for (x = 0; x < im->xsize; x++)
+ if (imMask->image8[y][x] != 0) {
+ h->histogram[(*in++)]++;
+ h->histogram[(*in++)+256]++;
+ h->histogram[(*in++)+512]++;
+ h->histogram[(*in++)+768]++;
+ } else
+ in += 4;
+ }
+ ImagingSectionLeave(&cookie);
+ }
+ } else {
+ /* mask not given; process pixels in image */
+ if (im->image8) {
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < im->ysize; y++)
+ for (x = 0; x < im->xsize; x++)
+ h->histogram[im->image8[y][x]]++;
+ ImagingSectionLeave(&cookie);
+ } else {
+ switch (im->type) {
+ case IMAGING_TYPE_UINT8:
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < im->ysize; y++) {
+ UINT8* in = (UINT8*) im->image[y];
+ for (x = 0; x < im->xsize; x++) {
+ h->histogram[(*in++)]++;
+ h->histogram[(*in++)+256]++;
+ h->histogram[(*in++)+512]++;
+ h->histogram[(*in++)+768]++;
+ }
+ }
+ ImagingSectionLeave(&cookie);
+ break;
+ case IMAGING_TYPE_INT32:
+ if (!minmax)
+ return ImagingError_ValueError("min/max not given");
+ if (!im->xsize || !im->ysize)
+ break;
+ imin = ((INT32*) minmax)[0];
+ imax = ((INT32*) minmax)[1];
+ if (imin >= imax)
+ break;
+ ImagingSectionEnter(&cookie);
+ scale = 255.0F / (imax - imin);
+ for (y = 0; y < im->ysize; y++) {
+ INT32* in = im->image32[y];
+ for (x = 0; x < im->xsize; x++) {
+ i = (int) (((*in++)-imin)*scale);
+ if (i >= 0 && i < 256)
+ h->histogram[i]++;
+ }
+ }
+ ImagingSectionLeave(&cookie);
+ break;
+ case IMAGING_TYPE_FLOAT32:
+ if (!minmax)
+ return ImagingError_ValueError("min/max not given");
+ if (!im->xsize || !im->ysize)
+ break;
+ fmin = ((FLOAT32*) minmax)[0];
+ fmax = ((FLOAT32*) minmax)[1];
+ if (fmin >= fmax)
+ break;
+ ImagingSectionEnter(&cookie);
+ scale = 255.0F / (fmax - fmin);
+ for (y = 0; y < im->ysize; y++) {
+ FLOAT32* in = (FLOAT32*) im->image32[y];
+ for (x = 0; x < im->xsize; x++) {
+ i = (int) (((*in++)-fmin)*scale);
+ if (i >= 0 && i < 256)
+ h->histogram[i]++;
+ }
+ }
+ ImagingSectionLeave(&cookie);
+ break;
+ }
+ }
+ }
+
+ return h;
+}