Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/docs/reference/c/fitz/io.md @ 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 # Buffers & Streams | |
| 2 | |
| 3 ## Buffers | |
| 4 | |
| 5 In order to represent a generic chunks of data we use the `fz_buffer` structure. | |
| 6 | |
| 7 typedef struct { | |
| 8 unsigned char *data; | |
| 9 size_t len; // current length | |
| 10 size_t cap; // total capacity | |
| 11 ... reserved internal fields ... | |
| 12 } fz_buffer; | |
| 13 | |
| 14 fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf); | |
| 15 void fz_drop_buffer(fz_context *ctx, fz_buffer *buf); | |
| 16 | |
| 17 There are many ways to create a buffer. Some create a buffer shared immutable data, others with data you can edit, and others by copying or decoding other data. | |
| 18 | |
| 19 `fz_buffer *fz_new_buffer(fz_context *ctx, size_t capacity);` | |
| 20 : Create a new empty buffer, with the given initial capacity. | |
| 21 | |
| 22 `fz_buffer *fz_new_buffer_from_shared_data(fz_context *ctx, const unsigned char *data, size_t size);` | |
| 23 : Create a new buffer wrapping the given data pointer. The data is only referenced, and will not be freed when the buffer is destroyed. The data pointer must **not** change or disappear while the buffer lives. | |
| 24 | |
| 25 `fz_buffer *fz_new_buffer_from_copied_data(fz_context *ctx, const unsigned char *data, size_t size);` | |
| 26 : Create a buffer containing a copy of the data pointed to. | |
| 27 | |
| 28 `fz_buffer *fz_new_buffer_from_base64(fz_context *ctx, const char *data, size_t size);` | |
| 29 : Create a buffer containing the decoded `BASE64` data. | |
| 30 | |
| 31 Sometimes you want to create buffers piece by piece by appending strings or other data to it, while dynamically growing the underlying storage. | |
| 32 | |
| 33 void fz_append_data(fz_context *ctx, fz_buffer *buf, const void *data, size_t len); | |
| 34 void fz_append_string(fz_context *ctx, fz_buffer *buf, const char *string); | |
| 35 void fz_append_byte(fz_context *ctx, fz_buffer *buf, int byte); | |
| 36 void fz_append_rune(fz_context *ctx, fz_buffer *buf, int rune); | |
| 37 void fz_append_int16_be(fz_context *ctx, fz_buffer *buf, int x); | |
| 38 void fz_append_int16_le(fz_context *ctx, fz_buffer *buf, int x); | |
| 39 void fz_append_int32_be(fz_context *ctx, fz_buffer *buf, int x); | |
| 40 void fz_append_int32_le(fz_context *ctx, fz_buffer *buf, int x); | |
| 41 void fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...); | |
| 42 void fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args); | |
| 43 | |
| 44 You can also write a bit stream with the following functions. The buffer length always covers all the bits in the buffer, including any unused ones in the last byte, which will always be zero. | |
| 45 | |
| 46 `void fz_append_bits(fz_context *ctx, fz_buffer *buf, int value, int count);` | |
| 47 : Write the lower count bits from value into the buffer. | |
| 48 | |
| 49 `void fz_append_bits_pad(fz_context *ctx, fz_buffer *buf);` | |
| 50 : Write enough zero bits to be byte aligned. | |
| 51 | |
| 52 You can use the buffer data as a zero-terminated C string by calling the following function. This will ensure that there is a zero terminator after the last byte and return a pointer to the first byte. This pointer is only borrowed, and should only be used briefly, before the buffer is changed again (which may reallocate or free the data). | |
| 53 | |
| 54 `const char *fz_string_from_buffer(fz_context *ctx, fz_buffer *buf);` | |
| 55 : You can also read and write the contents of a buffer to file. | |
| 56 | |
| 57 `fz_buffer *fz_read_file(fz_context *ctx, const char *filename);` | |
| 58 : Read the contents of a file into a buffer. | |
| 59 | |
| 60 `void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename);` | |
| 61 : Save the contents of a buffer to a file. | |
| 62 | |
| 63 ## Input Streams | |
| 64 | |
| 65 An input stream reads data from a source. Some stream types can decompress and decrypt data, and these streams can be chained together in a pipeline. | |
| 66 | |
| 67 typedef struct { internal } fz_stream; | |
| 68 | |
| 69 fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm); | |
| 70 void fz_drop_stream(fz_context *ctx, fz_stream *stm); | |
| 71 | |
| 72 `fz_stream *fz_open_file(fz_context *ctx, const char *filename);` | |
| 73 : Open a stream reading the contents of a file. | |
| 74 | |
| 75 `fz_stream *fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len);` | |
| 76 : Open a stream reading from the data pointer. | |
| 77 | |
| 78 `fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);` | |
| 79 : Open a stream reading from a buffer. | |
| 80 | |
| 81 The basic stream operations you expect are available. | |
| 82 | |
| 83 int64_t fz_tell(fz_context *ctx, fz_stream *stm); | |
| 84 void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence); | |
| 85 size_t fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, size_t len); | |
| 86 size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len); | |
| 87 | |
| 88 `fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, size_t initial);` | |
| 89 : Read the remaining data into a new buffer. | |
| 90 | |
| 91 `char *fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, size_t n);` | |
| 92 : Behaves like `fgets()`. | |
| 93 | |
| 94 int fz_read_byte(fz_context *ctx, fz_stream *stm); | |
| 95 int fz_peek_byte(fz_context *ctx, fz_stream *stm); | |
| 96 int fz_is_eof(fz_context *ctx, fz_stream *stm); | |
| 97 | |
| 98 You can read binary data one integer at a time. The default is big endian, but LE versions are also provided. | |
| 99 | |
| 100 uint16_t fz_read_uint16(fz_context *ctx, fz_stream *stm); | |
| 101 uint32_t fz_read_uint24(fz_context *ctx, fz_stream *stm); | |
| 102 uint32_t fz_read_uint32(fz_context *ctx, fz_stream *stm); | |
| 103 uint64_t fz_read_uint64(fz_context *ctx, fz_stream *stm); | |
| 104 | |
| 105 uint16_t fz_read_uint16_le(fz_context *ctx, fz_stream *stm); | |
| 106 uint32_t fz_read_uint24_le(fz_context *ctx, fz_stream *stm); | |
| 107 uint32_t fz_read_uint32_le(fz_context *ctx, fz_stream *stm); | |
| 108 uint64_t fz_read_uint64_le(fz_context *ctx, fz_stream *stm); | |
| 109 | |
| 110 int16_t fz_read_int16(fz_context *ctx, fz_stream *stm); | |
| 111 int32_t fz_read_int32(fz_context *ctx, fz_stream *stm); | |
| 112 int64_t fz_read_int64(fz_context *ctx, fz_stream *stm); | |
| 113 | |
| 114 int16_t fz_read_int16_le(fz_context *ctx, fz_stream *stm); | |
| 115 int32_t fz_read_int32_le(fz_context *ctx, fz_stream *stm); | |
| 116 int64_t fz_read_int64_le(fz_context *ctx, fz_stream *stm); | |
| 117 | |
| 118 Reading bit streams is also possible: | |
| 119 | |
| 120 unsigned int fz_read_bits(fz_context *ctx, fz_stream *stm, int n); | |
| 121 unsigned int fz_read_rbits(fz_context *ctx, fz_stream *stm, int n); | |
| 122 void fz_sync_bits(fz_context *ctx, fz_stream *stm); | |
| 123 int fz_is_eof_bits(fz_context *ctx, fz_stream *stm); | |
| 124 | |
| 125 ## Filters | |
| 126 | |
| 127 Various decoding, decompression, and decryption filters can be chained together. | |
| 128 | |
| 129 fz_stream *fz_open_null_filter(fz_context *ctx, fz_stream *chain, int len, int64_t offset); | |
| 130 fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen); | |
| 131 fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen); | |
| 132 fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain); | |
| 133 fz_stream *fz_open_ahxd(fz_context *ctx, fz_stream *chain); | |
| 134 fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain); | |
| 135 fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits); | |
| 136 | |
| 137 fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, | |
| 138 int color_transform, | |
| 139 int invert_cmyk, | |
| 140 int l2factor, | |
| 141 fz_stream *jpegtables); | |
| 142 | |
| 143 fz_stream *fz_open_faxd(fz_context *ctx, fz_stream *chain, | |
| 144 int k, | |
| 145 int end_of_line, | |
| 146 int encoded_byte_align, | |
| 147 int columns, | |
| 148 int rows, | |
| 149 int end_of_block, | |
| 150 int black_is_1); | |
| 151 | |
| 152 fz_stream *fz_open_lzwd(fz_context *ctx, fz_stream *chain, | |
| 153 int early_change, | |
| 154 int min_bits, | |
| 155 int reverse_bits, | |
| 156 int old_tiff); | |
| 157 | |
| 158 fz_stream *fz_open_predict(fz_context *ctx, fz_stream *chain, | |
| 159 int predictor, | |
| 160 int columns, | |
| 161 int colors, | |
| 162 int bpc); | |
| 163 | |
| 164 ## Output Streams | |
| 165 | |
| 166 Output streams let us write data to a sink, usually a file on disk or a buffer. As with the input streams, output streams can be chained together to compress, encrypt, and encode data. | |
| 167 | |
| 168 typedef struct { internal } fz_output; | |
| 169 | |
| 170 Because output may be buffered in the writer, we need a separate close function to ensure that an output stream is properly flushed and any end of data markers are written. This is separate to the drop function, which just frees data. If a writing operation has succeeded, you need to call close on the output stream before dropping it. If you encounter an error while writing data, you can just drop the stream directly, since we couldn't finish writing it and closing it properly would be irrelevant. | |
| 171 | |
| 172 void fz_close_output(fz_context *ctx, fz_output *out); | |
| 173 void fz_drop_output(fz_context *ctx, fz_output *out); | |
| 174 | |
| 175 Outputs can be created to write to files or buffers. You can also implement your own data sink by providing a state pointer and callback functions. | |
| 176 | |
| 177 fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append); | |
| 178 fz_output *fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf); | |
| 179 | |
| 180 fz_output *fz_new_output(fz_context *ctx, | |
| 181 int buffer_size, | |
| 182 void *state, | |
| 183 void (*write)(fz_context *ctx, void *state, const void *data, size_t n), | |
| 184 void (*close)(fz_context *ctx, void *state), | |
| 185 void (*drop)(fz_context *ctx, void *state)); | |
| 186 | |
| 187 The usual suspects are available, as well as functions to write integers of various sizes and byte orders. | |
| 188 | |
| 189 `void fz_seek_output(fz_context *ctx, fz_output *out, int64_t off, int whence);` | |
| 190 : Seek to a location in the output. This is not available for all output types. | |
| 191 | |
| 192 `int64_t fz_tell_output(fz_context *ctx, fz_output *out);` | |
| 193 : Tell the current write location of the output stream. | |
| 194 | |
| 195 void fz_write_data(fz_context *ctx, fz_output *out, const void *data, size_t size); | |
| 196 void fz_write_string(fz_context *ctx, fz_output *out, const char *s); | |
| 197 void fz_write_byte(fz_context *ctx, fz_output *out, unsigned char x); | |
| 198 void fz_write_rune(fz_context *ctx, fz_output *out, int rune); | |
| 199 void fz_write_int16_be(fz_context *ctx, fz_output *out, int x); | |
| 200 void fz_write_int16_le(fz_context *ctx, fz_output *out, int x); | |
| 201 void fz_write_int32_be(fz_context *ctx, fz_output *out, int x); | |
| 202 void fz_write_int32_le(fz_context *ctx, fz_output *out, int x); | |
| 203 void fz_write_printf(fz_context *ctx, fz_output *out, const char *fmt, ...); | |
| 204 void fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list ap); | |
| 205 void fz_write_base64(fz_context *ctx, fz_output *out, const unsigned char *data, size_t size, int newline); | |
| 206 | |
| 207 Output streams can be chained together to add encryption, compression, and encoding. Note that these do not take ownership of the chained stream, they only write to it. For example, you can write a header, create a compression filter stream, write some data to the filter to compress the data, close the filter and then keep writing more data to the original stream. | |
| 208 | |
| 209 fz_output *fz_new_arc4_output(fz_context *ctx, fz_output *chain, unsigned char *key, size_t keylen); | |
| 210 fz_output *fz_new_ascii85_output(fz_context *ctx, fz_output *chain); | |
| 211 fz_output *fz_new_asciihex_output(fz_context *ctx, fz_output *chain); | |
| 212 fz_output *fz_new_deflate_output(fz_context *ctx, fz_output *chain, int effort, int no_header); | |
| 213 fz_output *fz_new_rle_output(fz_context *ctx, fz_output *chain); | |
| 214 | |
| 215 ## File Archives | |
| 216 | |
| 217 The archive structure is a read-only collection of files. This is typically a Zip file or directory on disk, but other formats are also supported. | |
| 218 | |
| 219 typedef struct { internal } fz_archive; | |
| 220 | |
| 221 void fz_drop_archive(fz_context *ctx, fz_archive *arch); | |
| 222 | |
| 223 int fz_is_directory(fz_context *ctx, const char *path); | |
| 224 | |
| 225 fz_archive *fz_open_directory(fz_context *ctx, const char *path); | |
| 226 fz_archive *fz_open_archive(fz_context *ctx, const char *filename); | |
| 227 fz_archive *fz_open_archive_with_stream(fz_context *ctx, fz_stream *file); | |
| 228 | |
| 229 int fz_count_archive_entries(fz_context *ctx, fz_archive *arch); | |
| 230 const char *fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx); | |
| 231 | |
| 232 int fz_has_archive_entry(fz_context *ctx, fz_archive *arch, const char *name); | |
| 233 fz_stream *fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name); | |
| 234 fz_buffer *fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name); | |
| 235 | |
| 236 We can also create new Zip archives. | |
| 237 | |
| 238 typedef struct { internal } fz_zip_writer; | |
| 239 | |
| 240 fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename); | |
| 241 fz_zip_writer *fz_new_zip_writer_with_output(fz_context *ctx, fz_output *out); | |
| 242 void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress); | |
| 243 void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip); | |
| 244 void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip); |
