Pillow
315 строк · 8.8 Кб
1/*
2* The Python Imaging Library
3* $Id$
4*
5* stuff to extract and paste back individual bands
6*
7* history:
8* 1996-03-20 fl Created
9* 1997-08-27 fl Fixed putband for single band targets.
10* 2003-09-26 fl Fixed getband/putband for 2-band images (LA, PA).
11*
12* Copyright (c) 1997-2003 by Secret Labs AB.
13* Copyright (c) 1996-1997 by Fredrik Lundh.
14*
15* See the README file for details on usage and redistribution.
16*/
17
18#include "Imaging.h"
19
20Imaging
21ImagingGetBand(Imaging imIn, int band) {
22Imaging imOut;
23int x, y;
24
25/* Check arguments */
26if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
27return (Imaging)ImagingError_ModeError();
28}
29
30if (band < 0 || band >= imIn->bands) {
31return (Imaging)ImagingError_ValueError("band index out of range");
32}
33
34/* Shortcuts */
35if (imIn->bands == 1) {
36return ImagingCopy(imIn);
37}
38
39/* Special case for LXXA etc */
40if (imIn->bands == 2 && band == 1) {
41band = 3;
42}
43
44imOut = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
45if (!imOut) {
46return NULL;
47}
48
49/* Extract band from image */
50for (y = 0; y < imIn->ysize; y++) {
51UINT8 *in = (UINT8 *)imIn->image[y] + band;
52UINT8 *out = imOut->image8[y];
53x = 0;
54for (; x < imIn->xsize - 3; x += 4) {
55UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
56memcpy(out + x, &v, sizeof(v));
57in += 16;
58}
59for (; x < imIn->xsize; x++) {
60out[x] = *in;
61in += 4;
62}
63}
64
65return imOut;
66}
67
68int
69ImagingSplit(Imaging imIn, Imaging bands[4]) {
70int i, j, x, y;
71
72/* Check arguments */
73if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
74(void)ImagingError_ModeError();
75return 0;
76}
77
78/* Shortcuts */
79if (imIn->bands == 1) {
80bands[0] = ImagingCopy(imIn);
81return imIn->bands;
82}
83
84for (i = 0; i < imIn->bands; i++) {
85bands[i] = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
86if (!bands[i]) {
87for (j = 0; j < i; ++j) {
88ImagingDelete(bands[j]);
89}
90return 0;
91}
92}
93
94/* Extract bands from image */
95if (imIn->bands == 2) {
96for (y = 0; y < imIn->ysize; y++) {
97UINT8 *in = (UINT8 *)imIn->image[y];
98UINT8 *out0 = bands[0]->image8[y];
99UINT8 *out1 = bands[1]->image8[y];
100x = 0;
101for (; x < imIn->xsize - 3; x += 4) {
102UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
103memcpy(out0 + x, &v, sizeof(v));
104v = MAKE_UINT32(in[0 + 3], in[4 + 3], in[8 + 3], in[12 + 3]);
105memcpy(out1 + x, &v, sizeof(v));
106in += 16;
107}
108for (; x < imIn->xsize; x++) {
109out0[x] = in[0];
110out1[x] = in[3];
111in += 4;
112}
113}
114} else if (imIn->bands == 3) {
115for (y = 0; y < imIn->ysize; y++) {
116UINT8 *in = (UINT8 *)imIn->image[y];
117UINT8 *out0 = bands[0]->image8[y];
118UINT8 *out1 = bands[1]->image8[y];
119UINT8 *out2 = bands[2]->image8[y];
120x = 0;
121for (; x < imIn->xsize - 3; x += 4) {
122UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
123memcpy(out0 + x, &v, sizeof(v));
124v = MAKE_UINT32(in[0 + 1], in[4 + 1], in[8 + 1], in[12 + 1]);
125memcpy(out1 + x, &v, sizeof(v));
126v = MAKE_UINT32(in[0 + 2], in[4 + 2], in[8 + 2], in[12 + 2]);
127memcpy(out2 + x, &v, sizeof(v));
128in += 16;
129}
130for (; x < imIn->xsize; x++) {
131out0[x] = in[0];
132out1[x] = in[1];
133out2[x] = in[2];
134in += 4;
135}
136}
137} else {
138for (y = 0; y < imIn->ysize; y++) {
139UINT8 *in = (UINT8 *)imIn->image[y];
140UINT8 *out0 = bands[0]->image8[y];
141UINT8 *out1 = bands[1]->image8[y];
142UINT8 *out2 = bands[2]->image8[y];
143UINT8 *out3 = bands[3]->image8[y];
144x = 0;
145for (; x < imIn->xsize - 3; x += 4) {
146UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
147memcpy(out0 + x, &v, sizeof(v));
148v = MAKE_UINT32(in[0 + 1], in[4 + 1], in[8 + 1], in[12 + 1]);
149memcpy(out1 + x, &v, sizeof(v));
150v = MAKE_UINT32(in[0 + 2], in[4 + 2], in[8 + 2], in[12 + 2]);
151memcpy(out2 + x, &v, sizeof(v));
152v = MAKE_UINT32(in[0 + 3], in[4 + 3], in[8 + 3], in[12 + 3]);
153memcpy(out3 + x, &v, sizeof(v));
154in += 16;
155}
156for (; x < imIn->xsize; x++) {
157out0[x] = in[0];
158out1[x] = in[1];
159out2[x] = in[2];
160out3[x] = in[3];
161in += 4;
162}
163}
164}
165
166return imIn->bands;
167}
168
169Imaging
170ImagingPutBand(Imaging imOut, Imaging imIn, int band) {
171int x, y;
172
173/* Check arguments */
174if (!imIn || imIn->bands != 1 || !imOut) {
175return (Imaging)ImagingError_ModeError();
176}
177
178if (band < 0 || band >= imOut->bands) {
179return (Imaging)ImagingError_ValueError("band index out of range");
180}
181
182if (imIn->type != imOut->type || imIn->xsize != imOut->xsize ||
183imIn->ysize != imOut->ysize) {
184return (Imaging)ImagingError_Mismatch();
185}
186
187/* Shortcuts */
188if (imOut->bands == 1) {
189return ImagingCopy2(imOut, imIn);
190}
191
192/* Special case for LXXA etc */
193if (imOut->bands == 2 && band == 1) {
194band = 3;
195}
196
197/* Insert band into image */
198for (y = 0; y < imIn->ysize; y++) {
199UINT8 *in = imIn->image8[y];
200UINT8 *out = (UINT8 *)imOut->image[y] + band;
201for (x = 0; x < imIn->xsize; x++) {
202*out = in[x];
203out += 4;
204}
205}
206
207return imOut;
208}
209
210Imaging
211ImagingFillBand(Imaging imOut, int band, int color) {
212int x, y;
213
214/* Check arguments */
215if (!imOut || imOut->type != IMAGING_TYPE_UINT8) {
216return (Imaging)ImagingError_ModeError();
217}
218
219if (band < 0 || band >= imOut->bands) {
220return (Imaging)ImagingError_ValueError("band index out of range");
221}
222
223/* Special case for LXXA etc */
224if (imOut->bands == 2 && band == 1) {
225band = 3;
226}
227
228color = CLIP8(color);
229
230/* Insert color into image */
231for (y = 0; y < imOut->ysize; y++) {
232UINT8 *out = (UINT8 *)imOut->image[y] + band;
233for (x = 0; x < imOut->xsize; x++) {
234*out = (UINT8)color;
235out += 4;
236}
237}
238
239return imOut;
240}
241
242Imaging
243ImagingMerge(const char *mode, Imaging bands[4]) {
244int i, x, y;
245int bandsCount = 0;
246Imaging imOut;
247Imaging firstBand;
248
249firstBand = bands[0];
250if (!firstBand) {
251return (Imaging)ImagingError_ValueError("wrong number of bands");
252}
253
254for (i = 0; i < 4; ++i) {
255if (!bands[i]) {
256break;
257}
258if (bands[i]->bands != 1) {
259return (Imaging)ImagingError_ModeError();
260}
261if (bands[i]->xsize != firstBand->xsize ||
262bands[i]->ysize != firstBand->ysize) {
263return (Imaging)ImagingError_Mismatch();
264}
265}
266bandsCount = i;
267
268imOut = ImagingNewDirty(mode, firstBand->xsize, firstBand->ysize);
269if (!imOut) {
270return NULL;
271}
272
273if (imOut->bands != bandsCount) {
274ImagingDelete(imOut);
275return (Imaging)ImagingError_ValueError("wrong number of bands");
276}
277
278if (imOut->bands == 1) {
279return ImagingCopy2(imOut, firstBand);
280}
281
282if (imOut->bands == 2) {
283for (y = 0; y < imOut->ysize; y++) {
284UINT8 *in0 = bands[0]->image8[y];
285UINT8 *in1 = bands[1]->image8[y];
286UINT32 *out = (UINT32 *)imOut->image32[y];
287for (x = 0; x < imOut->xsize; x++) {
288out[x] = MAKE_UINT32(in0[x], 0, 0, in1[x]);
289}
290}
291} else if (imOut->bands == 3) {
292for (y = 0; y < imOut->ysize; y++) {
293UINT8 *in0 = bands[0]->image8[y];
294UINT8 *in1 = bands[1]->image8[y];
295UINT8 *in2 = bands[2]->image8[y];
296UINT32 *out = (UINT32 *)imOut->image32[y];
297for (x = 0; x < imOut->xsize; x++) {
298out[x] = MAKE_UINT32(in0[x], in1[x], in2[x], 0);
299}
300}
301} else if (imOut->bands == 4) {
302for (y = 0; y < imOut->ysize; y++) {
303UINT8 *in0 = bands[0]->image8[y];
304UINT8 *in1 = bands[1]->image8[y];
305UINT8 *in2 = bands[2]->image8[y];
306UINT8 *in3 = bands[3]->image8[y];
307UINT32 *out = (UINT32 *)imOut->image32[y];
308for (x = 0; x < imOut->xsize; x++) {
309out[x] = MAKE_UINT32(in0[x], in1[x], in2[x], in3[x]);
310}
311}
312}
313
314return imOut;
315}
316