/src/serenity/Userland/Libraries/LibPDF/DocumentParser.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021-2022, Matthew Olsson <mattco@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <LibPDF/Parser.h> |
10 | | |
11 | | namespace PDF { |
12 | | |
13 | | struct Version { |
14 | | int major { 0 }; |
15 | | int minor { 0 }; |
16 | | }; |
17 | | |
18 | | class DocumentParser final : public RefCounted<DocumentParser> |
19 | | , public Parser { |
20 | | public: |
21 | | static PDFErrorOr<size_t> scan_for_header_start(ReadonlyBytes); |
22 | | |
23 | | DocumentParser(Document*, ReadonlyBytes); |
24 | | |
25 | | enum class LinearizationResult { |
26 | | NotLinearized, |
27 | | Linearized, |
28 | | }; |
29 | | |
30 | 0 | [[nodiscard]] ALWAYS_INLINE RefPtr<DictObject> const& trailer() const { return m_xref_table->trailer(); } |
31 | | |
32 | | // Parses the header and initializes the xref table and trailer |
33 | | PDFErrorOr<Version> initialize(); |
34 | | |
35 | 0 | bool can_resolve_references() { return m_xref_table; } |
36 | | |
37 | | PDFErrorOr<Value> parse_object_with_index(u32 index); |
38 | | |
39 | | // Specialized version of parse_dict which aborts early if the dict being parsed |
40 | | // is not a page object |
41 | | PDFErrorOr<RefPtr<DictObject>> conditionally_parse_page_tree_node(u32 object_index); |
42 | | |
43 | | private: |
44 | | struct LinearizationDictionary { |
45 | | u32 length_of_file { 0 }; |
46 | | u32 primary_hint_stream_offset { 0 }; |
47 | | u32 primary_hint_stream_length { 0 }; |
48 | | u32 overflow_hint_stream_offset { 0 }; |
49 | | u32 overflow_hint_stream_length { 0 }; |
50 | | u32 first_page_object_number { 0 }; |
51 | | u32 offset_of_first_page_end { 0 }; |
52 | | u16 number_of_pages { 0 }; |
53 | | u32 offset_of_main_xref_table { 0 }; |
54 | | u32 first_page { 0 }; // The page to initially open (I think, the spec isn't all that clear here) |
55 | | }; |
56 | | |
57 | | struct PageOffsetHintTable { |
58 | | u32 least_number_of_objects_in_a_page { 0 }; |
59 | | u32 location_of_first_page_object { 0 }; |
60 | | u16 bits_required_for_object_number { 0 }; |
61 | | u32 least_length_of_a_page { 0 }; |
62 | | u16 bits_required_for_page_length { 0 }; |
63 | | u32 least_offset_of_any_content_stream { 0 }; |
64 | | u16 bits_required_for_content_stream_offsets { 0 }; |
65 | | u32 least_content_stream_length { 0 }; |
66 | | u16 bits_required_for_content_stream_length { 0 }; |
67 | | u16 bits_required_for_number_of_shared_obj_refs { 0 }; |
68 | | u16 bits_required_for_greatest_shared_obj_identifier { 0 }; |
69 | | u16 bits_required_for_fraction_numerator { 0 }; |
70 | | u16 shared_object_reference_fraction_denominator { 0 }; |
71 | | }; |
72 | | |
73 | | struct PageOffsetHintTableEntry { |
74 | | u32 objects_in_page_number { 0 }; |
75 | | u32 page_length_number { 0 }; |
76 | | u32 number_of_shared_objects { 0 }; |
77 | | Vector<u32> shared_object_identifiers {}; |
78 | | Vector<u32> shared_object_location_numerators {}; |
79 | | u32 page_content_stream_offset_number { 0 }; |
80 | | u32 page_content_stream_length_number { 0 }; |
81 | | }; |
82 | | |
83 | | friend struct AK::Formatter<LinearizationDictionary>; |
84 | | friend struct AK::Formatter<PageOffsetHintTable>; |
85 | | friend struct AK::Formatter<PageOffsetHintTableEntry>; |
86 | | |
87 | | PDFErrorOr<Version> parse_header(); |
88 | | PDFErrorOr<LinearizationResult> initialize_linearization_dict(); |
89 | | PDFErrorOr<void> initialize_linearized_xref_table(); |
90 | | PDFErrorOr<void> initialize_non_linearized_xref_table(); |
91 | | PDFErrorOr<void> validate_xref_table_and_fix_if_necessary(); |
92 | | PDFErrorOr<void> initialize_hint_tables(); |
93 | | PDFErrorOr<PageOffsetHintTable> parse_page_offset_hint_table(ReadonlyBytes hint_stream_bytes); |
94 | | PDFErrorOr<Vector<PageOffsetHintTableEntry>> parse_all_page_offset_hint_table_entries(PageOffsetHintTable const&, ReadonlyBytes hint_stream_bytes); |
95 | | PDFErrorOr<NonnullRefPtr<XRefTable>> parse_xref_stream(); |
96 | | PDFErrorOr<NonnullRefPtr<XRefTable>> parse_xref_table(); |
97 | | PDFErrorOr<NonnullRefPtr<DictObject>> parse_file_trailer(); |
98 | | PDFErrorOr<Value> parse_compressed_object_with_index(u32 index); |
99 | | |
100 | | bool navigate_to_before_eof_marker(); |
101 | | bool navigate_to_after_startxref(); |
102 | | |
103 | | RefPtr<XRefTable> m_xref_table; |
104 | | Optional<LinearizationDictionary> m_linearization_dictionary; |
105 | | }; |
106 | | |
107 | | } |