Pillow
201 строка · 6.6 Кб
1/*
2* The Python Imaging Library
3* $Id$
4*
5* histogram support
6*
7* history:
8* 1995-06-15 fl Created.
9* 1996-04-05 fl Fixed histogram for multiband images.
10* 1997-02-23 fl Added mask support
11* 1998-07-01 fl Added basic 32-bit float/integer support
12*
13* Copyright (c) 1997-2003 by Secret Labs AB.
14* Copyright (c) 1995-2003 by Fredrik Lundh.
15*
16* See the README file for information on usage and redistribution.
17*/
18
19#include "Imaging.h"20
21/* HISTOGRAM */
22/* --------------------------------------------------------------------
23* Take a histogram of an image. Returns a histogram object containing
24* 256 slots per band in the input image.
25*/
26
27void
28ImagingHistogramDelete(ImagingHistogram h) {29if (h) {30if (h->histogram) {31free(h->histogram);32}33free(h);34}35}
36
37ImagingHistogram
38ImagingHistogramNew(Imaging im) {39ImagingHistogram h;40
41/* Create histogram descriptor */42h = calloc(1, sizeof(struct ImagingHistogramInstance));43if (!h) {44return (ImagingHistogram)ImagingError_MemoryError();45}46strncpy(h->mode, im->mode, IMAGING_MODE_LENGTH - 1);47h->mode[IMAGING_MODE_LENGTH - 1] = 0;48
49h->bands = im->bands;50h->histogram = calloc(im->pixelsize, 256 * sizeof(long));51if (!h->histogram) {52free(h);53return (ImagingHistogram)ImagingError_MemoryError();54}55
56return h;57}
58
59ImagingHistogram
60ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) {61ImagingSectionCookie cookie;62int x, y, i;63ImagingHistogram h;64INT32 imin, imax;65FLOAT32 fmin, fmax, scale;66
67if (!im) {68return ImagingError_ModeError();69}70
71if (imMask) {72/* Validate mask */73if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) {74return ImagingError_Mismatch();75}76if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) {77return ImagingError_ValueError("bad transparency mask");78}79}80
81h = ImagingHistogramNew(im);82if (!h) {83return NULL;84}85
86if (imMask) {87/* mask */88if (im->image8) {89ImagingSectionEnter(&cookie);90for (y = 0; y < im->ysize; y++) {91for (x = 0; x < im->xsize; x++) {92if (imMask->image8[y][x] != 0) {93h->histogram[im->image8[y][x]]++;94}95}96}97ImagingSectionLeave(&cookie);98} else { /* yes, we need the braces. C isn't Python! */99if (im->type != IMAGING_TYPE_UINT8) {100ImagingHistogramDelete(h);101return ImagingError_ModeError();102}103ImagingSectionEnter(&cookie);104for (y = 0; y < im->ysize; y++) {105UINT8 *in = (UINT8 *)im->image32[y];106for (x = 0; x < im->xsize; x++) {107if (imMask->image8[y][x] != 0) {108h->histogram[(*in++)]++;109h->histogram[(*in++) + 256]++;110h->histogram[(*in++) + 512]++;111h->histogram[(*in++) + 768]++;112} else {113in += 4;114}115}116}117ImagingSectionLeave(&cookie);118}119} else {120/* mask not given; process pixels in image */121if (im->image8) {122ImagingSectionEnter(&cookie);123for (y = 0; y < im->ysize; y++) {124for (x = 0; x < im->xsize; x++) {125h->histogram[im->image8[y][x]]++;126}127}128ImagingSectionLeave(&cookie);129} else {130switch (im->type) {131case IMAGING_TYPE_UINT8:132ImagingSectionEnter(&cookie);133for (y = 0; y < im->ysize; y++) {134UINT8 *in = (UINT8 *)im->image[y];135for (x = 0; x < im->xsize; x++) {136h->histogram[(*in++)]++;137h->histogram[(*in++) + 256]++;138h->histogram[(*in++) + 512]++;139h->histogram[(*in++) + 768]++;140}141}142ImagingSectionLeave(&cookie);143break;144case IMAGING_TYPE_INT32:145if (!minmax) {146ImagingHistogramDelete(h);147return ImagingError_ValueError("min/max not given");148}149if (!im->xsize || !im->ysize) {150break;151}152memcpy(&imin, minmax, sizeof(imin));153memcpy(&imax, ((char *)minmax) + sizeof(imin), sizeof(imax));154if (imin >= imax) {155break;156}157ImagingSectionEnter(&cookie);158scale = 255.0F / (imax - imin);159for (y = 0; y < im->ysize; y++) {160INT32 *in = im->image32[y];161for (x = 0; x < im->xsize; x++) {162i = (int)(((*in++) - imin) * scale);163if (i >= 0 && i < 256) {164h->histogram[i]++;165}166}167}168ImagingSectionLeave(&cookie);169break;170case IMAGING_TYPE_FLOAT32:171if (!minmax) {172ImagingHistogramDelete(h);173return ImagingError_ValueError("min/max not given");174}175if (!im->xsize || !im->ysize) {176break;177}178memcpy(&fmin, minmax, sizeof(fmin));179memcpy(&fmax, ((char *)minmax) + sizeof(fmin), sizeof(fmax));180if (fmin >= fmax) {181break;182}183ImagingSectionEnter(&cookie);184scale = 255.0F / (fmax - fmin);185for (y = 0; y < im->ysize; y++) {186FLOAT32 *in = (FLOAT32 *)im->image32[y];187for (x = 0; x < im->xsize; x++) {188i = (int)(((*in++) - fmin) * scale);189if (i >= 0 && i < 256) {190h->histogram[i]++;191}192}193}194ImagingSectionLeave(&cookie);195break;196}197}198}199
200return h;201}
202