Merge optimize
This commit is contained in:
+68
-14
@@ -27,8 +27,8 @@ If you want to adjust the amount of time spent on OCR, change ``--tesseract-time
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Allow 300 seconds for OCR; skip any page larger than 50 megapixels
|
||||
ocrmypdf --tesseract-timeout 300 --skip-big 50 bigfile.pdf output.pdf
|
||||
# Allow 300 seconds for OCR; skip any page larger than 50 megapixels
|
||||
ocrmypdf --tesseract-timeout 300 --skip-big 50 bigfile.pdf output.pdf
|
||||
|
||||
Overriding default tesseract
|
||||
""""""""""""""""""""""""""""
|
||||
@@ -39,20 +39,20 @@ Some relevant environment variables that influence Tesseract's behavior include:
|
||||
|
||||
.. envvar:: TESSDATA_PREFIX
|
||||
|
||||
Overrides the path to Tesseract's data files. This can allow simultaneous installation of the "best" and "fast" training data sets. OCRmyPDF does not manage this environment variable.
|
||||
Overrides the path to Tesseract's data files. This can allow simultaneous installation of the "best" and "fast" training data sets. OCRmyPDF does not manage this environment variable.
|
||||
|
||||
.. envvar:: OMP_THREAD_LIMIT
|
||||
|
||||
Controls the number of threads Tesseract will use. OCRmyPDF will manage this environment if it is not already set. (Currently, it will set it to 1 because this gives the best results in testing.)
|
||||
Controls the number of threads Tesseract will use. OCRmyPDF will manage this environment if it is not already set. (Currently, it will set it to 1 because this gives the best results in testing.)
|
||||
|
||||
For example, if you are testing tesseract 4.00 and don't wish to use an existing tesseract 3.04 installation, you can launch OCRmyPDF as follows:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
env \
|
||||
PATH=/home/user/src/tesseract4/api:$PATH \
|
||||
TESSDATA_PREFIX=/home/user/src/tesseract4 \
|
||||
ocrmypdf --tesseract-oem 2 input.pdf output.pdf
|
||||
env \
|
||||
PATH=/home/user/src/tesseract4/api:$PATH \
|
||||
TESSDATA_PREFIX=/home/user/src/tesseract4 \
|
||||
ocrmypdf --tesseract-oem 2 input.pdf output.pdf
|
||||
|
||||
In this example ``TESSDATA_PREFIX`` directs Tesseract 4.0 to use LSTM training data. ``--tesseract-oem 1`` requests tesseract 4.0's new LSTM engine. (Tesseract 4.0 only.)
|
||||
|
||||
@@ -80,19 +80,19 @@ Create a file named "no-dict.cfg" with these contents:
|
||||
|
||||
::
|
||||
|
||||
load_system_dawg 0
|
||||
language_model_penalty_non_dict_word 0
|
||||
language_model_penalty_non_freq_dict_word 0
|
||||
load_system_dawg 0
|
||||
language_model_penalty_non_dict_word 0
|
||||
language_model_penalty_non_freq_dict_word 0
|
||||
|
||||
then run ocrmypdf as follows (along with any other desired arguments):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ocrmypdf --tesseract-config no-dict.cfg input.pdf output.pdf
|
||||
ocrmypdf --tesseract-config no-dict.cfg input.pdf output.pdf
|
||||
|
||||
.. warning::
|
||||
|
||||
Some combinations of control parameters will break Tesseract or break assumptions that OCRmyPDF makes about Tesseract's output.
|
||||
Some combinations of control parameters will break Tesseract or break assumptions that OCRmyPDF makes about Tesseract's output.
|
||||
|
||||
|
||||
Changing the PDF renderer
|
||||
@@ -132,4 +132,58 @@ This works in all versions of Tesseract.
|
||||
The ``tesseract`` renderer
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
The ``tesseract`` renderer was removed. OCRmyPDF's new approach to text layer grafting makes it functionally equivalent to ``sandwich``.
|
||||
The ``tesseract`` renderer was removed. OCRmyPDF's new approach to text layer grafting makes it functionally equivalent to ``sandwich``.
|
||||
|
||||
Return code policy
|
||||
------------------
|
||||
|
||||
OCRmyPDF writes all messages to ``stderr``. ``stdout`` is reserved for piping
|
||||
output files. ``stdin`` is reserved for piping input files.
|
||||
|
||||
The return codes generated by the OCRmyPDF are considered part of the stable
|
||||
user interface.
|
||||
|
||||
.. list-table:: Return codes
|
||||
:widths: 5 35 60
|
||||
:header-rows: 1
|
||||
|
||||
* - Code
|
||||
- Name
|
||||
- Interpretation
|
||||
* - 0
|
||||
- ``ocrmypdf.exceptions.ExitCode.ok``
|
||||
- Everything worked as expected.
|
||||
* - 1
|
||||
- ``ocrmypdf.exceptions.ExitCode.bad_args``
|
||||
- Invalid arguments, exited with an error.
|
||||
* - 2
|
||||
- ``ocrmypdf.exceptions.ExitCode.input_file``
|
||||
- The input file does not seem to be a valid PDF.
|
||||
* - 3
|
||||
- ``ocrmypdf.exceptions.missing_dependency``
|
||||
- An external program required by OCRmyPDF is missing.
|
||||
* - 4
|
||||
- ``ocrmypdf.exceptions.invalid_output_pdf``
|
||||
- An output file was created, but it does not seem to be a valid PDF or
|
||||
PDF/A. The file will be available.
|
||||
* - 5
|
||||
- ``ocrmypdf.exceptions.file_access_error``
|
||||
- The user running OCRmyPDF does not have sufficient permissions to read the input file and write the output file.
|
||||
* - 6
|
||||
- ``ocrmypdf.exceptions.already_done_ocr``
|
||||
- The file already appears to contain text so it may not need OCR. See output message.
|
||||
* - 7
|
||||
- ``ocrmypdf.exceptions.child_process_error``
|
||||
- An error occurred in an external program (child process) and OCRmyPDF cannot continue.
|
||||
* - 8
|
||||
- ``ocrmypdf.exceptions.encrypted_pdf``
|
||||
- The input PDF is encrypted. OCRmyPDF does not read encrypted PDFs. Use another program such as ``qpdf`` to remove encryption.
|
||||
* - 9
|
||||
- ``ocrmypdf.exceptions.invalid_config``
|
||||
- A custom configuration file was forwarded to Tesseract using ``--tesseract-config``, and Tesseract rejected this file.
|
||||
* - 15
|
||||
- ``ocrmypdf.exceptions.other_error``
|
||||
- Some other error occurred.
|
||||
* - 130
|
||||
- ``ocrmypdf.exceptions.ctrl_c``
|
||||
- The program was interrupted by pressing Ctrl+C.
|
||||
|
||||
@@ -198,4 +198,3 @@ The `Image processing`_ features can improve OCR quality.
|
||||
Rotating pages and deskewing helps to ensure that the page orientation is correct before OCR begins. Removing the background and/or cleaning the page can also improve results. The ``--oversample DPI`` argument can be specified to resample images to higher resolution before attempting OCR; this can improve results as well.
|
||||
|
||||
OCR quality will suffer if the resolution of input images is not correct (since the range of pixel sizes that will be checked for possible fonts will also be incorrect).
|
||||
|
||||
|
||||
+210
-222
@@ -4,401 +4,389 @@
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: Pipeline: Pages: 1 -->
|
||||
<svg width="1504pt" height="1219pt"
|
||||
viewBox="0.00 0.00 1504.00 1219.20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1215.1977)">
|
||||
<svg width="1484pt" height="1277pt"
|
||||
viewBox="0.00 0.00 1484.00 1277.20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1273.1977)">
|
||||
<title>Pipeline:</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1215.1977 1500,-1215.1977 1500,4 -4,4"/>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1273.1977 1480,-1273.1977 1480,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>clustertasks</title>
|
||||
<polygon fill="none" stroke="#000000" points="8,-8 8,-1203.1977 1488,-1203.1977 1488,-8 8,-8"/>
|
||||
<text text-anchor="middle" x="748" y="-1175.1977" font-family="Times,serif" font-size="30.00" fill="#ff3232">Pipeline:</text>
|
||||
<polygon fill="none" stroke="#000000" points="8,-8 8,-1261.1977 1468,-1261.1977 1468,-8 8,-8"/>
|
||||
<text text-anchor="middle" x="738" y="-1233.1977" font-family="Times,serif" font-size="30.00" fill="#ff3232">Pipeline:</text>
|
||||
</g>
|
||||
<!-- t0 -->
|
||||
<g id="node1" class="node">
|
||||
<title>t0</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1143.7053,-1157.1977 934.2947,-1157.1977 930.2947,-1153.1977 930.2947,-1121.1977 1139.7053,-1121.1977 1143.7053,-1125.1977 1143.7053,-1157.1977"/>
|
||||
<polyline fill="none" stroke="#000000" points="1139.7053,-1153.1977 930.2947,-1153.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1139.7053,-1153.1977 1139.7053,-1121.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1139.7053,-1153.1977 1143.7053,-1157.1977 "/>
|
||||
<text text-anchor="middle" x="1037" y="-1133.1977" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.triage</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1215.7053,-1215.1977 1006.2947,-1215.1977 1002.2947,-1211.1977 1002.2947,-1179.1977 1211.7053,-1179.1977 1215.7053,-1183.1977 1215.7053,-1215.1977"/>
|
||||
<polyline fill="none" stroke="#000000" points="1211.7053,-1211.1977 1002.2947,-1211.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1211.7053,-1211.1977 1211.7053,-1179.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1211.7053,-1211.1977 1215.7053,-1215.1977 "/>
|
||||
<text text-anchor="middle" x="1109" y="-1191.1977" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.triage</text>
|
||||
</g>
|
||||
<!-- t1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>t1</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1208.0433,-1099.1977 869.9567,-1099.1977 865.9567,-1095.1977 865.9567,-1063.1977 1204.0433,-1063.1977 1208.0433,-1067.1977 1208.0433,-1099.1977"/>
|
||||
<polyline fill="none" stroke="#000000" points="1204.0433,-1095.1977 865.9567,-1095.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1204.0433,-1095.1977 1204.0433,-1063.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1204.0433,-1095.1977 1208.0433,-1099.1977 "/>
|
||||
<text text-anchor="middle" x="1037" y="-1075.1977" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.repair_and_parse_pdf</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1280.0433,-1157.1977 941.9567,-1157.1977 937.9567,-1153.1977 937.9567,-1121.1977 1276.0433,-1121.1977 1280.0433,-1125.1977 1280.0433,-1157.1977"/>
|
||||
<polyline fill="none" stroke="#000000" points="1276.0433,-1153.1977 937.9567,-1153.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1276.0433,-1153.1977 1276.0433,-1121.1977 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1276.0433,-1153.1977 1280.0433,-1157.1977 "/>
|
||||
<text text-anchor="middle" x="1109" y="-1133.1977" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.repair_and_parse_pdf</text>
|
||||
</g>
|
||||
<!-- t0->t1 -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>t0->t1</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1037,-1121.1641C1037,-1117.4895 1037,-1113.5395 1037,-1109.604"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1040.5001,-1109.4199 1037,-1099.4199 1033.5001,-1109.42 1040.5001,-1109.4199"/>
|
||||
<path fill="none" stroke="#0044a0" d="M1109,-1179.1641C1109,-1175.4895 1109,-1171.5395 1109,-1167.604"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1112.5001,-1167.4199 1109,-1157.4199 1105.5001,-1167.42 1112.5001,-1167.4199"/>
|
||||
</g>
|
||||
<!-- t2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>t2</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1127.0926,-1020.2732 882,-1037.1731 636.9074,-1020.2732 637.1362,-992.9285 1126.8638,-992.9285 1127.0926,-1020.2732"/>
|
||||
<polygon fill="none" stroke="#000000" points="1131.1249,-1024.0021 882,-1041.1801 632.8751,-1024.0021 633.1685,-988.931 1130.8315,-988.931 1131.1249,-1024.0021"/>
|
||||
<text text-anchor="middle" x="882" y="-1006.7153" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.marker_pages</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1030.0926,-1078.2732 785,-1095.1731 539.9074,-1078.2732 540.1362,-1050.9285 1029.8638,-1050.9285 1030.0926,-1078.2732"/>
|
||||
<polygon fill="none" stroke="#000000" points="1034.1249,-1082.0021 785,-1099.1801 535.8751,-1082.0021 536.1685,-1046.931 1033.8315,-1046.931 1034.1249,-1082.0021"/>
|
||||
<text text-anchor="middle" x="785" y="-1064.7153" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.marker_pages</text>
|
||||
</g>
|
||||
<!-- t1->t2 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>t1->t2</title>
|
||||
<path fill="none" stroke="#0044a0" d="M995.8698,-1063.0255C981.0253,-1056.4668 963.8784,-1048.891 947.4691,-1041.641"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="948.4773,-1038.26 937.9158,-1037.4201 945.6483,-1044.663 948.4773,-1038.26"/>
|
||||
<path fill="none" stroke="#0044a0" d="M1023.449,-1121.1152C984.5695,-1112.8974 938.0675,-1103.0685 896.4957,-1094.2816"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="897.1066,-1090.8335 886.5989,-1092.1898 895.6589,-1097.6822 897.1066,-1090.8335"/>
|
||||
</g>
|
||||
<!-- t16 -->
|
||||
<g id="node17" class="node">
|
||||
<title>t16</title>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="1215.5059,-328.1861 942.4941,-328.1861 938.4941,-324.1861 938.4941,-292.1861 1211.5059,-292.1861 1215.5059,-296.1861 1215.5059,-328.1861"/>
|
||||
<polyline fill="none" stroke="#000000" points="1211.5059,-324.1861 938.4941,-324.1861 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1211.5059,-324.1861 1211.5059,-292.1861 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1211.5059,-324.1861 1215.5059,-328.1861 "/>
|
||||
<text text-anchor="middle" x="1077" y="-304.1861" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.weave_layers</text>
|
||||
</g>
|
||||
<!-- t1->t16 -->
|
||||
<g id="edge24" class="edge">
|
||||
<title>t1->t16</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1097.2373,-1120.9576C1077.987,-1088.7184 1043.7317,-1019.7372 1063,-963.2656 1106.87,-834.6914 1482.8098,-573.3183 1409,-459.2656 1362.7595,-387.8137 1273.2613,-350.2799 1198.8305,-330.7528"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1199.4555,-327.3005 1188.9015,-328.2301 1197.7316,-334.0849 1199.4555,-327.3005"/>
|
||||
</g>
|
||||
<!-- t17 -->
|
||||
<g id="node17" class="node">
|
||||
<g id="node18" class="node">
|
||||
<title>t17</title>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="762.5059,-270.1861 489.4941,-270.1861 485.4941,-266.1861 485.4941,-234.1861 758.5059,-234.1861 762.5059,-238.1861 762.5059,-270.1861"/>
|
||||
<polyline fill="none" stroke="#000000" points="758.5059,-266.1861 485.4941,-266.1861 "/>
|
||||
<polyline fill="none" stroke="#000000" points="758.5059,-266.1861 758.5059,-234.1861 "/>
|
||||
<polyline fill="none" stroke="#000000" points="758.5059,-266.1861 762.5059,-270.1861 "/>
|
||||
<text text-anchor="middle" x="624" y="-246.1861" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.weave_layers</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1439.5156,-1009.7492 1076.4844,-1009.7492 1072.4844,-1005.7492 1072.4844,-973.7492 1435.5156,-973.7492 1439.5156,-977.7492 1439.5156,-1009.7492"/>
|
||||
<polyline fill="none" stroke="#000000" points="1435.5156,-1005.7492 1072.4844,-1005.7492 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1435.5156,-1005.7492 1435.5156,-973.7492 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1435.5156,-1005.7492 1439.5156,-1009.7492 "/>
|
||||
<text text-anchor="middle" x="1256" y="-985.7492" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.generate_postscript_stub</text>
|
||||
</g>
|
||||
<!-- t1->t17 -->
|
||||
<g id="edge24" class="edge">
|
||||
<g id="edge25" class="edge">
|
||||
<title>t1->t17</title>
|
||||
<path fill="none" stroke="#0044a0" d="M865.7,-1073.6476C575.1688,-1058.5285 17,-1018.4586 17,-933.7492 17,-933.7492 17,-933.7492 17,-429.2656 17,-368.2377 -17.9719,-335.5198 25,-292.1861 40.6952,-276.3587 302.9615,-263.8206 475.2081,-257.2446"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="475.5316,-260.735 485.3919,-256.8588 475.2665,-253.74 475.5316,-260.735"/>
|
||||
<path fill="none" stroke="#0044a0" d="M1127.0251,-1121.1176C1153.0342,-1095.0292 1201.2007,-1046.7157 1230.7429,-1017.0834"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1233.2458,-1019.5302 1237.8275,-1009.9772 1228.2885,-1014.5879 1233.2458,-1019.5302"/>
|
||||
</g>
|
||||
<!-- t18 -->
|
||||
<g id="node19" class="node">
|
||||
<title>t18</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1459.5156,-951.7492 1096.4844,-951.7492 1092.4844,-947.7492 1092.4844,-915.7492 1455.5156,-915.7492 1459.5156,-919.7492 1459.5156,-951.7492"/>
|
||||
<polyline fill="none" stroke="#000000" points="1455.5156,-947.7492 1092.4844,-947.7492 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1455.5156,-947.7492 1455.5156,-915.7492 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1455.5156,-947.7492 1459.5156,-951.7492 "/>
|
||||
<text text-anchor="middle" x="1276" y="-927.7492" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.generate_postscript_stub</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1070.189,-214.4288 1263,-187.1099 1455.811,-214.4288 1455.631,-258.6317 1070.369,-258.6317 1070.189,-214.4288"/>
|
||||
<polygon fill="none" stroke="#000000" points="1066.1715,-210.9543 1263,-183.0662 1459.8285,-210.9543 1459.6181,-262.6353 1066.3819,-262.6353 1066.1715,-210.9543"/>
|
||||
<text text-anchor="middle" x="1263" y="-220.6461" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.metadata_fixup</text>
|
||||
</g>
|
||||
<!-- t1->t18 -->
|
||||
<g id="edge27" class="edge">
|
||||
<g id="edge28" class="edge">
|
||||
<title>t1->t18</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1092.3885,-1063.1613C1108.2153,-1057.0913 1125.1799,-1049.674 1140,-1041.1977 1181.1886,-1017.6399 1223.2361,-982.3362 1249.4567,-958.6949"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1252.0343,-961.0813 1257.0676,-951.7583 1247.319,-955.9076 1252.0343,-961.0813"/>
|
||||
</g>
|
||||
<!-- t19 -->
|
||||
<g id="node20" class="node">
|
||||
<title>t19</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1015.189,-156.4288 1208,-129.1099 1400.811,-156.4288 1400.631,-200.6317 1015.369,-200.6317 1015.189,-156.4288"/>
|
||||
<polygon fill="none" stroke="#000000" points="1011.1715,-152.9543 1208,-125.0662 1404.8285,-152.9543 1404.6181,-204.6353 1011.3819,-204.6353 1011.1715,-152.9543"/>
|
||||
<text text-anchor="middle" x="1208" y="-162.6461" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.metadata_fixup</text>
|
||||
</g>
|
||||
<!-- t1->t19 -->
|
||||
<g id="edge31" class="edge">
|
||||
<title>t1->t19</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1103.146,-1063.1053C1128.1671,-1056.2536 1156.8994,-1048.3763 1183,-1041.1977 1317.9441,-1004.0832 1479,-1073.7042 1479,-933.7492 1479,-933.7492 1479,-933.7492 1479,-335.7258 1479,-283.5318 1462.7563,-264.1212 1420,-234.1861 1405.9522,-224.3508 1390.38,-215.9542 1374.2381,-208.7935"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1375.2471,-205.419 1364.6755,-204.7186 1372.503,-211.8587 1375.2471,-205.419"/>
|
||||
<path fill="none" stroke="#0044a0" d="M1241.1115,-1121.1192C1311.0076,-1105.2558 1393.5851,-1075.5895 1449,-1020.2329 1458.4922,-1010.7507 1459,-1005.1661 1459,-991.7492 1459,-991.7492 1459,-991.7492 1459,-393.7258 1459,-341.9727 1441.8377,-325.2216 1402,-292.1861 1390.9869,-283.0534 1378.4885,-274.871 1365.6104,-267.6415"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1367.1079,-264.4723 1356.6476,-262.7888 1363.775,-270.6279 1367.1079,-264.4723"/>
|
||||
</g>
|
||||
<!-- t3 -->
|
||||
<g id="node4" class="node">
|
||||
<title>t3</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1070.5194,-941.3074 840,-958.2081 609.4806,-941.3074 609.6958,-913.9616 1070.3042,-913.9616 1070.5194,-941.3074"/>
|
||||
<polygon fill="none" stroke="#000000" points="1074.5491,-945.0204 840,-962.2165 605.4509,-945.0204 605.7267,-909.9639 1074.2733,-909.9639 1074.5491,-945.0204"/>
|
||||
<text text-anchor="middle" x="840" y="-927.7492" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.ocr_or_skip</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1015.5194,-999.3074 785,-1016.2081 554.4806,-999.3074 554.6958,-971.9616 1015.3042,-971.9616 1015.5194,-999.3074"/>
|
||||
<polygon fill="none" stroke="#000000" points="1019.5491,-1003.0204 785,-1020.2165 550.4509,-1003.0204 550.7267,-967.9639 1019.2733,-967.9639 1019.5491,-1003.0204"/>
|
||||
<text text-anchor="middle" x="785" y="-985.7492" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.ocr_or_skip</text>
|
||||
</g>
|
||||
<!-- t2->t3 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>t2->t3</title>
|
||||
<path fill="none" stroke="#0044a0" d="M869.1704,-988.5938C866.0908,-982.8038 862.7335,-976.4916 859.4285,-970.2775"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="862.4479,-968.5011 854.6619,-961.3157 856.2677,-971.7882 862.4479,-968.5011"/>
|
||||
<path fill="none" stroke="#0044a0" d="M785,-1046.5938C785,-1041.5635 785,-1036.139 785,-1030.7273"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="788.5001,-1030.4427 785,-1020.4427 781.5001,-1030.4428 788.5001,-1030.4427"/>
|
||||
</g>
|
||||
<!-- t4 -->
|
||||
<g id="node5" class="node">
|
||||
<title>t4</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1160.3166,-883.2656 853.6834,-883.2656 849.6834,-879.2656 849.6834,-847.2656 1156.3166,-847.2656 1160.3166,-851.2656 1160.3166,-883.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="1156.3166,-879.2656 849.6834,-879.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1156.3166,-879.2656 1156.3166,-847.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1156.3166,-879.2656 1160.3166,-883.2656 "/>
|
||||
<text text-anchor="middle" x="1005" y="-859.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.rasterize_preview</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="889.3166,-941.2656 582.6834,-941.2656 578.6834,-937.2656 578.6834,-905.2656 885.3166,-905.2656 889.3166,-909.2656 889.3166,-941.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="885.3166,-937.2656 578.6834,-937.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="885.3166,-937.2656 885.3166,-905.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="885.3166,-937.2656 889.3166,-941.2656 "/>
|
||||
<text text-anchor="middle" x="734" y="-917.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.rasterize_preview</text>
|
||||
</g>
|
||||
<!-- t3->t4 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>t3->t4</title>
|
||||
<path fill="none" stroke="#0044a0" d="M897.709,-909.797C915.43,-902.4418 934.8333,-894.3884 952.2078,-887.1771"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="953.7336,-890.3334 961.628,-883.2672 951.0502,-883.8681 953.7336,-890.3334"/>
|
||||
<path fill="none" stroke="#0044a0" d="M767.1627,-967.797C762.8396,-961.9919 758.1927,-955.7519 753.7858,-949.8343"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="756.3465,-947.4129 747.5666,-941.483 750.7323,-951.5939 756.3465,-947.4129"/>
|
||||
</g>
|
||||
<!-- t5 -->
|
||||
<g id="node6" class="node">
|
||||
<title>t5</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1118.0824,-825.2656 859.9176,-825.2656 855.9176,-821.2656 855.9176,-789.2656 1114.0824,-789.2656 1118.0824,-793.2656 1118.0824,-825.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="1114.0824,-821.2656 855.9176,-821.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1114.0824,-821.2656 1114.0824,-789.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1114.0824,-821.2656 1118.0824,-825.2656 "/>
|
||||
<text text-anchor="middle" x="987" y="-801.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.orient_page</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1028.0824,-883.2656 769.9176,-883.2656 765.9176,-879.2656 765.9176,-847.2656 1024.0824,-847.2656 1028.0824,-851.2656 1028.0824,-883.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="1024.0824,-879.2656 765.9176,-879.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1024.0824,-879.2656 1024.0824,-847.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1024.0824,-879.2656 1028.0824,-883.2656 "/>
|
||||
<text text-anchor="middle" x="897" y="-859.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.orient_page</text>
|
||||
</g>
|
||||
<!-- t3->t5 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>t3->t5</title>
|
||||
<path fill="none" stroke="#0044a0" d="M833.1324,-909.9518C829.2069,-891.0127 827.4191,-864.8559 841,-847.2656 846.6916,-839.8936 860.4225,-833.5377 877.3049,-828.2001"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="878.3804,-831.532 886.9772,-825.3397 876.3952,-824.8194 878.3804,-831.532"/>
|
||||
<path fill="none" stroke="#0044a0" d="M869.1177,-967.8063C880.553,-961.0264 890.81,-952.3527 898,-941.2656 907.042,-927.3226 906.9457,-908.7053 904.5139,-893.387"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="907.914,-892.5383 902.5408,-883.4071 901.0469,-893.8961 907.914,-892.5383"/>
|
||||
</g>
|
||||
<!-- t4->t5 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>t4->t5</title>
|
||||
<path fill="none" stroke="#0044a0" d="M999.4034,-847.2319C998.2294,-843.4493 996.9649,-839.3747 995.708,-835.3247"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="998.962,-834.001 992.6552,-825.4878 992.2765,-836.0759 998.962,-834.001"/>
|
||||
<path fill="none" stroke="#0044a0" d="M784.6807,-905.2319C801.0865,-899.3943 819.4462,-892.8614 836.4913,-886.7963"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="838.1026,-889.938 846.3506,-883.288 835.7559,-883.343 838.1026,-889.938"/>
|
||||
</g>
|
||||
<!-- t6 -->
|
||||
<g id="node7" class="node">
|
||||
<title>t6</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1166.7325,-767.2656 791.2675,-767.2656 787.2675,-763.2656 787.2675,-731.2656 1162.7325,-731.2656 1166.7325,-735.2656 1166.7325,-767.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="1162.7325,-763.2656 787.2675,-763.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1162.7325,-763.2656 1162.7325,-731.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1162.7325,-763.2656 1166.7325,-767.2656 "/>
|
||||
<text text-anchor="middle" x="977" y="-743.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.rasterize_with_ghostscript</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1064.7325,-825.2656 689.2675,-825.2656 685.2675,-821.2656 685.2675,-789.2656 1060.7325,-789.2656 1064.7325,-793.2656 1064.7325,-825.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="1060.7325,-821.2656 685.2675,-821.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1060.7325,-821.2656 1060.7325,-789.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1060.7325,-821.2656 1064.7325,-825.2656 "/>
|
||||
<text text-anchor="middle" x="875" y="-801.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.rasterize_with_ghostscript</text>
|
||||
</g>
|
||||
<!-- t5->t6 -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>t5->t6</title>
|
||||
<path fill="none" stroke="#0044a0" d="M983.8908,-789.2319C983.2572,-785.5574 982.5762,-781.6073 981.8976,-777.6719"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="985.29,-776.7477 980.1418,-767.4878 978.3918,-777.9371 985.29,-776.7477"/>
|
||||
<path fill="none" stroke="#0044a0" d="M890.1597,-847.2319C888.6839,-843.3412 887.0909,-839.1417 885.5115,-834.9776"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="888.731,-833.5965 881.9119,-825.4878 882.186,-836.0791 888.731,-833.5965"/>
|
||||
</g>
|
||||
<!-- t13 -->
|
||||
<g id="node16" class="node">
|
||||
<title>t13</title>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="1117,-457.2656 794.4141,-429.2656 1117,-401.2656 1439.5859,-429.2656 1117,-457.2656"/>
|
||||
<text text-anchor="middle" x="1117" y="-423.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.select_image_layer</text>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="1077,-515.2656 754.4141,-487.2656 1077,-459.2656 1399.5859,-487.2656 1077,-515.2656"/>
|
||||
<text text-anchor="middle" x="1077" y="-481.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.select_image_layer</text>
|
||||
</g>
|
||||
<!-- t5->t13 -->
|
||||
<g id="edge20" class="edge">
|
||||
<title>t5->t13</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1118.1879,-790.6395C1144.3794,-784.8205 1166.7114,-777.1767 1176,-767.2656 1199.3386,-742.3628 1187,-725.3953 1187,-691.2656 1187,-691.2656 1187,-691.2656 1187,-575.2656 1187,-532.368 1197.1859,-517.117 1177,-479.2656 1173.4907,-472.6851 1168.7198,-466.6243 1163.3915,-461.1636"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1165.5374,-458.3781 1155.8461,-454.0967 1160.7522,-463.4872 1165.5374,-458.3781"/>
|
||||
<path fill="none" stroke="#0044a0" d="M1000.2704,-847.241C1031.2359,-840.6873 1060.5415,-832.9862 1074,-825.2656 1114.0954,-802.2644 1145,-795.4899 1145,-749.2656 1145,-749.2656 1145,-749.2656 1145,-633.2656 1145,-590.368 1154.8687,-575.2844 1135,-537.2656 1131.571,-530.7041 1126.8893,-524.6314 1121.6622,-519.1451"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1123.8989,-516.4405 1114.2626,-512.0367 1119.0494,-521.4885 1123.8989,-516.4405"/>
|
||||
</g>
|
||||
<!-- t7 -->
|
||||
<g id="node8" class="node">
|
||||
<title>t7</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="958.0801,-709.2656 533.9199,-709.2656 529.9199,-705.2656 529.9199,-673.2656 954.0801,-673.2656 958.0801,-677.2656 958.0801,-709.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="954.0801,-705.2656 529.9199,-705.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="954.0801,-705.2656 954.0801,-673.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="954.0801,-705.2656 958.0801,-709.2656 "/>
|
||||
<text text-anchor="middle" x="744" y="-685.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.preprocess_remove_background</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="856.0801,-767.2656 431.9199,-767.2656 427.9199,-763.2656 427.9199,-731.2656 852.0801,-731.2656 856.0801,-735.2656 856.0801,-767.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="852.0801,-763.2656 427.9199,-763.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="852.0801,-763.2656 852.0801,-731.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="852.0801,-763.2656 856.0801,-767.2656 "/>
|
||||
<text text-anchor="middle" x="642" y="-743.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.preprocess_remove_background</text>
|
||||
</g>
|
||||
<!-- t6->t7 -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>t6->t7</title>
|
||||
<path fill="none" stroke="#0044a0" d="M904.5546,-731.2319C879.7884,-725.067 851.9071,-718.1266 826.4138,-711.7806"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="826.95,-708.3073 816.4006,-709.288 825.259,-715.1 826.95,-708.3073"/>
|
||||
<path fill="none" stroke="#0044a0" d="M802.5546,-789.2319C777.7884,-783.067 749.9071,-776.1266 724.4138,-769.7806"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="724.95,-766.3073 714.4006,-767.288 723.259,-773.1 724.95,-766.3073"/>
|
||||
</g>
|
||||
<!-- t12 -->
|
||||
<g id="node15" class="node">
|
||||
<title>t12</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="784,-535.2656 400.1874,-507.2656 784,-479.2656 1167.8126,-507.2656 784,-535.2656"/>
|
||||
<text text-anchor="middle" x="784" y="-501.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.select_visible_page_image</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="742,-593.2656 358.1874,-565.2656 742,-537.2656 1125.8126,-565.2656 742,-593.2656"/>
|
||||
<text text-anchor="middle" x="742" y="-559.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.select_visible_page_image</text>
|
||||
</g>
|
||||
<!-- t6->t12 -->
|
||||
<g id="edge18" class="edge">
|
||||
<title>t6->t12</title>
|
||||
<path fill="none" stroke="#0044a0" d="M978.1978,-731.0693C979.6326,-693.2308 977.2953,-605.5735 930,-557.2656 919.8727,-546.9215 907.5166,-538.7165 894.3237,-532.2085"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="895.6224,-528.9537 885.0735,-527.9686 892.7057,-535.3171 895.6224,-528.9537"/>
|
||||
<path fill="none" stroke="#0044a0" d="M875.1443,-789.1129C874.6867,-773.2956 872.5831,-750.0189 865,-731.2656 844.2991,-680.0716 804.0126,-630.4165 775.1838,-598.9641"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="777.4937,-596.3085 768.1202,-591.3701 772.3682,-601.076 777.4937,-596.3085"/>
|
||||
</g>
|
||||
<!-- t8 -->
|
||||
<g id="node9" class="node">
|
||||
<title>t8</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="930.6759,-651.2656 611.3241,-651.2656 607.3241,-647.2656 607.3241,-615.2656 926.6759,-615.2656 930.6759,-619.2656 930.6759,-651.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="926.6759,-647.2656 607.3241,-647.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="926.6759,-647.2656 926.6759,-615.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="926.6759,-647.2656 930.6759,-651.2656 "/>
|
||||
<text text-anchor="middle" x="769" y="-627.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.preprocess_deskew</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="732.6759,-709.2656 413.3241,-709.2656 409.3241,-705.2656 409.3241,-673.2656 728.6759,-673.2656 732.6759,-677.2656 732.6759,-709.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="728.6759,-705.2656 409.3241,-705.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="728.6759,-705.2656 728.6759,-673.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="728.6759,-705.2656 732.6759,-709.2656 "/>
|
||||
<text text-anchor="middle" x="571" y="-685.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.preprocess_deskew</text>
|
||||
</g>
|
||||
<!-- t7->t8 -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>t7->t8</title>
|
||||
<path fill="none" stroke="#0044a0" d="M751.7731,-673.2319C753.4501,-669.3412 755.2603,-665.1417 757.0552,-660.9776"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="760.4014,-662.0565 761.1456,-651.4878 753.9731,-659.2856 760.4014,-662.0565"/>
|
||||
<path fill="none" stroke="#0044a0" d="M619.9243,-731.2319C613.9709,-726.3685 607.4267,-721.0226 601.115,-715.8666"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="603.2653,-713.1037 593.3065,-709.4878 598.8367,-718.5248 603.2653,-713.1037"/>
|
||||
</g>
|
||||
<!-- t7->t12 -->
|
||||
<g id="edge17" class="edge">
|
||||
<title>t7->t12</title>
|
||||
<path fill="none" stroke="#0044a0" d="M643.9087,-673.2441C622.7156,-667.3649 604.695,-660.0415 598,-651.2656 572.6604,-618.0498 572.5807,-590.4204 598,-557.2656 606.6447,-545.9902 630.0462,-536.6909 657.4547,-529.2983"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="658.4879,-532.6465 667.2989,-526.7629 656.7419,-525.8677 658.4879,-532.6465"/>
|
||||
<path fill="none" stroke="#0044a0" d="M717.0346,-731.1646C726.8757,-725.6884 735.7103,-718.5557 742,-709.2656 763.0291,-678.205 759.4083,-634.0888 752.8082,-602.8898"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="756.1481,-601.7976 750.487,-592.842 749.3278,-603.3733 756.1481,-601.7976"/>
|
||||
</g>
|
||||
<!-- t9 -->
|
||||
<g id="node10" class="node">
|
||||
<title>t9</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="912.8828,-593.2656 611.1172,-593.2656 607.1172,-589.2656 607.1172,-557.2656 908.8828,-557.2656 912.8828,-561.2656 912.8828,-593.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="908.8828,-589.2656 607.1172,-589.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="908.8828,-589.2656 908.8828,-557.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="908.8828,-589.2656 912.8828,-593.2656 "/>
|
||||
<text text-anchor="middle" x="760" y="-569.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.preprocess_clean</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="712.8828,-651.2656 411.1172,-651.2656 407.1172,-647.2656 407.1172,-615.2656 708.8828,-615.2656 712.8828,-619.2656 712.8828,-651.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="708.8828,-647.2656 407.1172,-647.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="708.8828,-647.2656 708.8828,-615.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="708.8828,-647.2656 712.8828,-651.2656 "/>
|
||||
<text text-anchor="middle" x="560" y="-627.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.preprocess_clean</text>
|
||||
</g>
|
||||
<!-- t8->t9 -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>t8->t9</title>
|
||||
<path fill="none" stroke="#0044a0" d="M766.2017,-615.2319C765.6315,-611.5574 765.0185,-607.6073 764.4079,-603.6719"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="767.8197,-602.8328 762.8276,-593.4878 760.9024,-603.9063 767.8197,-602.8328"/>
|
||||
<path fill="none" stroke="#0044a0" d="M567.5798,-673.2319C566.8624,-669.4493 566.0897,-665.3747 565.3216,-661.3247"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="568.7581,-660.6605 563.4559,-651.4878 561.8807,-661.9649 568.7581,-660.6605"/>
|
||||
</g>
|
||||
<!-- t8->t12 -->
|
||||
<g id="edge16" class="edge">
|
||||
<title>t8->t12</title>
|
||||
<path fill="none" stroke="#0044a0" d="M875.8215,-615.19C897.1712,-609.3919 915.1622,-602.1209 922,-593.2656 931.7788,-580.6016 931.1868,-570.3653 922,-557.2656 915.7828,-548.4003 898.4853,-539.9108 878.1493,-532.5246"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="879.2156,-529.1899 868.6208,-529.2112 876.9164,-535.8016 879.2156,-529.1899"/>
|
||||
<path fill="none" stroke="#0044a0" d="M670.0045,-673.2618C693.2528,-667.2338 713.6919,-659.8307 722,-651.2656 734.1971,-638.6912 739.4901,-620.2051 741.6123,-603.5914"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="745.1041,-603.8427 742.5574,-593.5585 738.1349,-603.1862 745.1041,-603.8427"/>
|
||||
</g>
|
||||
<!-- t10 -->
|
||||
<g id="node11" class="node">
|
||||
<title>t10</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="382.1094,-525.2656 77.8906,-525.2656 73.8906,-521.2656 73.8906,-489.2656 378.1094,-489.2656 382.1094,-493.2656 382.1094,-525.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="378.1094,-521.2656 73.8906,-521.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="378.1094,-521.2656 378.1094,-489.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="378.1094,-521.2656 382.1094,-525.2656 "/>
|
||||
<text text-anchor="middle" x="228" y="-501.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.select_ocr_image</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="340.1094,-583.2656 35.8906,-583.2656 31.8906,-579.2656 31.8906,-547.2656 336.1094,-547.2656 340.1094,-551.2656 340.1094,-583.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="336.1094,-579.2656 31.8906,-579.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="336.1094,-579.2656 336.1094,-547.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="336.1094,-579.2656 340.1094,-583.2656 "/>
|
||||
<text text-anchor="middle" x="186" y="-559.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.select_ocr_image</text>
|
||||
</g>
|
||||
<!-- t9->t10 -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>t9->t10</title>
|
||||
<path fill="none" stroke="#0044a0" d="M606.6862,-560.7998C540.2619,-553.9762 461.6761,-545.1568 391,-535.2656 373.4852,-532.8143 354.9627,-529.9218 336.9313,-526.9421"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="337.4138,-523.4743 326.9739,-525.28 336.2612,-530.3788 337.4138,-523.4743"/>
|
||||
<path fill="none" stroke="#0044a0" d="M460.7568,-615.2213C409.7279,-605.9434 347.4237,-594.6153 295.0537,-585.0935"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="295.5223,-581.6214 285.0575,-583.276 294.2701,-588.5085 295.5223,-581.6214"/>
|
||||
</g>
|
||||
<!-- t9->t12 -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>t9->t12</title>
|
||||
<path fill="none" stroke="#0044a0" d="M766.4316,-557.0428C767.8283,-553.0854 769.3544,-548.7615 770.905,-544.368"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="774.2705,-545.3486 774.2983,-534.7538 767.6695,-543.0188 774.2705,-545.3486"/>
|
||||
<path fill="none" stroke="#0044a0" d="M608.2948,-615.2213C627.0226,-608.2242 648.8712,-600.0609 669.4134,-592.3859"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="670.9148,-595.5613 679.0573,-588.7826 668.4648,-589.004 670.9148,-595.5613"/>
|
||||
</g>
|
||||
<!-- t11 -->
|
||||
<g id="node12" class="node">
|
||||
<title>t11</title>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="756.0996,-447.2656 441.9004,-447.2656 437.9004,-443.2656 437.9004,-411.2656 752.0996,-411.2656 756.0996,-415.2656 756.0996,-447.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="752.0996,-443.2656 437.9004,-443.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="752.0996,-443.2656 752.0996,-411.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="752.0996,-443.2656 756.0996,-447.2656 "/>
|
||||
<text text-anchor="middle" x="597" y="-423.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.ocr_tesseract_hocr</text>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="334.0996,-505.2656 19.9004,-505.2656 15.9004,-501.2656 15.9004,-469.2656 330.0996,-469.2656 334.0996,-473.2656 334.0996,-505.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="330.0996,-501.2656 15.9004,-501.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="330.0996,-501.2656 330.0996,-469.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="330.0996,-501.2656 334.0996,-505.2656 "/>
|
||||
<text text-anchor="middle" x="175" y="-481.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.ocr_tesseract_hocr</text>
|
||||
</g>
|
||||
<!-- t10->t11 -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>t10->t11</title>
|
||||
<path fill="none" stroke="#0044a0" d="M313.5835,-489.1748C369.8356,-477.2841 443.5049,-461.7117 501.6353,-449.424"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="502.5017,-452.8182 511.5616,-447.3257 501.0539,-445.9696 502.5017,-452.8182"/>
|
||||
<path fill="none" stroke="#0044a0" d="M183.4487,-547.1748C182.1254,-537.7914 180.4788,-526.1154 178.9917,-515.5701"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="182.4378,-514.9417 177.5755,-505.5285 175.5064,-515.9193 182.4378,-514.9417"/>
|
||||
</g>
|
||||
<!-- t16 -->
|
||||
<!-- t15 -->
|
||||
<g id="node14" class="node">
|
||||
<title>t16</title>
|
||||
<polygon fill="#ff69b4" stroke="#000000" points="420.2696,-447.2656 39.7304,-447.2656 35.7304,-443.2656 35.7304,-411.2656 416.2696,-411.2656 420.2696,-415.2656 420.2696,-447.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="416.2696,-443.2656 35.7304,-443.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="416.2696,-443.2656 416.2696,-411.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="416.2696,-443.2656 420.2696,-447.2656 "/>
|
||||
<text text-anchor="middle" x="228" y="-423.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.ocr_tesseract_textonly_pdf</text>
|
||||
<title>t15</title>
|
||||
<polygon fill="#ff69b4" stroke="#000000" points="736.2696,-505.2656 355.7304,-505.2656 351.7304,-501.2656 351.7304,-469.2656 732.2696,-469.2656 736.2696,-473.2656 736.2696,-505.2656"/>
|
||||
<polyline fill="none" stroke="#000000" points="732.2696,-501.2656 351.7304,-501.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="732.2696,-501.2656 732.2696,-469.2656 "/>
|
||||
<polyline fill="none" stroke="#000000" points="732.2696,-501.2656 736.2696,-505.2656 "/>
|
||||
<text text-anchor="middle" x="544" y="-481.2656" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.ocr_tesseract_textonly_pdf</text>
|
||||
</g>
|
||||
<!-- t10->t16 -->
|
||||
<!-- t10->t15 -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>t10->t16</title>
|
||||
<path fill="none" stroke="#0044a0" d="M228,-489.1748C228,-479.7914 228,-468.1154 228,-457.5701"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="231.5001,-457.5284 228,-447.5285 224.5001,-457.5285 231.5001,-457.5284"/>
|
||||
<title>t10->t15</title>
|
||||
<path fill="none" stroke="#0044a0" d="M269.0322,-547.1748C323.4947,-535.3086 394.7854,-519.776 451.1284,-507.5002"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="452.0829,-510.8744 461.1086,-505.3257 450.5927,-504.0348 452.0829,-510.8744"/>
|
||||
</g>
|
||||
<!-- t14 -->
|
||||
<g id="node13" class="node">
|
||||
<title>t14</title>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="780.0433,-353.7258 471.9567,-353.7258 467.9567,-349.7258 467.9567,-317.7258 776.0433,-317.7258 780.0433,-321.7258 780.0433,-353.7258"/>
|
||||
<polyline fill="none" stroke="#000000" points="776.0433,-349.7258 467.9567,-349.7258 "/>
|
||||
<polyline fill="none" stroke="#000000" points="776.0433,-349.7258 776.0433,-317.7258 "/>
|
||||
<polyline fill="none" stroke="#000000" points="776.0433,-349.7258 780.0433,-353.7258 "/>
|
||||
<text text-anchor="middle" x="624" y="-329.7258" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.render_hocr_page</text>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="330.0433,-411.7258 21.9567,-411.7258 17.9567,-407.7258 17.9567,-375.7258 326.0433,-375.7258 330.0433,-379.7258 330.0433,-411.7258"/>
|
||||
<polyline fill="none" stroke="#000000" points="326.0433,-407.7258 17.9567,-407.7258 "/>
|
||||
<polyline fill="none" stroke="#000000" points="326.0433,-407.7258 326.0433,-375.7258 "/>
|
||||
<polyline fill="none" stroke="#000000" points="326.0433,-407.7258 330.0433,-411.7258 "/>
|
||||
<text text-anchor="middle" x="174" y="-387.7258" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.render_hocr_page</text>
|
||||
</g>
|
||||
<!-- t11->t14 -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>t11->t14</title>
|
||||
<path fill="none" stroke="#0044a0" d="M602.2059,-411.2302C606.0656,-397.8584 611.4022,-379.3702 615.8284,-364.0357"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="619.3074,-364.6035 618.718,-354.025 612.5819,-362.6621 619.3074,-364.6035"/>
|
||||
<path fill="none" stroke="#0044a0" d="M174.8072,-469.2302C174.6642,-455.8584 174.4666,-437.3702 174.3027,-422.0357"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="177.8024,-421.987 174.1956,-412.025 170.8028,-422.0619 177.8024,-421.987"/>
|
||||
</g>
|
||||
<!-- t15 -->
|
||||
<g id="node18" class="node">
|
||||
<title>t15</title>
|
||||
<polygon fill="#00cc66" stroke="#000000" points="1169.9202,-353.7258 802.0798,-353.7258 798.0798,-349.7258 798.0798,-317.7258 1165.9202,-317.7258 1169.9202,-321.7258 1169.9202,-353.7258"/>
|
||||
<polyline fill="none" stroke="#000000" points="1165.9202,-349.7258 798.0798,-349.7258 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1165.9202,-349.7258 1165.9202,-317.7258 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1165.9202,-349.7258 1169.9202,-353.7258 "/>
|
||||
<text text-anchor="middle" x="984" y="-329.7258" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.render_hocr_debug_page</text>
|
||||
</g>
|
||||
<!-- t11->t15 -->
|
||||
<g id="edge26" class="edge">
|
||||
<title>t11->t15</title>
|
||||
<path fill="none" stroke="#0044a0" d="M671.6175,-411.2302C736.8294,-395.4681 831.4531,-372.5971 899.4498,-356.162"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="900.3844,-359.537 909.2822,-353.7855 898.7398,-352.7329 900.3844,-359.537"/>
|
||||
</g>
|
||||
<!-- t20 -->
|
||||
<!-- t19 -->
|
||||
<g id="node22" class="node">
|
||||
<title>t20</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="59.7205,-323.5085 253,-296.1897 446.2795,-323.5085 446.0991,-367.7112 59.9009,-367.7112 59.7205,-323.5085"/>
|
||||
<polygon fill="none" stroke="#000000" points="55.7033,-320.0329 253,-292.1463 450.2967,-320.0329 450.0858,-371.7148 55.9142,-371.7148 55.7033,-320.0329"/>
|
||||
<text text-anchor="middle" x="253" y="-329.7258" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.merge_sidecars</text>
|
||||
<title>t19</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="351.7205,-381.5085 545,-354.1897 738.2795,-381.5085 738.0991,-425.7112 351.9009,-425.7112 351.7205,-381.5085"/>
|
||||
<polygon fill="none" stroke="#000000" points="347.7033,-378.0329 545,-350.1463 742.2967,-378.0329 742.0858,-429.7148 347.9142,-429.7148 347.7033,-378.0329"/>
|
||||
<text text-anchor="middle" x="545" y="-387.7258" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.merge_sidecars</text>
|
||||
</g>
|
||||
<!-- t11->t20 -->
|
||||
<g id="edge34" class="edge">
|
||||
<title>t11->t20</title>
|
||||
<path fill="none" stroke="#0044a0" d="M530.6733,-411.2302C492.1331,-400.7504 442.0357,-387.128 395.0218,-374.3441"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="395.9216,-370.9617 385.3536,-371.7151 394.0848,-377.7165 395.9216,-370.9617"/>
|
||||
<!-- t11->t19 -->
|
||||
<g id="edge32" class="edge">
|
||||
<title>t11->t19</title>
|
||||
<path fill="none" stroke="#0044a0" d="M246.3397,-469.2302C287.966,-458.7066 342.1269,-445.0142 392.8772,-432.184"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="393.8058,-435.5594 402.6429,-429.7151 392.0901,-428.773 393.8058,-435.5594"/>
|
||||
</g>
|
||||
<!-- t14->t17 -->
|
||||
<!-- t14->t16 -->
|
||||
<g id="edge22" class="edge">
|
||||
<title>t14->t17</title>
|
||||
<path fill="none" stroke="#0044a0" d="M624,-317.5989C624,-306.7612 624,-292.7572 624,-280.4888"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="627.5001,-280.2775 624,-270.2776 620.5001,-280.2776 627.5001,-280.2775"/>
|
||||
<title>t14->t16</title>
|
||||
<path fill="none" stroke="#0044a0" d="M230.6615,-375.7128C262.2207,-366.4581 302.4172,-355.9425 339,-350.1861 448.3957,-332.9725 745.7869,-320.7866 927.9215,-314.6743"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="928.248,-318.1655 938.1258,-314.3342 928.0148,-311.1693 928.248,-318.1655"/>
|
||||
</g>
|
||||
<!-- t16->t17 -->
|
||||
<!-- t15->t16 -->
|
||||
<g id="edge21" class="edge">
|
||||
<title>t16->t17</title>
|
||||
<path fill="none" stroke="#0044a0" d="M121.729,-411.2329C88.1524,-403.224 57.1198,-392.5599 47,-379.2656 23.5584,-348.4705 20.5968,-320.483 47,-292.1861 61.4893,-276.6576 308.9021,-264.1817 474.9995,-257.507"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="475.4699,-260.9912 485.3225,-257.0955 475.1909,-253.9967 475.4699,-260.9912"/>
|
||||
<title>t15->t16</title>
|
||||
<path fill="none" stroke="#0044a0" d="M630.0636,-469.2083C667.5329,-460.6467 711.76,-449.5912 751,-437.2656 850.4985,-406.0121 963.1653,-359.5222 1026.586,-332.2894"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1028.1566,-335.4238 1035.9553,-328.2523 1025.3866,-328.9951 1028.1566,-335.4238"/>
|
||||
</g>
|
||||
<!-- t16->t20 -->
|
||||
<g id="edge33" class="edge">
|
||||
<title>t16->t20</title>
|
||||
<path fill="none" stroke="#0044a0" d="M232.8203,-411.2302C235.0783,-402.7816 237.8822,-392.2905 240.6745,-381.8429"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="244.1291,-382.4721 243.3299,-371.9075 237.3665,-380.6646 244.1291,-382.4721"/>
|
||||
<!-- t15->t19 -->
|
||||
<g id="edge31" class="edge">
|
||||
<title>t15->t19</title>
|
||||
<path fill="none" stroke="#0044a0" d="M544.1928,-469.2302C544.2822,-460.8687 544.393,-450.5066 544.5035,-440.166"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="548.006,-439.9443 544.6132,-429.9075 541.0064,-439.8694 548.006,-439.9443"/>
|
||||
</g>
|
||||
<!-- t12->t13 -->
|
||||
<g id="edge19" class="edge">
|
||||
<title>t12->t13</title>
|
||||
<path fill="none" stroke="#0044a0" d="M875.4342,-485.8486C920.1893,-475.3654 974.0965,-462.7385 1019.6212,-452.075"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1020.5619,-455.4495 1029.5001,-449.761 1018.9654,-448.634 1020.5619,-455.4495"/>
|
||||
<path fill="none" stroke="#0044a0" d="M833.9833,-543.8486C879.0975,-533.3444 933.4556,-520.6879 979.3116,-510.0109"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="980.3156,-513.3709 989.2614,-507.6943 978.7282,-506.5532 980.3156,-513.3709"/>
|
||||
</g>
|
||||
<!-- t12->t15 -->
|
||||
<g id="edge25" class="edge">
|
||||
<title>t12->t15</title>
|
||||
<path fill="none" stroke="#0044a0" d="M776.0923,-479.7209C771.2028,-456.5505 768.6047,-423.7032 785,-401.2656 797.9932,-383.4838 843.2193,-367.8601 887.2779,-356.3313"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="888.4172,-359.6528 897.2399,-353.7867 886.6847,-352.8705 888.4172,-359.6528"/>
|
||||
</g>
|
||||
<!-- t13->t17 -->
|
||||
<!-- t13->t16 -->
|
||||
<g id="edge23" class="edge">
|
||||
<title>t13->t17</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1158.1724,-404.745C1166.5787,-397.655 1174.2871,-389.1208 1179,-379.2656 1195.6968,-344.3505 1205.3645,-320.5191 1179,-292.1861 1165.2457,-277.4048 932.6999,-264.8684 773.033,-257.9499"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="772.7656,-254.4353 762.6245,-257.5024 772.4649,-261.4288 772.7656,-254.4353"/>
|
||||
<title>t13->t16</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1077,-459.2068C1077,-426.2624 1077,-371.9187 1077,-338.7552"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1080.5001,-338.3818 1077,-328.3819 1073.5001,-338.3819 1080.5001,-338.3818"/>
|
||||
</g>
|
||||
<!-- t17->t19 -->
|
||||
<!-- t16->t18 -->
|
||||
<g id="edge27" class="edge">
|
||||
<title>t16->t18</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1117.3592,-292.0592C1133.8695,-284.6437 1153.6803,-275.7459 1173.2953,-266.9361"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1174.8979,-270.0531 1182.586,-262.7632 1172.0299,-263.6676 1174.8979,-270.0531"/>
|
||||
</g>
|
||||
<!-- t17->t18 -->
|
||||
<g id="edge26" class="edge">
|
||||
<title>t17->t18</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1326.2292,-973.7283C1377.8362,-955.768 1439,-922.4247 1439,-865.2656 1439,-865.2656 1439,-865.2656 1439,-393.7258 1439,-338.7092 1393.2056,-296.3464 1348.3356,-268.0433"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1350.0403,-264.9831 1339.6842,-262.7465 1346.3852,-270.9531 1350.0403,-264.9831"/>
|
||||
</g>
|
||||
<!-- t20 -->
|
||||
<g id="node20" class="node">
|
||||
<title>t20</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1400.3184,-161.1062 1129.6816,-161.1062 1125.6816,-157.1062 1125.6816,-125.1062 1396.3184,-125.1062 1400.3184,-129.1062 1400.3184,-161.1062"/>
|
||||
<polyline fill="none" stroke="#000000" points="1396.3184,-157.1062 1125.6816,-157.1062 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1396.3184,-157.1062 1396.3184,-125.1062 "/>
|
||||
<polyline fill="none" stroke="#000000" points="1396.3184,-157.1062 1400.3184,-161.1062 "/>
|
||||
<text text-anchor="middle" x="1263" y="-137.1062" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.optimize_pdf</text>
|
||||
</g>
|
||||
<!-- t18->t20 -->
|
||||
<g id="edge29" class="edge">
|
||||
<title>t17->t19</title>
|
||||
<path fill="none" stroke="#0044a0" d="M750.0003,-234.162C823.2979,-223.6769 917.4921,-210.2027 1001.3789,-198.2028"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1001.8891,-201.6656 1011.2927,-196.7847 1000.8978,-194.7361 1001.8891,-201.6656"/>
|
||||
</g>
|
||||
<!-- t15->t19 -->
|
||||
<g id="edge30" class="edge">
|
||||
<title>t15->t19</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1008.3983,-317.5273C1042.5211,-292.0754 1105.4861,-245.1103 1151.601,-210.7137"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1153.7921,-213.4458 1159.7152,-204.6613 1149.6068,-207.8347 1153.7921,-213.4458"/>
|
||||
</g>
|
||||
<!-- t18->t19 -->
|
||||
<g id="edge28" class="edge">
|
||||
<title>t18->t19</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1346.2292,-915.7283C1397.8362,-897.768 1459,-864.4247 1459,-807.2656 1459,-807.2656 1459,-807.2656 1459,-335.7258 1459,-274.6094 1406.7951,-234.4876 1350.0021,-208.9223"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1351.0491,-205.5613 1340.4826,-204.7869 1348.26,-211.9816 1351.0491,-205.5613"/>
|
||||
<title>t18->t20</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1263,-182.9188C1263,-179.129 1263,-175.3607 1263,-171.739"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1266.5001,-171.4394 1263,-161.4394 1259.5001,-171.4394 1266.5001,-171.4394"/>
|
||||
</g>
|
||||
<!-- t21 -->
|
||||
<g id="node21" class="node">
|
||||
<title>t21</title>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1041.0652,-47.332 1208,-20.0049 1374.9348,-47.332 1374.779,-91.5483 1041.221,-91.5483 1041.0652,-47.332"/>
|
||||
<polygon fill="none" stroke="#000000" points="1037.0538,-43.9306 1208,-15.9468 1378.9462,-43.9306 1378.7643,-95.5532 1037.2357,-95.5532 1037.0538,-43.9306"/>
|
||||
<text text-anchor="middle" x="1208" y="-53.5531" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.copy_final</text>
|
||||
<polygon fill="#efa03b" stroke="#000000" points="1096.0652,-47.332 1263,-20.0049 1429.9348,-47.332 1429.779,-91.5483 1096.221,-91.5483 1096.0652,-47.332"/>
|
||||
<polygon fill="none" stroke="#000000" points="1092.0538,-43.9306 1263,-15.9468 1433.9462,-43.9306 1433.7643,-95.5532 1092.2357,-95.5532 1092.0538,-43.9306"/>
|
||||
<text text-anchor="middle" x="1263" y="-53.5531" font-family="Times,serif" font-size="20.00" fill="#000000">ocrmypdf.pipeline.copy_final</text>
|
||||
</g>
|
||||
<!-- t19->t21 -->
|
||||
<g id="edge32" class="edge">
|
||||
<title>t19->t21</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1208,-124.9024C1208,-118.6745 1208,-112.2508 1208,-105.974"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1211.5001,-105.6096 1208,-95.6097 1204.5001,-105.6097 1211.5001,-105.6096"/>
|
||||
<!-- t20->t21 -->
|
||||
<g id="edge30" class="edge">
|
||||
<title>t20->t21</title>
|
||||
<path fill="none" stroke="#0044a0" d="M1263,-124.9764C1263,-119.37 1263,-112.9163 1263,-106.2938"/>
|
||||
<polygon fill="#0044a0" stroke="#0044a0" points="1266.5001,-105.8456 1263,-95.8457 1259.5001,-105.8457 1266.5001,-105.8456"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
@@ -826,9 +826,10 @@ def run_pipeline():
|
||||
|
||||
# Performance is improved by setting Tesseract to single threaded. In tests
|
||||
# this gives better throughput than letting a smaller number of Tesseract
|
||||
# jobs run multithreaded.
|
||||
if tesseract.v4():
|
||||
os.environ.setdefault('OMP_THREAD_LIMIT', '1')
|
||||
# jobs run multithreaded. Same story for pngquant. Tess <4 ignores this
|
||||
# variable, but harmless to set if ignored.
|
||||
os.environ.setdefault('OMP_THREAD_LIMIT', '1')
|
||||
|
||||
check_environ(options, _log)
|
||||
if os.environ.get('PYTEST_CURRENT_TEST'):
|
||||
os.environ['_OCRMYPDF_TEST_INFILE'] = options.input_file
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
# © 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 pathlib import Path
|
||||
from subprocess import run, PIPE
|
||||
import concurrent.futures
|
||||
from collections import defaultdict
|
||||
import struct
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
|
||||
from .lib import fitz
|
||||
import pikepdf
|
||||
|
||||
from . import leptonica
|
||||
from .helpers import re_symlink
|
||||
from .exec import pngquant
|
||||
|
||||
PAGE_GROUP_SIZE = 10
|
||||
SIMPLE_COLORSPACES = ('/DeviceRGB', '/DeviceGray', '/CalRGB', '/CalGray')
|
||||
|
||||
|
||||
def filter_decodeparms(obj):
|
||||
"""
|
||||
PDF has a lot of optional data structures concerning /Filter and
|
||||
/DecodeParms. /Filter can be absent or a name or an array, /DecodeParms
|
||||
can be absent or a dictionary (if /Filter is a name) or an array (if
|
||||
/Filter is an array). When both are arrays the lengths match.
|
||||
|
||||
Normalize this into:
|
||||
[(/FilterName, {/DecodeParmName: Value, ...}), ...]
|
||||
|
||||
If there are no filters then the return is
|
||||
[('', {})]
|
||||
|
||||
The order of /Filter matters as indicates the encoding/decoding sequence.
|
||||
|
||||
"""
|
||||
normalized = []
|
||||
filters = []
|
||||
filt = obj.get('/Filter', None)
|
||||
if filt is None:
|
||||
return [('', {})]
|
||||
if filt.type_code == pikepdf.ObjectType.array:
|
||||
filters.extend(filt)
|
||||
elif filt.type_code == pikepdf.ObjectType.name:
|
||||
filters.append(filt)
|
||||
|
||||
decodeparms = obj.get('/DecodeParms', pikepdf.Array([]))
|
||||
if decodeparms.type_code == pikepdf.ObjectType.dictionary:
|
||||
decodeparms = pikepdf.Array([decodeparms])
|
||||
|
||||
for n, dp in enumerate(decodeparms):
|
||||
filt_parm = (filters[n], dp)
|
||||
normalized.append(filt_parm)
|
||||
if len(normalized) == 0:
|
||||
for filt in filters:
|
||||
filt_parm = (filt, {})
|
||||
normalized.append(filt_parm)
|
||||
|
||||
if len(normalized) == 0:
|
||||
return [('', {})]
|
||||
return normalized
|
||||
|
||||
|
||||
def generate_ccitt_header(data, w, h, decode_parms):
|
||||
# https://stackoverflow.com/questions/2641770/
|
||||
# https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf
|
||||
|
||||
if not decode_parms:
|
||||
raise ValueError("/CCITTFaxDecode without /DecodeParms")
|
||||
|
||||
if decode_parms.get("/K", 1) < 0:
|
||||
ccitt_group = 4 # Pure two-dimensional encoding (Group 4)
|
||||
else:
|
||||
ccitt_group = 3
|
||||
|
||||
img_size = len(data)
|
||||
tiff_header_struct = '<' + '2s' + 'H' + 'L' + 'H' + 'HHLL' * 8 + 'L'
|
||||
tiff_header = struct.pack(
|
||||
tiff_header_struct,
|
||||
b'II', # Byte order indication: Little endian
|
||||
42, # Version number (always 42)
|
||||
8, # Offset to first IFD
|
||||
8, # Number of tags in IFD
|
||||
256, 4, 1, w, # ImageWidth, LONG, 1, width
|
||||
257, 4, 1, h, # ImageLength, LONG, 1, length
|
||||
258, 3, 1, 1, # BitsPerSample, SHORT, 1, 1
|
||||
259, 3, 1, ccitt_group, # Compression, SHORT, 1, 4 = CCITT Group 4 fax encoding
|
||||
262, 3, 1, 0, # Thresholding, SHORT, 1, 0 = WhiteIsZero
|
||||
273, 4, 1, struct.calcsize(tiff_header_struct), # StripOffsets, LONG, 1, length of header
|
||||
278, 4, 1, h, # RowsPerStrip, LONG, 1, length
|
||||
279, 4, 1, img_size, # StripByteCounts, LONG, 1, size of image
|
||||
0 # last IFD
|
||||
)
|
||||
|
||||
return tiff_header
|
||||
|
||||
|
||||
def make_img_name(root, xref):
|
||||
return str(root / '{:08d}.png'.format(xref))
|
||||
|
||||
|
||||
def extract_image(doc, pike, root, log, image, xref, jbig2s,
|
||||
pngs, jpegs):
|
||||
if image.Subtype != '/Image':
|
||||
return False
|
||||
if image.Length < 100:
|
||||
log.debug("Skipping small image, xref {}".format(xref))
|
||||
return False
|
||||
|
||||
bpc = image.get('/BitsPerComponent', 8)
|
||||
cs = image.get('/ColorSpace', '')
|
||||
w = int(image.Width)
|
||||
h = int(image.Height)
|
||||
filtdps = filter_decodeparms(image)
|
||||
if len(filtdps) > 1:
|
||||
log.debug("Skipping multiply filtered, xref {}".format(xref))
|
||||
return False
|
||||
filtdp = filtdps[0]
|
||||
|
||||
if bpc == 1 and filtdp[0] != '/JBIG2Decode':
|
||||
if filtdp[0] == '/CCITTFaxDecode':
|
||||
data = image.read_raw_bytes()
|
||||
try:
|
||||
header = generate_ccitt_header(data, w, h, filtdp[1])
|
||||
except ValueError as e:
|
||||
log.info(e)
|
||||
return False
|
||||
stream = BytesIO()
|
||||
stream.write(header)
|
||||
stream.write(data)
|
||||
stream.seek(0)
|
||||
with Image.open(stream) as im:
|
||||
im.save(make_img_name(root, xref))
|
||||
else:
|
||||
return False
|
||||
jbig2s.append(xref)
|
||||
elif filtdp[0] == '/JPXDecode':
|
||||
return False
|
||||
elif filtdp[0] == '/DCTDecode' and cs in SIMPLE_COLORSPACES:
|
||||
raw_jpeg = pike._get_object_id(xref, 0)
|
||||
color_transform = filtdp[1].get('/ColorTransform', 1)
|
||||
if color_transform != 1:
|
||||
return False # Don't mess with JPEGs other than YUV
|
||||
|
||||
# This is a simple heuristic derived from some training data, that has
|
||||
# about a 70% chance of guessing whether the JPEG is high quality,
|
||||
# and possibly recompressible, or not. The number itself doesn't mean
|
||||
# anything.
|
||||
# bytes_per_pixel = int(raw_jpeg.Length) / (w * h)
|
||||
# jpeg_quality_estimate = 117.0 * (bytes_per_pixel ** 0.213)
|
||||
# if jpeg_quality_estimate < 65:
|
||||
# return False
|
||||
|
||||
raw_jpeg_data = raw_jpeg.read_raw_bytes()
|
||||
(root / '{:08d}.jpg'.format(xref)).write_bytes(raw_jpeg_data)
|
||||
jpegs.append(xref)
|
||||
elif cs in SIMPLE_COLORSPACES:
|
||||
# For any 'inferior' filter include /FlateDecode we extract
|
||||
# and recode as /FlateDecode
|
||||
# raw_png = pike._get_object_id(xref, 0)
|
||||
# raw_png_data = raw_png.read_raw_bytes()
|
||||
# (root / '{:08d}.png'.format(xref)).write_bytes(raw_png_data)
|
||||
pix = fitz.Pixmap(doc, xref)
|
||||
pix.writePNG(make_img_name(root, xref), savealpha=False)
|
||||
pngs.append(xref)
|
||||
else:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def extract_images(doc, pike, root, log):
|
||||
# Extract images we can improve
|
||||
changed_xrefs = set()
|
||||
jbig2_groups = defaultdict(lambda: [])
|
||||
jpegs = []
|
||||
pngs = []
|
||||
errors = 0
|
||||
for pageno, page in enumerate(pike.pages):
|
||||
group, _ = divmod(pageno, PAGE_GROUP_SIZE)
|
||||
try:
|
||||
xobjs = page.Resources.XObject
|
||||
except AttributeError:
|
||||
continue
|
||||
for imname, image in dict(xobjs).items():
|
||||
xref = image._objgen[0]
|
||||
if xref in changed_xrefs:
|
||||
continue # Don't improve same image twice
|
||||
try:
|
||||
result = extract_image(
|
||||
doc, pike, root, log, image, xref,
|
||||
jbig2_groups[group], pngs, jpegs)
|
||||
if result:
|
||||
changed_xrefs.add(xref)
|
||||
except Exception as e:
|
||||
log.debug("Image {} xref {}".format(imname, xref))
|
||||
log.debug(repr(e))
|
||||
errors += 1
|
||||
|
||||
# Elide empty groups
|
||||
jbig2_groups = {group: xrefs for group, xrefs in jbig2_groups.items()
|
||||
if len(xrefs) > 0}
|
||||
log.debug(
|
||||
"Optimizable images: "
|
||||
"JBIG2 groups: {} JPEGs: {} PNGs: {} Errors: {}".format(
|
||||
len(jbig2_groups), len(jpegs), len(pngs), errors
|
||||
))
|
||||
|
||||
return changed_xrefs, jbig2_groups, jpegs, pngs
|
||||
|
||||
|
||||
def convert_to_jbig2(pike, jbig2_groups, root, log, options):
|
||||
"""
|
||||
Convert a group of JBIG2 images and insert into PDF.
|
||||
|
||||
We use a group because JBIG2 works best with a symbol dictionary that spans
|
||||
multiple pages. When inserted back into the PDF, each JBIG2 must reference
|
||||
the symbol dictionary it is associated with. So convert a group at a time,
|
||||
and replace their streams with a parameter set that points to the
|
||||
appropriate dictionary.
|
||||
|
||||
If too many pages shared the same dictionary JBIG2 encoding becomes more
|
||||
expensive and less efficient.
|
||||
|
||||
"""
|
||||
with concurrent.futures.ThreadPoolExecutor(
|
||||
max_workers=options.jobs) as executor:
|
||||
futures = []
|
||||
for group, xrefs in jbig2_groups.items():
|
||||
prefix = 'group{:08d}'.format(group)
|
||||
cmd = ['jbig2', '-b', prefix, '-s', '-p']
|
||||
cmd.extend(make_img_name(root, xref) for xref in xrefs)
|
||||
future = executor.submit(
|
||||
run, cmd, cwd=str(root), stdout=PIPE, stderr=PIPE)
|
||||
futures.append(future)
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
proc = future.result()
|
||||
proc.check_returncode()
|
||||
log.debug(proc.stderr)
|
||||
|
||||
for group, xrefs in jbig2_groups.items():
|
||||
prefix = 'group{:08d}'.format(group)
|
||||
jbig2_globals_data = (root / (prefix + '.sym')).read_bytes()
|
||||
jbig2_globals = pikepdf.Stream(pike, jbig2_globals_data)
|
||||
|
||||
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)
|
||||
im_obj.write(
|
||||
jbig2_im_data, pikepdf.Name('/JBIG2Decode'),
|
||||
pikepdf.Dictionary({
|
||||
'/JBIG2Globals': jbig2_globals
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
def transcode_jpegs(pike, jpegs, root, log, options):
|
||||
for xref in jpegs:
|
||||
in_jpg = root / '{:08d}.jpg'.format(xref)
|
||||
opt_jpg = root / '{:08d}_opt.jpg'.format(xref)
|
||||
with Image.open(str(in_jpg)) as im:
|
||||
im.save(str(opt_jpg),
|
||||
optimize=True,
|
||||
quality=70)
|
||||
if opt_jpg.stat().st_size > in_jpg.stat().st_size:
|
||||
log.debug("xref {}, jpeg, made larger - skip".format(xref))
|
||||
continue
|
||||
|
||||
compdata = leptonica.CompressedData.open(opt_jpg)
|
||||
im_obj = pike._get_object_id(xref, 0)
|
||||
im_obj.write(
|
||||
compdata.read(), pikepdf.Name('/DCTDecode'),
|
||||
pikepdf.Null()
|
||||
)
|
||||
|
||||
|
||||
def transcode_pngs(pike, pngs, root, options):
|
||||
with concurrent.futures.ThreadPoolExecutor(
|
||||
max_workers=options.jobs) as executor:
|
||||
for xref in pngs:
|
||||
executor.submit(
|
||||
pngquant.quantize,
|
||||
make_img_name(root, xref), make_img_name(root, xref), 65, 80)
|
||||
|
||||
for xref in pngs:
|
||||
im_obj = pike._get_object_id(xref, 0)
|
||||
pix = leptonica.Pix.read(make_img_name(root, xref))
|
||||
compdata = pix.generate_pdf_ci_data(leptonica.lept.L_FLATE_ENCODE, 0)
|
||||
predictor = pikepdf.Null()
|
||||
if compdata.predictor > 0:
|
||||
predictor = pikepdf.Dictionary({'/Predictor': compdata.predictor})
|
||||
|
||||
im_obj.BitsPerComponent = compdata.bps
|
||||
im_obj.Width = compdata.w
|
||||
im_obj.Height = compdata.h
|
||||
|
||||
if compdata.ncolors > 0:
|
||||
palette_pdf_string = compdata.get_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 = 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)
|
||||
|
||||
|
||||
def optimize(
|
||||
input_file,
|
||||
output_file,
|
||||
log,
|
||||
context):
|
||||
|
||||
if not fitz:
|
||||
re_symlink(input_file, output_file)
|
||||
return
|
||||
|
||||
options = context.get_options()
|
||||
doc = fitz.open(input_file)
|
||||
pike = pikepdf.Pdf.open(input_file)
|
||||
|
||||
root = Path(output_file).parent / 'images'
|
||||
root.mkdir(exist_ok=True)
|
||||
changed_xrefs, jbig2_groups, jpegs, pngs = extract_images(
|
||||
doc, pike, root, log)
|
||||
|
||||
convert_to_jbig2(pike, jbig2_groups, root, log, options)
|
||||
|
||||
transcode_jpegs(pike, jpegs, root, log, options)
|
||||
|
||||
transcode_pngs(pike, pngs, root, options)
|
||||
|
||||
# Not object_stream_mode + preserve_pdfa generates noncompliant PDFs
|
||||
target_file = output_file + '_opt.pdf'
|
||||
pike.save(target_file, preserve_pdfa=True)
|
||||
|
||||
input_size = Path(input_file).stat().st_size
|
||||
output_size = Path(target_file).stat().st_size
|
||||
ratio = input_size / output_size
|
||||
savings = 1 - output_size / input_size
|
||||
log.info("Optimize ratio: {:.2f} savings: {:.1f}%".format(
|
||||
ratio, 100 * savings))
|
||||
|
||||
if savings < 0:
|
||||
log.info("Optimize did not improve the file - discarded")
|
||||
re_symlink(input_file, output_file)
|
||||
else:
|
||||
re_symlink(target_file, output_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import logging
|
||||
import sys
|
||||
from .pipeline import JobContext
|
||||
from collections import namedtuple
|
||||
Options = namedtuple('Options', 'jobs')
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
log = logging.getLogger()
|
||||
|
||||
ctx = JobContext()
|
||||
options = Options(jobs=4)
|
||||
ctx.set_options(options)
|
||||
|
||||
optimize(sys.argv[1], sys.argv[2], log, ctx)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,45 @@
|
||||
# © 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
|
||||
from functools import lru_cache
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from . import get_version
|
||||
from ..exceptions import ExitCode
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def version():
|
||||
return get_version('pngquant', regex=r'(\d+(\.\d+)*).*')
|
||||
|
||||
|
||||
def quantize(input_file, output_file, quality_min, quality_max):
|
||||
args = [
|
||||
'pngquant',
|
||||
'--force',
|
||||
'--skip-if-larger',
|
||||
'--output', output_file,
|
||||
'--quality', '{}-{}'.format(quality_min, quality_max),
|
||||
'--',
|
||||
input_file
|
||||
]
|
||||
proc = run(args)
|
||||
proc.check_returncode()
|
||||
@@ -24,6 +24,7 @@ import argparse
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import warnings
|
||||
from tempfile import TemporaryFile
|
||||
from ctypes.util import find_library
|
||||
from .lib._leptonica import ffi
|
||||
@@ -219,6 +220,11 @@ class Pix:
|
||||
|
||||
@classmethod
|
||||
def read(cls, path):
|
||||
warnings.warn('Use Pix.open() instead', DeprecationWarning)
|
||||
return cls.open(path)
|
||||
|
||||
@classmethod
|
||||
def open(cls, path):
|
||||
"""Load an image file into a PIX object.
|
||||
|
||||
Leptonica can load TIFF, PNM (PBM, PGM, PPM), PNG, and JPEG. If
|
||||
@@ -476,6 +482,15 @@ class Pix:
|
||||
raise LeptonicaError("Correlation failed")
|
||||
return correlation[0]
|
||||
|
||||
def generate_pdf_ci_data(self, type_, quality):
|
||||
"Convert to PDF data, with transcoding"
|
||||
p_compdata = ffi.new('L_COMP_DATA **')
|
||||
result = lept.pixGenerateCIData(self._pix, type_, quality, 0,
|
||||
p_compdata)
|
||||
if result != 0:
|
||||
raise LeptonicaError("Generate PDF data failed")
|
||||
return CompressedData(p_compdata[0])
|
||||
|
||||
@staticmethod
|
||||
def _pix_destroy(pix):
|
||||
p_pix = ffi.new('PIX **', pix)
|
||||
@@ -483,6 +498,43 @@ class Pix:
|
||||
# print('pix destroy ' + repr(pix))
|
||||
|
||||
|
||||
class CompressedData:
|
||||
def __init__(self, compdata):
|
||||
self._compdata = ffi.gc(compdata, CompressedData._destroy)
|
||||
|
||||
@classmethod
|
||||
def open(cls, path, jpeg_quality=75):
|
||||
"Open compressed data, without transcoding"
|
||||
filename = fspath(path)
|
||||
|
||||
p_compdata = ffi.new('L_COMP_DATA **')
|
||||
result = lept.l_generateCIDataForPdf(
|
||||
os.fsencode(filename), ffi.NULL, jpeg_quality, p_compdata)
|
||||
if result != 0:
|
||||
raise LeptonicaError("CompressedData.open")
|
||||
return CompressedData(p_compdata[0])
|
||||
|
||||
def read(self):
|
||||
buf = ffi.buffer(self._compdata.datacomp, self._compdata.nbytescomp)
|
||||
return bytes(buf)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if hasattr(self._compdata, name):
|
||||
return getattr(self._compdata, name)
|
||||
raise AttributeError(name)
|
||||
|
||||
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):
|
||||
pp = ffi.new('L_COMP_DATA **', compdata)
|
||||
lept.l_CIDataDestroy(pp)
|
||||
|
||||
|
||||
class Box:
|
||||
"""Wrapper around Leptonica's BOX objects.
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ import _cffi_backend
|
||||
|
||||
ffi = _cffi_backend.FFI('ocrmypdf.lib._leptonica',
|
||||
_version = 0x2601,
|
||||
_types = b'\x00\x00\x0F\x0D\x00\x00\xBB\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xBE\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\xBA\x03\x00\x00\x0F\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x02\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xC9\x03\x00\x00\x1C\x01\x00\x00\x00\x0F\x00\x00\xBD\x0D\x00\x00\x00\x0F\x00\x00\x49\x0D\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x1F\x03\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x49\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x01\x03\x00\x00\x9D\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\xC8\x03\x00\x00\x65\x03\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x08\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\xC6\x03\x00\x00\xA3\x11\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\xCC\x0D\x00\x00\x10\x11\x00\x00\x00\x0F\x00\x00\xCC\x0D\x00\x00\x9D\x11\x00\x00\x00\x0F\x00\x00\xCC\x0D\x00\x00\xCC\x03\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x09\x00\x00\xBE\x03\x00\x00\x02\x01\x00\x00\x0E\x01\x00\x00\x00\x0B\x00\x00\x01\x0B\x00\x00\x0B\x01\x00\x00\x05\x01\x00\x00\x03\x01\x00\x00\xBC\x03\x00\x00\xC7\x03\x00\x00\x04\x01\x00\x00\xC9\x03\x00\x00\x08\x01\x00\x00\x0C\x01\x00\x00\x06\x01\x00\x00\x00\x01',
|
||||
_globals = (b'\xFF\xFF\xFF\x0BL_CLONE',2,b'\xFF\xFF\xFF\x0BL_COPY',1,b'\xFF\xFF\xFF\x0BL_COPY_CLONE',3,b'\xFF\xFF\xFF\x0BL_INSERT',0,b'\xFF\xFF\xFF\x0BL_NOCOPY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_BASED_ON_SRC',4,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_BINARY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_FULL_COLOR',2,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_GRAYSCALE',1,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_WITH_ALPHA',3,b'\x00\x00\xB1\x23boxDestroy',0,b'\x00\x00\x67\x23getLeptonicaVersion',0,b'\x00\x00\xB7\x23lept_free',0,b'\x00\x00\x69\x23makePixelSumTab8',0,b'\x00\x00\x16\x23pixAnd',0,b'\x00\x00\x23\x23pixBackgroundNorm',0,b'\x00\x00\x1B\x23pixCleanBackgroundToWhite',0,b'\x00\x00\x0D\x23pixClipRectangle',0,b'\x00\x00\x8D\x23pixColorFraction',0,b'\x00\x00\x59\x23pixColorMagnitude',0,b'\x00\x00\x0A\x23pixConvertRGBToLuminance',0,b'\x00\x00\x6B\x23pixCorrelationBinary',0,b'\x00\x00\x80\x23pixCountPixels',0,b'\x00\x00\x63\x23pixDeserializeFromMemory',0,b'\x00\x00\x50\x23pixDeskew',0,b'\x00\x00\xB4\x23pixDestroy',0,b'\x00\x00\x0A\x23pixEndianByteSwapNew',0,b'\x00\x00\x00\x23pixFindPageForeground',0,b'\x00\x00\x7B\x23pixFindSkew',0,b'\x00\x00\x2F\x23pixGammaTRC',0,b'\x00\x00\x70\x23pixGetAverageMaskedRGB',0,b'\x00\x00\x36\x23pixGlobalNormRGB',0,b'\x00\x00\x12\x23pixInvert',0,b'\x00\x00\x54\x23pixMaskOverColorPixels',0,b'\x00\x00\x85\x23pixNumSignificantGrayColors',0,b'\x00\x00\x96\x23pixOtsuAdaptiveThreshold',0,b'\x00\x00\x3E\x23pixOtsuThreshOnBackgroundNorm',0,b'\x00\x00\x60\x23pixRead',0,b'\x00\x00\x50\x23pixRemoveColormap',0,b'\x00\x00\x54\x23pixRemoveColormapGeneral',0,b'\x00\x00\x12\x23pixRotate180',0,b'\x00\x00\x50\x23pixRotateOrth',0,b'\x00\x00\x4B\x23pixScale',0,b'\x00\x00\xA0\x23pixSerializeToMemory',0,b'\x00\x00\xA5\x23pixWriteImpliedFormat',0,b'\x00\x00\xAB\x23pixWriteMemPng',0),
|
||||
_struct_unions = ((b'\x00\x00\x00\xBA\x00\x00\x00\x02Box',b'\x00\x00\x02\x11x',b'\x00\x00\x02\x11y',b'\x00\x00\x02\x11w',b'\x00\x00\x02\x11h',b'\x00\x00\xC9\x11refcount'),(b'\x00\x00\x00\xBB\x00\x00\x00\x02Pix',b'\x00\x00\xC9\x11w',b'\x00\x00\xC9\x11h',b'\x00\x00\xC9\x11d',b'\x00\x00\xC9\x11spp',b'\x00\x00\xC9\x11wpl',b'\x00\x00\xC9\x11refcount',b'\x00\x00\x02\x11xres',b'\x00\x00\x02\x11yres',b'\x00\x00\x02\x11informat',b'\x00\x00\x02\x11special',b'\x00\x00\xBD\x11text',b'\x00\x00\xC5\x11colormap',b'\x00\x00\xC8\x11data'),(b'\x00\x00\x00\xBC\x00\x00\x00\x02PixColormap',b'\x00\x00\xB8\x11array',b'\x00\x00\x02\x11depth',b'\x00\x00\x02\x11nalloc',b'\x00\x00\x02\x11n')),
|
||||
_enums = (b'\x00\x00\x00\xC0\x00\x00\x00\x16$1\x00REMOVE_CMAP_TO_BINARY,REMOVE_CMAP_TO_GRAYSCALE,REMOVE_CMAP_TO_FULL_COLOR,REMOVE_CMAP_WITH_ALPHA,REMOVE_CMAP_BASED_ON_SRC',b'\x00\x00\x00\xC1\x00\x00\x00\x16$2\x00L_NOCOPY,L_INSERT,L_COPY,L_CLONE,L_COPY_CLONE'),
|
||||
_typenames = (b'\x00\x00\x00\xBABOX',b'\x00\x00\x00\xBBPIX',b'\x00\x00\x00\xBCPIXCMAP',b'\x00\x00\x00\x1Fl_float32',b'\x00\x00\x00\xBFl_float64',b'\x00\x00\x00\xC3l_int16',b'\x00\x00\x00\x02l_int32',b'\x00\x00\x00\xC2l_int64',b'\x00\x00\x00\xC4l_int8',b'\x00\x00\x00\xCBl_uint16',b'\x00\x00\x00\xC9l_uint32',b'\x00\x00\x00\xCAl_uint64',b'\x00\x00\x00\xC7l_uint8'),
|
||||
_types = b'\x00\x00\x0F\x0D\x00\x00\xCD\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xD0\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\xCA\x03\x00\x00\x0F\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x02\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xDC\x03\x00\x00\x1C\x01\x00\x00\x00\x0F\x00\x00\xCF\x0D\x00\x00\x00\x0F\x00\x00\x49\x0D\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x1F\x03\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x49\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xCB\x03\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6E\x11\x00\x00\x6E\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x01\x03\x00\x00\xA4\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x01\x11\x00\x00\xDB\x03\x00\x00\x65\x03\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x08\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x92\x11\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x08\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\xD9\x03\x00\x00\xAA\x11\x00\x00\x01\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\xDF\x0D\x00\x00\x10\x11\x00\x00\x00\x0F\x00\x00\xDF\x0D\x00\x00\x92\x11\x00\x00\x00\x0F\x00\x00\xDF\x0D\x00\x00\xA4\x11\x00\x00\x00\x0F\x00\x00\xDF\x0D\x00\x00\xDF\x03\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\xCC\x03\x00\x00\x01\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\xD0\x03\x00\x00\x02\x01\x00\x00\x0E\x01\x00\x00\x00\x0B\x00\x00\x01\x0B\x00\x00\x02\x0B\x00\x00\x0B\x01\x00\x00\x05\x01\x00\x00\x03\x01\x00\x00\xCE\x03\x00\x00\xDA\x03\x00\x00\x04\x01\x00\x00\xDC\x03\x00\x00\x08\x01\x00\x00\x0C\x01\x00\x00\x06\x01\x00\x00\x00\x01',
|
||||
_globals = (b'\xFF\xFF\xFF\x0BL_CLONE',2,b'\xFF\xFF\xFF\x0BL_COPY',1,b'\xFF\xFF\xFF\x0BL_COPY_CLONE',3,b'\xFF\xFF\xFF\x0BL_DEFAULT_ENCODE',0,b'\xFF\xFF\xFF\x0BL_FLATE_ENCODE',3,b'\xFF\xFF\xFF\x0BL_G4_ENCODE',2,b'\xFF\xFF\xFF\x0BL_INSERT',0,b'\xFF\xFF\xFF\x0BL_JP2K_ENCODE',4,b'\xFF\xFF\xFF\x0BL_JPEG_ENCODE',1,b'\xFF\xFF\xFF\x0BL_NOCOPY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_BASED_ON_SRC',4,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_BINARY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_FULL_COLOR',2,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_GRAYSCALE',1,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_WITH_ALPHA',3,b'\x00\x00\xBE\x23boxDestroy',0,b'\x00\x00\x67\x23getLeptonicaVersion',0,b'\x00\x00\xC1\x23l_CIDataDestroy',0,b'\x00\x00\xAC\x23l_generateCIDataForPdf',0,b'\x00\x00\xC7\x23lept_free',0,b'\x00\x00\x69\x23makePixelSumTab8',0,b'\x00\x00\x16\x23pixAnd',0,b'\x00\x00\x23\x23pixBackgroundNorm',0,b'\x00\x00\x1B\x23pixCleanBackgroundToWhite',0,b'\x00\x00\x0D\x23pixClipRectangle',0,b'\x00\x00\x94\x23pixColorFraction',0,b'\x00\x00\x59\x23pixColorMagnitude',0,b'\x00\x00\x0A\x23pixConvertRGBToLuminance',0,b'\x00\x00\x6B\x23pixCorrelationBinary',0,b'\x00\x00\x80\x23pixCountPixels',0,b'\x00\x00\x63\x23pixDeserializeFromMemory',0,b'\x00\x00\x50\x23pixDeskew',0,b'\x00\x00\xC4\x23pixDestroy',0,b'\x00\x00\x0A\x23pixEndianByteSwapNew',0,b'\x00\x00\x00\x23pixFindPageForeground',0,b'\x00\x00\x7B\x23pixFindSkew',0,b'\x00\x00\x2F\x23pixGammaTRC',0,b'\x00\x00\x8D\x23pixGenerateCIData',0,b'\x00\x00\x70\x23pixGetAverageMaskedRGB',0,b'\x00\x00\x36\x23pixGlobalNormRGB',0,b'\x00\x00\x12\x23pixInvert',0,b'\x00\x00\x54\x23pixMaskOverColorPixels',0,b'\x00\x00\x85\x23pixNumSignificantGrayColors',0,b'\x00\x00\x9D\x23pixOtsuAdaptiveThreshold',0,b'\x00\x00\x3E\x23pixOtsuThreshOnBackgroundNorm',0,b'\x00\x00\x60\x23pixRead',0,b'\x00\x00\x50\x23pixRemoveColormap',0,b'\x00\x00\x54\x23pixRemoveColormapGeneral',0,b'\x00\x00\x12\x23pixRotate180',0,b'\x00\x00\x50\x23pixRotateOrth',0,b'\x00\x00\x4B\x23pixScale',0,b'\x00\x00\xA7\x23pixSerializeToMemory',0,b'\x00\x00\xB2\x23pixWriteImpliedFormat',0,b'\x00\x00\xB8\x23pixWriteMemPng',0),
|
||||
_struct_unions = ((b'\x00\x00\x00\xCA\x00\x00\x00\x02Box',b'\x00\x00\x02\x11x',b'\x00\x00\x02\x11y',b'\x00\x00\x02\x11w',b'\x00\x00\x02\x11h',b'\x00\x00\xDC\x11refcount'),(b'\x00\x00\x00\xCC\x00\x00\x00\x02L_Compressed_Data',b'\x00\x00\x02\x11type',b'\x00\x00\xD9\x11datacomp',b'\x00\x00\x65\x11nbytescomp',b'\x00\x00\xCF\x11data85',b'\x00\x00\x65\x11nbytes85',b'\x00\x00\xCF\x11cmapdata85',b'\x00\x00\xCF\x11cmapdatahex',b'\x00\x00\x02\x11ncolors',b'\x00\x00\x02\x11w',b'\x00\x00\x02\x11h',b'\x00\x00\x02\x11bps',b'\x00\x00\x02\x11spp',b'\x00\x00\x02\x11minisblack',b'\x00\x00\x02\x11predictor',b'\x00\x00\x65\x11nbytescomp',b'\x00\x00\xCF\x11data85',b'\x00\x00\x65\x11nbytes85',b'\x00\x00\xCF\x11cmapdata85',b'\x00\x00\xCF\x11cmapdatahex',b'\x00\x00\x02\x11ncolors',b'\x00\x00\x02\x11w',b'\x00\x00\x02\x11h',b'\x00\x00\x02\x11bps',b'\x00\x00\x02\x11spp',b'\x00\x00\x02\x11minisblack',b'\x00\x00\x02\x11predictor',b'\x00\x00\x65\x11nbytes',b'\x00\x00\x02\x11res'),(b'\x00\x00\x00\xCD\x00\x00\x00\x02Pix',b'\x00\x00\xDC\x11w',b'\x00\x00\xDC\x11h',b'\x00\x00\xDC\x11d',b'\x00\x00\xDC\x11spp',b'\x00\x00\xDC\x11wpl',b'\x00\x00\xDC\x11refcount',b'\x00\x00\x02\x11xres',b'\x00\x00\x02\x11yres',b'\x00\x00\x02\x11informat',b'\x00\x00\x02\x11special',b'\x00\x00\xCF\x11text',b'\x00\x00\xD8\x11colormap',b'\x00\x00\xDB\x11data'),(b'\x00\x00\x00\xCE\x00\x00\x00\x02PixColormap',b'\x00\x00\xC8\x11array',b'\x00\x00\x02\x11depth',b'\x00\x00\x02\x11nalloc',b'\x00\x00\x02\x11n')),
|
||||
_enums = (b'\x00\x00\x00\xD2\x00\x00\x00\x16$1\x00L_DEFAULT_ENCODE,L_JPEG_ENCODE,L_G4_ENCODE,L_FLATE_ENCODE,L_JP2K_ENCODE',b'\x00\x00\x00\xD3\x00\x00\x00\x16$2\x00REMOVE_CMAP_TO_BINARY,REMOVE_CMAP_TO_GRAYSCALE,REMOVE_CMAP_TO_FULL_COLOR,REMOVE_CMAP_WITH_ALPHA,REMOVE_CMAP_BASED_ON_SRC',b'\x00\x00\x00\xD4\x00\x00\x00\x16$3\x00L_NOCOPY,L_INSERT,L_COPY,L_CLONE,L_COPY_CLONE'),
|
||||
_typenames = (b'\x00\x00\x00\xCABOX',b'\x00\x00\x00\xCCL_COMP_DATA',b'\x00\x00\x00\xCDPIX',b'\x00\x00\x00\xCEPIXCMAP',b'\x00\x00\x00\x1Fl_float32',b'\x00\x00\x00\xD1l_float64',b'\x00\x00\x00\xD6l_int16',b'\x00\x00\x00\x02l_int32',b'\x00\x00\x00\xD5l_int64',b'\x00\x00\x00\xD7l_int8',b'\x00\x00\x00\xDEl_uint16',b'\x00\x00\x00\xDCl_uint32',b'\x00\x00\x00\xDDl_uint64',b'\x00\x00\x00\xDAl_uint8'),
|
||||
)
|
||||
|
||||
@@ -72,6 +72,49 @@ struct Box
|
||||
};
|
||||
typedef struct Box BOX;
|
||||
|
||||
|
||||
/*! Pdf formatted encoding types */
|
||||
enum {
|
||||
L_DEFAULT_ENCODE = 0, /*!< use default encoding based on image */
|
||||
L_JPEG_ENCODE = 1, /*!< use dct encoding: 8 and 32 bpp, no cmap */
|
||||
L_G4_ENCODE = 2, /*!< use ccitt g4 fax encoding: 1 bpp */
|
||||
L_FLATE_ENCODE = 3, /*!< use flate encoding: any depth, cmap ok */
|
||||
L_JP2K_ENCODE = 4 /*!< use jp2k encoding: 8 and 32 bpp, no cmap */
|
||||
};
|
||||
|
||||
struct L_Compressed_Data
|
||||
{
|
||||
l_int32 type; /*!< encoding type: L_JPEG_ENCODE, etc */
|
||||
l_uint8 *datacomp; /*!< gzipped raster data */
|
||||
size_t nbytescomp; /*!< number of compressed bytes */
|
||||
char *data85; /*!< ascii85-encoded gzipped raster data */
|
||||
size_t nbytes85; /*!< number of ascii85 encoded bytes */
|
||||
char *cmapdata85; /*!< ascii85-encoded uncompressed cmap */
|
||||
char *cmapdatahex; /*!< hex pdf array for the cmap */
|
||||
l_int32 ncolors; /*!< number of colors in cmap */
|
||||
l_int32 w; /*!< image width */
|
||||
l_int32 h; /*!< image height */
|
||||
l_int32 bps; /*!< bits/sample; typ. 1, 2, 4 or 8 */
|
||||
l_int32 spp; /*!< samples/pixel; typ. 1 or 3 */
|
||||
l_int32 minisblack; /*!< tiff g4 photometry */
|
||||
l_int32 predictor; /*!< flate data has PNG predictors */
|
||||
size_t nbytescomp; /*!< number of compressed bytes */
|
||||
char *data85; /*!< ascii85-encoded gzipped raster data */
|
||||
size_t nbytes85; /*!< number of ascii85 encoded bytes */
|
||||
char *cmapdata85; /*!< ascii85-encoded uncompressed cmap */
|
||||
char *cmapdatahex; /*!< hex pdf array for the cmap */
|
||||
l_int32 ncolors; /*!< number of colors in cmap */
|
||||
l_int32 w; /*!< image width */
|
||||
l_int32 h; /*!< image height */
|
||||
l_int32 bps; /*!< bits/sample; typ. 1, 2, 4 or 8 */
|
||||
l_int32 spp; /*!< samples/pixel; typ. 1 or 3 */
|
||||
l_int32 minisblack; /*!< tiff g4 photometry */
|
||||
l_int32 predictor; /*!< flate data has PNG predictors */
|
||||
size_t nbytes; /*!< number of uncompressed raster bytes */
|
||||
l_int32 res; /*!< resolution (ppi) */
|
||||
};
|
||||
typedef struct L_Compressed_Data L_COMP_DATA;
|
||||
|
||||
enum {
|
||||
REMOVE_CMAP_TO_BINARY = 0, /*!< remove colormap for conv to 1 bpp */
|
||||
REMOVE_CMAP_TO_GRAYSCALE = 1, /*!< remove colormap for conv to 8 bpp */
|
||||
@@ -250,9 +293,25 @@ pixRemoveColormapGeneral(PIX *pixs,
|
||||
l_int32 type,
|
||||
l_int32 ifnocmap);
|
||||
|
||||
l_int32
|
||||
pixGenerateCIData(PIX *pixs,
|
||||
l_int32 type,
|
||||
l_int32 quality,
|
||||
l_int32 ascii85,
|
||||
L_COMP_DATA **pcid);
|
||||
|
||||
l_int32
|
||||
l_generateCIDataForPdf(const char *fname,
|
||||
PIX *pix,
|
||||
l_int32 quality,
|
||||
L_COMP_DATA **pcid);
|
||||
|
||||
void
|
||||
boxDestroy(BOX **pbox);
|
||||
|
||||
void
|
||||
l_CIDataDestroy(L_COMP_DATA **pcid);
|
||||
|
||||
void
|
||||
lept_free(void *ptr);
|
||||
""")
|
||||
|
||||
@@ -43,7 +43,7 @@ from .exceptions import PdfMergeFailedError, UnsupportedImageFormatError, \
|
||||
DpiError, PriorOcrFoundError, InputFileError
|
||||
from . import leptonica
|
||||
from . import PROGRAM_NAME, VERSION
|
||||
|
||||
from ._optimize import optimize
|
||||
|
||||
|
||||
VECTOR_PAGE_DPI = 400
|
||||
@@ -1144,6 +1144,14 @@ def _do_merge_mupdf(
|
||||
doc.save(output_file, clean=False, garbage=4, deflate=True)
|
||||
|
||||
|
||||
def optimize_pdf(
|
||||
input_file,
|
||||
output_file,
|
||||
log,
|
||||
context):
|
||||
optimize(input_file, output_file, log, context)
|
||||
|
||||
|
||||
def merge_sidecars(
|
||||
input_files_groups,
|
||||
output_file,
|
||||
@@ -1390,9 +1398,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_metadata_fixup,
|
||||
filter=suffix('.pdf'),
|
||||
output='.optimized.pdf',
|
||||
output_dir=work_folder,
|
||||
extras=[log, context])
|
||||
|
||||
# Finalize
|
||||
main_pipeline.merge(
|
||||
task_func=copy_final,
|
||||
input=[task_metadata_fixup],
|
||||
input=[task_optimize_pdf],
|
||||
output=options.output_file,
|
||||
extras=[log, context])
|
||||
|
||||
Reference in New Issue
Block a user