123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /*
- * The Python Imaging Library
- * $Id$
- *
- * stuff to extract and paste back individual bands
- *
- * history:
- * 1996-03-20 fl Created
- * 1997-08-27 fl Fixed putband for single band targets.
- * 2003-09-26 fl Fixed getband/putband for 2-band images (LA, PA).
- *
- * Copyright (c) 1997-2003 by Secret Labs AB.
- * Copyright (c) 1996-1997 by Fredrik Lundh.
- *
- * See the README file for details on usage and redistribution.
- */
- #include "Imaging.h"
- Imaging
- ImagingGetBand(Imaging imIn, int band)
- {
- Imaging imOut;
- int x, y;
- /* Check arguments */
- if (!imIn || imIn->type != IMAGING_TYPE_UINT8)
- return (Imaging) ImagingError_ModeError();
- if (band < 0 || band >= imIn->bands)
- return (Imaging) ImagingError_ValueError("band index out of range");
- /* Shortcuts */
- if (imIn->bands == 1)
- return ImagingCopy(imIn);
- /* Special case for LXXA etc */
- if (imIn->bands == 2 && band == 1)
- band = 3;
- imOut = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
- if (!imOut)
- return NULL;
- /* Extract band from image */
- for (y = 0; y < imIn->ysize; y++) {
- UINT8* in = (UINT8*) imIn->image[y] + band;
- UINT8* out = imOut->image8[y];
- x = 0;
- for (; x < imIn->xsize - 3; x += 4) {
- UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
- memcpy(out + x, &v, sizeof(v));
- in += 16;
- }
- for (; x < imIn->xsize; x++) {
- out[x] = *in;
- in += 4;
- }
- }
- return imOut;
- }
- int
- ImagingSplit(Imaging imIn, Imaging bands[4])
- {
- int i, j, x, y;
- /* Check arguments */
- if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
- (void) ImagingError_ModeError();
- return 0;
- }
- /* Shortcuts */
- if (imIn->bands == 1) {
- bands[0] = ImagingCopy(imIn);
- return imIn->bands;
- }
- for (i = 0; i < imIn->bands; i++) {
- bands[i] = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
- if ( ! bands[i]) {
- for (j = 0; j < i; ++j) {
- ImagingDelete(bands[j]);
- }
- return 0;
- }
- }
- /* Extract bands from image */
- if (imIn->bands == 2) {
- for (y = 0; y < imIn->ysize; y++) {
- UINT8* in = (UINT8*) imIn->image[y];
- UINT8* out0 = bands[0]->image8[y];
- UINT8* out1 = bands[1]->image8[y];
- x = 0;
- for (; x < imIn->xsize - 3; x += 4) {
- UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
- memcpy(out0 + x, &v, sizeof(v));
- v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]);
- memcpy(out1 + x, &v, sizeof(v));
- in += 16;
- }
- for (; x < imIn->xsize; x++) {
- out0[x] = in[0];
- out1[x] = in[3];
- in += 4;
- }
- }
- } else if (imIn->bands == 3) {
- for (y = 0; y < imIn->ysize; y++) {
- UINT8* in = (UINT8*) imIn->image[y];
- UINT8* out0 = bands[0]->image8[y];
- UINT8* out1 = bands[1]->image8[y];
- UINT8* out2 = bands[2]->image8[y];
- x = 0;
- for (; x < imIn->xsize - 3; x += 4) {
- UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
- memcpy(out0 + x, &v, sizeof(v));
- v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]);
- memcpy(out1 + x, &v, sizeof(v));
- v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]);
- memcpy(out2 + x, &v, sizeof(v));
- in += 16;
- }
- for (; x < imIn->xsize; x++) {
- out0[x] = in[0];
- out1[x] = in[1];
- out2[x] = in[2];
- in += 4;
- }
- }
- } else {
- for (y = 0; y < imIn->ysize; y++) {
- UINT8* in = (UINT8*) imIn->image[y];
- UINT8* out0 = bands[0]->image8[y];
- UINT8* out1 = bands[1]->image8[y];
- UINT8* out2 = bands[2]->image8[y];
- UINT8* out3 = bands[3]->image8[y];
- x = 0;
- for (; x < imIn->xsize - 3; x += 4) {
- UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
- memcpy(out0 + x, &v, sizeof(v));
- v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]);
- memcpy(out1 + x, &v, sizeof(v));
- v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]);
- memcpy(out2 + x, &v, sizeof(v));
- v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]);
- memcpy(out3 + x, &v, sizeof(v));
- in += 16;
- }
- for (; x < imIn->xsize; x++) {
- out0[x] = in[0];
- out1[x] = in[1];
- out2[x] = in[2];
- out3[x] = in[3];
- in += 4;
- }
- }
- }
- return imIn->bands;
- }
- Imaging
- ImagingPutBand(Imaging imOut, Imaging imIn, int band)
- {
- int x, y;
- /* Check arguments */
- if (!imIn || imIn->bands != 1 || !imOut)
- return (Imaging) ImagingError_ModeError();
- if (band < 0 || band >= imOut->bands)
- return (Imaging) ImagingError_ValueError("band index out of range");
- if (imIn->type != imOut->type ||
- imIn->xsize != imOut->xsize ||
- imIn->ysize != imOut->ysize)
- return (Imaging) ImagingError_Mismatch();
- /* Shortcuts */
- if (imOut->bands == 1)
- return ImagingCopy2(imOut, imIn);
- /* Special case for LXXA etc */
- if (imOut->bands == 2 && band == 1)
- band = 3;
- /* Insert band into image */
- for (y = 0; y < imIn->ysize; y++) {
- UINT8* in = imIn->image8[y];
- UINT8* out = (UINT8*) imOut->image[y] + band;
- for (x = 0; x < imIn->xsize; x++) {
- *out = in[x];
- out += 4;
- }
- }
- return imOut;
- }
- Imaging
- ImagingFillBand(Imaging imOut, int band, int color)
- {
- int x, y;
- /* Check arguments */
- if (!imOut || imOut->type != IMAGING_TYPE_UINT8)
- return (Imaging) ImagingError_ModeError();
- if (band < 0 || band >= imOut->bands)
- return (Imaging) ImagingError_ValueError("band index out of range");
- /* Special case for LXXA etc */
- if (imOut->bands == 2 && band == 1)
- band = 3;
- color = CLIP8(color);
- /* Insert color into image */
- for (y = 0; y < imOut->ysize; y++) {
- UINT8* out = (UINT8*) imOut->image[y] + band;
- for (x = 0; x < imOut->xsize; x++) {
- *out = (UINT8) color;
- out += 4;
- }
- }
- return imOut;
- }
- Imaging
- ImagingMerge(const char* mode, Imaging bands[4])
- {
- int i, x, y;
- int bandsCount = 0;
- Imaging imOut;
- Imaging firstBand;
- firstBand = bands[0];
- if ( ! firstBand) {
- return (Imaging) ImagingError_ValueError("wrong number of bands");
- }
- for (i = 0; i < 4; ++i) {
- if ( ! bands[i]) {
- break;
- }
- if (bands[i]->bands != 1) {
- return (Imaging) ImagingError_ModeError();
- }
- if (bands[i]->xsize != firstBand->xsize
- || bands[i]->ysize != firstBand->ysize) {
- return (Imaging) ImagingError_Mismatch();
- }
- }
- bandsCount = i;
- imOut = ImagingNewDirty(mode, firstBand->xsize, firstBand->ysize);
- if ( ! imOut)
- return NULL;
- if (imOut->bands != bandsCount) {
- ImagingDelete(imOut);
- return (Imaging) ImagingError_ValueError("wrong number of bands");
- }
- if (imOut->bands == 1)
- return ImagingCopy2(imOut, firstBand);
- if (imOut->bands == 2) {
- for (y = 0; y < imOut->ysize; y++) {
- UINT8* in0 = bands[0]->image8[y];
- UINT8* in1 = bands[1]->image8[y];
- UINT32* out = (UINT32*) imOut->image32[y];
- for (x = 0; x < imOut->xsize; x++) {
- out[x] = MAKE_UINT32(in0[x], 0, 0, in1[x]);
- }
- }
- } else if (imOut->bands == 3) {
- for (y = 0; y < imOut->ysize; y++) {
- UINT8* in0 = bands[0]->image8[y];
- UINT8* in1 = bands[1]->image8[y];
- UINT8* in2 = bands[2]->image8[y];
- UINT32* out = (UINT32*) imOut->image32[y];
- for (x = 0; x < imOut->xsize; x++) {
- out[x] = MAKE_UINT32(in0[x], in1[x], in2[x], 0);
- }
- }
- } else if (imOut->bands == 4) {
- for (y = 0; y < imOut->ysize; y++) {
- UINT8* in0 = bands[0]->image8[y];
- UINT8* in1 = bands[1]->image8[y];
- UINT8* in2 = bands[2]->image8[y];
- UINT8* in3 = bands[3]->image8[y];
- UINT32* out = (UINT32*) imOut->image32[y];
- for (x = 0; x < imOut->xsize; x++) {
- out[x] = MAKE_UINT32(in0[x], in1[x], in2[x], in3[x]);
- }
- }
- }
- return imOut;
- }
|