From 47fdaf90d9ca7f20d271fa601ad76b3d3a282e6b Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 9 Jul 2026 10:20:58 +0300 Subject: [PATCH 1/4] Add PIL._imaging.NotSupportedError --- src/_imaging.c | 30 ++++++++++++++++++++++++++++++ src/libImaging/Imaging.h | 4 ++++ 2 files changed, 34 insertions(+) diff --git a/src/_imaging.c b/src/_imaging.c index 2a4bcd16bbf..0123acafa0f 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -370,6 +370,19 @@ ImagingError_ModeError(void) { 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; +} + void * ImagingError_ValueError(const char *message) { PyErr_SetString( @@ -4956,6 +4969,23 @@ setup_module(PyObject *m) { if (display_setup() < 0) { 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 { diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index 68b7027e5f6..fdc096b3f52 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -281,6 +281,10 @@ extern void * ImagingError_Mismatch(void); /* maps to ValueError by default */ extern void * ImagingError_ValueError(const char *message); +extern void * +ImagingError_NotSupportedError( + const char *message +); /* derives from NotImplementedError and ValueError */ /* Transform callbacks */ /* ------------------- */ From d9325c9e23d964b86340d97cc5e2583f1882cc19 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 9 Jul 2026 10:23:11 +0300 Subject: [PATCH 2/4] Allow custom error message for ImagingError_ModeError and ImagingError_Mismatch --- src/_imaging.c | 14 +++++++++----- src/display.c | 4 ++-- src/libImaging/AlphaComposite.c | 4 ++-- src/libImaging/Bands.c | 14 +++++++------- src/libImaging/Blend.c | 4 ++-- src/libImaging/BoxBlur.c | 4 ++-- src/libImaging/Chops.c | 4 ++-- src/libImaging/ColorLUT.c | 4 ++-- src/libImaging/Convert.c | 6 +++--- src/libImaging/Crop.c | 2 +- src/libImaging/Dib.c | 2 +- src/libImaging/Fill.c | 4 ++-- src/libImaging/Filter.c | 2 +- src/libImaging/Geometry.c | 6 +++--- src/libImaging/GetBBox.c | 6 +++--- src/libImaging/Histo.c | 6 +++--- src/libImaging/Imaging.h | 4 ++-- src/libImaging/Matrix.c | 4 ++-- src/libImaging/ModeFilter.c | 2 +- src/libImaging/Negative.c | 2 +- src/libImaging/Offset.c | 2 +- src/libImaging/Palette.c | 2 +- src/libImaging/Paste.c | 10 +++++----- src/libImaging/Point.c | 4 ++-- src/libImaging/Quant.c | 6 +++--- src/libImaging/RankFilter.c | 4 ++-- src/libImaging/Reduce.c | 2 +- src/libImaging/Resample.c | 4 ++-- src/libImaging/Storage.c | 2 +- src/libImaging/UnsharpMask.c | 2 +- 30 files changed, 70 insertions(+), 66 deletions(-) diff --git a/src/_imaging.c b/src/_imaging.c index 0123acafa0f..9cd0743d9c6 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -359,14 +359,18 @@ 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; } @@ -2369,7 +2373,7 @@ im_setalpha_impl(ImagingObject *self, PyObject *args) { /* attempt to modify the mode of an image in place */ Imaging im = self->image; if (im->mode != IMAGING_MODE_RGB && im->mode != IMAGING_MODE_RGBX) { - return ImagingError_ModeError(); + return ImagingError_ModeError("only RGB/RGBX modes supported"); } im->mode = IMAGING_MODE_RGBA; im->bands = 4; diff --git a/src/display.c b/src/display.c index 70261281128..e5133365c1f 100644 --- a/src/display.c +++ b/src/display.c @@ -139,7 +139,7 @@ _paste(ImagingDisplayObject *display, PyObject *args) { if (xy[2] <= xy[0]) { xy[2] = xy[0] + im->xsize; } else if (xy[2] - xy[0] != im->xsize) { - return ImagingError_Mismatch(); + return ImagingError_Mismatch(NULL); } if (xy[0] < 0) { PyErr_SetString(PyExc_ValueError, "left box co-ordinate cannot be negative"); @@ -152,7 +152,7 @@ _paste(ImagingDisplayObject *display, PyObject *args) { if (xy[3] <= xy[1]) { xy[3] = xy[1] + im->ysize; } else if (xy[3] - xy[1] != im->ysize) { - return ImagingError_Mismatch(); + return ImagingError_Mismatch(NULL); } if (xy[1] < 0) { PyErr_SetString(PyExc_ValueError, "upper box co-ordinate cannot be negative"); diff --git a/src/libImaging/AlphaComposite.c b/src/libImaging/AlphaComposite.c index f7db1769b0d..1208254435e 100644 --- a/src/libImaging/AlphaComposite.c +++ b/src/libImaging/AlphaComposite.c @@ -31,12 +31,12 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { /* Check arguments */ if (!imDst || !imSrc || (imDst->mode != IMAGING_MODE_RGBA && imDst->mode != IMAGING_MODE_LA)) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } if (imDst->mode != imSrc->mode || imDst->xsize != imSrc->xsize || imDst->ysize != imSrc->ysize) { - return ImagingError_Mismatch(); + return ImagingError_Mismatch(NULL); } imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize); diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index dd90a36a70f..919cf1e1bc8 100644 --- a/src/libImaging/Bands.c +++ b/src/libImaging/Bands.c @@ -29,7 +29,7 @@ ImagingGetBand(Imaging imIn, int band) { /* Check arguments */ if (!imIn || imIn->type != IMAGING_TYPE_UINT8) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (band < 0 || band >= imIn->bands) { @@ -90,7 +90,7 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) { /* Check arguments */ if (!imIn || imIn->type != IMAGING_TYPE_UINT8) { - (void)ImagingError_ModeError(); + (void)ImagingError_ModeError(NULL); return -1; } @@ -200,7 +200,7 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) { /* Check arguments */ if (!imIn || imIn->bands != 1 || !imOut) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (band < 0 || band >= imOut->bands) { @@ -209,7 +209,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(NULL); } /* Shortcuts */ @@ -249,7 +249,7 @@ ImagingFillBand(Imaging imOut, int band, int color) { /* Check arguments */ if (!imOut || imOut->type != IMAGING_TYPE_UINT8) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (band < 0 || band >= imOut->bands) { @@ -301,11 +301,11 @@ ImagingMerge(const ModeID mode, Imaging bands[4]) { } for (i = 0; i < bandsCount; ++i) { if (bands[i]->bands != 1 || (bandsCount != 1 && bands[i]->pixelsize == 4)) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (bands[i]->xsize != firstBand->xsize || bands[i]->ysize != firstBand->ysize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } } diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index 1589bf2bdc5..af808bcf5e7 100644 --- a/src/libImaging/Blend.c +++ b/src/libImaging/Blend.c @@ -32,12 +32,12 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { if (!imIn1 || !imIn2 || 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(NULL); } /* Shortcuts */ diff --git a/src/libImaging/BoxBlur.c b/src/libImaging/BoxBlur.c index 222b527c48a..44f8fe7de70 100644 --- a/src/libImaging/BoxBlur.c +++ b/src/libImaging/BoxBlur.c @@ -354,7 +354,7 @@ 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(NULL); } if (!(imIn->type == IMAGING_TYPE_UINT8 && @@ -363,7 +363,7 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float xradius, float yradius, int n) imIn->mode == IMAGING_MODE_CMYK || imIn->mode == IMAGING_MODE_L || imIn->mode == IMAGING_MODE_LA || imIn->mode == IMAGING_MODE_La)) && imIn->type != IMAGING_TYPE_I16) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } /* Apply blur in one dimension. diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index 1aa0671f0a3..fb0f7f0df9b 100644 --- a/src/libImaging/Chops.c +++ b/src/libImaging/Chops.c @@ -72,10 +72,10 @@ create(Imaging im1, Imaging im2, const ModeID mode) { if (!im1 || !im2 || 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(NULL); } xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize; diff --git a/src/libImaging/ColorLUT.c b/src/libImaging/ColorLUT.c index fe4c752a88b..671935fdac7 100644 --- a/src/libImaging/ColorLUT.c +++ b/src/libImaging/ColorLUT.c @@ -93,12 +93,12 @@ ImagingColorLUT3D_linear( if (imIn->type != IMAGING_TYPE_UINT8 || imOut->type != IMAGING_TYPE_UINT8 || imIn->bands < 3 || imOut->bands < table_channels) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } /* 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(NULL); } ImagingSectionEnter(&cookie); diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index 2c524002070..da0576b5b79 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1601,13 +1601,13 @@ ImagingConvert( ImagingShuffler convert; if (!imIn) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(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 { @@ -1678,7 +1678,7 @@ ImagingConvertTransparent(Imaging imIn, const ModeID mode, int r, int g, int b) int y; if (!imIn) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (imIn->mode == IMAGING_MODE_RGB && diff --git a/src/libImaging/Crop.c b/src/libImaging/Crop.c index 2425b4cd589..7bbdc86c474 100644 --- a/src/libImaging/Crop.c +++ b/src/libImaging/Crop.c @@ -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_ModeError(NULL); } xsize = sx1 - sx0; diff --git a/src/libImaging/Dib.c b/src/libImaging/Dib.c index eace04617a7..8d09d4fe2ac 100644 --- a/src/libImaging/Dib.c +++ b/src/libImaging/Dib.c @@ -59,7 +59,7 @@ 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_ModeError(NULL); } const int pixelsize = mode == IMAGING_MODE_RGB ? 3 : 1; diff --git a/src/libImaging/Fill.c b/src/libImaging/Fill.c index 30dfbcf22a5..d1f2791c1b0 100644 --- a/src/libImaging/Fill.c +++ b/src/libImaging/Fill.c @@ -86,7 +86,7 @@ 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_ModeError(NULL); } im = ImagingNewDirty(mode, 256, 256); @@ -125,7 +125,7 @@ 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_ModeError(NULL); } im = ImagingNewDirty(mode, 256, 256); diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index cef7c93b198..ce042d3928c 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -513,7 +513,7 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 o ImagingSectionCookie cookie; if (im->type == IMAGING_TYPE_FLOAT32) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (im->xsize < xsize || im->ysize < ysize) { diff --git a/src/libImaging/Geometry.c b/src/libImaging/Geometry.c index d0870165b50..34c73762d42 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -747,7 +747,7 @@ ImagingGenericTransform( double xx, yy; if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(); + ImagingError_ModeError(NULL); return -1; } @@ -808,7 +808,7 @@ ImagingScaleAffine( int *xintab; if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(); + ImagingError_ModeError(NULL); return -1; } @@ -1003,7 +1003,7 @@ ImagingTransformAffine( double xo, yo; if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(); + ImagingError_ModeError(NULL); return -1; } diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c index 1952cd9ccb4..d78935bd81d 100644 --- a/src/libImaging/GetBBox.c +++ b/src/libImaging/GetBBox.c @@ -184,7 +184,7 @@ ImagingGetExtrema(Imaging im, void *extrema) { FLOAT32 fmin, fmax; if (im->bands != 1) { - (void)ImagingError_ModeError(); + (void)ImagingError_ModeError(NULL); return -1; /* mismatch */ } @@ -274,7 +274,7 @@ ImagingGetExtrema(Imaging im, void *extrema) { } /* FALL THROUGH */ default: - (void)ImagingError_ModeError(); + (void)ImagingError_ModeError(NULL); return -1; } return 1; /* ok */ @@ -332,7 +332,7 @@ getcolors32(Imaging im, int maxcolors, int *size) { } if (!im->image32) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } table = calloc(code_size + 1, sizeof(ImagingColorItem)); diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index d81f6081572..8f9b004cb55 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -70,14 +70,14 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { FLOAT32 fmin, fmax, scale; if (!im) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } int xsize = im->xsize, ysize = im->ysize; if (imMask) { /* Validate mask */ if (xsize != imMask->xsize || ysize != imMask->ysize) { - return ImagingError_Mismatch(); + return ImagingError_Mismatch(NULL); } if (imMask->mode != IMAGING_MODE_1 && imMask->mode != IMAGING_MODE_L) { return ImagingError_ValueError("bad transparency mask"); @@ -114,7 +114,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { } else { /* yes, we need the braces. C isn't Python! */ if (im->type != IMAGING_TYPE_UINT8) { ImagingHistogramDelete(h); - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } ImagingSectionEnter(&cookie); MUTEX_LOCK(&im->mutex); diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index fdc096b3f52..0a574b579a6 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -276,9 +276,9 @@ ImagingSectionLeave(ImagingSectionCookie *cookie); extern void * ImagingError_MemoryError(void); extern void * -ImagingError_ModeError(void); /* maps to ValueError by default */ +ImagingError_ModeError(const char *message); /* maps to ValueError by default */ extern void * -ImagingError_Mismatch(void); /* maps to ValueError by default */ +ImagingError_Mismatch(const char *message); /* maps to ValueError by default */ extern void * ImagingError_ValueError(const char *message); extern void * diff --git a/src/libImaging/Matrix.c b/src/libImaging/Matrix.c index 3e47d346bfa..906bf53bdad 100644 --- a/src/libImaging/Matrix.c +++ b/src/libImaging/Matrix.c @@ -30,7 +30,7 @@ ImagingConvertMatrix(Imaging im, const ModeID mode, const float m[12]) { /* Assume there's enough data in the buffer */ if (!im || im->bands != 3) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (mode == IMAGING_MODE_L) { @@ -83,7 +83,7 @@ ImagingConvertMatrix(Imaging im, const ModeID mode, const float m[12]) { ImagingSectionLeave(&cookie); } } else { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } return imOut; diff --git a/src/libImaging/ModeFilter.c b/src/libImaging/ModeFilter.c index 757cbc3fb86..018c6e61460 100644 --- a/src/libImaging/ModeFilter.c +++ b/src/libImaging/ModeFilter.c @@ -25,7 +25,7 @@ ImagingModeFilter(Imaging im, int size) { int histogram[256]; if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); diff --git a/src/libImaging/Negative.c b/src/libImaging/Negative.c index ea04563851d..6cb4778e4f7 100644 --- a/src/libImaging/Negative.c +++ b/src/libImaging/Negative.c @@ -29,7 +29,7 @@ ImagingNegative(Imaging im) { int x, y; if (!im) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); diff --git a/src/libImaging/Offset.c b/src/libImaging/Offset.c index 48c60b3c4f2..dfdab306eb2 100644 --- a/src/libImaging/Offset.c +++ b/src/libImaging/Offset.c @@ -25,7 +25,7 @@ Imaging ImagingOffset(Imaging im, int xoffset, int yoffset) { if (!im) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = im->xsize, ysize = im->ysize; diff --git a/src/libImaging/Palette.c b/src/libImaging/Palette.c index ceb69d3dc6b..4572239d808 100644 --- a/src/libImaging/Palette.c +++ b/src/libImaging/Palette.c @@ -29,7 +29,7 @@ ImagingPaletteNew(const ModeID mode) { if (mode != IMAGING_MODE_RGB && mode != IMAGING_MODE_RGBA && mode != IMAGING_MODE_CMYK) { - return (ImagingPalette)ImagingError_ModeError(); + return (ImagingPalette)ImagingError_ModeError(NULL); } palette = calloc(1, sizeof(struct ImagingPaletteInstance)); diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index 9e4451cbc38..e9802fb38c4 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -280,7 +280,7 @@ ImagingPaste( ImagingSectionCookie cookie; if (!imOut || !imIn) { - (void)ImagingError_ModeError(); + (void)ImagingError_ModeError(NULL); return -1; } @@ -290,12 +290,12 @@ ImagingPaste( ysize = (int64_t)dy1 - dy0; if (xsize != imIn->xsize || ysize != imIn->ysize || pixelsize != imIn->pixelsize) { - (void)ImagingError_Mismatch(); + (void)ImagingError_Mismatch(NULL); return -1; } if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { - (void)ImagingError_Mismatch(); + (void)ImagingError_Mismatch(NULL); return -1; } @@ -603,7 +603,7 @@ ImagingFill2( int sx0, sy0; if (!imOut || !ink) { - (void)ImagingError_ModeError(); + (void)ImagingError_ModeError(NULL); return -1; } @@ -613,7 +613,7 @@ ImagingFill2( ysize = (int64_t)dy1 - dy0; if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { - (void)ImagingError_Mismatch(); + (void)ImagingError_Mismatch(NULL); return -1; } diff --git a/src/libImaging/Point.c b/src/libImaging/Point.c index 9cb9fbbca7d..c1b9a212d4c 100644 --- a/src/libImaging/Point.c +++ b/src/libImaging/Point.c @@ -137,7 +137,7 @@ ImagingPoint(Imaging imIn, ModeID mode, const void *table) { void (*point)(Imaging imIn, Imaging imOut, im_point_context *context); if (!imIn) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (mode == IMAGING_MODE_UNKNOWN) { @@ -218,7 +218,7 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) { if (!imIn || (imIn->mode != IMAGING_MODE_I && imIn->mode != IMAGING_MODE_I_16 && imIn->mode != IMAGING_MODE_F)) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index 376c446a0a0..3ffd596fb64 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1276,7 +1276,7 @@ ImagingQuantize(Imaging im, int colors, ImagingQuantizeMethod method, int kmeans ImagingSectionCookie cookie; if (!im) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } if (colors < 1 || colors > 256) { /* FIXME: for colors > 256, consider returning an RGB image @@ -1286,13 +1286,13 @@ ImagingQuantize(Imaging im, int colors, ImagingQuantizeMethod method, int kmeans if (im->mode != IMAGING_MODE_L && im->mode != IMAGING_MODE_P && im->mode != IMAGING_MODE_RGB && im->mode != IMAGING_MODE_RGBA) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } /* only octree and imagequant supports RGBA */ if (im->mode == IMAGING_MODE_RGBA && method != IMAGING_QUANTIZE_FASTOCTREE && method != IMAGING_QUANTIZE_LIBIMAGEQUANT) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } // Hoisted here as these are invariant over the loops below. diff --git a/src/libImaging/RankFilter.c b/src/libImaging/RankFilter.c index fc8ce2db96d..7201c716df8 100644 --- a/src/libImaging/RankFilter.c +++ b/src/libImaging/RankFilter.c @@ -65,7 +65,7 @@ MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32) int i, margin, size2; if (!im || im->bands != 1 || im->type == IMAGING_TYPE_I16) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (!(size & 1)) { @@ -121,7 +121,7 @@ MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32) } else { /* safety net (we shouldn't end up here) */ ImagingDelete(imOut); - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } ImagingCopyPalette(imOut, im); diff --git a/src/libImaging/Reduce.c b/src/libImaging/Reduce.c index 7e5634bed46..e5c31e3848f 100644 --- a/src/libImaging/Reduce.c +++ b/src/libImaging/Reduce.c @@ -1454,7 +1454,7 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]) { if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_1 || imIn->type == IMAGING_TYPE_I16) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } /* Round the size up. Dividing before adding avoids overflowing for a diff --git a/src/libImaging/Resample.c b/src/libImaging/Resample.c index ef020491821..bdd6cd360a0 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -786,7 +786,7 @@ ImagingResample( ResampleFunction ResampleVertical; if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_1) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } if (imIn->type == IMAGING_TYPE_I16) { @@ -807,7 +807,7 @@ ImagingResample( ResampleVertical = _ImagingResampleVertical_32bpc; break; default: - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } } diff --git a/src/libImaging/Storage.c b/src/libImaging/Storage.c index c79031359de..1345365352d 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -760,7 +760,7 @@ ImagingNew2Dirty(const ModeID mode, Imaging imOut, Imaging imIn) { /* make sure images match */ if (imOut->mode != mode || imOut->xsize != imIn->xsize || imOut->ysize != imIn->ysize) { - return ImagingError_Mismatch(); + return ImagingError_Mismatch(NULL); } } else { /* create new image */ diff --git a/src/libImaging/UnsharpMask.c b/src/libImaging/UnsharpMask.c index b56e01631ca..a8bb9956020 100644 --- a/src/libImaging/UnsharpMask.c +++ b/src/libImaging/UnsharpMask.c @@ -36,7 +36,7 @@ ImagingUnsharpMask( UINT8 *lineOut8 = NULL; if (imIn->type != IMAGING_TYPE_UINT8) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } /* First, do a gaussian blur on the image, putting results in imOut From 6c7bd1c2f8d91ba9cc63ac0076a81aceff183768 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 9 Jul 2026 10:48:23 +0300 Subject: [PATCH 3/4] Add bespoke error messages where suitable Co-authored-by: Andrew Murray --- Tests/test_color_lut.py | 2 +- Tests/test_image.py | 2 +- Tests/test_image_convert.py | 4 ++-- Tests/test_image_histogram.py | 4 ++-- Tests/test_image_paste.py | 2 +- Tests/test_image_putalpha.py | 2 +- Tests/test_imagepalette.py | 2 +- Tests/test_imagewin.py | 2 +- src/_imaging.c | 2 +- src/display.c | 4 ++-- src/libImaging/AlphaComposite.c | 10 ++++++---- src/libImaging/Bands.c | 27 +++++++++++++++++++-------- src/libImaging/Blend.c | 6 ++++-- src/libImaging/BoxBlur.c | 6 ++++-- src/libImaging/Chops.c | 2 +- src/libImaging/ColorLUT.c | 19 +++++++++++++------ src/libImaging/Convert.c | 2 +- src/libImaging/Dib.c | 4 +++- src/libImaging/Effects.c | 4 +++- src/libImaging/Fill.c | 8 ++++++-- src/libImaging/Filter.c | 2 +- src/libImaging/Geometry.c | 27 +++++++++++++++++++++------ src/libImaging/GetBBox.c | 6 +++--- src/libImaging/Histo.c | 4 ++-- src/libImaging/Matrix.c | 9 +++++++-- src/libImaging/ModeFilter.c | 8 +++++++- src/libImaging/Palette.c | 4 +++- src/libImaging/Paste.c | 12 ++++++++---- src/libImaging/Point.c | 7 +++++-- src/libImaging/Quant.c | 7 ++++--- src/libImaging/RankFilter.c | 6 +++++- src/libImaging/Reduce.c | 4 +++- src/libImaging/Resample.c | 6 ++++-- src/libImaging/Storage.c | 2 +- 34 files changed, 147 insertions(+), 71 deletions(-) diff --git a/Tests/test_color_lut.py b/Tests/test_color_lut.py index 085f07fcc38..196b1943a39 100644 --- a/Tests/test_color_lut.py +++ b/Tests/test_color_lut.py @@ -140,7 +140,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, diff --git a/Tests/test_image.py b/Tests/test_image.py index 95d457852f1..2e21d4a1973 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -1152,7 +1152,7 @@ def test_merge_pa(self) -> None: def test_merge_i(self) -> None: i = Image.new("I", (1, 1)) a = Image.new("L", (1, 1)) - with pytest.raises(ValueError, match="image has wrong mode"): + with pytest.raises(ValueError, match="source image must have exactly 1 band"): Image.merge("PA", (i, a)) def test_constants(self) -> None: diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index 6573e30ebe7..7eca22c0c1e 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -46,7 +46,7 @@ def convert(im: Image.Image, mode: str) -> None: def test_unsupported_conversion() -> None: im = hopper() - with pytest.raises(ValueError, match="image has wrong mode"): + with pytest.raises(ValueError): im.convert("INVALID") @@ -322,7 +322,7 @@ def test_matrix_wrong_mode() -> None: im = hopper("L") # Act / Assert - with pytest.raises(ValueError, match="image has wrong mode"): + with pytest.raises(ValueError, match="image must have exactly 3 bands"): im.convert(mode="L", matrix=rgb2xyz_matrix) diff --git a/Tests/test_image_histogram.py b/Tests/test_image_histogram.py index c3f3c391601..d79526e2285 100644 --- a/Tests/test_image_histogram.py +++ b/Tests/test_image_histogram.py @@ -52,13 +52,13 @@ def histogram(mode: str) -> tuple[int, int, int]: @pytest.mark.parametrize("mode", ("I", "F")) def test_histogram_masked_unsupported_mode(mode: str) -> None: mask = Image.new("1", (128, 128)) - with pytest.raises(ValueError, match="image has wrong mode"): + with pytest.raises(ValueError, match="only 8-bit images supported"): hopper(mode).histogram(mask) def test_histogram_mask_size_mismatch() -> None: mask = Image.new("1", (1, 1)) - with pytest.raises(ValueError, match="images do not match"): + with pytest.raises(ValueError, match="mask must have the same size as the image"): hopper("L").histogram(mask) diff --git a/Tests/test_image_paste.py b/Tests/test_image_paste.py index 976b1b2b681..22e2cbf837e 100644 --- a/Tests/test_image_paste.py +++ b/Tests/test_image_paste.py @@ -370,7 +370,7 @@ 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="box must match image size"): im.paste(im.copy(), box) def test_incorrect_abbreviated_form(self) -> None: diff --git a/Tests/test_image_putalpha.py b/Tests/test_image_putalpha.py index 404e3433e57..917e9dd5aad 100644 --- a/Tests/test_image_putalpha.py +++ b/Tests/test_image_putalpha.py @@ -41,7 +41,7 @@ def test_promote() -> None: assert im.mode == "RGBA" assert im.getpixel((0, 0)) == (1, 2, 3, 4) - with pytest.raises(ValueError, match="image has wrong mode"): + with pytest.raises(ValueError, match="RGB"): im.im.setalpha() diff --git a/Tests/test_imagepalette.py b/Tests/test_imagepalette.py index d2b995dcfa3..1143fbf30c2 100644 --- a/Tests/test_imagepalette.py +++ b/Tests/test_imagepalette.py @@ -39,7 +39,7 @@ def test_wrong_mode() -> None: im.palette = ImagePalette.ImagePalette() im.palette.mode = "L" im.palette.dirty = 1 - with pytest.raises(ValueError, match="image has wrong mode"): + with pytest.raises(ValueError, match="only modes RGB/RGBA/CMYK supported"): im.load() diff --git a/Tests/test_imagewin.py b/Tests/test_imagewin.py index 3a72878f695..bfc297c5b85 100644 --- a/Tests/test_imagewin.py +++ b/Tests/test_imagewin.py @@ -101,7 +101,7 @@ def test_dib_paste_bbox(self) -> None: # Assert assert dib.size == (128, 128) - with pytest.raises(ValueError, match="images do not match"): + with pytest.raises(ValueError, match="box must match image size"): dib.paste(im, (0, 0, 1, 1)) with pytest.raises(ValueError, match="left box co-ordinate cannot be negative"): diff --git a/src/_imaging.c b/src/_imaging.c index 9cd0743d9c6..11bf01cd499 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -2373,7 +2373,7 @@ im_setalpha_impl(ImagingObject *self, PyObject *args) { /* attempt to modify the mode of an image in place */ Imaging im = self->image; if (im->mode != IMAGING_MODE_RGB && im->mode != IMAGING_MODE_RGBX) { - return ImagingError_ModeError("only RGB/RGBX modes supported"); + return ImagingError_NotSupportedError("only modes RGB/RGBX supported"); } im->mode = IMAGING_MODE_RGBA; im->bands = 4; diff --git a/src/display.c b/src/display.c index e5133365c1f..e01a9b54c72 100644 --- a/src/display.c +++ b/src/display.c @@ -139,7 +139,7 @@ _paste(ImagingDisplayObject *display, PyObject *args) { if (xy[2] <= xy[0]) { xy[2] = xy[0] + im->xsize; } else if (xy[2] - xy[0] != im->xsize) { - return ImagingError_Mismatch(NULL); + return ImagingError_Mismatch("box must match image size"); } if (xy[0] < 0) { PyErr_SetString(PyExc_ValueError, "left box co-ordinate cannot be negative"); @@ -152,7 +152,7 @@ _paste(ImagingDisplayObject *display, PyObject *args) { if (xy[3] <= xy[1]) { xy[3] = xy[1] + im->ysize; } else if (xy[3] - xy[1] != im->ysize) { - return ImagingError_Mismatch(NULL); + return ImagingError_Mismatch("box must match image size"); } if (xy[1] < 0) { PyErr_SetString(PyExc_ValueError, "upper box co-ordinate cannot be negative"); diff --git a/src/libImaging/AlphaComposite.c b/src/libImaging/AlphaComposite.c index 1208254435e..709a693b096 100644 --- a/src/libImaging/AlphaComposite.c +++ b/src/libImaging/AlphaComposite.c @@ -29,14 +29,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(NULL); + 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(NULL); + return ImagingError_Mismatch("images must have the same mode and size"); } imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize); diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index 919cf1e1bc8..de809aa3185 100644 --- a/src/libImaging/Bands.c +++ b/src/libImaging/Bands.c @@ -29,7 +29,7 @@ ImagingGetBand(Imaging imIn, int band) { /* Check arguments */ if (!imIn || imIn->type != IMAGING_TYPE_UINT8) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_NotSupportedError(NULL); } if (band < 0 || band >= imIn->bands) { @@ -90,7 +90,7 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) { /* Check arguments */ if (!imIn || imIn->type != IMAGING_TYPE_UINT8) { - (void)ImagingError_ModeError(NULL); + (void)ImagingError_NotSupportedError(NULL); return -1; } @@ -199,9 +199,12 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) { int x, y; /* Check arguments */ - if (!imIn || imIn->bands != 1 || !imOut) { + if (!imIn || !imOut) { return (Imaging)ImagingError_ModeError(NULL); } + if (imIn->bands != 1) { + return (Imaging)ImagingError_ModeError("source image must have exactly 1 band"); + } if (band < 0 || band >= imOut->bands) { return (Imaging)ImagingError_ValueError("band index out of range"); @@ -209,7 +212,9 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) { if (imIn->type != imOut->type || imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch( + "images must have the same type and size" + ); } /* Shortcuts */ @@ -248,8 +253,12 @@ ImagingFillBand(Imaging imOut, int band, int color) { int x, y; /* Check arguments */ - if (!imOut || imOut->type != IMAGING_TYPE_UINT8) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut) { + return (Imaging)ImagingError_ValueError(NULL); + } + + if (imOut->type != IMAGING_TYPE_UINT8) { + return (Imaging)ImagingError_NotSupportedError("only 8-bit images supported"); } if (band < 0 || band >= imOut->bands) { @@ -301,11 +310,13 @@ ImagingMerge(const ModeID mode, Imaging bands[4]) { } for (i = 0; i < bandsCount; ++i) { if (bands[i]->bands != 1 || (bandsCount != 1 && bands[i]->pixelsize == 4)) { - return (Imaging)ImagingError_ModeError(NULL); + 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(NULL); + return (Imaging)ImagingError_Mismatch("images must have the same size"); } } diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index af808bcf5e7..0e2acfd37a1 100644 --- a/src/libImaging/Blend.c +++ b/src/libImaging/Blend.c @@ -32,12 +32,14 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette || imIn1->mode == IMAGING_MODE_1 || imIn2->palette || imIn2->mode == IMAGING_MODE_1) { - return ImagingError_ModeError(NULL); + return ImagingError_ModeError( + "images must have 8-bit data and must not use mode P or 1" + ); } if (imIn1->type != imIn2->type || imIn1->bands != imIn2->bands || imIn1->xsize != imIn2->xsize || imIn1->ysize != imIn2->ysize) { - return ImagingError_Mismatch(NULL); + return ImagingError_Mismatch("image types, band count and sizes must match"); } /* Shortcuts */ diff --git a/src/libImaging/BoxBlur.c b/src/libImaging/BoxBlur.c index 44f8fe7de70..476b78ddd05 100644 --- a/src/libImaging/BoxBlur.c +++ b/src/libImaging/BoxBlur.c @@ -354,7 +354,7 @@ 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(NULL); + return ImagingError_Mismatch("images must have the same mode and size"); } if (!(imIn->type == IMAGING_TYPE_UINT8 && @@ -363,7 +363,9 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float xradius, float yradius, int n) imIn->mode == IMAGING_MODE_CMYK || imIn->mode == IMAGING_MODE_L || imIn->mode == IMAGING_MODE_LA || imIn->mode == IMAGING_MODE_La)) && imIn->type != IMAGING_TYPE_I16) { - return ImagingError_ModeError(NULL); + return ImagingError_NotSupportedError( + "only modes RGB/RGBA/RGBa/RGBX/CMYK/L/LA/La and I;16 supported" + ); } /* Apply blur in one dimension. diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index fb0f7f0df9b..90b326ca92b 100644 --- a/src/libImaging/Chops.c +++ b/src/libImaging/Chops.c @@ -75,7 +75,7 @@ create(Imaging im1, Imaging im2, const ModeID mode) { return (Imaging)ImagingError_ModeError(NULL); } if (im1->type != im2->type || im1->bands != im2->bands) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch("image types and band count must match"); } xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize; diff --git a/src/libImaging/ColorLUT.c b/src/libImaging/ColorLUT.c index 671935fdac7..cb7c7396a95 100644 --- a/src/libImaging/ColorLUT.c +++ b/src/libImaging/ColorLUT.c @@ -91,14 +91,21 @@ 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(NULL); + if (imIn->type != IMAGING_TYPE_UINT8 || imOut->type != IMAGING_TYPE_UINT8) { + return (Imaging)ImagingError_NotSupportedError("only 8-bit images 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(NULL); + return (Imaging)ImagingError_ModeError( + "output image has more bands than input image and table" + ); } ImagingSectionEnter(&cookie); diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index da0576b5b79..dbad73b55db 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1607,7 +1607,7 @@ ImagingConvert( if (mode == IMAGING_MODE_UNKNOWN) { /* Map palette image to full depth */ if (!imIn->palette) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ModeError("image has no palette"); } mode = imIn->palette->mode; } else { diff --git a/src/libImaging/Dib.c b/src/libImaging/Dib.c index 8d09d4fe2ac..e69e742a9f5 100644 --- a/src/libImaging/Dib.c +++ b/src/libImaging/Dib.c @@ -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(NULL); + return (ImagingDIB)ImagingError_NotSupportedError( + "only modes 1/L/RGB supported" + ); } const int pixelsize = mode == IMAGING_MODE_RGB ? 3 : 1; diff --git a/src/libImaging/Effects.c b/src/libImaging/Effects.c index c05c5764e44..cee7aeeab18 100644 --- a/src/libImaging/Effects.c +++ b/src/libImaging/Effects.c @@ -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 >=0 and quality >= 2" + ); } im = ImagingNewDirty(IMAGING_MODE_L, xsize, ysize); diff --git a/src/libImaging/Fill.c b/src/libImaging/Fill.c index d1f2791c1b0..cb4227b956c 100644 --- a/src/libImaging/Fill.c +++ b/src/libImaging/Fill.c @@ -86,7 +86,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(NULL); + return (Imaging)ImagingError_NotSupportedError( + "only modes 1/F/I/L/P supported" + ); } im = ImagingNewDirty(mode, 256, 256); @@ -125,7 +127,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(NULL); + return (Imaging)ImagingError_NotSupportedError( + "only modes 1/F/I/L/P supported" + ); } im = ImagingNewDirty(mode, 256, 256); diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index ce042d3928c..32cc4d8b142 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -513,7 +513,7 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 o ImagingSectionCookie cookie; if (im->type == IMAGING_TYPE_FLOAT32) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_NotSupportedError("mode F not supported"); } if (im->xsize < xsize || im->ysize < ysize) { diff --git a/src/libImaging/Geometry.c b/src/libImaging/Geometry.c index 34c73762d42..3eab065d261 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -746,8 +746,13 @@ ImagingGenericTransform( char *out; double xx, yy; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + ImagingError_ValueError(NULL); + return -1; + } + + if (imIn->mode != imOut->mode) { + ImagingError_ModeError("images must have the same mode"); return -1; } @@ -807,8 +812,13 @@ ImagingScaleAffine( int xmin, xmax; int *xintab; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + ImagingError_ValueError(NULL); + return -1; + } + + if (imIn->mode != imOut->mode) { + ImagingError_ModeError("images must have the same mode"); return -1; } @@ -1002,8 +1012,13 @@ ImagingTransformAffine( double xx, yy; double xo, yo; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + ImagingError_ValueError(NULL); + return -1; + } + + if (imIn->mode != imOut->mode) { + ImagingError_ModeError("images must have the same mode"); return -1; } diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c index d78935bd81d..2e5126e5913 100644 --- a/src/libImaging/GetBBox.c +++ b/src/libImaging/GetBBox.c @@ -184,7 +184,7 @@ ImagingGetExtrema(Imaging im, void *extrema) { FLOAT32 fmin, fmax; if (im->bands != 1) { - (void)ImagingError_ModeError(NULL); + (void)ImagingError_ModeError("image must have exactly 1 band"); return -1; /* mismatch */ } @@ -274,7 +274,7 @@ ImagingGetExtrema(Imaging im, void *extrema) { } /* FALL THROUGH */ default: - (void)ImagingError_ModeError(NULL); + (void)ImagingError_NotSupportedError("mode not supported"); return -1; } return 1; /* ok */ @@ -332,7 +332,7 @@ getcolors32(Imaging im, int maxcolors, int *size) { } if (!im->image32) { - return ImagingError_ModeError(NULL); + return ImagingError_ModeError("image must have 32-bit data"); } table = calloc(code_size + 1, sizeof(ImagingColorItem)); diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index 8f9b004cb55..80ce3631c8e 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -77,7 +77,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { if (imMask) { /* Validate mask */ if (xsize != imMask->xsize || ysize != imMask->ysize) { - return ImagingError_Mismatch(NULL); + return ImagingError_Mismatch("mask must have the same size as the image"); } if (imMask->mode != IMAGING_MODE_1 && imMask->mode != IMAGING_MODE_L) { return ImagingError_ValueError("bad transparency mask"); @@ -114,7 +114,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { } else { /* yes, we need the braces. C isn't Python! */ if (im->type != IMAGING_TYPE_UINT8) { ImagingHistogramDelete(h); - return ImagingError_ModeError(NULL); + return ImagingError_NotSupportedError("only 8-bit images supported"); } ImagingSectionEnter(&cookie); MUTEX_LOCK(&im->mutex); diff --git a/src/libImaging/Matrix.c b/src/libImaging/Matrix.c index 906bf53bdad..0e182732b4f 100644 --- a/src/libImaging/Matrix.c +++ b/src/libImaging/Matrix.c @@ -29,9 +29,12 @@ ImagingConvertMatrix(Imaging im, const ModeID mode, const float m[12]) { ImagingSectionCookie cookie; /* Assume there's enough data in the buffer */ - if (!im || im->bands != 3) { + if (!im) { return (Imaging)ImagingError_ModeError(NULL); } + if (im->bands != 3) { + return (Imaging)ImagingError_ModeError("image must have exactly 3 bands"); + } if (mode == IMAGING_MODE_L) { imOut = ImagingNewDirty(IMAGING_MODE_L, im->xsize, im->ysize); @@ -83,7 +86,9 @@ ImagingConvertMatrix(Imaging im, const ModeID mode, const float m[12]) { ImagingSectionLeave(&cookie); } } else { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_NotSupportedError( + "only conversions to modes L and RGB are supported" + ); } return imOut; diff --git a/src/libImaging/ModeFilter.c b/src/libImaging/ModeFilter.c index 018c6e61460..9c5240f1ad3 100644 --- a/src/libImaging/ModeFilter.c +++ b/src/libImaging/ModeFilter.c @@ -24,9 +24,15 @@ ImagingModeFilter(Imaging im, int size) { UINT8 maxpixel; int histogram[256]; - if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) { + if (!im) { return (Imaging)ImagingError_ModeError(NULL); } + if (im->bands != 1) { + return (Imaging)ImagingError_ModeError("image must have exactly 1 band"); + } + if (im->type != IMAGING_TYPE_UINT8) { + return (Imaging)ImagingError_NotSupportedError("only 8-bit images supported"); + } imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); if (!imOut) { diff --git a/src/libImaging/Palette.c b/src/libImaging/Palette.c index 4572239d808..645e35090ad 100644 --- a/src/libImaging/Palette.c +++ b/src/libImaging/Palette.c @@ -29,7 +29,9 @@ ImagingPaletteNew(const ModeID mode) { if (mode != IMAGING_MODE_RGB && mode != IMAGING_MODE_RGBA && mode != IMAGING_MODE_CMYK) { - return (ImagingPalette)ImagingError_ModeError(NULL); + return (ImagingPalette)ImagingError_NotSupportedError( + "only modes RGB/RGBA/CMYK supported" + ); } palette = calloc(1, sizeof(struct ImagingPaletteInstance)); diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index e9802fb38c4..1d51f06d94e 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -289,13 +289,17 @@ ImagingPaste( xsize = (int64_t)dx1 - dx0; ysize = (int64_t)dy1 - dy0; - if (xsize != imIn->xsize || ysize != imIn->ysize || pixelsize != imIn->pixelsize) { - (void)ImagingError_Mismatch(NULL); + if (xsize != imIn->xsize || ysize != imIn->ysize) { + (void)ImagingError_Mismatch("box must match image size"); + return -1; + } + if (pixelsize != imIn->pixelsize) { + (void)ImagingError_Mismatch("images must have the same pixel size"); return -1; } if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { - (void)ImagingError_Mismatch(NULL); + (void)ImagingError_Mismatch("mask must have the same size as the image"); return -1; } @@ -613,7 +617,7 @@ ImagingFill2( ysize = (int64_t)dy1 - dy0; if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { - (void)ImagingError_Mismatch(NULL); + (void)ImagingError_Mismatch("mask must have the same size as the image"); return -1; } diff --git a/src/libImaging/Point.c b/src/libImaging/Point.c index c1b9a212d4c..5767ecd6812 100644 --- a/src/libImaging/Point.c +++ b/src/libImaging/Point.c @@ -216,10 +216,13 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) { Imaging imOut; int x, y; - if (!imIn || (imIn->mode != IMAGING_MODE_I && imIn->mode != IMAGING_MODE_I_16 && - imIn->mode != IMAGING_MODE_F)) { + if (!imIn) { return (Imaging)ImagingError_ModeError(NULL); } + if (imIn->mode != IMAGING_MODE_I && imIn->mode != IMAGING_MODE_I_16 && + imIn->mode != IMAGING_MODE_F) { + return (Imaging)ImagingError_NotSupportedError("only modes I/I;16/F supported"); + } imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); if (!imOut) { diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index 3ffd596fb64..db6bf65e57f 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1286,13 +1286,14 @@ ImagingQuantize(Imaging im, int colors, ImagingQuantizeMethod method, int kmeans if (im->mode != IMAGING_MODE_L && im->mode != IMAGING_MODE_P && im->mode != IMAGING_MODE_RGB && im->mode != IMAGING_MODE_RGBA) { - return ImagingError_ModeError(NULL); + return ImagingError_NotSupportedError("only modes L/P/RGB/RGBA supported"); } - /* only octree and imagequant supports RGBA */ if (im->mode == IMAGING_MODE_RGBA && method != IMAGING_QUANTIZE_FASTOCTREE && method != IMAGING_QUANTIZE_LIBIMAGEQUANT) { - return ImagingError_ModeError(NULL); + return ImagingError_NotSupportedError( + "only octree and imagequant support RGBA" + ); } // Hoisted here as these are invariant over the loops below. diff --git a/src/libImaging/RankFilter.c b/src/libImaging/RankFilter.c index 7201c716df8..2f3407e4e10 100644 --- a/src/libImaging/RankFilter.c +++ b/src/libImaging/RankFilter.c @@ -64,7 +64,11 @@ MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32) int x, y; int i, margin, size2; - if (!im || im->bands != 1 || im->type == IMAGING_TYPE_I16) { + if (!im) { + return (Imaging)ImagingError_ValueError(NULL); + } + + if (im->bands != 1 || im->type == IMAGING_TYPE_I16) { return (Imaging)ImagingError_ModeError(NULL); } diff --git a/src/libImaging/Reduce.c b/src/libImaging/Reduce.c index e5c31e3848f..e07957dbbb9 100644 --- a/src/libImaging/Reduce.c +++ b/src/libImaging/Reduce.c @@ -1454,7 +1454,9 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]) { if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_1 || imIn->type == IMAGING_TYPE_I16) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_NotSupportedError( + "modes P, 1 and I;16 not supported" + ); } /* Round the size up. Dividing before adding avoids overflowing for a diff --git a/src/libImaging/Resample.c b/src/libImaging/Resample.c index bdd6cd360a0..1fcaa85954e 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -786,7 +786,7 @@ ImagingResample( ResampleFunction ResampleVertical; if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_1) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_NotSupportedError("modes P and 1 not supported"); } if (imIn->type == IMAGING_TYPE_I16) { @@ -807,7 +807,9 @@ ImagingResample( ResampleVertical = _ImagingResampleVertical_32bpc; break; default: - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_NotSupportedError( + "special image types are not supported" + ); } } diff --git a/src/libImaging/Storage.c b/src/libImaging/Storage.c index 1345365352d..d892337a23e 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -760,7 +760,7 @@ ImagingNew2Dirty(const ModeID mode, Imaging imOut, Imaging imIn) { /* make sure images match */ if (imOut->mode != mode || imOut->xsize != imIn->xsize || imOut->ysize != imIn->ysize) { - return ImagingError_Mismatch(NULL); + return ImagingError_Mismatch("images must have the same mode and size"); } } else { /* create new image */ From ecc77069d7e84bd0d41325a9a4f4ec46541fe400 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 9 Jul 2026 11:03:29 +0300 Subject: [PATCH 4/4] Make sure image nullness checks raise ValueErrors, not ModeErrors --- src/libImaging/Bands.c | 19 ++++++++++++++----- src/libImaging/Blend.c | 17 +++++++++++------ src/libImaging/Chops.c | 17 ++++++++++++----- src/libImaging/Convert.c | 4 ++-- src/libImaging/Crop.c | 2 +- src/libImaging/Histo.c | 2 +- src/libImaging/Matrix.c | 2 +- src/libImaging/ModeFilter.c | 2 +- src/libImaging/Negative.c | 2 +- src/libImaging/Offset.c | 2 +- src/libImaging/Paste.c | 4 ++-- src/libImaging/Point.c | 4 ++-- src/libImaging/Quant.c | 2 +- src/libImaging/RankFilter.c | 7 +++++-- 14 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index de809aa3185..6aa215517a3 100644 --- a/src/libImaging/Bands.c +++ b/src/libImaging/Bands.c @@ -28,8 +28,12 @@ ImagingGetBand(Imaging imIn, int band) { int x, y; /* Check arguments */ - if (!imIn || imIn->type != IMAGING_TYPE_UINT8) { - return (Imaging)ImagingError_NotSupportedError(NULL); + 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) { @@ -89,8 +93,13 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) { int i, j, x, y; /* Check arguments */ - if (!imIn || imIn->type != IMAGING_TYPE_UINT8) { - (void)ImagingError_NotSupportedError(NULL); + if (!imIn) { + (void)ImagingError_ValueError(NULL); + return -1; + } + + if (imIn->type != IMAGING_TYPE_UINT8) { + (void)ImagingError_NotSupportedError("only 8-bit images supported"); return -1; } @@ -200,7 +209,7 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) { /* Check arguments */ if (!imIn || !imOut) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (imIn->bands != 1) { return (Imaging)ImagingError_ModeError("source image must have exactly 1 band"); diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index 0e2acfd37a1..222bdd4ae15 100644 --- a/src/libImaging/Blend.c +++ b/src/libImaging/Blend.c @@ -29,17 +29,22 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { int x, y; /* Check arguments */ - if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette || - imIn1->mode == IMAGING_MODE_1 || imIn2->palette || + if (!imIn1 || !imIn2) { + return ImagingError_ValueError(NULL); + } + if (imIn1->type != IMAGING_TYPE_UINT8) { + return ImagingError_NotSupportedError("only 8-bit images supported"); + } + if (imIn1->palette || imIn1->mode == IMAGING_MODE_1 || imIn2->palette || imIn2->mode == IMAGING_MODE_1) { - return ImagingError_ModeError( - "images must have 8-bit data and must not use mode P or 1" - ); + return ImagingError_NotSupportedError("modes P, PA and 1 not supported"); } if (imIn1->type != imIn2->type || imIn1->bands != imIn2->bands || imIn1->xsize != imIn2->xsize || imIn1->ysize != imIn2->ysize) { - return ImagingError_Mismatch("image types, band count and sizes must match"); + return ImagingError_Mismatch( + "images must have the same type, band count and size" + ); } /* Shortcuts */ diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index 90b326ca92b..ba434f4ea50 100644 --- a/src/libImaging/Chops.c +++ b/src/libImaging/Chops.c @@ -69,13 +69,20 @@ static Imaging create(Imaging im1, Imaging im2, const ModeID mode) { int xsize, ysize; - if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 || - (mode != IMAGING_MODE_UNKNOWN && - (im1->mode != IMAGING_MODE_1 || im2->mode != IMAGING_MODE_1))) { - return (Imaging)ImagingError_ModeError(NULL); + if (!im1 || !im2) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (im1->type != IMAGING_TYPE_UINT8) { + return (Imaging)ImagingError_NotSupportedError("only 8-bit images supported"); + } + if (mode != IMAGING_MODE_UNKNOWN && + (im1->mode != IMAGING_MODE_1 || im2->mode != IMAGING_MODE_1)) { + return (Imaging)ImagingError_ModeError("both images must have mode 1"); } if (im1->type != im2->type || im1->bands != im2->bands) { - return (Imaging)ImagingError_Mismatch("image types and band count must match"); + return (Imaging)ImagingError_Mismatch( + "images must have the same type and band count" + ); } xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize; diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index dbad73b55db..45443eeec7e 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1601,7 +1601,7 @@ ImagingConvert( ImagingShuffler convert; if (!imIn) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (mode == IMAGING_MODE_UNKNOWN) { @@ -1678,7 +1678,7 @@ ImagingConvertTransparent(Imaging imIn, const ModeID mode, int r, int g, int b) int y; if (!imIn) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (imIn->mode == IMAGING_MODE_RGB && diff --git a/src/libImaging/Crop.c b/src/libImaging/Crop.c index 7bbdc86c474..7379671fe86 100644 --- a/src/libImaging/Crop.c +++ b/src/libImaging/Crop.c @@ -25,7 +25,7 @@ ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1) { INT32 zero = 0; if (!imIn) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } xsize = sx1 - sx0; diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index 80ce3631c8e..118b750731b 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -70,7 +70,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { FLOAT32 fmin, fmax, scale; if (!im) { - return ImagingError_ModeError(NULL); + return ImagingError_ValueError(NULL); } int xsize = im->xsize, ysize = im->ysize; diff --git a/src/libImaging/Matrix.c b/src/libImaging/Matrix.c index 0e182732b4f..fcfa3c3475e 100644 --- a/src/libImaging/Matrix.c +++ b/src/libImaging/Matrix.c @@ -30,7 +30,7 @@ ImagingConvertMatrix(Imaging im, const ModeID mode, const float m[12]) { /* Assume there's enough data in the buffer */ if (!im) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (im->bands != 3) { return (Imaging)ImagingError_ModeError("image must have exactly 3 bands"); diff --git a/src/libImaging/ModeFilter.c b/src/libImaging/ModeFilter.c index 9c5240f1ad3..6f61691d641 100644 --- a/src/libImaging/ModeFilter.c +++ b/src/libImaging/ModeFilter.c @@ -25,7 +25,7 @@ ImagingModeFilter(Imaging im, int size) { int histogram[256]; if (!im) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (im->bands != 1) { return (Imaging)ImagingError_ModeError("image must have exactly 1 band"); diff --git a/src/libImaging/Negative.c b/src/libImaging/Negative.c index 6cb4778e4f7..93ff9e12db3 100644 --- a/src/libImaging/Negative.c +++ b/src/libImaging/Negative.c @@ -29,7 +29,7 @@ ImagingNegative(Imaging im) { int x, y; if (!im) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); diff --git a/src/libImaging/Offset.c b/src/libImaging/Offset.c index dfdab306eb2..2506b637415 100644 --- a/src/libImaging/Offset.c +++ b/src/libImaging/Offset.c @@ -25,7 +25,7 @@ Imaging ImagingOffset(Imaging im, int xoffset, int yoffset) { if (!im) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } int xsize = im->xsize, ysize = im->ysize; diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index 1d51f06d94e..52d78d14f4a 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -280,7 +280,7 @@ ImagingPaste( ImagingSectionCookie cookie; if (!imOut || !imIn) { - (void)ImagingError_ModeError(NULL); + (void)ImagingError_ValueError(NULL); return -1; } @@ -607,7 +607,7 @@ ImagingFill2( int sx0, sy0; if (!imOut || !ink) { - (void)ImagingError_ModeError(NULL); + (void)ImagingError_ValueError(NULL); return -1; } diff --git a/src/libImaging/Point.c b/src/libImaging/Point.c index 5767ecd6812..ced3d3c59fd 100644 --- a/src/libImaging/Point.c +++ b/src/libImaging/Point.c @@ -137,7 +137,7 @@ ImagingPoint(Imaging imIn, ModeID mode, const void *table) { void (*point)(Imaging imIn, Imaging imOut, im_point_context *context); if (!imIn) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (mode == IMAGING_MODE_UNKNOWN) { @@ -217,7 +217,7 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) { int x, y; if (!imIn) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (imIn->mode != IMAGING_MODE_I && imIn->mode != IMAGING_MODE_I_16 && imIn->mode != IMAGING_MODE_F) { diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index db6bf65e57f..1930248b7b5 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1276,7 +1276,7 @@ ImagingQuantize(Imaging im, int colors, ImagingQuantizeMethod method, int kmeans ImagingSectionCookie cookie; if (!im) { - return ImagingError_ModeError(NULL); + return ImagingError_ValueError(NULL); } if (colors < 1 || colors > 256) { /* FIXME: for colors > 256, consider returning an RGB image diff --git a/src/libImaging/RankFilter.c b/src/libImaging/RankFilter.c index 2f3407e4e10..abb5fb1752b 100644 --- a/src/libImaging/RankFilter.c +++ b/src/libImaging/RankFilter.c @@ -68,8 +68,11 @@ MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32) return (Imaging)ImagingError_ValueError(NULL); } - if (im->bands != 1 || im->type == IMAGING_TYPE_I16) { - return (Imaging)ImagingError_ModeError(NULL); + if (im->bands != 1) { + return (Imaging)ImagingError_ModeError("image must have exactly 1 band"); + } + if (im->type == IMAGING_TYPE_I16) { + return (Imaging)ImagingError_NotSupportedError("mode I;16 not supported"); } if (!(size & 1)) {