From d291d4899154ffb710962125e750c576db46aa5d Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Mon, 16 Apr 2018 12:15:19 -0700 Subject: [PATCH] PNG palette: parse PDF string from leptonica instead Seems better to accept whatever leptonica rather than make detailed assumptions about how it encodes the palette. Experimented with setting FlateDecode on the palette but it seems to expand it. --- src/ocrmypdf/leptonica.py | 12 +++++------- src/ocrmypdf/pipeline.py | 12 +++++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ocrmypdf/leptonica.py b/src/ocrmypdf/leptonica.py index 3a8cefe1..d9a48262 100644 --- a/src/ocrmypdf/leptonica.py +++ b/src/ocrmypdf/leptonica.py @@ -27,7 +27,6 @@ import logging import warnings from tempfile import TemporaryFile from ctypes.util import find_library -from binascii import unhexlify from .lib._leptonica import ffi from functools import lru_cache from enum import Enum @@ -518,12 +517,11 @@ class CompressedData: return getattr(self._compdata, name) raise AttributeError(name) - def get_palette(self): - buf = ffi.buffer(self._compdata.cmapdatahex, - self._compdata.ncolors * 7 + 3) - hex_str = bytes(buf).decode('ascii') - hex_str = hex_str[1:-1].replace(' ', '') - return unhexlify(hex_str) + def get_palette_pdf_string(self): + "Returns palette pre-formatted for use in PDF" + buflen = len('< ') + len(' rrggbb') * self._compdata.ncolors + len('>') + buf = ffi.buffer(self._compdata.cmapdatahex, buflen) + return bytes(buf) @staticmethod def _destroy(compdata): diff --git a/src/ocrmypdf/pipeline.py b/src/ocrmypdf/pipeline.py index 2240b945..04bdfd6f 100644 --- a/src/ocrmypdf/pipeline.py +++ b/src/ocrmypdf/pipeline.py @@ -1176,10 +1176,12 @@ def optimize_pdf( im_obj.Height = compdata.h if compdata.ncolors > 0: - palette_stream = pikepdf.Stream(pike, compdata.get_palette()) + palette_pdf_string = compdata.get_palette_pdf_string() + log.info(palette_pdf_string) + palette_data = pikepdf.Object.parse(palette_pdf_string) + palette_stream = pikepdf.Stream(pike, bytes(palette_data)) palette = [pikepdf.Name('/Indexed'), pikepdf.Name('/DeviceRGB'), compdata.ncolors - 1, palette_stream] - #cs = pike.make_indirect(palette) cs = palette else: if compdata.spp == 1: @@ -1192,13 +1194,13 @@ def optimize_pdf( im_obj.write(compdata.read(), pikepdf.Name('/FlateDecode'), predictor) - - + # Not object_stream_mode + preserve_pdfa generates noncompliant PDFs pike.save(output_file, preserve_pdfa=True) + input_size = Path(input_file).stat().st_size output_size = Path(output_file).stat().st_size improvement = input_size / output_size - log.info("Optimize reduced size by {:.1f}".format(improvement)) + log.info("Optimize reduced size by {:.3f}".format(improvement)) def merge_sidecars(