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:
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user