Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/include/mupdf/fitz/store.h @ 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 #ifndef MUPDF_FITZ_STORE_H | |
| 24 #define MUPDF_FITZ_STORE_H | |
| 25 | |
| 26 #include "mupdf/fitz/system.h" | |
| 27 #include "mupdf/fitz/context.h" | |
| 28 #include "mupdf/fitz/output.h" | |
| 29 #include "mupdf/fitz/log.h" | |
| 30 #include "mupdf/fitz/types.h" | |
| 31 | |
| 32 /** | |
| 33 Resource store | |
| 34 | |
| 35 MuPDF stores decoded "objects" into a store for potential reuse. | |
| 36 If the size of the store gets too big, objects stored within it | |
| 37 can be evicted and freed to recover space. When MuPDF comes to | |
| 38 decode such an object, it will check to see if a version of this | |
| 39 object is already in the store - if it is, it will simply reuse | |
| 40 it. If not, it will decode it and place it into the store. | |
| 41 | |
| 42 All objects that can be placed into the store are derived from | |
| 43 the fz_storable type (i.e. this should be the first component of | |
| 44 the objects structure). This allows for consistent (thread safe) | |
| 45 reference counting, and includes a function that will be called | |
| 46 to free the object as soon as the reference count reaches zero. | |
| 47 | |
| 48 Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived | |
| 49 from fz_keep_storable/fz_drop_storable. Creation of such objects | |
| 50 includes a call to FZ_INIT_STORABLE to set up the fz_storable | |
| 51 header. | |
| 52 */ | |
| 53 typedef struct fz_storable fz_storable; | |
| 54 | |
| 55 /** | |
| 56 Function type for a function to drop a storable object. | |
| 57 | |
| 58 Objects within the store are identified by type by comparing | |
| 59 their drop_fn pointers. | |
| 60 */ | |
| 61 typedef void (fz_store_drop_fn)(fz_context *, fz_storable *); | |
| 62 | |
| 63 /** | |
| 64 Function type for a function to check whether a storable | |
| 65 object can be dropped at the moment. | |
| 66 | |
| 67 Return 0 for 'cannot be dropped', 1 otherwise. | |
| 68 */ | |
| 69 typedef int (fz_store_droppable_fn)(fz_context *, fz_storable *); | |
| 70 | |
| 71 /** | |
| 72 Any storable object should include an fz_storable structure | |
| 73 at the start (by convention at least) of their structure. | |
| 74 (Unless it starts with an fz_key_storable, see below). | |
| 75 */ | |
| 76 struct fz_storable { | |
| 77 int refs; | |
| 78 fz_store_drop_fn *drop; | |
| 79 fz_store_droppable_fn *droppable; | |
| 80 }; | |
| 81 | |
| 82 /** | |
| 83 Any storable object that can appear in the key of another | |
| 84 storable object should include an fz_key_storable structure | |
| 85 at the start (by convention at least) of their structure. | |
| 86 */ | |
| 87 typedef struct | |
| 88 { | |
| 89 fz_storable storable; | |
| 90 short store_key_refs; | |
| 91 } fz_key_storable; | |
| 92 | |
| 93 /** | |
| 94 Macros to initialise a storable object. | |
| 95 */ | |
| 96 #define FZ_INIT_STORABLE(S_,RC,DROP) \ | |
| 97 do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ | |
| 98 S->drop = (DROP); S->droppable = NULL; \ | |
| 99 } while (0) | |
| 100 | |
| 101 #define FZ_INIT_AWKWARD_STORABLE(S_,RC,DROP,DROPPABLE) \ | |
| 102 do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ | |
| 103 S->drop = (DROP); S->droppable = (DROPPABLE); \ | |
| 104 } while (0) | |
| 105 | |
| 106 /** | |
| 107 Macro to initialise a key storable object. | |
| 108 */ | |
| 109 #define FZ_INIT_KEY_STORABLE(KS_,RC,DROP) \ | |
| 110 do { fz_key_storable *KS = &(KS_)->key_storable; KS->store_key_refs = 0;\ | |
| 111 FZ_INIT_STORABLE(KS,RC,DROP); \ | |
| 112 } while (0) | |
| 113 | |
| 114 /** | |
| 115 Increment the reference count for a storable object. | |
| 116 Returns the same pointer. | |
| 117 | |
| 118 Never throws exceptions. | |
| 119 */ | |
| 120 void *fz_keep_storable(fz_context *, const fz_storable *); | |
| 121 | |
| 122 /** | |
| 123 Decrement the reference count for a storable object. When the | |
| 124 reference count hits zero, the drop function for that object | |
| 125 is called to free the object. | |
| 126 | |
| 127 Never throws exceptions. | |
| 128 */ | |
| 129 void fz_drop_storable(fz_context *, const fz_storable *); | |
| 130 | |
| 131 /** | |
| 132 Increment the (normal) reference count for a key storable | |
| 133 object. Returns the same pointer. | |
| 134 | |
| 135 Never throws exceptions. | |
| 136 */ | |
| 137 void *fz_keep_key_storable(fz_context *, const fz_key_storable *); | |
| 138 | |
| 139 /** | |
| 140 Decrement the (normal) reference count for a storable object. | |
| 141 When the total reference count hits zero, the drop function for | |
| 142 that object is called to free the object. | |
| 143 | |
| 144 Never throws exceptions. | |
| 145 */ | |
| 146 void fz_drop_key_storable(fz_context *, const fz_key_storable *); | |
| 147 | |
| 148 /** | |
| 149 Increment the (key) reference count for a key storable | |
| 150 object. Returns the same pointer. | |
| 151 | |
| 152 Never throws exceptions. | |
| 153 */ | |
| 154 void *fz_keep_key_storable_key(fz_context *, const fz_key_storable *); | |
| 155 | |
| 156 /** | |
| 157 Decrement the (key) reference count for a storable object. | |
| 158 When the total reference count hits zero, the drop function for | |
| 159 that object is called to free the object. | |
| 160 | |
| 161 Never throws exceptions. | |
| 162 */ | |
| 163 void fz_drop_key_storable_key(fz_context *, const fz_key_storable *); | |
| 164 | |
| 165 /** | |
| 166 The store can be seen as a dictionary that maps keys to | |
| 167 fz_storable values. In order to allow keys of different types to | |
| 168 be stored, we have a structure full of functions for each key | |
| 169 'type'; this fz_store_type pointer is stored with each key, and | |
| 170 tells the store how to perform certain operations (like taking/ | |
| 171 dropping a reference, comparing two keys, outputting details for | |
| 172 debugging etc). | |
| 173 | |
| 174 The store uses a hash table internally for speed where possible. | |
| 175 In order for this to work, we need a mechanism for turning a | |
| 176 generic 'key' into 'a hashable string'. For this purpose the | |
| 177 type structure contains a make_hash_key function pointer that | |
| 178 maps from a void * to a fz_store_hash structure. If | |
| 179 make_hash_key function returns 0, then the key is determined not | |
| 180 to be hashable, and the value is not stored in the hash table. | |
| 181 | |
| 182 Some objects can be used both as values within the store, and as | |
| 183 a component of keys within the store. We refer to these objects | |
| 184 as "key storable" objects. In this case, we need to take | |
| 185 additional care to ensure that we do not end up keeping an item | |
| 186 within the store, purely because its value is referred to by | |
| 187 another key in the store. | |
| 188 | |
| 189 An example of this are fz_images in PDF files. Each fz_image is | |
| 190 placed into the store to enable it to be easily reused. When the | |
| 191 image is rendered, a pixmap is generated from the image, and the | |
| 192 pixmap is placed into the store so it can be reused on | |
| 193 subsequent renders. The image forms part of the key for the | |
| 194 pixmap. | |
| 195 | |
| 196 When we close the pdf document (and any associated pages/display | |
| 197 lists etc), we drop the images from the store. This may leave us | |
| 198 in the position of the images having non-zero reference counts | |
| 199 purely because they are used as part of the keys for the | |
| 200 pixmaps. | |
| 201 | |
| 202 We therefore use special reference counting functions to keep | |
| 203 track of these "key storable" items, and hence store the number | |
| 204 of references to these items that are used in keys. | |
| 205 | |
| 206 When the number of references to an object == the number of | |
| 207 references to an object from keys in the store, we know that we | |
| 208 can remove all the items which have that object as part of the | |
| 209 key. This is done by running a pass over the store, 'reaping' | |
| 210 those items. | |
| 211 | |
| 212 Reap passes are slower than we would like as they touch every | |
| 213 item in the store. We therefore provide a way to 'batch' such | |
| 214 reap passes together, using fz_defer_reap_start/ | |
| 215 fz_defer_reap_end to bracket a region in which many may be | |
| 216 triggered. | |
| 217 */ | |
| 218 typedef struct | |
| 219 { | |
| 220 fz_store_drop_fn *drop; | |
| 221 union | |
| 222 { | |
| 223 struct | |
| 224 { | |
| 225 const void *ptr; | |
| 226 int i; | |
| 227 } pi; /* 8 or 12 bytes */ | |
| 228 struct | |
| 229 { | |
| 230 const void *ptr; | |
| 231 int i; | |
| 232 fz_irect r; | |
| 233 } pir; /* 24 or 28 bytes */ | |
| 234 struct | |
| 235 { | |
| 236 int id; | |
| 237 char has_shape; | |
| 238 char has_group_alpha; | |
| 239 float m[4]; | |
| 240 void *ptr; | |
| 241 int doc_id; | |
| 242 } im; /* 32 or 36 bytes */ | |
| 243 struct | |
| 244 { | |
| 245 unsigned char src_md5[16]; | |
| 246 unsigned char dst_md5[16]; | |
| 247 unsigned int ri:2; | |
| 248 unsigned int bp:1; | |
| 249 unsigned int format:1; | |
| 250 unsigned int proof:1; | |
| 251 unsigned int src_extras:5; | |
| 252 unsigned int dst_extras:5; | |
| 253 unsigned int copy_spots:1; | |
| 254 unsigned int bgr:1; | |
| 255 } link; /* 36 bytes */ | |
| 256 } u; | |
| 257 /* 0 or 4 bytes padding */ | |
| 258 } fz_store_hash; /* 40 or 48 bytes */ | |
| 259 | |
| 260 /** | |
| 261 Every type of object to be placed into the store defines an | |
| 262 fz_store_type. This contains the pointers to functions to | |
| 263 make hashes, manipulate keys, and check for needing reaping. | |
| 264 */ | |
| 265 typedef struct | |
| 266 { | |
| 267 const char *name; | |
| 268 int (*make_hash_key)(fz_context *ctx, fz_store_hash *hash, void *key); | |
| 269 void *(*keep_key)(fz_context *ctx, void *key); | |
| 270 void (*drop_key)(fz_context *ctx, void *key); | |
| 271 int (*cmp_key)(fz_context *ctx, void *a, void *b); | |
| 272 void (*format_key)(fz_context *ctx, char *buf, size_t size, void *key); | |
| 273 int (*needs_reap)(fz_context *ctx, void *key); | |
| 274 } fz_store_type; | |
| 275 | |
| 276 /** | |
| 277 Create a new store inside the context | |
| 278 | |
| 279 max: The maximum size (in bytes) that the store is allowed to | |
| 280 grow to. FZ_STORE_UNLIMITED means no limit. | |
| 281 */ | |
| 282 void fz_new_store_context(fz_context *ctx, size_t max); | |
| 283 | |
| 284 /** | |
| 285 Increment the reference count for the store context. Returns | |
| 286 the same pointer. | |
| 287 | |
| 288 Never throws exceptions. | |
| 289 */ | |
| 290 fz_store *fz_keep_store_context(fz_context *ctx); | |
| 291 | |
| 292 /** | |
| 293 Decrement the reference count for the store context. When the | |
| 294 reference count hits zero, the store context is freed. | |
| 295 | |
| 296 Never throws exceptions. | |
| 297 */ | |
| 298 void fz_drop_store_context(fz_context *ctx); | |
| 299 | |
| 300 /** | |
| 301 Add an item to the store. | |
| 302 | |
| 303 Add an item into the store, returning NULL for success. If an | |
| 304 item with the same key is found in the store, then our item will | |
| 305 not be inserted, and the function will return a pointer to that | |
| 306 value instead. This function takes its own reference to val, as | |
| 307 required (i.e. the caller maintains ownership of its own | |
| 308 reference). | |
| 309 | |
| 310 key: The key used to index the item. | |
| 311 | |
| 312 val: The value to store. | |
| 313 | |
| 314 itemsize: The size in bytes of the value (as counted towards the | |
| 315 store size). | |
| 316 | |
| 317 type: Functions used to manipulate the key. | |
| 318 */ | |
| 319 void *fz_store_item(fz_context *ctx, void *key, void *val, size_t itemsize, const fz_store_type *type); | |
| 320 | |
| 321 /** | |
| 322 Find an item within the store. | |
| 323 | |
| 324 drop: The function used to free the value (to ensure we get a | |
| 325 value of the correct type). | |
| 326 | |
| 327 key: The key used to index the item. | |
| 328 | |
| 329 type: Functions used to manipulate the key. | |
| 330 | |
| 331 Returns NULL for not found, otherwise returns a pointer to the | |
| 332 value indexed by key to which a reference has been taken. | |
| 333 */ | |
| 334 void *fz_find_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type); | |
| 335 | |
| 336 /** | |
| 337 Remove an item from the store. | |
| 338 | |
| 339 If an item indexed by the given key exists in the store, remove | |
| 340 it. | |
| 341 | |
| 342 drop: The function used to free the value (to ensure we get a | |
| 343 value of the correct type). | |
| 344 | |
| 345 key: The key used to find the item to remove. | |
| 346 | |
| 347 type: Functions used to manipulate the key. | |
| 348 */ | |
| 349 void fz_remove_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type); | |
| 350 | |
| 351 /** | |
| 352 Evict every item from the store. | |
| 353 */ | |
| 354 void fz_empty_store(fz_context *ctx); | |
| 355 | |
| 356 /** | |
| 357 Internal function used as part of the scavenging | |
| 358 allocator; when we fail to allocate memory, before returning a | |
| 359 failure to the caller, we try to scavenge space within the store | |
| 360 by evicting at least 'size' bytes. The allocator then retries. | |
| 361 | |
| 362 size: The number of bytes we are trying to have free. | |
| 363 | |
| 364 phase: What phase of the scavenge we are in. Updated on exit. | |
| 365 | |
| 366 Returns non zero if we managed to free any memory. | |
| 367 */ | |
| 368 int fz_store_scavenge(fz_context *ctx, size_t size, int *phase); | |
| 369 | |
| 370 /** | |
| 371 External function for callers to use | |
| 372 to scavenge while trying allocations. | |
| 373 | |
| 374 size: The number of bytes we are trying to have free. | |
| 375 | |
| 376 phase: What phase of the scavenge we are in. Updated on exit. | |
| 377 | |
| 378 Returns non zero if we managed to free any memory. | |
| 379 */ | |
| 380 int fz_store_scavenge_external(fz_context *ctx, size_t size, int *phase); | |
| 381 | |
| 382 /** | |
| 383 Evict items from the store until the total size of | |
| 384 the objects in the store is reduced to a given percentage of its | |
| 385 current size. | |
| 386 | |
| 387 percent: %age of current size to reduce the store to. | |
| 388 | |
| 389 Returns non zero if we managed to free enough memory, zero | |
| 390 otherwise. | |
| 391 */ | |
| 392 int fz_shrink_store(fz_context *ctx, unsigned int percent); | |
| 393 | |
| 394 /** | |
| 395 Callback function called by fz_filter_store on every item within | |
| 396 the store. | |
| 397 | |
| 398 Return 1 to drop the item from the store, 0 to retain. | |
| 399 */ | |
| 400 typedef int (fz_store_filter_fn)(fz_context *ctx, void *arg, void *key); | |
| 401 | |
| 402 /** | |
| 403 Filter every element in the store with a matching type with the | |
| 404 given function. | |
| 405 | |
| 406 If the function returns 1 for an element, drop the element. | |
| 407 */ | |
| 408 void fz_filter_store(fz_context *ctx, fz_store_filter_fn *fn, void *arg, const fz_store_type *type); | |
| 409 | |
| 410 /** | |
| 411 Filter the store and throw away any stored tiles drawn for a | |
| 412 given document. | |
| 413 */ | |
| 414 void fz_drop_drawn_tiles_for_document(fz_context *ctx, fz_document *doc); | |
| 415 | |
| 416 /** | |
| 417 Output debugging information for the current state of the store | |
| 418 to the given output channel. | |
| 419 */ | |
| 420 void fz_debug_store(fz_context *ctx, fz_output *out); | |
| 421 | |
| 422 /** | |
| 423 Increment the defer reap count. | |
| 424 | |
| 425 No reap operations will take place (except for those | |
| 426 triggered by an immediate failed malloc) until the | |
| 427 defer reap count returns to 0. | |
| 428 | |
| 429 Call this at the start of a process during which you | |
| 430 potentially might drop many reapable objects. | |
| 431 | |
| 432 It is vital that every fz_defer_reap_start is matched | |
| 433 by a fz_defer_reap_end call. | |
| 434 */ | |
| 435 void fz_defer_reap_start(fz_context *ctx); | |
| 436 | |
| 437 /** | |
| 438 Decrement the defer reap count. | |
| 439 | |
| 440 If the defer reap count returns to 0, and the store | |
| 441 has reapable objects in, a reap pass will begin. | |
| 442 | |
| 443 Call this at the end of a process during which you | |
| 444 potentially might drop many reapable objects. | |
| 445 | |
| 446 It is vital that every fz_defer_reap_start is matched | |
| 447 by a fz_defer_reap_end call. | |
| 448 */ | |
| 449 void fz_defer_reap_end(fz_context *ctx); | |
| 450 | |
| 451 #ifdef ENABLE_STORE_LOGGING | |
| 452 | |
| 453 void fz_log_dump_store(fz_context *ctx, const char *fmt, ...); | |
| 454 | |
| 455 #define FZ_LOG_STORE(CTX, ...) fz_log_module(CTX, "STORE", __VA_ARGS__) | |
| 456 #define FZ_LOG_DUMP_STORE(...) fz_log_dump_store(__VA_ARGS__) | |
| 457 | |
| 458 #else | |
| 459 | |
| 460 #define FZ_LOG_STORE(...) do {} while (0) | |
| 461 #define FZ_LOG_DUMP_STORE(...) do {} while (0) | |
| 462 | |
| 463 #endif | |
| 464 | |
| 465 #endif |
