From 7219637ef59a8e0ae8c4f46ac7634b069571f1d0 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Sat, 29 Aug 2026 10:53:40 +0300 Subject: [PATCH 1/5] Deprecate JpegImageFile.load_djpeg --- docs/releasenotes/13.0.0.rst | 11 +++++++++-- src/PIL/JpegImagePlugin.py | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/releasenotes/13.0.0.rst b/docs/releasenotes/13.0.0.rst index 45667d9ec07..3ad4b2ef157 100644 --- a/docs/releasenotes/13.0.0.rst +++ b/docs/releasenotes/13.0.0.rst @@ -69,8 +69,15 @@ ImageCms.ImageCmsProfile.product_name and .product_info Deprecations ============ -TODO -^^^^ +JpegImageFile.load_djpeg +^^^^^^^^^^^^^^^^^^^^^^^^ + +``JpegImageFile.load_djpeg`` has been deprecated, +and will be removed in Pillow 14 (2027-10-15). + +Use the built-in JPEG decoder instead, or call ``djpeg`` directly and +decode the resulting PNM output with Pillow. + TODO diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index 5d4347818d4..3d89951319e 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -48,6 +48,7 @@ from ._binary import i32be as i32 from ._binary import o8 from ._binary import o16be as o16 +from ._deprecate import deprecate from .JpegPresets import presets TYPE_CHECKING = False @@ -467,6 +468,11 @@ def draft( def load_djpeg(self) -> None: # ALTERNATIVE: handle JPEGs via the IJG command line utilities + deprecate( + "load_djpeg", + 14, + action="Use the built-in JPEG decoder instead, or call djpeg yourself.", + ) f, path = tempfile.mkstemp() os.close(f) From 876f84bdf9ce54c1c095ce40397ad4ea0bdd7b30 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 29 Aug 2026 18:02:04 +1000 Subject: [PATCH 2/5] Catch DeprecationWarning --- Tests/test_file_jpeg.py | 3 ++- Tests/test_shell_injection.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 0e16d867a3b..07f136821fe 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -734,7 +734,8 @@ def test_restart_markers(self, blocks: int, rows: int, markers: int) -> None: def test_load_djpeg(self) -> None: with Image.open(TEST_FILE) as img: assert isinstance(img, JpegImagePlugin.JpegImageFile) - img.load_djpeg() + with pytest.warns(DeprecationWarning, match="load_djpeg"): + img.load_djpeg() assert_image_similar_tofile(img, TEST_FILE, 5) def test_no_duplicate_0x1001_tag(self) -> None: diff --git a/Tests/test_shell_injection.py b/Tests/test_shell_injection.py index a7e95ed83c8..bd7b2cecb0f 100644 --- a/Tests/test_shell_injection.py +++ b/Tests/test_shell_injection.py @@ -44,7 +44,8 @@ def test_load_djpeg_filename(self, tmp_path: Path) -> None: with Image.open(src_file) as im: assert isinstance(im, JpegImagePlugin.JpegImageFile) - im.load_djpeg() + with pytest.warns(DeprecationWarning, match="load_djpeg"): + im.load_djpeg() @pytest.mark.skipif(not netpbm_available(), reason="Netpbm not available") def test_save_netpbm_filename_bmp_mode(self, tmp_path: Path) -> None: From de3862a35f4f471dbb700af6cf418ea51a2321db Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Mon, 31 Aug 2026 14:59:24 +0300 Subject: [PATCH 3/5] Remove TODO Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- docs/releasenotes/13.0.0.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/releasenotes/13.0.0.rst b/docs/releasenotes/13.0.0.rst index 3ad4b2ef157..2b5aa446fe4 100644 --- a/docs/releasenotes/13.0.0.rst +++ b/docs/releasenotes/13.0.0.rst @@ -79,8 +79,6 @@ Use the built-in JPEG decoder instead, or call ``djpeg`` directly and decode the resulting PNM output with Pillow. -TODO - API changes =========== From 3f73add06b5c232f79a2b0d3bfd7818afef1ae33 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Mon, 31 Aug 2026 14:59:52 +0300 Subject: [PATCH 4/5] Note djpeg outputs more than just PNMs Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- docs/releasenotes/13.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/releasenotes/13.0.0.rst b/docs/releasenotes/13.0.0.rst index 2b5aa446fe4..1b25cdee64b 100644 --- a/docs/releasenotes/13.0.0.rst +++ b/docs/releasenotes/13.0.0.rst @@ -76,7 +76,7 @@ JpegImageFile.load_djpeg and will be removed in Pillow 14 (2027-10-15). Use the built-in JPEG decoder instead, or call ``djpeg`` directly and -decode the resulting PNM output with Pillow. +decode the resulting image with Pillow. API changes From 371e2531f090ed4bc16973da0a5ff1800126abea Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 31 Aug 2026 22:37:38 +1000 Subject: [PATCH 5/5] Add to list of deprecations --- docs/deprecations.rst | 12 ++++++++++++ docs/releasenotes/13.0.0.rst | 9 ++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/deprecations.rst b/docs/deprecations.rst index 70745104483..6ee46a0a76a 100644 --- a/docs/deprecations.rst +++ b/docs/deprecations.rst @@ -30,6 +30,18 @@ Image getdata() identical, except that it returns a tuple of pixel values, instead of an internal Pillow data type. + +JpegImageFile.load_djpeg +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. deprecated:: 13.0.0 + +``JpegImageFile.load_djpeg`` has been deprecated, and will be removed in Pillow 14 +(2027-10-15). + +Use the built-in JPEG decoder instead, or call ``djpeg`` directly and decode the +resulting image with Pillow. + Removed features ---------------- diff --git a/docs/releasenotes/13.0.0.rst b/docs/releasenotes/13.0.0.rst index 1b25cdee64b..a04828a87ea 100644 --- a/docs/releasenotes/13.0.0.rst +++ b/docs/releasenotes/13.0.0.rst @@ -72,12 +72,11 @@ Deprecations JpegImageFile.load_djpeg ^^^^^^^^^^^^^^^^^^^^^^^^ -``JpegImageFile.load_djpeg`` has been deprecated, -and will be removed in Pillow 14 (2027-10-15). - -Use the built-in JPEG decoder instead, or call ``djpeg`` directly and -decode the resulting image with Pillow. +``JpegImageFile.load_djpeg`` has been deprecated, and will be removed in Pillow 14 +(2027-10-15). +Use the built-in JPEG decoder instead, or call ``djpeg`` directly and decode the +resulting image with Pillow. API changes ===========