Implement functional, single threaded optimize

Passes verapdf
This commit is contained in:
James R. Barlow
2018-04-06 15:49:16 -07:00
parent 709c01c7a1
commit 1d25823746
+83 -67
View File
@@ -803,72 +803,6 @@ def combine_layers(
pdf_output.write(out)
def jbig2_10to1(
infiles,
output_file,
log,
context):
import fitz
import pikepdf
options = context.get_options()
infiles = list(flatten_groups(infiles))
# pdf = pikepdf.Pdf.new()
# for infile in infiles:
# subdoc = pikepdf.Pdf.open(infile)
# pdf.pages.extend(subdoc.pages)
doc = fitz.open()
for infile in infiles:
subdoc = fitz.open(infile)
doc.insertPDF(subdoc)
root = Path(output_file).parent / Path(output_file).stem
root.mkdir()
changed_xrefs = []
for pageno in range(len(infiles)):
images = doc.getPageImageList(pageno)
for image in images:
xref, smask, w, h, bpc, cs, alt_cs, name, filt = image
if bpc != 1:
continue
pix = fitz.Pixmap(doc, xref)
pix.writePNG(str(root / '{:08d}.png'.format(xref)), savealpha=False)
changed_xrefs.append(xref)
doc.save(output_file + '_tmp.pdf')
from subprocess import run, PIPE
args = ['jbig2', '-s', '-p', '-v', '-S']
args.extend(root.glob('*.png'))
proc = run(args, cwd=str(root), stdout=PIPE, stderr=PIPE)
proc.check_returncode()
log.debug(proc.stderr)
pike = pikepdf.Pdf.open(output_file + '_tmp.pdf')
jbig2_globals_data = (root / 'output.sym').read_bytes()
jbig2_globals = pikepdf.Stream(pike, jbig2_globals_data)
jbig2_globals_indirect = pike.make_indirect(jbig2_globals)
for n, xref in enumerate(changed_xrefs):
jbig2_im_file = root / 'output.{:04d}'.format(n)
jbig2_im_data = jbig2_im_file.read_bytes()
im_obj = pike._get_object_id(xref, 0)
log.info(xref)
log.info(repr(im_obj))
im_obj.write(
jbig2_im_data, pikepdf.Name('/JBIG2Decode'),
pikepdf.Dictionary({
'/JBIG2Globals': pike.make_indirect(jbig2_globals_indirect)
})
)
log.info(repr(im_obj))
pike.save(output_file, preserve_pdfa=True)
def ocr_tesseract_and_render_pdf(
infiles,
outfiles,
@@ -1115,6 +1049,79 @@ def _do_merge_mupdf(
doc.save(output_file, garbage=4, deflate=True)
def optimize_pdf(
input_file,
output_file,
log,
context):
import fitz
import pikepdf
doc = fitz.open(input_file)
root = Path(output_file).parent / 'images'
root.mkdir()
def make_img_name(xref):
return str(root / '{:08d}.png'.format(xref))
# Write all images out
PAGE_GROUP_SIZE = 20
changed_xrefs = set()
from collections import defaultdict
image_groups = defaultdict(lambda: [])
for pageno in range(doc.pageCount):
group, index = divmod(pageno, PAGE_GROUP_SIZE)
page_images = doc.getPageImageList(pageno)
for image in page_images:
xref, smask, w, h, bpc, cs, alt_cs, name, filt = image
if xref in changed_xrefs:
continue
if bpc != 1:
continue
pix = fitz.Pixmap(doc, xref)
pix.writePNG(make_img_name(xref), savealpha=False)
changed_xrefs.add(xref)
image_groups[group].append(xref)
from subprocess import run, PIPE
for imgrp, xrefs in image_groups.items():
prefix = 'group{:08d}'.format(imgrp)
args = ['jbig2', '-b', prefix, '-s', '-p', '-S']
for xref in xrefs:
args.append(make_img_name(xref))
proc = run(args, cwd=str(root), stdout=PIPE, stderr=PIPE)
proc.check_returncode()
log.debug(proc.stderr)
pike = pikepdf.Pdf.open(input_file)
for imgrp, xrefs in image_groups.items():
prefix = 'group{:08d}'.format(imgrp)
jbig2_globals_data = (root / (prefix + '.sym')).read_bytes()
jbig2_globals = pikepdf.Stream(pike, jbig2_globals_data)
jbig2_globals_indirect = pike.make_indirect(jbig2_globals)
for n, xref in enumerate(xrefs):
jbig2_im_file = root / (prefix + '.{:04d}'.format(n))
jbig2_im_data = jbig2_im_file.read_bytes()
im_obj = pike._get_object_id(xref, 0)
log.info(xref)
log.info(repr(im_obj))
im_obj.write(
jbig2_im_data, pikepdf.Name('/JBIG2Decode'),
pikepdf.Dictionary({
'/JBIG2Globals': pike.make_indirect(jbig2_globals_indirect)
})
)
log.info(repr(im_obj))
pike.save(output_file, preserve_pdfa=True)
def merge_sidecars(
input_files_groups,
output_file,
@@ -1408,9 +1415,18 @@ def build_pipeline(options, work_folder, log, context):
extras=[log, context])
task_merge_sidecars.active_if(options.sidecar)
# Optimize
task_optimize_pdf = main_pipeline.transform(
task_func=optimize_pdf,
input=task_merge_pages,
filter=suffix('.pdf'),
output='.optimized.pdf',
output_dir=work_folder,
extras=[log, context])
# Finalize
main_pipeline.merge(
task_func=copy_final,
input=[task_merge_pages],
input=[task_optimize_pdf, task_merge_pages],
output=options.output_file,
extras=[log, context])