comparison mupdf-source/source/pdf/pdf-store.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 // Copyright (C) 2004-2021 Artifex Software, Inc.
2 //
3 // This file is part of MuPDF.
4 //
5 // MuPDF is free software: you can redistribute it and/or modify it under the
6 // terms of the GNU Affero General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17 //
18 // Alternative licensing terms are available from the licensor.
19 // For commercial licensing, see <https://www.artifex.com/> or contact
20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21 // CA 94129, USA, for further information.
22
23 #include "mupdf/fitz.h"
24 #include "mupdf/pdf.h"
25
26 #include <assert.h>
27
28 static int
29 pdf_make_hash_key(fz_context *ctx, fz_store_hash *hash, void *key_)
30 {
31 pdf_obj *key = (pdf_obj *)key_;
32
33 if (!pdf_is_indirect(ctx, key))
34 return 0;
35 hash->u.pi.i = pdf_to_num(ctx, key);
36 hash->u.pi.ptr = pdf_get_indirect_document(ctx, key);
37 return 1;
38 }
39
40 static void *
41 pdf_keep_key(fz_context *ctx, void *key)
42 {
43 return (void *)pdf_keep_obj(ctx, (pdf_obj *)key);
44 }
45
46 static void
47 pdf_drop_key(fz_context *ctx, void *key)
48 {
49 pdf_drop_obj(ctx, (pdf_obj *)key);
50 }
51
52 static int
53 pdf_cmp_key(fz_context *ctx, void *k0, void *k1)
54 {
55 return pdf_objcmp(ctx, (pdf_obj *)k0, (pdf_obj *)k1);
56 }
57
58 static void
59 pdf_format_key(fz_context *ctx, char *s, size_t n, void *key_)
60 {
61 pdf_obj *key = (pdf_obj *)key_;
62 if (pdf_is_indirect(ctx, key))
63 fz_snprintf(s, n, "(%d 0 R)", pdf_to_num(ctx, key));
64 else
65 {
66 size_t t;
67 char *p = pdf_sprint_obj(ctx, s, n, &t, key, 1, 0);
68 if (p != s) {
69 fz_strlcpy(s, p, n);
70 fz_free(ctx, p);
71 }
72 }
73 }
74
75 static const fz_store_type pdf_obj_store_type =
76 {
77 "pdf_obj",
78 pdf_make_hash_key,
79 pdf_keep_key,
80 pdf_drop_key,
81 pdf_cmp_key,
82 pdf_format_key,
83 NULL
84 };
85
86 void
87 pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, size_t itemsize)
88 {
89 void *existing;
90
91 assert(pdf_is_name(ctx, key) || pdf_is_array(ctx, key) || pdf_is_dict(ctx, key) || pdf_is_indirect(ctx, key));
92 existing = fz_store_item(ctx, key, val, itemsize, &pdf_obj_store_type);
93 if (existing)
94 fz_warn(ctx, "unexpectedly replacing entry in PDF store");
95 }
96
97 void *
98 pdf_find_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key)
99 {
100 return fz_find_item(ctx, drop, key, &pdf_obj_store_type);
101 }
102
103 void
104 pdf_remove_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key)
105 {
106 fz_remove_item(ctx, drop, key, &pdf_obj_store_type);
107 }
108
109 static int
110 pdf_filter_store(fz_context *ctx, void *doc_, void *key)
111 {
112 pdf_document *doc = (pdf_document *)doc_;
113 pdf_obj *obj = (pdf_obj *)key;
114 pdf_document *key_doc = pdf_get_bound_document(ctx, obj);
115
116 return (doc == key_doc);
117 }
118
119 void
120 pdf_empty_store(fz_context *ctx, pdf_document *doc)
121 {
122 fz_filter_store(ctx, pdf_filter_store, doc, &pdf_obj_store_type);
123 fz_drop_drawn_tiles_for_document(ctx, (fz_document *)doc);
124 }
125
126 static int
127 pdf_filter_locals(fz_context *ctx, void *doc_, void *key)
128 {
129 pdf_document *doc = (pdf_document *)doc_;
130 pdf_obj *obj = (pdf_obj *)key;
131 pdf_document *key_doc = pdf_get_bound_document(ctx, obj);
132
133 return (doc == key_doc && pdf_is_local_object(ctx, doc, obj));
134 }
135
136 void pdf_purge_locals_from_store(fz_context *ctx, pdf_document *doc)
137 {
138 fz_filter_store(ctx, pdf_filter_locals, doc, &pdf_obj_store_type);
139 }
140
141 struct doc_num_info {
142 pdf_document *doc;
143 int num;
144 };
145
146 static int
147 pdf_filter_object_number(fz_context *ctx, void *ref_, void *key_)
148 {
149 struct doc_num_info *ref = ref_;
150 pdf_obj *key_obj = (pdf_obj *)key_;
151 pdf_document *key_doc = pdf_get_bound_document(ctx, key_obj);
152 return (ref->doc == key_doc && ref->num == pdf_to_num(ctx, key_obj));
153 }
154
155 void pdf_purge_object_from_store(fz_context *ctx, pdf_document *doc, int num)
156 {
157 struct doc_num_info ref = { doc, num };
158 fz_filter_store(ctx, pdf_filter_object_number, &ref, &pdf_obj_store_type);
159 }