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.
This commit is contained in:
James R. Barlow
2018-04-16 12:16:13 -07:00
parent 0e6b8042b0
commit d291d48991
2 changed files with 12 additions and 12 deletions
+5 -7
View File
@@ -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):
+7 -5
View File
@@ -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(