From 34b1799dd4f6b71ee702d41173eccf4ccf65102d Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 7 Jun 2026 13:39:25 +1000 Subject: [PATCH] Use Python PPM save, instead of C --- Tests/test_image.py | 5 ++- setup.py | 1 - src/PIL/Image.py | 21 ++++-------- src/_imaging.c | 30 +++-------------- src/libImaging/File.c | 77 ------------------------------------------- 5 files changed, 15 insertions(+), 119 deletions(-) delete mode 100644 src/libImaging/File.c diff --git a/Tests/test_image.py b/Tests/test_image.py index 81bd4729926..cc6e4d137ca 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -270,8 +270,11 @@ def test_dump(self, tmp_path: Path) -> None: im = Image.new("RGB", (10, 10)) im._dump(str(tmp_path / "temp_RGB.ppm")) + im = Image.new("RGBA", (10, 10)) + im._dump(str(tmp_path / "temp_RGBA.ppm")) + im = Image.new("HSV", (10, 10)) - with pytest.raises(ValueError): + with pytest.raises(OSError): im._dump(str(tmp_path / "temp_HSV.ppm")) def test_comparison_with_other_type(self) -> None: diff --git a/setup.py b/setup.py index 6a6bffab6f9..b67d4534a39 100644 --- a/setup.py +++ b/setup.py @@ -94,7 +94,6 @@ def get_version() -> str: "Draw", "Effects", "EpsEncode", - "File", "Fill", "Filter", "FliDecode", diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 81add2f7a41..a63959bc589 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -731,24 +731,17 @@ def _ensure_mutable(self) -> None: def _dump( self, file: str | None = None, format: str | None = None, **options: Any ) -> str: - suffix = "" - if format: - suffix = f".{format}" + suffix = f".{format}" if format else "" - if not file: - f, filename = tempfile.mkstemp(suffix) - os.close(f) - else: + if file: filename = file if not filename.endswith(suffix): - filename = filename + suffix - - self.load() - - if not format or format == "PPM": - self.im.save_ppm(filename) + filename += suffix else: - self.save(filename, format, **options) + f, filename = tempfile.mkstemp(suffix) + os.close(f) + + self.save(filename, format or "PPM", **options) return filename diff --git a/src/_imaging.c b/src/_imaging.c index 7fee411149c..2158574fd93 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -108,7 +108,7 @@ #define S16(v) ((v) < 32768 ? (v) : ((v) - 65536)) /* -------------------------------------------------------------------- */ -/* OBJECT ADMINISTRATION */ +/* OBJECT ADMINISTRATION */ /* -------------------------------------------------------------------- */ typedef struct { @@ -379,7 +379,7 @@ ImagingError_ValueError(const char *message) { } /* -------------------------------------------------------------------- */ -/* HELPERS */ +/* HELPERS */ /* -------------------------------------------------------------------- */ static int @@ -683,7 +683,7 @@ getink(PyObject *color, Imaging im, char *ink) { } /* -------------------------------------------------------------------- */ -/* FACTORIES */ +/* FACTORIES */ /* -------------------------------------------------------------------- */ static PyObject * @@ -3611,7 +3611,7 @@ _effect_spread(ImagingObject *self, PyObject *args) { } /* -------------------------------------------------------------------- */ -/* UTILITIES */ +/* UTILITIES */ /* -------------------------------------------------------------------- */ static PyObject * @@ -3646,25 +3646,6 @@ _getcodecstatus(PyObject *self, PyObject *args) { return PyUnicode_FromString(msg); } -/* -------------------------------------------------------------------- */ -/* DEBUGGING HELPERS */ -/* -------------------------------------------------------------------- */ - -static PyObject * -_save_ppm(ImagingObject *self, PyObject *args) { - char *filename; - - if (!PyArg_ParseTuple(args, "s", &filename)) { - return NULL; - } - - if (!ImagingSavePPM(self->image, filename)) { - return NULL; - } - - Py_RETURN_NONE; -} - /* -------------------------------------------------------------------- */ /* methods */ @@ -3748,9 +3729,6 @@ static struct PyMethodDef methods[] = { /* Special effects */ {"effect_spread", (PyCFunction)_effect_spread, METH_VARARGS}, - /* Misc. */ - {"save_ppm", (PyCFunction)_save_ppm, METH_VARARGS}, - /* arrow */ {"__arrow_c_schema__", (PyCFunction)ExportArrowSchemaPyCapsule, METH_VARARGS}, {"__arrow_c_array__", (PyCFunction)ExportArrowArrayPyCapsule, METH_VARARGS}, diff --git a/src/libImaging/File.c b/src/libImaging/File.c deleted file mode 100644 index 435dbeca0d4..00000000000 --- a/src/libImaging/File.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * built-in image file handling - * - * history: - * 1995-11-26 fl Created, supports PGM/PPM - * 1996-08-07 fl Write "1" images as PGM - * 1999-02-21 fl Don't write non-standard modes - * - * Copyright (c) 1997-99 by Secret Labs AB. - * Copyright (c) 1995-96 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -#include - -int -ImagingSaveRaw(Imaging im, FILE *fp) { - int x, y, i; - - if (im->mode == IMAGING_MODE_1 || im->mode == IMAGING_MODE_L) { - /* @PIL227: FIXME: for mode "1", map != 0 to 255 */ - - /* PGM "L" */ - for (y = 0; y < im->ysize; y++) { - fwrite(im->image[y], 1, im->xsize, fp); - } - } else { - /* PPM "RGB" or other internal format */ - for (y = 0; y < im->ysize; y++) { - for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) { - fwrite(im->image[y] + i, 1, im->bands, fp); - } - } - } - - return 1; -} - -int -ImagingSavePPM(Imaging im, const char *outfile) { - FILE *fp; - - if (!im) { - (void)ImagingError_ValueError(NULL); - return 0; - } - - fp = fopen(outfile, "wb"); - if (!fp) { - PyErr_SetString(PyExc_OSError, "error when accessing file"); - return 0; - } - - if (im->mode == IMAGING_MODE_1 || im->mode == IMAGING_MODE_L) { - /* Write "PGM" */ - fprintf(fp, "P5\n%d %d\n255\n", im->xsize, im->ysize); - } else if (im->mode == IMAGING_MODE_RGB) { - /* Write "PPM" */ - fprintf(fp, "P6\n%d %d\n255\n", im->xsize, im->ysize); - } else { - fclose(fp); - (void)ImagingError_ModeError(); - return 0; - } - - ImagingSaveRaw(im, fp); - - fclose(fp); - - return 1; -}