123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /*
- * The Python Imaging Library
- * $Id$
- *
- * 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));
- strncpy(h->mode, im->mode, IMAGING_MODE_LENGTH-1);
- h->mode[IMAGING_MODE_LENGTH-1] = 0;
- 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) {
- ImagingHistogramDelete(h);
- 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) {
- ImagingHistogramDelete(h);
- return ImagingError_ValueError("min/max not given");
- }
- if (!im->xsize || !im->ysize)
- break;
- memcpy(&imin, minmax, sizeof(imin));
- memcpy(&imax, ((char*)minmax) + sizeof(imin), sizeof(imax));
- 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) {
- ImagingHistogramDelete(h);
- return ImagingError_ValueError("min/max not given");
- }
- if (!im->xsize || !im->ysize)
- break;
- memcpy(&fmin, minmax, sizeof(fmin));
- memcpy(&fmax, ((char*)minmax) + sizeof(fmin), sizeof(fmax));
- 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;
- }
|