1 #ifndef MUPDF_PDF_XREF_H 2 #define MUPDF_PDF_XREF_H 3 4 /* 5 Allocate a slot in the xref table and return a fresh unused object number. 6 */ 7 int pdf_create_object(fz_context *ctx, pdf_document *doc); 8 9 /* 10 Remove object from xref table, marking the slot as free. 11 */ 12 void pdf_delete_object(fz_context *ctx, pdf_document *doc, int num); 13 14 /* 15 Replace object in xref table with the passed in object. 16 */ 17 void pdf_update_object(fz_context *ctx, pdf_document *doc, int num, pdf_obj *obj); 18 19 /* 20 Replace stream contents for object in xref table with the passed in buffer. 21 22 The buffer contents must match the /Filter setting if 'compressed' is true. 23 If 'compressed' is false, the /Filter and /DecodeParms entries are deleted. 24 The /Length entry is updated. 25 */ 26 void pdf_update_stream(fz_context *ctx, pdf_document *doc, pdf_obj *ref, fz_buffer *buf, int compressed); 27 28 pdf_obj *pdf_add_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj); 29 pdf_obj *pdf_add_object_drop(fz_context *ctx, pdf_document *doc, pdf_obj *obj); 30 pdf_obj *pdf_add_stream(fz_context *ctx, pdf_document *doc, fz_buffer *buf, pdf_obj *obj, int compressed); 31 32 pdf_obj *pdf_add_new_dict(fz_context *ctx, pdf_document *doc, int initial); 33 pdf_obj *pdf_add_new_array(fz_context *ctx, pdf_document *doc, int initial); 34 35 typedef struct 36 { 37 char type; /* 0=unset (f)ree i(n)use (o)bjstm */ 38 unsigned char marked; /* marked to keep alive with pdf_mark_xref */ 39 unsigned short gen; /* generation / objstm index */ 40 int num; /* original object number (for decryption after renumbering) */ 41 int64_t ofs; /* file offset / objstm object number */ 42 int64_t stm_ofs; /* on-disk stream */ 43 fz_buffer *stm_buf; /* in-memory stream (for updated objects) */ 44 pdf_obj *obj; /* stored/cached object */ 45 } pdf_xref_entry; 46 47 typedef struct pdf_xref_subsec 48 { 49 struct pdf_xref_subsec *next; 50 int len; 51 int start; 52 pdf_xref_entry *table; 53 } pdf_xref_subsec; 54 55 struct pdf_xref 56 { 57 int num_objects; 58 pdf_xref_subsec *subsec; 59 pdf_obj *trailer; 60 pdf_obj *pre_repair_trailer; 61 pdf_unsaved_sig *unsaved_sigs; 62 pdf_unsaved_sig **unsaved_sigs_end; 63 int64_t end_ofs; /* file offset to end of xref */ 64 }; 65 66 pdf_xref_entry *pdf_cache_object(fz_context *ctx, pdf_document *doc, int num); 67 68 int pdf_count_objects(fz_context *ctx, pdf_document *doc); 69 pdf_obj *pdf_resolve_indirect(fz_context *ctx, pdf_obj *ref); 70 pdf_obj *pdf_resolve_indirect_chain(fz_context *ctx, pdf_obj *ref); 71 pdf_obj *pdf_load_object(fz_context *ctx, pdf_document *doc, int num); 72 pdf_obj *pdf_load_unencrypted_object(fz_context *ctx, pdf_document *doc, int num); 73 74 /* 75 Load raw (compressed but decrypted) contents of a stream into buf. 76 */ 77 fz_buffer *pdf_load_raw_stream_number(fz_context *ctx, pdf_document *doc, int num); 78 fz_buffer *pdf_load_raw_stream(fz_context *ctx, pdf_obj *ref); 79 80 /* 81 Load uncompressed contents of a stream into buf. 82 */ 83 fz_buffer *pdf_load_stream_number(fz_context *ctx, pdf_document *doc, int num); 84 fz_buffer *pdf_load_stream(fz_context *ctx, pdf_obj *ref); 85 86 /* 87 Open a stream for reading the raw (compressed but decrypted) data. 88 */ 89 fz_stream *pdf_open_raw_stream_number(fz_context *ctx, pdf_document *doc, int num); 90 fz_stream *pdf_open_raw_stream(fz_context *ctx, pdf_obj *ref); 91 92 /* 93 Open a stream for reading uncompressed data. 94 Put the opened file in doc->stream. 95 Using doc->file while a stream is open is a Bad idea. 96 */ 97 fz_stream *pdf_open_stream_number(fz_context *ctx, pdf_document *doc, int num); 98 fz_stream *pdf_open_stream(fz_context *ctx, pdf_obj *ref); 99 100 /* 101 Construct a filter to decode a stream, without 102 constraining to stream length, and without decryption. 103 */ 104 fz_stream *pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, fz_compression_params *params); 105 fz_compressed_buffer *pdf_load_compressed_stream(fz_context *ctx, pdf_document *doc, int num); 106 void pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *cstm, int indexed, fz_compressed_image *image); 107 fz_stream *pdf_open_stream_with_offset(fz_context *ctx, pdf_document *doc, int num, pdf_obj *dict, int64_t stm_ofs); 108 fz_stream *pdf_open_contents_stream(fz_context *ctx, pdf_document *doc, pdf_obj *obj); 109 110 int pdf_version(fz_context *ctx, pdf_document *doc); 111 pdf_obj *pdf_trailer(fz_context *ctx, pdf_document *doc); 112 void pdf_set_populating_xref_trailer(fz_context *ctx, pdf_document *doc, pdf_obj *trailer); 113 int pdf_xref_len(fz_context *ctx, pdf_document *doc); 114 115 /* 116 Used while reading the individual xref sections from a file. 117 */ 118 pdf_xref_entry *pdf_get_populating_xref_entry(fz_context *ctx, pdf_document *doc, int i); 119 120 /* 121 Used after loading a document to access entries. 122 123 This will never throw anything, or return NULL if it is 124 only asked to return objects in range within a 'solid' 125 xref. 126 */ 127 pdf_xref_entry *pdf_get_xref_entry(fz_context *ctx, pdf_document *doc, int i); 128 void pdf_replace_xref(fz_context *ctx, pdf_document *doc, pdf_xref_entry *entries, int n); 129 void pdf_forget_xref(fz_context *ctx, pdf_document *doc); 130 131 /* 132 Ensure that an object has been cloned into the incremental xref section. 133 */ 134 void pdf_xref_ensure_incremental_object(fz_context *ctx, pdf_document *doc, int num); 135 int pdf_xref_is_incremental(fz_context *ctx, pdf_document *doc, int num); 136 void pdf_xref_store_unsaved_signature(fz_context *ctx, pdf_document *doc, pdf_obj *field, pdf_pkcs7_signer *signer); 137 int pdf_xref_obj_is_unsaved_signature(pdf_document *doc, pdf_obj *obj); 138 139 void pdf_repair_xref(fz_context *ctx, pdf_document *doc); 140 void pdf_repair_obj_stms(fz_context *ctx, pdf_document *doc); 141 142 /* 143 Ensure that the current populating xref has a single subsection 144 that covers the entire range. 145 */ 146 void pdf_ensure_solid_xref(fz_context *ctx, pdf_document *doc, int num); 147 void pdf_mark_xref(fz_context *ctx, pdf_document *doc); 148 void pdf_clear_xref(fz_context *ctx, pdf_document *doc); 149 void pdf_clear_xref_to_mark(fz_context *ctx, pdf_document *doc); 150 151 int pdf_repair_obj(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf, int64_t *stmofsp, int *stmlenp, pdf_obj **encrypt, pdf_obj **id, pdf_obj **page, int64_t *tmpofs, pdf_obj **root); 152 153 pdf_obj *pdf_progressive_advance(fz_context *ctx, pdf_document *doc, int pagenum); 154 155 /* 156 Return the number of versions that there 157 are in a file. i.e. 1 + the number of updates that 158 the file on disc has been through. i.e. internal 159 unsaved changes to the file (such as appearance streams) 160 are ignored. Also, the initial write of a linearized 161 file (which appears as a base file write + an incremental 162 update) is treated as a single version. 163 */ 164 int pdf_count_versions(fz_context *ctx, pdf_document *doc); 165 int pdf_count_unsaved_versions(fz_context *ctx, pdf_document *doc); 166 int pdf_validate_changes(fz_context *ctx, pdf_document *doc, int version); 167 int pdf_doc_was_linearized(fz_context *ctx, pdf_document *doc); 168 169 typedef struct pdf_locked_fields pdf_locked_fields; 170 int pdf_is_field_locked(fz_context *ctx, pdf_locked_fields *locked, const char *name); 171 void pdf_drop_locked_fields(fz_context *ctx, pdf_locked_fields *locked); 172 pdf_locked_fields *pdf_find_locked_fields(fz_context *ctx, pdf_document *doc, int version); 173 pdf_locked_fields *pdf_find_locked_fields_for_sig(fz_context *ctx, pdf_document *doc, pdf_obj *sig); 174 175 /* 176 Check the entire history of the document, and return the number of 177 the last version that checked out OK. 178 i.e. 0 = "the entire history checks out OK". 179 n = "none of the history checked out OK". 180 */ 181 int pdf_validate_change_history(fz_context *ctx, pdf_document *doc); 182 183 /* 184 Find which version of a document the current version of obj 185 was defined in. 186 187 version = 0 = latest, 1 = previous update etc, allowing for 188 the first incremental update in a linearized file being ignored. 189 */ 190 int pdf_find_version_for_obj(fz_context *ctx, pdf_document *doc, pdf_obj *obj); 191 192 /* 193 Return the number of updates ago when a signature became invalid, 194 not counting any unsaved changes. 195 196 Thus: 197 -1 => Has changed in the current unsaved changes. 198 0 => still valid. 199 1 => became invalid on the last save 200 n => became invalid n saves ago 201 */ 202 int pdf_validate_signature(fz_context *ctx, pdf_widget *widget); 203 int pdf_was_pure_xfa(fz_context *ctx, pdf_document *doc); 204 205 #endif 206