From 7bfe3ecd5bdeb9a2b47e9481f5861cf82628f83f Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Tue, 13 Jan 2026 01:41:59 -0800 Subject: [PATCH] Fix double-compression of already-deflated JPEGs Images with [FlateDecode, DCTDecode] filter chain were incorrectly being marked for additional FlateDecode compression, resulting in double-compressed data and invalid output PDFs. Add _already_flate_encoded() helper to check if an image already has FlateDecode in its filter chain, and skip such images in _find_deflatable_jpeg(). --- src/ocrmypdf/optimize.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ocrmypdf/optimize.py b/src/ocrmypdf/optimize.py index e5a543e4..63c74427 100644 --- a/src/ocrmypdf/optimize.py +++ b/src/ocrmypdf/optimize.py @@ -18,6 +18,7 @@ from zlib import compress import img2pdf from packaging.version import Version from pikepdf import ( + Array, Dictionary, Name, Object, @@ -480,6 +481,16 @@ def transcode_jpegs( ) +def _already_flate_encoded(image: Stream) -> bool: + """Check if the image already has FlateDecode in its filter chain.""" + filt = image.get(Name.Filter) + if filt is None: + return False + if isinstance(filt, Array): + return Name.FlateDecode in list(filt) + return filt == Name.FlateDecode + + def _find_deflatable_jpeg( *, pdf: Pdf, root: Path, image: Stream, xref: Xref, options ) -> XrefExt | None: @@ -488,6 +499,10 @@ def _find_deflatable_jpeg( return None _pim, filtdp = result + # Skip if already FlateDecode compressed - would double-compress + if _already_flate_encoded(image): + return None + if ( filtdp[0] == Name.DCTDecode and not filtdp[1]