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


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


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))

with pytest.raises(ValueError, match="left box co-ordinate cannot be negative"):
Expand Down
45 changes: 40 additions & 5 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,14 +361,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 @@ -2109,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_NotSupportedError("only modes RGB/RGBX supported");
}
im->mode = IMAGING_MODE_RGBA;
im->bands = 4;
Expand Down Expand Up @@ -4354,6 +4371,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,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");
Expand All @@ -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");
Expand Down
10 changes: 6 additions & 4 deletions src/libImaging/AlphaComposite.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
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("images must have the same mode and size");
}

imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize);
Expand Down
46 changes: 35 additions & 11 deletions src/libImaging/Bands.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,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 @@ -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_ModeError();
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);
Expand Down Expand Up @@ -199,8 +208,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 @@ -209,7 +221,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();
return (Imaging)ImagingError_Mismatch(
"images must have the same type and size"
);
}

/* Shortcuts */
Expand Down Expand Up @@ -248,8 +262,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 @@ -301,11 +323,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();
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("images must have the same size");
}
}

Expand Down
15 changes: 11 additions & 4 deletions src/libImaging/Blend.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +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();
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();
return ImagingError_Mismatch(
"images must have the same type, band count and size"
);
}

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

if (imIn->type != IMAGING_TYPE_UINT8) {
return ImagingError_ModeError();
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();
return ImagingError_NotSupportedError(
"only modes RGB/RGBA/RGBa/RGBX/CMYK/L/LA/La supported"
);
}

/* Apply blur in one dimension.
Expand Down
17 changes: 12 additions & 5 deletions src/libImaging/Chops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
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();
return (Imaging)ImagingError_Mismatch(
"images must have the same type and band count"
);
}

xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize;
Expand Down
19 changes: 13 additions & 6 deletions src/libImaging/ColorLUT.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
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();
return (Imaging)ImagingError_ModeError(
"output image has more bands than input image and table"
);
}

ImagingSectionEnter(&cookie);
Expand Down
Loading
Loading