mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-03 19:33:07 +03:00
introduce multi-band format (TIFF only)
This commit is contained in:
parent
03df35777c
commit
936439b481
|
@ -877,14 +877,14 @@ class TestFileTiff:
|
||||||
def test_open_tiff_uint16_multiband(self):
|
def test_open_tiff_uint16_multiband(self):
|
||||||
"""Test opening multiband TIFFs and reading all channels."""
|
"""Test opening multiband TIFFs and reading all channels."""
|
||||||
base_value = 4660
|
base_value = 4660
|
||||||
for i in range(2, 6):
|
for i in range(1, 6):
|
||||||
infile = f"Tests/images/uint16_{i}_{base_value}.tif"
|
infile = f"Tests/images/uint16_{i}_{base_value}.tif"
|
||||||
im = Image.open(infile)
|
im = Image.open(infile)
|
||||||
im.load()
|
im.load()
|
||||||
pixel = [base_value + j for j in range(0, i)]
|
pixel = tuple([base_value + j for j in range(0, i)])
|
||||||
actual_pixel = im.getpixel((0, 0))
|
actual_pixel = im.getpixel((0, 0))
|
||||||
if isinstance(actual_pixel, int):
|
if isinstance(actual_pixel, int):
|
||||||
actual_pixel = [actual_pixel]
|
actual_pixel = (actual_pixel,)
|
||||||
assert actual_pixel == pixel
|
assert actual_pixel == pixel
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,8 @@ class ImageFile(Image.Image):
|
||||||
|
|
||||||
self.readonly = 1 # until we know better
|
self.readonly = 1 # until we know better
|
||||||
|
|
||||||
|
self.newconfig = ()
|
||||||
|
|
||||||
self.decoderconfig = ()
|
self.decoderconfig = ()
|
||||||
self.decodermaxblock = MAXBLOCK
|
self.decodermaxblock = MAXBLOCK
|
||||||
|
|
||||||
|
@ -317,7 +319,7 @@ class ImageFile(Image.Image):
|
||||||
def load_prepare(self) -> None:
|
def load_prepare(self) -> None:
|
||||||
# create image memory if necessary
|
# create image memory if necessary
|
||||||
if not self.im or self.im.mode != self.mode or self.im.size != self.size:
|
if not self.im or self.im.mode != self.mode or self.im.size != self.size:
|
||||||
self.im = Image.core.new(self.mode, self.size)
|
self.im = Image.core.new(self.mode, self.size, *self.newconfig)
|
||||||
# create palette (optional)
|
# create palette (optional)
|
||||||
if self.mode == "P":
|
if self.mode == "P":
|
||||||
Image.Image.load(self)
|
Image.Image.load(self)
|
||||||
|
|
|
@ -183,7 +183,7 @@ OPEN_INFO = {
|
||||||
(II, 1, (1,), 1, (12,), ()): ("I;16", "I;12"),
|
(II, 1, (1,), 1, (12,), ()): ("I;16", "I;12"),
|
||||||
(II, 0, (1,), 1, (16,), ()): ("I;16", "I;16"),
|
(II, 0, (1,), 1, (16,), ()): ("I;16", "I;16"),
|
||||||
(II, 1, (1,), 1, (16,), ()): ("I;16", "I;16"),
|
(II, 1, (1,), 1, (16,), ()): ("I;16", "I;16"),
|
||||||
(II, 1, (1, 1), 1, (16, 16), (0,)): ("I;16", "I;16"),
|
(II, 1, (1, 1), 1, (16, 16), (0,)): ("MB", "MB"),
|
||||||
(
|
(
|
||||||
II,
|
II,
|
||||||
1,
|
1,
|
||||||
|
@ -194,7 +194,7 @@ OPEN_INFO = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
): ("I;16", "I;16"),
|
): ("MB", "MB"),
|
||||||
(
|
(
|
||||||
II,
|
II,
|
||||||
1,
|
1,
|
||||||
|
@ -206,7 +206,7 @@ OPEN_INFO = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
): ("I;16", "I;16"),
|
): ("MB", "MB"),
|
||||||
(
|
(
|
||||||
II,
|
II,
|
||||||
1,
|
1,
|
||||||
|
@ -219,7 +219,7 @@ OPEN_INFO = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
): ("I;16", "I;16"),
|
): ("MB", "MB"),
|
||||||
(MM, 1, (1,), 1, (16,), ()): ("I;16B", "I;16B"),
|
(MM, 1, (1,), 1, (16,), ()): ("I;16B", "I;16B"),
|
||||||
(II, 1, (1,), 2, (16,), ()): ("I;16", "I;16R"),
|
(II, 1, (1,), 2, (16,), ()): ("I;16", "I;16R"),
|
||||||
(II, 1, (2,), 1, (16,), ()): ("I", "I;16S"),
|
(II, 1, (2,), 1, (16,), ()): ("I", "I;16S"),
|
||||||
|
@ -1474,6 +1474,9 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
logger.debug("- raw mode: %s", rawmode)
|
logger.debug("- raw mode: %s", rawmode)
|
||||||
logger.debug("- pil mode: %s", self.mode)
|
logger.debug("- pil mode: %s", self.mode)
|
||||||
|
if self.mode == "MB":
|
||||||
|
assert max(bps_tuple) == min(bps_tuple)
|
||||||
|
self.newconfig = (max(bps_tuple), samples_per_pixel)
|
||||||
|
|
||||||
self.info["compression"] = self._compression
|
self.info["compression"] = self._compression
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ getbands(const char *mode) {
|
||||||
int bands;
|
int bands;
|
||||||
|
|
||||||
/* FIXME: add primitive to libImaging to avoid extra allocation */
|
/* FIXME: add primitive to libImaging to avoid extra allocation */
|
||||||
im = ImagingNew(mode, 0, 0);
|
im = ImagingNew(mode, 0, 0, -1, -1);
|
||||||
if (!im) {
|
if (!im) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -434,6 +434,35 @@ float16tofloat32(const FLOAT16 in) {
|
||||||
return out[0];
|
return out[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline PyObject *
|
||||||
|
getpixel_mb(Imaging im, ImagingAccess access, int x, int y) {
|
||||||
|
UINT8 pixel[im->pixelsize];
|
||||||
|
access->get_pixel(im, x, y, &pixel);
|
||||||
|
|
||||||
|
PyObject *tuple = PyTuple_New(im->bands);
|
||||||
|
if (tuple == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 *pos = pixel;
|
||||||
|
for (int i = 0; i < im->bands; ++i) {
|
||||||
|
switch (im->depth) {
|
||||||
|
case CHAR_BIT:
|
||||||
|
PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(*pos));
|
||||||
|
break;
|
||||||
|
case 2 * CHAR_BIT:
|
||||||
|
PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(*(UINT16 *)pos));
|
||||||
|
break;
|
||||||
|
case 4 * CHAR_BIT:
|
||||||
|
PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(*(INT32 *)pos));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += im->depth / CHAR_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuple;
|
||||||
|
}
|
||||||
|
|
||||||
static inline PyObject *
|
static inline PyObject *
|
||||||
getpixel(Imaging im, ImagingAccess access, int x, int y) {
|
getpixel(Imaging im, ImagingAccess access, int x, int y) {
|
||||||
union {
|
union {
|
||||||
|
@ -455,6 +484,10 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (im->type == IMAGING_TYPE_MB) {
|
||||||
|
return getpixel_mb(im, access, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
access->get_pixel(im, x, y, &pixel);
|
access->get_pixel(im, x, y, &pixel);
|
||||||
|
|
||||||
switch (im->type) {
|
switch (im->type) {
|
||||||
|
@ -685,13 +718,13 @@ _fill(PyObject *self, PyObject *args) {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_new(PyObject *self, PyObject *args) {
|
_new(PyObject *self, PyObject *args) {
|
||||||
char *mode;
|
char *mode;
|
||||||
int xsize, ysize;
|
int xsize, ysize, depth = -1, bands = -1;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) {
|
if (!PyArg_ParseTuple(args, "s(ii)|ii", &mode, &xsize, &ysize, &depth, &bands)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyImagingNew(ImagingNew(mode, xsize, ysize));
|
return PyImagingNew(ImagingNew(mode, xsize, ysize, depth, bands));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1714,7 +1747,8 @@ _quantize(ImagingObject *self, PyObject *args) {
|
||||||
|
|
||||||
if (!self->image->xsize || !self->image->ysize) {
|
if (!self->image->xsize || !self->image->ysize) {
|
||||||
/* no content; return an empty image */
|
/* no content; return an empty image */
|
||||||
return PyImagingNew(ImagingNew("P", self->image->xsize, self->image->ysize));
|
return PyImagingNew(
|
||||||
|
ImagingNew("P", self->image->xsize, self->image->ysize, -1, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans));
|
return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans));
|
||||||
|
@ -2782,7 +2816,7 @@ _font_getmask(ImagingFontObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
im = ImagingNew(self->bitmap->mode, textwidth(self, text), self->ysize);
|
im = ImagingNew(self->bitmap->mode, textwidth(self, text), self->ysize, -1, -1);
|
||||||
if (!im) {
|
if (!im) {
|
||||||
free(text);
|
free(text);
|
||||||
return ImagingError_MemoryError();
|
return ImagingError_MemoryError();
|
||||||
|
|
25
src/decode.c
25
src/decode.c
|
@ -291,11 +291,33 @@ static PyTypeObject ImagingDecoderType = {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
static void
|
||||||
|
mb_shuffle_passthru(UINT8 *dst, const UINT8 *src, Imaging im, ImagingCodecState state) {
|
||||||
|
state->shuffle(dst, src, state->xsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shuffle_mb_unavail(UINT8 *dst, const UINT8 *src, int pixels) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mb_shuffle(UINT8 *dst, const UINT8 *src, Imaging im, ImagingCodecState state) {
|
||||||
|
memcpy(dst, src, state->xsize * im->pixelsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
get_unpacker(ImagingDecoderObject *decoder, const char *mode, const char *rawmode) {
|
get_unpacker(ImagingDecoderObject *decoder, const char *mode, const char *rawmode) {
|
||||||
int bits;
|
int bits;
|
||||||
ImagingShuffler unpack;
|
ImagingShuffler unpack;
|
||||||
|
|
||||||
|
if (strcmp(mode, IMAGING_MODE_MB) == 0) {
|
||||||
|
decoder->state.shuffle = shuffle_mb_unavail;
|
||||||
|
decoder->state.mb_shuffle = mb_shuffle;
|
||||||
|
decoder->state.bits = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unpack = ImagingFindUnpacker(mode, rawmode, &bits);
|
unpack = ImagingFindUnpacker(mode, rawmode, &bits);
|
||||||
if (!unpack) {
|
if (!unpack) {
|
||||||
Py_DECREF(decoder);
|
Py_DECREF(decoder);
|
||||||
|
@ -304,6 +326,7 @@ get_unpacker(ImagingDecoderObject *decoder, const char *mode, const char *rawmod
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->state.shuffle = unpack;
|
decoder->state.shuffle = unpack;
|
||||||
|
decoder->state.mb_shuffle = mb_shuffle_passthru;
|
||||||
decoder->state.bits = bits;
|
decoder->state.bits = bits;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -133,6 +133,11 @@ get_pixel_32B(Imaging im, int x, int y, void *color) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_pixel_mb(Imaging im, int x, int y, void *color) {
|
||||||
|
memcpy(color, &im->image[y][x * im->pixelsize], im->pixelsize);
|
||||||
|
}
|
||||||
|
|
||||||
/* store individual pixel */
|
/* store individual pixel */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -183,6 +188,11 @@ put_pixel_32(Imaging im, int x, int y, const void *color) {
|
||||||
memcpy(&im->image32[y][x], color, sizeof(INT32));
|
memcpy(&im->image32[y][x], color, sizeof(INT32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_pixel_mb(Imaging im, int x, int y, void *color) {
|
||||||
|
memcpy(&im->image[y][x * im->pixelsize], color, im->pixelsize);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingAccessInit() {
|
ImagingAccessInit() {
|
||||||
#define ADD(mode_, get_pixel_, put_pixel_) \
|
#define ADD(mode_, get_pixel_, put_pixel_) \
|
||||||
|
@ -222,6 +232,7 @@ ImagingAccessInit() {
|
||||||
ADD("YCbCr", get_pixel_32, put_pixel_32);
|
ADD("YCbCr", get_pixel_32, put_pixel_32);
|
||||||
ADD("LAB", get_pixel_32, put_pixel_32);
|
ADD("LAB", get_pixel_32, put_pixel_32);
|
||||||
ADD("HSV", get_pixel_32, put_pixel_32);
|
ADD("HSV", get_pixel_32, put_pixel_32);
|
||||||
|
ADD("MB", get_pixel_mb, put_pixel_mb);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingAccess
|
ImagingAccess
|
||||||
|
|
|
@ -68,10 +68,13 @@ typedef struct ImagingPaletteInstance *ImagingPalette;
|
||||||
#define IMAGING_TYPE_INT32 1
|
#define IMAGING_TYPE_INT32 1
|
||||||
#define IMAGING_TYPE_FLOAT32 2
|
#define IMAGING_TYPE_FLOAT32 2
|
||||||
#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */
|
#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */
|
||||||
|
#define IMAGING_TYPE_MB 4 /* multi-band format */
|
||||||
|
|
||||||
#define IMAGING_MODE_LENGTH \
|
#define IMAGING_MODE_LENGTH \
|
||||||
6 + 1 /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */
|
6 + 1 /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */
|
||||||
|
|
||||||
|
#define IMAGING_MODE_MB "MB" /* multi-band format */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int size;
|
int size;
|
||||||
|
@ -80,9 +83,9 @@ typedef struct {
|
||||||
struct ImagingMemoryInstance {
|
struct ImagingMemoryInstance {
|
||||||
/* Format */
|
/* Format */
|
||||||
char mode[IMAGING_MODE_LENGTH]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK",
|
char mode[IMAGING_MODE_LENGTH]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK",
|
||||||
"YCbCr", "BGR;xy") */
|
"YCbCr", "BGR;xy", "MB") */
|
||||||
int type; /* Data type (IMAGING_TYPE_*) */
|
int type; /* Data type (IMAGING_TYPE_*) */
|
||||||
int depth; /* Depth (ignored in this version) */
|
int depth; /* Sample size (1, 2, or 4) in multi-band format */
|
||||||
int bands; /* Number of bands (1, 2, 3, or 4) */
|
int bands; /* Number of bands (1, 2, 3, or 4) */
|
||||||
int xsize; /* Image dimension. */
|
int xsize; /* Image dimension. */
|
||||||
int ysize;
|
int ysize;
|
||||||
|
@ -173,7 +176,7 @@ extern void
|
||||||
ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size);
|
ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size);
|
||||||
|
|
||||||
extern Imaging
|
extern Imaging
|
||||||
ImagingNew(const char *mode, int xsize, int ysize);
|
ImagingNew(const char *mode, int xsize, int ysize, int depth, int bands);
|
||||||
extern Imaging
|
extern Imaging
|
||||||
ImagingNewDirty(const char *mode, int xsize, int ysize);
|
ImagingNewDirty(const char *mode, int xsize, int ysize);
|
||||||
extern Imaging
|
extern Imaging
|
||||||
|
@ -185,9 +188,10 @@ extern Imaging
|
||||||
ImagingNewBlock(const char *mode, int xsize, int ysize);
|
ImagingNewBlock(const char *mode, int xsize, int ysize);
|
||||||
|
|
||||||
extern Imaging
|
extern Imaging
|
||||||
ImagingNewPrologue(const char *mode, int xsize, int ysize);
|
ImagingNewPrologue(const char *mode, int xsize, int ysize, int depth, int bands);
|
||||||
extern Imaging
|
extern Imaging
|
||||||
ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int structure_size);
|
ImagingNewPrologueSubtype(
|
||||||
|
const char *mode, int xsize, int ysize, int depth, int bands, int structure_size);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
ImagingCopyPalette(Imaging destination, Imaging source);
|
ImagingCopyPalette(Imaging destination, Imaging source);
|
||||||
|
@ -663,6 +667,8 @@ struct ImagingCodecStateInstance {
|
||||||
int ystep;
|
int ystep;
|
||||||
int xsize, ysize, xoff, yoff;
|
int xsize, ysize, xoff, yoff;
|
||||||
ImagingShuffler shuffle;
|
ImagingShuffler shuffle;
|
||||||
|
void (*mb_shuffle)(
|
||||||
|
UINT8 *dst, const UINT8 *src, Imaging im, ImagingCodecState state);
|
||||||
int bits, bytes;
|
int bits, bytes;
|
||||||
UINT8 *buffer;
|
UINT8 *buffer;
|
||||||
void *context;
|
void *context;
|
||||||
|
|
|
@ -152,7 +152,7 @@ ImagingPoint(Imaging imIn, const char *mode, const void *table) {
|
||||||
goto mode_mismatch;
|
goto mode_mismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
imOut = ImagingNew(mode, imIn->xsize, imIn->ysize);
|
imOut = ImagingNew(mode, imIn->xsize, imIn->ysize, -1, -1);
|
||||||
if (!imOut) {
|
if (!imOut) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
|
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize, -1, -1);
|
||||||
if (!imOut) {
|
if (!imOut) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,8 @@ MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32)
|
||||||
return (Imaging)ImagingError_ValueError("bad rank value");
|
return (Imaging)ImagingError_ValueError("bad rank value");
|
||||||
}
|
}
|
||||||
|
|
||||||
imOut = ImagingNew(im->mode, im->xsize - 2 * margin, im->ysize - 2 * margin);
|
imOut =
|
||||||
|
ImagingNew(im->mode, im->xsize - 2 * margin, im->ysize - 2 * margin, -1, -1);
|
||||||
if (!imOut) {
|
if (!imOut) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,11 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack data */
|
/* Unpack data */
|
||||||
state->shuffle(
|
state->mb_shuffle(
|
||||||
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
|
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
|
||||||
ptr,
|
ptr,
|
||||||
state->xsize);
|
im,
|
||||||
|
state);
|
||||||
|
|
||||||
ptr += state->bytes;
|
ptr += state->bytes;
|
||||||
bytes -= state->bytes;
|
bytes -= state->bytes;
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
|
ImagingNewPrologueSubtype(
|
||||||
|
const char *mode, int xsize, int ysize, int depth, int bands, int size) {
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
/* linesize overflow check, roughly the current largest space req'd */
|
/* linesize overflow check, roughly the current largest space req'd */
|
||||||
|
@ -190,6 +191,17 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
|
||||||
im->pixelsize = 4;
|
im->pixelsize = 4;
|
||||||
im->linesize = xsize * 4;
|
im->linesize = xsize * 4;
|
||||||
|
|
||||||
|
} else if (strcmp(mode, IMAGING_MODE_MB) == 0) {
|
||||||
|
if (bands <= 0 || depth <= 0) {
|
||||||
|
return (Imaging)ImagingError_ValueError(
|
||||||
|
"multi-band missing bands and depth");
|
||||||
|
}
|
||||||
|
im->bands = bands;
|
||||||
|
im->depth = depth;
|
||||||
|
im->pixelsize = depth * bands;
|
||||||
|
im->linesize = xsize * im->pixelsize;
|
||||||
|
im->type = IMAGING_TYPE_MB;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
free(im);
|
free(im);
|
||||||
return (Imaging)ImagingError_ValueError("unrecognized image mode");
|
return (Imaging)ImagingError_ValueError("unrecognized image mode");
|
||||||
|
@ -225,9 +237,9 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewPrologue(const char *mode, int xsize, int ysize) {
|
ImagingNewPrologue(const char *mode, int xsize, int ysize, int depth, int bands) {
|
||||||
return ImagingNewPrologueSubtype(
|
return ImagingNewPrologueSubtype(
|
||||||
mode, xsize, ysize, sizeof(struct ImagingMemoryInstance));
|
mode, xsize, ysize, depth, bands, sizeof(struct ImagingMemoryInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -485,15 +497,16 @@ ImagingAllocateBlock(Imaging im) {
|
||||||
* Create a new, internally allocated, image.
|
* Create a new, internally allocated, image.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Imaging
|
static Imaging
|
||||||
ImagingNewInternal(const char *mode, int xsize, int ysize, int dirty) {
|
ImagingNewInternal(
|
||||||
|
const char *mode, int xsize, int ysize, int depth, int bands, int dirty) {
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
if (xsize < 0 || ysize < 0) {
|
if (xsize < 0 || ysize < 0) {
|
||||||
return (Imaging)ImagingError_ValueError("bad image size");
|
return (Imaging)ImagingError_ValueError("bad image size");
|
||||||
}
|
}
|
||||||
|
|
||||||
im = ImagingNewPrologue(mode, xsize, ysize);
|
im = ImagingNewPrologue(mode, xsize, ysize, depth, bands);
|
||||||
if (!im) {
|
if (!im) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -514,13 +527,13 @@ ImagingNewInternal(const char *mode, int xsize, int ysize, int dirty) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNew(const char *mode, int xsize, int ysize) {
|
ImagingNew(const char *mode, int xsize, int ysize, int depth, int bands) {
|
||||||
return ImagingNewInternal(mode, xsize, ysize, 0);
|
return ImagingNewInternal(mode, xsize, ysize, depth, bands, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewDirty(const char *mode, int xsize, int ysize) {
|
ImagingNewDirty(const char *mode, int xsize, int ysize) {
|
||||||
return ImagingNewInternal(mode, xsize, ysize, 1);
|
return ImagingNewInternal(mode, xsize, ysize, -1, -1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
|
@ -531,7 +544,7 @@ ImagingNewBlock(const char *mode, int xsize, int ysize) {
|
||||||
return (Imaging)ImagingError_ValueError("bad image size");
|
return (Imaging)ImagingError_ValueError("bad image size");
|
||||||
}
|
}
|
||||||
|
|
||||||
im = ImagingNewPrologue(mode, xsize, ysize);
|
im = ImagingNewPrologue(mode, xsize, ysize, -1, -1);
|
||||||
if (!im) {
|
if (!im) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,8 @@ PyImaging_MapBuffer(PyObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
im = ImagingNewPrologueSubtype(mode, xsize, ysize, sizeof(ImagingBufferInstance));
|
im = ImagingNewPrologueSubtype(
|
||||||
|
mode, xsize, ysize, -1, -1, sizeof(ImagingBufferInstance));
|
||||||
if (!im) {
|
if (!im) {
|
||||||
PyBuffer_Release(&view);
|
PyBuffer_Release(&view);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user