From cb2e4adef995a0ff34e27e21277f390f09000e32 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 | 31 +++++++++++++++++++++++++++++++ src/libImaging/Imaging.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/src/_imaging.c b/src/_imaging.c index fa42332a815..bbaaae85ff0 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -372,6 +372,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( @@ -4354,6 +4367,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); diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index fd4628c40ad..3e43059fe01 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -273,6 +273,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 3036bc27ccc83dfb138f212bfcea8ca2f8b951c1 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/libImaging/AlphaComposite.c | 4 ++-- src/libImaging/Bands.c | 14 +++++++------- src/libImaging/Blend.c | 4 ++-- src/libImaging/BoxBlur.c | 6 +++--- 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 | 34 ++++++++++++++++----------------- 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 +- 28 files changed, 82 insertions(+), 78 deletions(-) diff --git a/src/_imaging.c b/src/_imaging.c index bbaaae85ff0..1b04cc47508 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -361,14 +361,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; } @@ -2122,7 +2126,7 @@ im_setalpha(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/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 9c4005c3071..7fa1e0f9dc0 100644 --- a/src/libImaging/BoxBlur.c +++ b/src/libImaging/BoxBlur.c @@ -251,18 +251,18 @@ 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) { - return ImagingError_ModeError(); + return ImagingError_ModeError(NULL); } 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_ModeError(NULL); } /* Apply blur in one dimension. diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index 0a0244cd932..ce6f70bd44c 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 b2b7ff26a22..d5f546f0548 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1598,13 +1598,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 { @@ -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_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 70001bdf87d..6c8880fb7b8 100644 --- a/src/libImaging/Fill.c +++ b/src/libImaging/Fill.c @@ -81,7 +81,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); @@ -120,7 +120,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 7982419ff16..36ce89a9e42 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -500,7 +500,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 37766978651..a2aba803060 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -20,12 +20,12 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn) { int x, y, xr; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->xsize || ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -65,12 +65,12 @@ ImagingFlipTopBottom(Imaging imOut, Imaging imIn) { int y, yr; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int ysize = imIn->ysize; if (imIn->xsize != imOut->xsize || ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -94,12 +94,12 @@ ImagingRotate90(Imaging imOut, Imaging imIn) { int xxx, yyy, xxxsize, yyysize; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -156,12 +156,12 @@ ImagingTranspose(Imaging imOut, Imaging imIn) { int xxx, yyy, xxxsize, yyysize; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -217,12 +217,12 @@ ImagingTransverse(Imaging imOut, Imaging imIn) { int xxx, yyy, xxxsize, yyysize; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -279,12 +279,12 @@ ImagingRotate180(Imaging imOut, Imaging imIn) { int x, y, xr, yr; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->xsize || ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -326,12 +326,12 @@ ImagingRotate270(Imaging imOut, Imaging imIn) { int xxx, yyy, xxxsize, yyysize; if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(); + return (Imaging)ImagingError_ModeError(NULL); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(); + return (Imaging)ImagingError_Mismatch(NULL); } ImagingCopyPalette(imOut, imIn); @@ -801,7 +801,7 @@ ImagingGenericTransform( double xx, yy; if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(); + ImagingError_ModeError(NULL); return -1; } @@ -860,7 +860,7 @@ ImagingScaleAffine( int *xintab; if (!imOut || !imIn || imIn->mode != imOut->mode) { - ImagingError_ModeError(); + ImagingError_ModeError(NULL); return -1; } @@ -1051,7 +1051,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 6f37f32608a..77cf7854e57 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"); @@ -112,7 +112,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); for (int y = 0; y < ysize; y++) { diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index 3e43059fe01..da07f79d549 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -268,9 +268,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 b2dacf656b5..a4a5a64b27d 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 0396cf58095..3c045ab9c7f 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 a6d39407c8d..050b5af6b5e 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1276,7 +1276,7 @@ ImagingQuantize(Imaging im, int colors, int mode, 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,12 +1286,12 @@ ImagingQuantize(Imaging im, int colors, int mode, 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 && mode != 2 && mode != 3) { - 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 fee4cf8d9dc..4d88e29f919 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -758,7 +758,7 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) { 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) { @@ -779,7 +779,7 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) { 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 0d33c48ed53..7ae971b82e3 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -746,7 +746,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 */ From 296a2c5d6eeaaf29415befdfe6e8c8dd96851126 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 | 8 ++- 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 | 98 ++++++++++++++++++++++++--------- 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, 198 insertions(+), 93 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 f4e2b341687..acd6b184415 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -1134,7 +1134,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 f596f009025..f72af583ade 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") @@ -318,7 +318,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 bb53a7cda68..e41d91e58d1 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 1b04cc47508..dd8f77265f7 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -2126,7 +2126,7 @@ im_setalpha(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 f15236e438b..32ea8a70587 100644 --- a/src/display.c +++ b/src/display.c @@ -135,7 +135,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("box must match image size"); } if (xy[0] < 0) { PyErr_SetString(PyExc_ValueError, "left box co-ordinate cannot be negative"); @@ -148,7 +148,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("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 7fa1e0f9dc0..dbbbcda7d77 100644 --- a/src/libImaging/BoxBlur.c +++ b/src/libImaging/BoxBlur.c @@ -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(NULL); + return ImagingError_Mismatch("images must have the same mode and size"); } if (imIn->type != IMAGING_TYPE_UINT8) { - return ImagingError_ModeError(NULL); + return ImagingError_NotSupportedError("only 8-bit images 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(NULL); + return ImagingError_NotSupportedError( + "only modes RGB/RGBA/RGBa/RGBX/CMYK/L/LA/La supported" + ); } /* Apply blur in one dimension. diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index ce6f70bd44c..df883237d9d 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 d5f546f0548..6e08c739f0f 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1604,7 +1604,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 6c8880fb7b8..a2136a4ff7e 100644 --- a/src/libImaging/Fill.c +++ b/src/libImaging/Fill.c @@ -81,7 +81,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); @@ -120,7 +122,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 36ce89a9e42..4b5af040bc0 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -500,7 +500,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 a2aba803060..453f285f1a5 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -19,13 +19,16 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn) { ImagingSectionCookie cookie; int x, y, xr; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->xsize || ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch("images must have the same size"); } ImagingCopyPalette(imOut, imIn); @@ -64,13 +67,16 @@ ImagingFlipTopBottom(Imaging imOut, Imaging imIn) { ImagingSectionCookie cookie; int y, yr; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int ysize = imIn->ysize; if (imIn->xsize != imOut->xsize || ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch("images must have the same size"); } ImagingCopyPalette(imOut, imIn); @@ -93,13 +99,18 @@ ImagingRotate90(Imaging imOut, Imaging imIn) { int x, y, xx, yy, xr, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch( + "output size must be the transpose of the input size" + ); } ImagingCopyPalette(imOut, imIn); @@ -155,13 +166,18 @@ ImagingTranspose(Imaging imOut, Imaging imIn) { int x, y, xx, yy, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch( + "output size must be the transpose of the input size" + ); } ImagingCopyPalette(imOut, imIn); @@ -216,13 +232,18 @@ ImagingTransverse(Imaging imOut, Imaging imIn) { int x, y, xr, yr, xx, yy, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch( + "output size must be the transpose of the input size" + ); } ImagingCopyPalette(imOut, imIn); @@ -278,13 +299,16 @@ ImagingRotate180(Imaging imOut, Imaging imIn) { ImagingSectionCookie cookie; int x, y, xr, yr; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->xsize || ysize != imOut->ysize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch("images must have the same size"); } ImagingCopyPalette(imOut, imIn); @@ -325,13 +349,18 @@ ImagingRotate270(Imaging imOut, Imaging imIn) { int x, y, xx, yy, yr, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || imIn->mode != imOut->mode) { - return (Imaging)ImagingError_ModeError(NULL); + if (!imOut || !imIn) { + return (Imaging)ImagingError_ValueError(NULL); + } + if (imIn->mode != imOut->mode) { + return (Imaging)ImagingError_ModeError("images must have the same mode"); } int xsize = imIn->xsize, ysize = imIn->ysize; if (xsize != imOut->ysize || ysize != imOut->xsize) { - return (Imaging)ImagingError_Mismatch(NULL); + return (Imaging)ImagingError_Mismatch( + "output size must be the transpose of the input size" + ); } ImagingCopyPalette(imOut, imIn); @@ -800,8 +829,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; } @@ -859,8 +893,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; } @@ -1050,8 +1089,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 77cf7854e57..8910284d486 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"); @@ -112,7 +112,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); for (int y = 0; y < ysize; y++) { 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 a4a5a64b27d..b13271e3806 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 3c045ab9c7f..67bedc760ec 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 050b5af6b5e..e89757f328d 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1286,12 +1286,13 @@ ImagingQuantize(Imaging im, int colors, int mode, 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 && mode != 2 && mode != 3) { - 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 4d88e29f919..a83d6a94baf 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -758,7 +758,7 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) { 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) { @@ -779,7 +779,9 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) { 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 7ae971b82e3..ee5770674d5 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -746,7 +746,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 5e17dea213eafd900329f695c733eb18106f5a8f 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 | 23 ++++++++++++++++++----- 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, 59 insertions(+), 31 deletions(-) diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index de809aa3185..195f9ef707b 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,11 +93,16 @@ 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 0; + } + /* Shortcuts */ if (imIn->bands == 1) { bands[0] = ImagingCopy(imIn); @@ -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"); @@ -257,6 +266,10 @@ ImagingFillBand(Imaging imOut, int band, int color) { 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"); } diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index 0e2acfd37a1..6a7ba6ecd07 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 (Imaging)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 df883237d9d..b649f1f04ac 100644 --- a/src/libImaging/Chops.c +++ b/src/libImaging/Chops.c @@ -68,14 +68,21 @@ 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 || - (mode != IMAGING_MODE_UNKNOWN && - (im1->mode != IMAGING_MODE_1 || im2->mode != IMAGING_MODE_1))) { - return (Imaging)ImagingError_ModeError(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 6e08c739f0f..10e4707d91f 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1598,7 +1598,7 @@ ImagingConvert( ImagingShuffler convert; if (!imIn) { - return (Imaging)ImagingError_ModeError(NULL); + return (Imaging)ImagingError_ValueError(NULL); } if (mode == IMAGING_MODE_UNKNOWN) { @@ -1673,7 +1673,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 8910284d486..b244800adc1 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 67bedc760ec..89af6ce09be 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 e89757f328d..c9cd53382ce 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1276,7 +1276,7 @@ ImagingQuantize(Imaging im, int colors, int mode, 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)) {