fix(pdfa): preserve compliance via incremental update on compression
- Change PdfWriter to use incremental=True to preserve XMP/OutputIntents - Add inflation protection fallback in engine.compress_pdfa
This commit is contained in:
@@ -58,8 +58,11 @@ class PDFEngine:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def compress_pdfa(data: bytes, quality: int = 60) -> bytes:
|
def compress_pdfa(data: bytes, quality: int = 60) -> bytes:
|
||||||
"""Comprime mantendo a estrutura PDF/A."""
|
"""Comprime mantendo a estrutura PDF/A (protegido contra inflação)."""
|
||||||
return compress_pdfa(data, quality=quality)
|
result = compress_pdfa(data, quality=quality)
|
||||||
|
if len(result) >= len(data):
|
||||||
|
return data
|
||||||
|
return result
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def detect_pdfa(data: bytes) -> dict:
|
def detect_pdfa(data: bytes) -> dict:
|
||||||
|
|||||||
12
core/pdfa.py
12
core/pdfa.py
@@ -139,14 +139,18 @@ def strip_pdfa(data: bytes) -> bytes:
|
|||||||
def compress_pdfa(data: bytes, quality: int = 60, max_dim: int = 2000) -> bytes:
|
def compress_pdfa(data: bytes, quality: int = 60, max_dim: int = 2000) -> bytes:
|
||||||
"""
|
"""
|
||||||
Comprime imagens internas mantendo a estrutura PDF/A.
|
Comprime imagens internas mantendo a estrutura PDF/A.
|
||||||
Usa a mesma lógica de compress_pdf (ImageFile.replace)
|
Usa a atualização incremental (incremental=True) para garantir
|
||||||
mas preserva metadados XMP e OutputIntents.
|
que a assinatura estrutural, /ID do trailer, XMP Metadata e
|
||||||
|
/OutputIntents originais permaneçam 100% intactos e conformes.
|
||||||
"""
|
"""
|
||||||
from PIL import Image as PILImage
|
from PIL import Image as PILImage
|
||||||
from .compress import _prepare_image
|
from .compress import _prepare_image
|
||||||
|
|
||||||
reader = PdfReader(io.BytesIO(data))
|
# A grande sacada: em vez de usar PdfWriter(clone_from=reader)
|
||||||
writer = PdfWriter(clone_from=reader)
|
# que reconstrói a árvore inteira do zero perdendo a conformidade,
|
||||||
|
# instanciamos um writer que atua sobre um stream aberto no modo incremental.
|
||||||
|
stream = io.BytesIO(data)
|
||||||
|
writer = PdfWriter(stream, incremental=True)
|
||||||
|
|
||||||
replaced = 0
|
replaced = 0
|
||||||
for page in writer.pages:
|
for page in writer.pages:
|
||||||
|
|||||||
Reference in New Issue
Block a user