edgeparse 0.3.0__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {edgeparse-0.3.0 → edgeparse-0.3.2}/Cargo.lock +96 -16
- {edgeparse-0.3.0 → edgeparse-0.3.2}/Cargo.toml +1 -1
- {edgeparse-0.3.0 → edgeparse-0.3.2}/PKG-INFO +1 -1
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/Cargo.toml +6 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/api/config.rs +9 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/hybrid.rs +2 -3
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/lib.rs +218 -30
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/chunks.rs +18 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/markdown.rs +156 -34
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/chunk_parser.rs +888 -99
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/encryption.rs +48 -28
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/font.rs +539 -113
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/font_style.rs +159 -0
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/font_type3.rs +206 -0
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/font_type3_ocr.rs +118 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/graphics_state.rs +10 -2
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/image_codecs.rs +217 -0
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/image_extractor.rs +530 -0
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/image_region.rs +146 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/inmem_raster.rs +280 -46
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/line_extractor.rs +97 -35
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/loader.rs +20 -8
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/mod.rs +13 -0
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/ocg.rs +188 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/ocr/mod.rs +1 -1
- edgeparse-0.3.2/crates/edgeparse-core/src/pdf/pdf_string.rs +107 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/raster_table_ocr.rs +30 -10
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/text_extractor.rs +20 -30
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/caption_linker.rs +1 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/cluster_table_detector.rs +7 -7
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/figure_detector.rs +1 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/header_footer.rs +19 -4
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/heading_detector.rs +129 -58
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/id_assignment.rs +1 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/list_detector.rs +71 -1
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/paragraph_detector.rs +1 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/reading_order.rs +1 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/table_detector.rs +2 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/text_block_grouper.rs +1 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/text_line_grouper.rs +62 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/tagged/struct_tree.rs +73 -4
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/image_dedup.rs +1 -1
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/xycut.rs +1 -0
- edgeparse-0.3.2/crates/edgeparse-core/testdata/pattern_form.pdf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-python/src/lib.rs +5 -1
- {edgeparse-0.3.0 → edgeparse-0.3.2}/edgeparse/__init__.py +4 -0
- edgeparse-0.3.0/crates/edgeparse-core/src/pdf/image_extractor.rs +0 -330
- {edgeparse-0.3.0 → edgeparse-0.3.2}/README.md +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/README.md +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/api/batch.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/api/config_loader.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/api/filter.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/api/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/bbox.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/content.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/document.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/enums.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/list.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/semantic.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/table.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/models/text.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/csv.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/docx.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/html.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/json.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/legacy_json.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/text.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/output/toc_builder.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/annotation_enrichment.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/annotation_extractor.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/bookmark_extractor.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/data/glyphlist.txt +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/form_extractor.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/hyperlink_extractor.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/metadata_writer.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/ocr/host_engine.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/ocr/ocrs_engine.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/ocr/tesseract_cli.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pdf/page_info.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/error_recovery.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/logging.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/orchestrator.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/parallel.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/boxed_heading_promoter.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/column_detector.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/content_filter.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/content_sanitizer.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/cross_page_linker.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/footnote_detector.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/footnote_linker.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/list_pass2.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/nesting_level.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/output_builder.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/table_content_assigner.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/toc_detector.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/pipeline/stages/watermark_detector.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/tagged/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/tagged/processor.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/diff.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/font_metrics_cache.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/language_detector.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/layout_analysis.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/page_range.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/sanitizer.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/statistics.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/text_normalizer.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/src/utils/xref_index.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/tests/integration_tests.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-core/tests/perf_benchmarks.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/edgeparse-python/Cargo.toml +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.cargo_vcs_info.json +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.chglog/CHANGELOG.tpl.md +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.chglog/config.yml +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.editorconfig +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.gitattributes +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.github/workflows/ci.yml +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.gitignore +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.vscode/launch.json +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/.vscode/settings.json +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/CHANGELOG.md +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/Cargo.toml +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/LICENSE +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/README.md +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/AnnotationDemo.pdf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/Incremental.pdf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/encrypted.pdf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/example.pdf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/pdf_icon.jpg +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/L16.png +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/L8.jpg +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/La16.png +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/La8.png +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/Rgb16.png +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/Rgb8.jpg +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/Rgba16.png +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/supported_color_type/Rgba8.png +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/assets/unicode.pdf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/benches/datetime.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/benches/parse.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/add_barcode.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/analyze_object_streams.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/analyze_page_contents.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/analyze_pdf.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/analyze_references.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/check_raw_objstream.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/compress_existing_pdf.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/create.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/create_text_heavy_pdf.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/debug_compression_detailed.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/debug_compression_full.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/debug_object_stream.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/debug_save_with_objstreams.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/decrypt.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/encrypt.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/extract_text.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/extract_toc.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/final_compression_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/inspect_object_stream.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/merge.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/object_streams.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/print_annotations.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/replace_partial_text.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/rotate.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_better_compression.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_decryption.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_direct_objstream.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_filter_roundtrip.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_metadata.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_object_stream_creation.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_object_stream_roundtrip.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_real_pdf_compression_with_fix.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/test_structural_compression.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/verify_decryption.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/verify_page_compression.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/verify_pdf.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/examples/verify_trailer_compression_fix.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/rustfmt.toml +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/bookmarks.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/cmap_section.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/common_data_structures/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/content.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/creator.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/datetime.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/destinations.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/document.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encodings/cmap.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encodings/glyphnames.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encodings/mappings.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encodings/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encryption/algorithms.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encryption/crypt_filters.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encryption/pkcs5.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encryption/rc4.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/encryption.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/error.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/filters/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/filters/png.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/font.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/incremental_document.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/lib.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/object.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/object_stream.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/outlines.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/parser/cmap_parser.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/parser/mod.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/parser_aux.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/processor.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/reader.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/save_options.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/toc.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/writer.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/xobject.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/src/xref.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/annotation.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/catalog_compression_integration_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/decryption.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/extract_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/font_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/incremental_document.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/metadata_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/modify.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/object_stream_comprehensive_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/object_stream_edge_cases_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/object_stream_methods_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/object_stream_performance_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/resources/fonts/Montserrat-Regular.ttf +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/simple_object_stream_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/trailer_reference_compression_test.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/unicode.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/crates/pdf-cos/tests/utils.rs +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/edgeparse/_types.py +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/edgeparse/cli.py +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/edgeparse/py.typed +0 -0
- {edgeparse-0.3.0 → edgeparse-0.3.2}/pyproject.toml +0 -0
|
@@ -184,7 +184,7 @@ dependencies = [
|
|
|
184
184
|
"num-traits",
|
|
185
185
|
"pastey",
|
|
186
186
|
"rayon",
|
|
187
|
-
"thiserror",
|
|
187
|
+
"thiserror 2.0.21",
|
|
188
188
|
"v_frame",
|
|
189
189
|
"y4m",
|
|
190
190
|
]
|
|
@@ -582,7 +582,7 @@ version = "1.0.0"
|
|
|
582
582
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
583
583
|
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
|
|
584
584
|
dependencies = [
|
|
585
|
-
"thiserror",
|
|
585
|
+
"thiserror 2.0.21",
|
|
586
586
|
]
|
|
587
587
|
|
|
588
588
|
[[package]]
|
|
@@ -655,7 +655,7 @@ dependencies = [
|
|
|
655
655
|
|
|
656
656
|
[[package]]
|
|
657
657
|
name = "edgeparse-cli"
|
|
658
|
-
version = "0.3.
|
|
658
|
+
version = "0.3.2"
|
|
659
659
|
dependencies = [
|
|
660
660
|
"anyhow",
|
|
661
661
|
"clap",
|
|
@@ -669,13 +669,15 @@ dependencies = [
|
|
|
669
669
|
|
|
670
670
|
[[package]]
|
|
671
671
|
name = "edgeparse-core"
|
|
672
|
-
version = "0.3.
|
|
672
|
+
version = "0.3.2"
|
|
673
673
|
dependencies = [
|
|
674
674
|
"anyhow",
|
|
675
675
|
"base64 0.22.1",
|
|
676
676
|
"euclid",
|
|
677
|
+
"hayro-jbig2",
|
|
677
678
|
"image",
|
|
678
679
|
"indexmap",
|
|
680
|
+
"jpeg2k",
|
|
679
681
|
"js-sys",
|
|
680
682
|
"log",
|
|
681
683
|
"ocrs",
|
|
@@ -688,7 +690,7 @@ dependencies = [
|
|
|
688
690
|
"rten-imageproc",
|
|
689
691
|
"serde",
|
|
690
692
|
"serde_json",
|
|
691
|
-
"thiserror",
|
|
693
|
+
"thiserror 2.0.21",
|
|
692
694
|
"tokio",
|
|
693
695
|
"ttf-parser",
|
|
694
696
|
"unicode-normalization",
|
|
@@ -698,7 +700,7 @@ dependencies = [
|
|
|
698
700
|
|
|
699
701
|
[[package]]
|
|
700
702
|
name = "edgeparse-node"
|
|
701
|
-
version = "0.3.
|
|
703
|
+
version = "0.3.2"
|
|
702
704
|
dependencies = [
|
|
703
705
|
"edgeparse-core",
|
|
704
706
|
"napi",
|
|
@@ -710,7 +712,7 @@ dependencies = [
|
|
|
710
712
|
|
|
711
713
|
[[package]]
|
|
712
714
|
name = "edgeparse-python"
|
|
713
|
-
version = "0.3.
|
|
715
|
+
version = "0.3.2"
|
|
714
716
|
dependencies = [
|
|
715
717
|
"edgeparse-core",
|
|
716
718
|
"pyo3",
|
|
@@ -719,7 +721,7 @@ dependencies = [
|
|
|
719
721
|
|
|
720
722
|
[[package]]
|
|
721
723
|
name = "edgeparse-wasm"
|
|
722
|
-
version = "0.3.
|
|
724
|
+
version = "0.3.2"
|
|
723
725
|
dependencies = [
|
|
724
726
|
"console_error_panic_hook",
|
|
725
727
|
"console_log",
|
|
@@ -1030,6 +1032,21 @@ version = "0.17.1"
|
|
|
1030
1032
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1031
1033
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|
1032
1034
|
|
|
1035
|
+
[[package]]
|
|
1036
|
+
name = "hayro-ccitt"
|
|
1037
|
+
version = "0.3.0"
|
|
1038
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1039
|
+
checksum = "9f4d0e94ddd48749f06bbe4e5389fb9799a0c45bcaf00495042076ef05e3241a"
|
|
1040
|
+
|
|
1041
|
+
[[package]]
|
|
1042
|
+
name = "hayro-jbig2"
|
|
1043
|
+
version = "0.3.0"
|
|
1044
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1045
|
+
checksum = "69374b3668dd45aeb3d3145cda68f2c7b4f223aaa2511e67d076f1c7d741388d"
|
|
1046
|
+
dependencies = [
|
|
1047
|
+
"hayro-ccitt",
|
|
1048
|
+
]
|
|
1049
|
+
|
|
1033
1050
|
[[package]]
|
|
1034
1051
|
name = "heck"
|
|
1035
1052
|
version = "0.5.0"
|
|
@@ -1442,6 +1459,20 @@ dependencies = [
|
|
|
1442
1459
|
"libc",
|
|
1443
1460
|
]
|
|
1444
1461
|
|
|
1462
|
+
[[package]]
|
|
1463
|
+
name = "jpeg2k"
|
|
1464
|
+
version = "0.9.1"
|
|
1465
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1466
|
+
checksum = "f5b1c0ab2091b7044e98ec1910d63f68cc51358ec0dfde83f0b1d7aab654adb9"
|
|
1467
|
+
dependencies = [
|
|
1468
|
+
"anyhow",
|
|
1469
|
+
"image",
|
|
1470
|
+
"log",
|
|
1471
|
+
"openjp2",
|
|
1472
|
+
"openjpeg-sys",
|
|
1473
|
+
"thiserror 1.0.69",
|
|
1474
|
+
]
|
|
1475
|
+
|
|
1445
1476
|
[[package]]
|
|
1446
1477
|
name = "js-sys"
|
|
1447
1478
|
version = "0.3.106"
|
|
@@ -1845,7 +1876,7 @@ dependencies = [
|
|
|
1845
1876
|
"rten",
|
|
1846
1877
|
"rten-imageproc",
|
|
1847
1878
|
"rten-tensor",
|
|
1848
|
-
"thiserror",
|
|
1879
|
+
"thiserror 2.0.21",
|
|
1849
1880
|
"wasm-bindgen",
|
|
1850
1881
|
]
|
|
1851
1882
|
|
|
@@ -1867,6 +1898,29 @@ version = "11.1.5"
|
|
|
1867
1898
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1868
1899
|
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
|
|
1869
1900
|
|
|
1901
|
+
[[package]]
|
|
1902
|
+
name = "openjp2"
|
|
1903
|
+
version = "0.5.3"
|
|
1904
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1905
|
+
checksum = "4c582a03232f5f2f2f0107a7327753df3c32f5505a195cd79cad6aa97d6bddf1"
|
|
1906
|
+
dependencies = [
|
|
1907
|
+
"bitflags 1.3.2",
|
|
1908
|
+
"libc",
|
|
1909
|
+
"log",
|
|
1910
|
+
"smallvec",
|
|
1911
|
+
"sprintf",
|
|
1912
|
+
]
|
|
1913
|
+
|
|
1914
|
+
[[package]]
|
|
1915
|
+
name = "openjpeg-sys"
|
|
1916
|
+
version = "1.0.12"
|
|
1917
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1918
|
+
checksum = "92682cb92e7b01e2c020cf8ec12f3374558924bb24621df1112d8a7c93d419ef"
|
|
1919
|
+
dependencies = [
|
|
1920
|
+
"cc",
|
|
1921
|
+
"libc",
|
|
1922
|
+
]
|
|
1923
|
+
|
|
1870
1924
|
[[package]]
|
|
1871
1925
|
name = "option-ext"
|
|
1872
1926
|
version = "0.2.0"
|
|
@@ -1950,7 +2004,7 @@ dependencies = [
|
|
|
1950
2004
|
"shellexpand",
|
|
1951
2005
|
"stringprep",
|
|
1952
2006
|
"tempfile",
|
|
1953
|
-
"thiserror",
|
|
2007
|
+
"thiserror 2.0.21",
|
|
1954
2008
|
"time",
|
|
1955
2009
|
"tokio",
|
|
1956
2010
|
"ttf-parser",
|
|
@@ -2180,7 +2234,7 @@ dependencies = [
|
|
|
2180
2234
|
"rustc-hash",
|
|
2181
2235
|
"rustls",
|
|
2182
2236
|
"socket2",
|
|
2183
|
-
"thiserror",
|
|
2237
|
+
"thiserror 2.0.21",
|
|
2184
2238
|
"tokio",
|
|
2185
2239
|
"tracing",
|
|
2186
2240
|
"web-time",
|
|
@@ -2202,7 +2256,7 @@ dependencies = [
|
|
|
2202
2256
|
"rustls",
|
|
2203
2257
|
"rustls-pki-types",
|
|
2204
2258
|
"slab",
|
|
2205
|
-
"thiserror",
|
|
2259
|
+
"thiserror 2.0.21",
|
|
2206
2260
|
"tinyvec",
|
|
2207
2261
|
"tracing",
|
|
2208
2262
|
"web-time",
|
|
@@ -2362,7 +2416,7 @@ dependencies = [
|
|
|
2362
2416
|
"rand 0.9.5",
|
|
2363
2417
|
"rand_chacha",
|
|
2364
2418
|
"simd_helpers",
|
|
2365
|
-
"thiserror",
|
|
2419
|
+
"thiserror 2.0.21",
|
|
2366
2420
|
"v_frame",
|
|
2367
2421
|
"wasm-bindgen",
|
|
2368
2422
|
]
|
|
@@ -2433,7 +2487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
2433
2487
|
checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0"
|
|
2434
2488
|
dependencies = [
|
|
2435
2489
|
"libredox",
|
|
2436
|
-
"thiserror",
|
|
2490
|
+
"thiserror 2.0.21",
|
|
2437
2491
|
]
|
|
2438
2492
|
|
|
2439
2493
|
[[package]]
|
|
@@ -2891,6 +2945,12 @@ dependencies = [
|
|
|
2891
2945
|
"windows-sys 0.61.2",
|
|
2892
2946
|
]
|
|
2893
2947
|
|
|
2948
|
+
[[package]]
|
|
2949
|
+
name = "sprintf"
|
|
2950
|
+
version = "0.1.4"
|
|
2951
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2952
|
+
checksum = "6c0cdea5a20a06e7c57f627094e7b1618e5665592cd88f2d45fa4014e348db58"
|
|
2953
|
+
|
|
2894
2954
|
[[package]]
|
|
2895
2955
|
name = "stable_deref_trait"
|
|
2896
2956
|
version = "1.2.1"
|
|
@@ -2981,13 +3041,33 @@ dependencies = [
|
|
|
2981
3041
|
"windows-sys 0.61.2",
|
|
2982
3042
|
]
|
|
2983
3043
|
|
|
3044
|
+
[[package]]
|
|
3045
|
+
name = "thiserror"
|
|
3046
|
+
version = "1.0.69"
|
|
3047
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3048
|
+
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
|
3049
|
+
dependencies = [
|
|
3050
|
+
"thiserror-impl 1.0.69",
|
|
3051
|
+
]
|
|
3052
|
+
|
|
2984
3053
|
[[package]]
|
|
2985
3054
|
name = "thiserror"
|
|
2986
3055
|
version = "2.0.21"
|
|
2987
3056
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2988
3057
|
checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e"
|
|
2989
3058
|
dependencies = [
|
|
2990
|
-
"thiserror-impl",
|
|
3059
|
+
"thiserror-impl 2.0.21",
|
|
3060
|
+
]
|
|
3061
|
+
|
|
3062
|
+
[[package]]
|
|
3063
|
+
name = "thiserror-impl"
|
|
3064
|
+
version = "1.0.69"
|
|
3065
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3066
|
+
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|
3067
|
+
dependencies = [
|
|
3068
|
+
"proc-macro2 1.0.107",
|
|
3069
|
+
"quote 1.0.47",
|
|
3070
|
+
"syn 2.0.119",
|
|
2991
3071
|
]
|
|
2992
3072
|
|
|
2993
3073
|
[[package]]
|
|
@@ -3771,7 +3851,7 @@ dependencies = [
|
|
|
3771
3851
|
"flate2",
|
|
3772
3852
|
"indexmap",
|
|
3773
3853
|
"memchr",
|
|
3774
|
-
"thiserror",
|
|
3854
|
+
"thiserror 2.0.21",
|
|
3775
3855
|
"zopfli",
|
|
3776
3856
|
]
|
|
3777
3857
|
|
|
@@ -40,6 +40,8 @@ rten = { version = "0.26", optional = true, default-features = false, features =
|
|
|
40
40
|
rten-imageproc = { version = "0.26", optional = true }
|
|
41
41
|
js-sys = { version = "0.3", optional = true }
|
|
42
42
|
wasm-bindgen = { version = "0.2", optional = true }
|
|
43
|
+
hayro-jbig2 = { version = "0.3", optional = true, default-features = false, features = ["std"] }
|
|
44
|
+
jpeg2k = { version = "0.9", optional = true }
|
|
43
45
|
|
|
44
46
|
[features]
|
|
45
47
|
default = ["native"]
|
|
@@ -49,5 +51,9 @@ native = ["dep:rayon", "image", "dep:zip", "lopdf/rayon"]
|
|
|
49
51
|
wasm = ["lopdf/wasm_js", "image", "dep:js-sys", "dep:wasm-bindgen"]
|
|
50
52
|
hybrid = ["dep:reqwest", "dep:tokio"]
|
|
51
53
|
ocr-ocrs = ["dep:ocrs", "dep:rten", "dep:rten-imageproc", "image"]
|
|
54
|
+
# Optional PDF image codecs for the OCR path (scanned / hybrid pages).
|
|
55
|
+
codecs-jbig2 = ["dep:hayro-jbig2", "image"]
|
|
56
|
+
codecs-jpx = ["dep:jpeg2k", "image"]
|
|
57
|
+
codecs = ["codecs-jbig2", "codecs-jpx"]
|
|
52
58
|
|
|
53
59
|
[dev-dependencies]
|
|
@@ -116,6 +116,9 @@ pub struct ProcessingConfig {
|
|
|
116
116
|
pub image_dir: Option<String>,
|
|
117
117
|
/// Enable raster table OCR recovery on image-based tables
|
|
118
118
|
pub raster_table_ocr: bool,
|
|
119
|
+
/// Soft wall-clock budget for raster OCR recovery (milliseconds).
|
|
120
|
+
/// `None` = unlimited. When exhausted, remaining images are skipped.
|
|
121
|
+
pub ocr_budget_ms: Option<u64>,
|
|
119
122
|
/// Pages to extract (e.g., "1,3,5-7")
|
|
120
123
|
pub pages: Option<String>,
|
|
121
124
|
/// Include headers/footers in output
|
|
@@ -153,6 +156,7 @@ impl Default for ProcessingConfig {
|
|
|
153
156
|
image_format: ImageFormat::Png,
|
|
154
157
|
image_dir: None,
|
|
155
158
|
raster_table_ocr: true,
|
|
159
|
+
ocr_budget_ms: None,
|
|
156
160
|
pages: None,
|
|
157
161
|
include_header_footer: false,
|
|
158
162
|
hybrid: HybridBackend::Off,
|
|
@@ -178,6 +182,11 @@ impl ProcessingConfig {
|
|
|
178
182
|
pub fn raster_table_ocr_enabled(&self) -> bool {
|
|
179
183
|
self.raster_table_ocr
|
|
180
184
|
}
|
|
185
|
+
|
|
186
|
+
/// OCR wall-clock budget for this document.
|
|
187
|
+
pub fn ocr_budget(&self) -> crate::pdf::image_region::OcrBudget {
|
|
188
|
+
crate::pdf::image_region::OcrBudget::from_millis(self.ocr_budget_ms)
|
|
189
|
+
}
|
|
181
190
|
}
|
|
182
191
|
|
|
183
192
|
#[cfg(test)]
|
|
@@ -381,11 +381,10 @@ fn typographic_heading_deficit(doc: &PdfDocument) -> bool {
|
|
|
381
381
|
body_weights.push(w);
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
|
-
ContentElement::Heading(h)
|
|
385
|
-
if h.base.base.semantic_type != SemanticType::Caption {
|
|
384
|
+
ContentElement::Heading(h)
|
|
385
|
+
if h.base.base.semantic_type != SemanticType::Caption => {
|
|
386
386
|
recovered += 1;
|
|
387
387
|
}
|
|
388
|
-
}
|
|
389
388
|
ContentElement::NumberHeading(_) => {
|
|
390
389
|
recovered += 1;
|
|
391
390
|
}
|
|
@@ -31,9 +31,50 @@ use crate::pdf::raster_table_ocr::{
|
|
|
31
31
|
};
|
|
32
32
|
use crate::pipeline::orchestrator::{run_pipeline, PipelineState};
|
|
33
33
|
use crate::pipeline::stages::heading_detector::refine_heading_hierarchy;
|
|
34
|
-
use crate::tagged::struct_tree::build_mcid_map;
|
|
34
|
+
use crate::tagged::struct_tree::{build_mcid_map, should_use_struct_tree};
|
|
35
35
|
use std::time::Instant;
|
|
36
36
|
|
|
37
|
+
/// Run dominant-image text + raster-table recovery for one page (native only).
|
|
38
|
+
///
|
|
39
|
+
/// Single gate for OCR enablement + wall-clock budget so callers stay DRY.
|
|
40
|
+
#[cfg(not(target_arch = "wasm32"))]
|
|
41
|
+
fn recover_page_image_content(
|
|
42
|
+
input_path: &std::path::Path,
|
|
43
|
+
config: &ProcessingConfig,
|
|
44
|
+
page_info_by_number: &[Option<&page_info::PageInfo>],
|
|
45
|
+
page_num: u32,
|
|
46
|
+
page_chunks: &crate::pdf::chunk_parser::PageChunks,
|
|
47
|
+
ocr_budget: &mut crate::pdf::image_region::OcrBudget,
|
|
48
|
+
) -> (
|
|
49
|
+
Vec<crate::models::chunks::TextChunk>,
|
|
50
|
+
Vec<crate::models::table::TableBorder>,
|
|
51
|
+
) {
|
|
52
|
+
if !config.raster_table_ocr_enabled() || ocr_budget.exhausted() {
|
|
53
|
+
return (Vec::new(), Vec::new());
|
|
54
|
+
}
|
|
55
|
+
let Some(Some(page_info)) = page_info_by_number.get(page_num as usize) else {
|
|
56
|
+
return (Vec::new(), Vec::new());
|
|
57
|
+
};
|
|
58
|
+
let text = recover_dominant_image_text_chunks(
|
|
59
|
+
input_path,
|
|
60
|
+
&page_info.crop_box,
|
|
61
|
+
page_num,
|
|
62
|
+
&page_chunks.text_chunks,
|
|
63
|
+
&page_chunks.image_chunks,
|
|
64
|
+
);
|
|
65
|
+
if ocr_budget.exhausted() {
|
|
66
|
+
return (text, Vec::new());
|
|
67
|
+
}
|
|
68
|
+
let tables = recover_raster_table_borders(
|
|
69
|
+
input_path,
|
|
70
|
+
&page_info.crop_box,
|
|
71
|
+
page_num,
|
|
72
|
+
&page_chunks.text_chunks,
|
|
73
|
+
&page_chunks.image_chunks,
|
|
74
|
+
);
|
|
75
|
+
(text, tables)
|
|
76
|
+
}
|
|
77
|
+
|
|
37
78
|
/// Main entry point: convert a PDF file to structured data.
|
|
38
79
|
///
|
|
39
80
|
/// # Arguments
|
|
@@ -81,28 +122,17 @@ pub fn convert(
|
|
|
81
122
|
let mut page_contents = Vec::with_capacity(pages_map.len());
|
|
82
123
|
|
|
83
124
|
let phase_start = Instant::now();
|
|
125
|
+
let mut ocr_budget = config.ocr_budget();
|
|
84
126
|
for (&page_num, &page_id) in &pages_map {
|
|
85
127
|
let page_chunks = extract_page_chunks(&raw_doc.document, page_num, page_id)?;
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
&page_chunks.text_chunks,
|
|
95
|
-
&page_chunks.image_chunks,
|
|
96
|
-
);
|
|
97
|
-
recovered_tables = recover_raster_table_borders(
|
|
98
|
-
input_path,
|
|
99
|
-
&page_info.crop_box,
|
|
100
|
-
page_num,
|
|
101
|
-
&page_chunks.text_chunks,
|
|
102
|
-
&page_chunks.image_chunks,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
128
|
+
let (recovered_text_chunks, recovered_tables) = recover_page_image_content(
|
|
129
|
+
input_path,
|
|
130
|
+
config,
|
|
131
|
+
&page_info_by_number,
|
|
132
|
+
page_num,
|
|
133
|
+
&page_chunks,
|
|
134
|
+
&mut ocr_budget,
|
|
135
|
+
);
|
|
106
136
|
let mut elements: Vec<ContentElement> = page_chunks
|
|
107
137
|
.text_chunks
|
|
108
138
|
.into_iter()
|
|
@@ -142,9 +172,12 @@ pub fn convert(
|
|
|
142
172
|
}
|
|
143
173
|
log_phase_duration(timing_enabled, "extract_page_chunks", phase_start);
|
|
144
174
|
|
|
145
|
-
// Run the processing pipeline
|
|
146
175
|
let phase_start = Instant::now();
|
|
147
|
-
let mcid_map =
|
|
176
|
+
let mcid_map = if should_use_struct_tree(&raw_doc.document, config.use_struct_tree) {
|
|
177
|
+
build_mcid_map(&raw_doc.document)
|
|
178
|
+
} else {
|
|
179
|
+
Default::default()
|
|
180
|
+
};
|
|
148
181
|
let mut pipeline_state = PipelineState::with_mcid_map(page_contents, config.clone(), mcid_map)
|
|
149
182
|
.with_page_info(page_info_list);
|
|
150
183
|
run_pipeline(&mut pipeline_state)?;
|
|
@@ -248,6 +281,10 @@ pub struct ExtractSession {
|
|
|
248
281
|
pub creation_date: Option<String>,
|
|
249
282
|
/// Modification date metadata.
|
|
250
283
|
pub modification_date: Option<String>,
|
|
284
|
+
/// Producer metadata.
|
|
285
|
+
pub producer: Option<String>,
|
|
286
|
+
/// Creator metadata.
|
|
287
|
+
pub creator: Option<String>,
|
|
251
288
|
/// Page count.
|
|
252
289
|
pub number_of_pages: u32,
|
|
253
290
|
/// Per-page content elements (tables not yet recovered from OCR candidates).
|
|
@@ -302,11 +339,18 @@ pub fn extract_session(
|
|
|
302
339
|
|
|
303
340
|
#[cfg(feature = "image")]
|
|
304
341
|
if config.raster_table_ocr_enabled() {
|
|
342
|
+
let (page_w, page_h) = page_info_list
|
|
343
|
+
.iter()
|
|
344
|
+
.find(|p| p.page_number == page_num)
|
|
345
|
+
.map(|p| (p.width, p.height))
|
|
346
|
+
.unwrap_or((612.0, 792.0));
|
|
305
347
|
let page_cands = pdf::inmem_raster::collect_raster_candidates(
|
|
306
348
|
&raw_doc.document,
|
|
307
349
|
page_id,
|
|
308
350
|
&page_chunks.image_chunks,
|
|
309
351
|
&page_chunks.text_chunks,
|
|
352
|
+
page_w,
|
|
353
|
+
page_h,
|
|
310
354
|
&mut next_id,
|
|
311
355
|
);
|
|
312
356
|
candidates.extend(page_cands);
|
|
@@ -344,7 +388,11 @@ pub fn extract_session(
|
|
|
344
388
|
}
|
|
345
389
|
}
|
|
346
390
|
|
|
347
|
-
let mcid_map =
|
|
391
|
+
let mcid_map = if should_use_struct_tree(&raw_doc.document, config.use_struct_tree) {
|
|
392
|
+
build_mcid_map(&raw_doc.document)
|
|
393
|
+
} else {
|
|
394
|
+
Default::default()
|
|
395
|
+
};
|
|
348
396
|
let bookmarks = extract_bookmarks(&raw_doc.document);
|
|
349
397
|
|
|
350
398
|
Ok(ExtractSession {
|
|
@@ -354,6 +402,8 @@ pub fn extract_session(
|
|
|
354
402
|
title: raw_doc.metadata.title,
|
|
355
403
|
creation_date: raw_doc.metadata.creation_date,
|
|
356
404
|
modification_date: raw_doc.metadata.modification_date,
|
|
405
|
+
producer: raw_doc.metadata.producer,
|
|
406
|
+
creator: raw_doc.metadata.creator,
|
|
357
407
|
number_of_pages: pages_map.len() as u32,
|
|
358
408
|
page_contents,
|
|
359
409
|
page_info_list,
|
|
@@ -389,6 +439,27 @@ impl ExtractSession {
|
|
|
389
439
|
}
|
|
390
440
|
}
|
|
391
441
|
|
|
442
|
+
/// Drop the source Image (by XObject index) and inject OCR words as text chunks.
|
|
443
|
+
#[cfg(feature = "image")]
|
|
444
|
+
fn inject_ocr_text_blocks(
|
|
445
|
+
session: &mut ExtractSession,
|
|
446
|
+
page_idx: usize,
|
|
447
|
+
cand: &pdf::inmem_raster::RasterCandidate,
|
|
448
|
+
words: &[pdf::ocr::OcrWord],
|
|
449
|
+
) {
|
|
450
|
+
if let Some(page) = session.page_contents.get_mut(page_idx) {
|
|
451
|
+
if let Some(idx) = cand.image_index {
|
|
452
|
+
page.retain(|el| match el {
|
|
453
|
+
ContentElement::Image(img) => img.index != Some(idx),
|
|
454
|
+
_ => true,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
for chunk in pdf::inmem_raster::ocr_words_to_text_chunks(cand, words) {
|
|
458
|
+
page.push(ContentElement::TextChunk(chunk));
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
392
463
|
/// Run the pipeline after injecting OCR-derived tables from session candidates.
|
|
393
464
|
pub fn assemble(
|
|
394
465
|
mut session: ExtractSession,
|
|
@@ -397,9 +468,11 @@ pub fn assemble(
|
|
|
397
468
|
#[cfg(feature = "image")]
|
|
398
469
|
if session.config.raster_table_ocr_enabled() {
|
|
399
470
|
use image::GrayImage;
|
|
471
|
+
use pdf::inmem_raster::RasterCandidateKind;
|
|
400
472
|
use pdf::ocr::{default_engine, OcrEngine};
|
|
401
473
|
|
|
402
|
-
|
|
474
|
+
let candidates = std::mem::take(&mut session.candidates);
|
|
475
|
+
for cand in &candidates {
|
|
403
476
|
let words = match &mode {
|
|
404
477
|
OcrAssembleMode::SyncEngine => {
|
|
405
478
|
if let Some(gray) =
|
|
@@ -423,15 +496,27 @@ pub fn assemble(
|
|
|
423
496
|
}
|
|
424
497
|
}
|
|
425
498
|
};
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
499
|
+
let page_idx = cand.page.saturating_sub(1) as usize;
|
|
500
|
+
match cand.kind {
|
|
501
|
+
RasterCandidateKind::Table => {
|
|
502
|
+
let table = pdf::inmem_raster::build_table_from_candidate(cand, &words)
|
|
503
|
+
.filter(pdf::inmem_raster::bordered_table_is_plausible);
|
|
504
|
+
if let Some(table) = table {
|
|
505
|
+
if let Some(page) = session.page_contents.get_mut(page_idx) {
|
|
506
|
+
page.push(ContentElement::TableBorder(table));
|
|
507
|
+
}
|
|
508
|
+
} else if !words.is_empty() {
|
|
509
|
+
// OCR found glyphs but no lattice — assemble as text,
|
|
510
|
+
// not discard (right assembly from evidence).
|
|
511
|
+
inject_ocr_text_blocks(&mut session, page_idx, cand, &words);
|
|
431
512
|
}
|
|
432
513
|
}
|
|
514
|
+
RasterCandidateKind::TextBlocks => {
|
|
515
|
+
inject_ocr_text_blocks(&mut session, page_idx, cand, &words);
|
|
516
|
+
}
|
|
433
517
|
}
|
|
434
518
|
}
|
|
519
|
+
session.candidates = candidates;
|
|
435
520
|
}
|
|
436
521
|
|
|
437
522
|
#[cfg(not(feature = "image"))]
|
|
@@ -452,6 +537,8 @@ pub fn assemble(
|
|
|
452
537
|
doc.title = session.title;
|
|
453
538
|
doc.creation_date = session.creation_date;
|
|
454
539
|
doc.modification_date = session.modification_date;
|
|
540
|
+
doc.producer = session.producer;
|
|
541
|
+
doc.creator = session.creator;
|
|
455
542
|
|
|
456
543
|
for page in pipeline_state.pages {
|
|
457
544
|
doc.kids.extend(page);
|
|
@@ -776,4 +863,105 @@ mod tests {
|
|
|
776
863
|
let _ = count_table_borders(&doc);
|
|
777
864
|
}
|
|
778
865
|
}
|
|
866
|
+
|
|
867
|
+
/// Pattern-painted page raster (Skia/Penpot style) must emit an OCR
|
|
868
|
+
/// candidate, skip page-edge lines, and not render artifact metadata titles.
|
|
869
|
+
#[cfg(feature = "image")]
|
|
870
|
+
#[test]
|
|
871
|
+
fn pattern_form_fixture_emits_text_blocks_candidate() {
|
|
872
|
+
let pdf =
|
|
873
|
+
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/pattern_form.pdf");
|
|
874
|
+
assert!(pdf.exists(), "missing fixture {}", pdf.display());
|
|
875
|
+
let data = std::fs::read(&pdf).unwrap();
|
|
876
|
+
let config = ProcessingConfig::default();
|
|
877
|
+
let session = extract_session(&data, "pattern_form.pdf", &config, None).unwrap();
|
|
878
|
+
assert!(
|
|
879
|
+
!session.candidates.is_empty(),
|
|
880
|
+
"expected ≥1 OCR candidate from pattern-painted image"
|
|
881
|
+
);
|
|
882
|
+
assert!(
|
|
883
|
+
session
|
|
884
|
+
.candidates
|
|
885
|
+
.iter()
|
|
886
|
+
.any(|c| c.kind == pdf::inmem_raster::RasterCandidateKind::TextBlocks),
|
|
887
|
+
"expected TextBlocks candidate for page-sized raster"
|
|
888
|
+
);
|
|
889
|
+
|
|
890
|
+
// No OCR words → still assemble; markdown must skip "Penpot - Render".
|
|
891
|
+
let doc = assemble(session, OcrAssembleMode::Provided).unwrap();
|
|
892
|
+
assert_eq!(doc.producer.as_deref(), Some("Skia/PDF m151"));
|
|
893
|
+
let md = output::markdown::to_markdown(&doc).unwrap();
|
|
894
|
+
assert!(
|
|
895
|
+
!md.contains("# Penpot - Render"),
|
|
896
|
+
"artifact metadata title must not become H1, got:\n{md}"
|
|
897
|
+
);
|
|
898
|
+
// Native text from the fixture should still appear.
|
|
899
|
+
assert!(
|
|
900
|
+
md.contains("NAME VALUE") || md.contains("ACME"),
|
|
901
|
+
"expected native text in markdown, got:\n{md}"
|
|
902
|
+
);
|
|
903
|
+
// Reading order: title (higher on page) before value text.
|
|
904
|
+
if let (Some(a), Some(b)) = (md.find("ACME"), md.find("NAME VALUE")) {
|
|
905
|
+
assert!(a < b, "expected ACME before NAME VALUE in:\n{md}");
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// Page-edge lines should not dominate kids.
|
|
909
|
+
let edge_lines = doc
|
|
910
|
+
.kids
|
|
911
|
+
.iter()
|
|
912
|
+
.filter(|e| {
|
|
913
|
+
matches!(
|
|
914
|
+
e,
|
|
915
|
+
models::content::ContentElement::Line(l)
|
|
916
|
+
if l.bbox.width() < 2.0 || l.bbox.height() < 2.0
|
|
917
|
+
)
|
|
918
|
+
})
|
|
919
|
+
.count();
|
|
920
|
+
assert_eq!(edge_lines, 0, "pattern fill must not emit page-edge lines");
|
|
921
|
+
assert!(
|
|
922
|
+
!doc.kids.iter().any(|e| matches!(
|
|
923
|
+
e,
|
|
924
|
+
models::content::ContentElement::Image(_)
|
|
925
|
+
| models::content::ContentElement::Figure(_)
|
|
926
|
+
)),
|
|
927
|
+
"page-sized TextBlocks source image should be dropped from layout"
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
#[test]
|
|
932
|
+
fn artifact_metadata_title_skipped_in_markdown() {
|
|
933
|
+
let mut doc = PdfDocument::new("x.pdf".into());
|
|
934
|
+
doc.title = Some("Penpot - Render".into());
|
|
935
|
+
doc.producer = Some("Skia/PDF m151".into());
|
|
936
|
+
doc.creator = Some("Chromium".into());
|
|
937
|
+
doc.number_of_pages = 1;
|
|
938
|
+
// Body text present but does not corroborate Info.Title → skip H1.
|
|
939
|
+
doc.kids.push(models::content::ContentElement::TextChunk(
|
|
940
|
+
models::chunks::TextChunk {
|
|
941
|
+
value: "MANSUY RAPHAEL".into(),
|
|
942
|
+
bbox: models::bbox::BoundingBox::new(Some(1), 10.0, 100.0, 200.0, 120.0),
|
|
943
|
+
font_name: "Helvetica".into(),
|
|
944
|
+
font_size: 12.0,
|
|
945
|
+
font_weight: 400.0,
|
|
946
|
+
italic_angle: 0.0,
|
|
947
|
+
font_color: "#000000".into(),
|
|
948
|
+
contrast_ratio: 21.0,
|
|
949
|
+
symbol_ends: vec![200.0],
|
|
950
|
+
text_format: models::enums::TextFormat::Normal,
|
|
951
|
+
text_type: models::enums::TextType::Regular,
|
|
952
|
+
pdf_layer: models::enums::PdfLayer::Main,
|
|
953
|
+
ocg_visible: true,
|
|
954
|
+
index: Some(0),
|
|
955
|
+
page_number: Some(1),
|
|
956
|
+
level: None,
|
|
957
|
+
mcid: None,
|
|
958
|
+
},
|
|
959
|
+
));
|
|
960
|
+
let md = output::markdown::to_markdown(&doc).unwrap();
|
|
961
|
+
assert!(
|
|
962
|
+
!md.contains("# Penpot - Render"),
|
|
963
|
+
"uncorroborated metadata title must be skipped when body text exists, got:\n{md}"
|
|
964
|
+
);
|
|
965
|
+
assert!(md.contains("MANSUY RAPHAEL"), "got:\n{md}");
|
|
966
|
+
}
|
|
779
967
|
}
|