Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Tests/test_color_lut.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def test_correct_args(
def test_wrong_mode(
self, image_mode: str, lut_mode: str, table_channels: int, table_size: int
) -> None:
with pytest.raises(ValueError, match="wrong mode"):
with pytest.raises(ValueError, match="bands"):
im = Image.new(image_mode, (10, 10), 0)
im.im.color_lut_3d(
lut_mode,
Expand Down
4 changes: 3 additions & 1 deletion Tests/test_image_paste.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,9 @@ def test_overflow(self, box: tuple[int, int, int, int]) -> None:
im = Image.new("1", (1, 1))
im.paste(1, box)

with pytest.raises(ValueError, match="images do not match"):
with pytest.raises(
ValueError, match="image dimensions and pixel size must match"
):
im.paste(im.copy(), box)

def test_incorrect_abbreviated_form(self) -> None:
Expand Down
44 changes: 39 additions & 5 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ _new_arrow(PyObject *self, PyObject *args) {
ModeID mode_id;
int xsize, ysize;
PyObject *schema_capsule, *array_capsule;
PyObject *ret;

if (!PyArg_ParseTuple(
args, "s(ii)OO", &mode, &xsize, &ysize, &schema_capsule, &array_capsule
Expand Down Expand Up @@ -371,14 +370,31 @@ ImagingError_MemoryError(void) {
}

void *
ImagingError_Mismatch(void) {
PyErr_SetString(PyExc_ValueError, "images do not match");
ImagingError_Mismatch(const char *message) {
PyErr_SetString(
PyExc_ValueError, (message) ? (char *)message : "images do not match"
);
return NULL;
}

void *
ImagingError_ModeError(void) {
PyErr_SetString(PyExc_ValueError, "image has wrong mode");
ImagingError_ModeError(const char *message) {
PyErr_SetString(
PyExc_ValueError, (message) ? (char *)message : "image has wrong mode"
);
return NULL;
}

// Derives from both NotImplementedError and ValueError
// (as the functions above raise ValueErrors).
static PyObject *ImagingNotSupportedError = NULL;

void *
ImagingError_NotSupportedError(const char *message) {
PyErr_SetString(
ImagingNotSupportedError ? ImagingNotSupportedError : PyExc_NotImplementedError,
(message) ? (char *)message : "operation not supported"
);
return NULL;
}

Expand Down Expand Up @@ -4326,6 +4342,24 @@ setup_module(PyObject *m) {
return -1;
}

if (ImagingNotSupportedError == NULL) {
// NotSupportedError derives from both NotImplementedError and ValueError,
// for compatibility with `except ValueError`.
PyObject *bases = PyTuple_Pack(2, PyExc_NotImplementedError, PyExc_ValueError);
if (bases == NULL) {
return -1;
}
ImagingNotSupportedError =
PyErr_NewException("PIL._imaging.NotSupportedError", bases, NULL);
Py_DECREF(bases);
if (ImagingNotSupportedError == NULL) {
return -1;
}
}
if (PyModule_AddObjectRef(m, "NotSupportedError", ImagingNotSupportedError) < 0) {
return -1;
}

#ifdef HAVE_LIBJPEG
{
extern const char *ImagingJpegVersion(void);
Expand Down
10 changes: 6 additions & 4 deletions src/libImaging/AlphaComposite.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) {
Imaging imOut;

/* Check arguments */
if (!imDst || !imSrc ||
(imDst->mode != IMAGING_MODE_RGBA && imDst->mode != IMAGING_MODE_LA)) {
return ImagingError_ModeError();
if (!imDst || !imSrc) {
return ImagingError_ValueError("imDst and imSrc must not be NULL");
}
if (imDst->mode != IMAGING_MODE_RGBA && imDst->mode != IMAGING_MODE_LA) {
return ImagingError_ModeError("destination image must have alpha channel");
}

if (imDst->mode != imSrc->mode || imDst->xsize != imSrc->xsize ||
imDst->ysize != imSrc->ysize) {
return ImagingError_Mismatch();
return ImagingError_Mismatch("image modes and dimensions must match");
}

imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize);
Expand Down
44 changes: 33 additions & 11 deletions src/libImaging/Bands.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ ImagingGetBand(Imaging imIn, int band) {
int x, y;

/* Check arguments */
if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
return (Imaging)ImagingError_ModeError();
if (!imIn) {
return (Imaging)ImagingError_ValueError(NULL);
}

if (imIn->type != IMAGING_TYPE_UINT8) {
return (Imaging)ImagingError_NotSupportedError("only 8-bit images supported");
}

if (band < 0 || band >= imIn->bands) {
Expand Down Expand Up @@ -73,8 +77,13 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) {
int i, j, x, y;

/* Check arguments */
if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
(void)ImagingError_ModeError();
if (!imIn) {
(void)ImagingError_ValueError(NULL);
return 0;
}

if (imIn->type != IMAGING_TYPE_UINT8) {
(void)ImagingError_NotSupportedError("only 8-bit images supported");
return 0;
}

Expand Down Expand Up @@ -178,8 +187,11 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) {
int x, y;

/* Check arguments */
if (!imIn || imIn->bands != 1 || !imOut) {
return (Imaging)ImagingError_ModeError();
if (!imIn || !imOut) {
return (Imaging)ImagingError_ValueError(NULL);
}
if (imIn->bands != 1) {
return (Imaging)ImagingError_ModeError("source image must have exactly 1 band");
}

if (band < 0 || band >= imOut->bands) {
Expand All @@ -188,7 +200,7 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) {

if (imIn->type != imOut->type || imIn->xsize != imOut->xsize ||
imIn->ysize != imOut->ysize) {
return (Imaging)ImagingError_Mismatch();
return (Imaging)ImagingError_Mismatch("image types and sizes must match");
}

/* Shortcuts */
Expand Down Expand Up @@ -224,8 +236,16 @@ ImagingFillBand(Imaging imOut, int band, int color) {
int x, y;

/* Check arguments */
if (!imOut || imOut->type != IMAGING_TYPE_UINT8) {
return (Imaging)ImagingError_ModeError();
if (!imOut) {
return (Imaging)ImagingError_ValueError(NULL);
}

if (!imOut) {
return (Imaging)ImagingError_ValueError("only 8-bit images supported");
}

if (imOut->type != IMAGING_TYPE_UINT8) {
return (Imaging)ImagingError_NotSupportedError("only 8-bit images supported");
}

if (band < 0 || band >= imOut->bands) {
Expand Down Expand Up @@ -270,11 +290,13 @@ ImagingMerge(const ModeID mode, Imaging bands[4]) {
break;
}
if (bands[i]->bands != 1) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ModeError(
"source image must have exactly 1 band"
);
}
if (bands[i]->xsize != firstBand->xsize ||
bands[i]->ysize != firstBand->ysize) {
return (Imaging)ImagingError_Mismatch();
return (Imaging)ImagingError_Mismatch("image sizes must match");
}
}
bandsCount = i;
Expand Down
9 changes: 6 additions & 3 deletions src/libImaging/Blend.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) {
int x, y;

/* Check arguments */
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
if (!imIn1 || !imIn2) {
return (Imaging)ImagingError_ValueError(NULL);
}
if (imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
imIn1->mode == IMAGING_MODE_1 || imIn2->palette ||
imIn2->mode == IMAGING_MODE_1) {
return ImagingError_ModeError();
return ImagingError_ModeError(NULL);
}

if (imIn1->type != imIn2->type || imIn1->bands != imIn2->bands ||
imIn1->xsize != imIn2->xsize || imIn1->ysize != imIn2->ysize) {
return ImagingError_Mismatch();
return ImagingError_Mismatch("image types, band count and sizes must match");
}

/* Shortcuts */
Expand Down
8 changes: 5 additions & 3 deletions src/libImaging/BoxBlur.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,18 +251,20 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float xradius, float yradius, int n)
if (imIn->mode != imOut->mode || imIn->type != imOut->type ||
imIn->bands != imOut->bands || imIn->xsize != imOut->xsize ||
imIn->ysize != imOut->ysize) {
return ImagingError_Mismatch();
return ImagingError_Mismatch("image mode, type, bands and size must match");
}

if (imIn->type != IMAGING_TYPE_UINT8) {
return ImagingError_ModeError();
return ImagingError_NotSupportedError("non-uint8 images not supported");
}

if (imIn->mode != IMAGING_MODE_RGB && imIn->mode != IMAGING_MODE_RGBA &&
imIn->mode != IMAGING_MODE_RGBa && imIn->mode != IMAGING_MODE_RGBX &&
imIn->mode != IMAGING_MODE_CMYK && imIn->mode != IMAGING_MODE_L &&
imIn->mode != IMAGING_MODE_LA && imIn->mode != IMAGING_MODE_La) {
return ImagingError_ModeError();
return ImagingError_NotSupportedError(
"BoxBlur operation not supported in this mode"
);
}

/* Apply blur in one dimension.
Expand Down
9 changes: 6 additions & 3 deletions src/libImaging/Chops.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@
static Imaging
create(Imaging im1, Imaging im2, const ModeID mode) {
int xsize, ysize;
if (!im1 || !im2) {
return (Imaging)ImagingError_ValueError(NULL);
}

if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 ||
if (im1->type != IMAGING_TYPE_UINT8 ||
(mode != IMAGING_MODE_UNKNOWN &&
(im1->mode != IMAGING_MODE_1 || im2->mode != IMAGING_MODE_1))) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ModeError(NULL);
}
if (im1->type != im2->type || im1->bands != im2->bands) {
return (Imaging)ImagingError_Mismatch();
return (Imaging)ImagingError_Mismatch("image types and band count must match");
}

xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize;
Expand Down
21 changes: 15 additions & 6 deletions src/libImaging/ColorLUT.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,23 @@ ImagingColorLUT3D_linear(
return NULL;
}

if (imIn->type != IMAGING_TYPE_UINT8 || imOut->type != IMAGING_TYPE_UINT8 ||
imIn->bands < 3 || imOut->bands < table_channels) {
return (Imaging)ImagingError_ModeError();
if (imIn->type != IMAGING_TYPE_UINT8 || imOut->type != IMAGING_TYPE_UINT8) {
return (Imaging)ImagingError_NotSupportedError(
"only uint8 images are supported"
);
}
if (imIn->bands < 3) {
return (Imaging)ImagingError_ModeError("input image needs at least 3 bands");
}
if (imOut->bands < table_channels) {
return (Imaging)ImagingError_ValueError(
"output image needs at least as many bands as the table"
);
}

/* In case we have one extra band in imOut and don't have in imIn.*/
if (imOut->bands > table_channels && imOut->bands > imIn->bands) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ModeError(
"output image has more bands than input image and table"
);
}

ImagingSectionEnter(&cookie);
Expand Down
10 changes: 6 additions & 4 deletions src/libImaging/Convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,13 +1581,13 @@ convert(Imaging imOut, Imaging imIn, ModeID mode, ImagingPalette palette, int di
ImagingShuffler convert;

if (!imIn) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ValueError(NULL);
}

if (mode == IMAGING_MODE_UNKNOWN) {
/* Map palette image to full depth */
if (!imIn->palette) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ModeError(NULL);
}
mode = imIn->palette->mode;
} else {
Expand Down Expand Up @@ -1673,7 +1673,7 @@ ImagingConvertTransparent(Imaging imIn, const ModeID mode, int r, int g, int b)
int y;

if (!imIn) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ValueError(NULL);
}

if (imIn->mode == IMAGING_MODE_RGB &&
Expand Down Expand Up @@ -1747,7 +1747,9 @@ ImagingConvertInPlace(Imaging imIn, const ModeID mode) {
} else if (imIn->mode == IMAGING_MODE_1 && mode == IMAGING_MODE_L) {
convert = bit2l;
} else {
return ImagingError_ModeError();
return ImagingError_NotSupportedError(
"in-place conversion not supported between these formats"
);
}

ImagingSectionEnter(&cookie);
Expand Down
2 changes: 1 addition & 1 deletion src/libImaging/Crop.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1) {
INT32 zero = 0;

if (!imIn) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ValueError(NULL);
}

xsize = sx1 - sx0;
Expand Down
4 changes: 3 additions & 1 deletion src/libImaging/Dib.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ ImagingNewDIB(const ModeID mode, int xsize, int ysize) {

/* Check mode */
if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_L && mode != IMAGING_MODE_RGB) {
return (ImagingDIB)ImagingError_ModeError();
return (ImagingDIB)ImagingError_NotSupportedError(
"only modes I/L/RGB supported"
);
}

const int pixelsize = mode == IMAGING_MODE_RGB ? 3 : 1;
Expand Down
4 changes: 3 additions & 1 deletion src/libImaging/Effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) {
width = extent[2] - extent[0];
height = extent[3] - extent[1];
if (width < 0.0 || height < 0.0 || quality < 2) {
return (Imaging)ImagingError_ValueError(NULL);
return (Imaging)ImagingError_ValueError(
"width and height must be positive and quality >= 2"
);
}

im = ImagingNewDirty(IMAGING_MODE_L, xsize, ysize);
Expand Down
8 changes: 6 additions & 2 deletions src/libImaging/Fill.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ ImagingFillLinearGradient(const ModeID mode) {

if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_F && mode != IMAGING_MODE_I &&
mode != IMAGING_MODE_L && mode != IMAGING_MODE_P) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_NotSupportedError(
"only modes 1/F/I/L/P supported"
);
}

im = ImagingNewDirty(mode, 256, 256);
Expand Down Expand Up @@ -117,7 +119,9 @@ ImagingFillRadialGradient(const ModeID mode) {

if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_F && mode != IMAGING_MODE_I &&
mode != IMAGING_MODE_L && mode != IMAGING_MODE_P) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_NotSupportedError(
"only modes 1/F/I/L/P supported"
);
}

im = ImagingNewDirty(mode, 256, 256);
Expand Down
4 changes: 3 additions & 1 deletion src/libImaging/Filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,9 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 o

if (im->type == IMAGING_TYPE_FLOAT32 ||
(im->type == IMAGING_TYPE_SPECIAL && im->bands != 1)) {
return (Imaging)ImagingError_ModeError();
return (Imaging)ImagingError_ModeError(
"32-bpc or special multiband image types not supported"
);
}

if (im->xsize < xsize || im->ysize < ysize) {
Expand Down
Loading
Loading