Experimental add jbig2

It appears that fitz forces conversion of jbig2 to ccitt no matter what,
so pikepdf will be needed to patch jbig2 images.
This commit is contained in:
James R. Barlow
2018-04-03 00:00:53 -07:00
parent 1b01d45dd2
commit a95ffcdc46
2 changed files with 103 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
# © 2018 James R. Barlow: github.com/jbarlow83
#
# This file is part of OCRmyPDF.
#
# OCRmyPDF is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OCRmyPDF is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see <http://www.gnu.org/licenses/>.
from subprocess import CalledProcessError, run
from tempfile import TemporaryFile
import sys
import os
import shutil
from ..exceptions import ExitCode
def convert(input_file, output_file):
args_jbig2 = [
'jbig2',
'-s',
input_file
]
with TemporaryFile(mode='w+b') as tmp:
proc = run(args_jbig2, stdout=tmp)
if proc.returncode == 0:
with open(output_file, 'wb') as output:
shutil.copyfileobj(tmp, output)
+64
View File
@@ -803,6 +803,60 @@ def combine_layers(
pdf_output.write(out)
def jbig2_10to1(
infiles,
output_file,
log,
context):
assert fitz
options = context.get_options()
infiles = list(flatten_groups(infiles))
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')
doc = fitz.open(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)
jbig2_globals_xref = doc._getNewXref()
log.info(jbig2_globals_xref)
doc._updateStream(xref, (root / 'output.sym').read_bytes())
for n, xref in enumerate(changed_xrefs):
jbig2_im_file = root / 'output.{:04d}'.format(n)
obj_str = doc._getObjectString(xref)
log.info(xref)
log.info(obj_str)
obj_str = obj_str.replace('/Filter/FlateDecode', '/Filter/JBIG2Decode')
obj_str = obj_str.replace(
'>>', '/DecodeParms << /JBIG2Globals {} 0 R >> >>'.format(jbig2_globals_xref))
doc._updateObject(xref, obj_str)
doc._updateStream(xref, jbig2_im_file.read_bytes())
doc.save(output_file, garbage=0, deflate=0, clean=0, expand=0)
def ocr_tesseract_and_render_pdf(
infiles,
outfiles,
@@ -1280,6 +1334,16 @@ def build_pipeline(options, work_folder, log, context):
task_combine_layers.active_if(options.pdf_renderer == 'hocr' or
options.pdf_renderer == 'sandwich')
task_jbig2_10to1 = main_pipeline.collate(
task_func=jbig2_10to1,
input=[combine_layers],
filter=regex(r".*/(\d{5})(\d)(?:\.rendered\.pdf)"),
output=os.path.join(work_folder, r'\1x.opt.pdf'),
extras=[log, context])
task_jbig2_10to1.graphviz(fillcolor='"#00cc66"')
task_jbig2_10to1.active_if(fitz and (options.pdf_renderer == 'hocr' or
options.pdf_renderer == 'sandwich'))
# Tesseract OCR+PDF
task_ocr_tesseract_and_render_pdf = main_pipeline.collate(
task_func=ocr_tesseract_and_render_pdf,