diff --git a/src/ocrmypdf/leptonica.py b/src/ocrmypdf/leptonica.py index bab7bb5f..3a8cefe1 100644 --- a/src/ocrmypdf/leptonica.py +++ b/src/ocrmypdf/leptonica.py @@ -27,6 +27,7 @@ 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 @@ -517,6 +518,13 @@ 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) + @staticmethod def _destroy(compdata): pp = ffi.new('L_COMP_DATA **', compdata) diff --git a/src/ocrmypdf/pipeline.py b/src/ocrmypdf/pipeline.py index f53457ce..2240b945 100644 --- a/src/ocrmypdf/pipeline.py +++ b/src/ocrmypdf/pipeline.py @@ -1171,15 +1171,33 @@ def optimize_pdf( if compdata.predictor > 0: predictor = pikepdf.Dictionary({'/Predictor': compdata.predictor}) - im_obj.write( - compdata.read(), pikepdf.Name('/FlateDecode'), predictor - ) + im_obj.BitsPerComponent = compdata.bps + im_obj.Width = compdata.w + im_obj.Height = compdata.h + + if compdata.ncolors > 0: + palette_stream = pikepdf.Stream(pike, compdata.get_palette()) + palette = [pikepdf.Name('/Indexed'), pikepdf.Name('/DeviceRGB'), + compdata.ncolors - 1, palette_stream] + #cs = pike.make_indirect(palette) + cs = palette + else: + if compdata.spp == 1: + cs = pikepdf.Name('/DeviceGray') + elif compdata.spp == 3: + cs = pikepdf.Name('/DeviceRGB') + elif compdata.spp == 4: + cs = pikepdf.Name('/DeviceCMYK') + im_obj.ColorSpace = cs + + im_obj.write(compdata.read(), pikepdf.Name('/FlateDecode'), predictor) + pike.save(output_file, preserve_pdfa=True) input_size = Path(input_file).stat().st_size output_size = Path(output_file).stat().st_size - improvement = 100.0 * ((input_size/output_size) - 1) + improvement = input_size / output_size log.info("Optimize reduced size by {:.1f}".format(improvement))