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().
This commit is contained in:
James R. Barlow
2026-01-13 01:41:59 -08:00
parent 5371cc5e39
commit 7bfe3ecd5b
+15
View File
@@ -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]