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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Tests/test_color_lut.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions Tests/test_image_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")


Expand Down Expand Up @@ -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)


Expand Down
4 changes: 3 additions & 1 deletion Tests/test_image_paste.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ def test_overflow(self, box: tuple[int, int, int, int]) -> None:
im = Image.new("1", (1, 1))
im.paste(1, box)

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

def test_incorrect_abbreviated_form(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_image_putalpha.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()


Expand Down
2 changes: 1 addition & 1 deletion Tests/test_imagewin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))

def test_dib_frombytes_tobytes_roundtrip(self) -> None:
Expand Down
45 changes: 40 additions & 5 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,14 +371,31 @@ ImagingError_MemoryError(void) {
}

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

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

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

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

Expand Down Expand Up @@ -2077,7 +2094,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;
Expand Down Expand Up @@ -4319,6 +4336,24 @@ setup_module(PyObject *m) {
return -1;
}

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

#ifdef HAVE_LIBJPEG
{
extern const char *ImagingJpegVersion(void);
Expand Down
4 changes: 2 additions & 2 deletions src/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,12 @@ _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[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");
}

ImagingPasteDIB(display->dib, im, xy);
Expand Down
10 changes: 6 additions & 4 deletions src/libImaging/AlphaComposite.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) {
Imaging imOut;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Check arguments */
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
if (!imIn1 || !imIn2) {
return (Imaging)ImagingError_ValueError(NULL);
}
if (imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
imIn1->mode == IMAGING_MODE_1 || imIn2->palette ||
imIn2->mode == IMAGING_MODE_1) {
return ImagingError_ModeError();
return ImagingError_ModeError(
"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();
return ImagingError_Mismatch("image types, band count and sizes must match");
}

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

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

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

/* Apply blur in one dimension.
Expand Down
15 changes: 10 additions & 5 deletions src/libImaging/Chops.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,19 @@
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();
if (im1->type != IMAGING_TYPE_UINT8) {
return (Imaging)ImagingError_ModeError("images must have 8-bit data");
}
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();
return (Imaging)ImagingError_Mismatch("image types and band count must match");
}

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

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

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

ImagingSectionEnter(&cookie);
Expand Down
6 changes: 3 additions & 3 deletions src/libImaging/Convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1608,13 +1608,13 @@ ImagingConvert(
ImagingShuffler convert;

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

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

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

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

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

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

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

const int pixelsize = mode == IMAGING_MODE_RGB ? 3 : 1;
Expand Down
Loading
Loading