Pillow

Форк
0
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

27
void
28
ImagingHistogramDelete(ImagingHistogram h) {
29
    if (h) {
30
        if (h->histogram) {
31
            free(h->histogram);
32
        }
33
        free(h);
34
    }
35
}
36

37
ImagingHistogram
38
ImagingHistogramNew(Imaging im) {
39
    ImagingHistogram h;
40

41
    /* Create histogram descriptor */
42
    h = calloc(1, sizeof(struct ImagingHistogramInstance));
43
    if (!h) {
44
        return (ImagingHistogram)ImagingError_MemoryError();
45
    }
46
    strncpy(h->mode, im->mode, IMAGING_MODE_LENGTH - 1);
47
    h->mode[IMAGING_MODE_LENGTH - 1] = 0;
48

49
    h->bands = im->bands;
50
    h->histogram = calloc(im->pixelsize, 256 * sizeof(long));
51
    if (!h->histogram) {
52
        free(h);
53
        return (ImagingHistogram)ImagingError_MemoryError();
54
    }
55

56
    return h;
57
}
58

59
ImagingHistogram
60
ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) {
61
    ImagingSectionCookie cookie;
62
    int x, y, i;
63
    ImagingHistogram h;
64
    INT32 imin, imax;
65
    FLOAT32 fmin, fmax, scale;
66

67
    if (!im) {
68
        return ImagingError_ModeError();
69
    }
70

71
    if (imMask) {
72
        /* Validate mask */
73
        if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) {
74
            return ImagingError_Mismatch();
75
        }
76
        if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) {
77
            return ImagingError_ValueError("bad transparency mask");
78
        }
79
    }
80

81
    h = ImagingHistogramNew(im);
82
    if (!h) {
83
        return NULL;
84
    }
85

86
    if (imMask) {
87
        /* mask */
88
        if (im->image8) {
89
            ImagingSectionEnter(&cookie);
90
            for (y = 0; y < im->ysize; y++) {
91
                for (x = 0; x < im->xsize; x++) {
92
                    if (imMask->image8[y][x] != 0) {
93
                        h->histogram[im->image8[y][x]]++;
94
                    }
95
                }
96
            }
97
            ImagingSectionLeave(&cookie);
98
        } else { /* yes, we need the braces. C isn't Python! */
99
            if (im->type != IMAGING_TYPE_UINT8) {
100
                ImagingHistogramDelete(h);
101
                return ImagingError_ModeError();
102
            }
103
            ImagingSectionEnter(&cookie);
104
            for (y = 0; y < im->ysize; y++) {
105
                UINT8 *in = (UINT8 *)im->image32[y];
106
                for (x = 0; x < im->xsize; x++) {
107
                    if (imMask->image8[y][x] != 0) {
108
                        h->histogram[(*in++)]++;
109
                        h->histogram[(*in++) + 256]++;
110
                        h->histogram[(*in++) + 512]++;
111
                        h->histogram[(*in++) + 768]++;
112
                    } else {
113
                        in += 4;
114
                    }
115
                }
116
            }
117
            ImagingSectionLeave(&cookie);
118
        }
119
    } else {
120
        /* mask not given; process pixels in image */
121
        if (im->image8) {
122
            ImagingSectionEnter(&cookie);
123
            for (y = 0; y < im->ysize; y++) {
124
                for (x = 0; x < im->xsize; x++) {
125
                    h->histogram[im->image8[y][x]]++;
126
                }
127
            }
128
            ImagingSectionLeave(&cookie);
129
        } else {
130
            switch (im->type) {
131
                case IMAGING_TYPE_UINT8:
132
                    ImagingSectionEnter(&cookie);
133
                    for (y = 0; y < im->ysize; y++) {
134
                        UINT8 *in = (UINT8 *)im->image[y];
135
                        for (x = 0; x < im->xsize; x++) {
136
                            h->histogram[(*in++)]++;
137
                            h->histogram[(*in++) + 256]++;
138
                            h->histogram[(*in++) + 512]++;
139
                            h->histogram[(*in++) + 768]++;
140
                        }
141
                    }
142
                    ImagingSectionLeave(&cookie);
143
                    break;
144
                case IMAGING_TYPE_INT32:
145
                    if (!minmax) {
146
                        ImagingHistogramDelete(h);
147
                        return ImagingError_ValueError("min/max not given");
148
                    }
149
                    if (!im->xsize || !im->ysize) {
150
                        break;
151
                    }
152
                    memcpy(&imin, minmax, sizeof(imin));
153
                    memcpy(&imax, ((char *)minmax) + sizeof(imin), sizeof(imax));
154
                    if (imin >= imax) {
155
                        break;
156
                    }
157
                    ImagingSectionEnter(&cookie);
158
                    scale = 255.0F / (imax - imin);
159
                    for (y = 0; y < im->ysize; y++) {
160
                        INT32 *in = im->image32[y];
161
                        for (x = 0; x < im->xsize; x++) {
162
                            i = (int)(((*in++) - imin) * scale);
163
                            if (i >= 0 && i < 256) {
164
                                h->histogram[i]++;
165
                            }
166
                        }
167
                    }
168
                    ImagingSectionLeave(&cookie);
169
                    break;
170
                case IMAGING_TYPE_FLOAT32:
171
                    if (!minmax) {
172
                        ImagingHistogramDelete(h);
173
                        return ImagingError_ValueError("min/max not given");
174
                    }
175
                    if (!im->xsize || !im->ysize) {
176
                        break;
177
                    }
178
                    memcpy(&fmin, minmax, sizeof(fmin));
179
                    memcpy(&fmax, ((char *)minmax) + sizeof(fmin), sizeof(fmax));
180
                    if (fmin >= fmax) {
181
                        break;
182
                    }
183
                    ImagingSectionEnter(&cookie);
184
                    scale = 255.0F / (fmax - fmin);
185
                    for (y = 0; y < im->ysize; y++) {
186
                        FLOAT32 *in = (FLOAT32 *)im->image32[y];
187
                        for (x = 0; x < im->xsize; x++) {
188
                            i = (int)(((*in++) - fmin) * scale);
189
                            if (i >= 0 && i < 256) {
190
                                h->histogram[i]++;
191
                            }
192
                        }
193
                    }
194
                    ImagingSectionLeave(&cookie);
195
                    break;
196
            }
197
        }
198
    }
199

200
    return h;
201
}
202

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.