Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/include/mupdf/fitz/stream.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/include/mupdf/fitz/stream.h Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,646 @@ +// Copyright (C) 2004-2021 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see <https://www.artifex.com/> or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +#ifndef MUPDF_FITZ_STREAM_H +#define MUPDF_FITZ_STREAM_H + +#include "mupdf/fitz/system.h" +#include "mupdf/fitz/context.h" +#include "mupdf/fitz/buffer.h" + +/** + Return true if the named file exists and is readable. +*/ +int fz_file_exists(fz_context *ctx, const char *path); + +/** + fz_stream is a buffered reader capable of seeking in both + directions. + + Streams are reference counted, so references must be dropped + by a call to fz_drop_stream. + + Only the data between rp and wp is valid. +*/ +typedef struct fz_stream fz_stream; + +/** + Open the named file and wrap it in a stream. + + filename: Path to a file. On non-Windows machines the filename + should be exactly as it would be passed to fopen(2). On Windows + machines, the path should be UTF-8 encoded so that non-ASCII + characters can be represented. Other platforms do the encoding + as standard anyway (and in most cases, particularly for MacOS + and Linux, the encoding they use is UTF-8 anyway). +*/ +fz_stream *fz_open_file(fz_context *ctx, const char *filename); + +/** + Do the same as fz_open_file, but delete the file upon close. +*/ +fz_stream *fz_open_file_autodelete(fz_context *ctx, const char *filename); + +/** + Open the named file and wrap it in a stream. + + Does the same as fz_open_file, but in the event the file + does not open, it will return NULL rather than throw an + exception. +*/ +fz_stream *fz_try_open_file(fz_context *ctx, const char *name); + +#ifdef _WIN32 +/** + Open the named file and wrap it in a stream. + + This function is only available when compiling for Win32. + + filename: Wide character path to the file as it would be given + to _wfopen(). +*/ +fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename); +#endif /* _WIN32 */ + +/** + Return the filename (UTF-8 encoded) from which a stream was opened. + + Returns NULL if the filename is not available (or the stream was + opened from a source other than a file). +*/ +const char *fz_stream_filename(fz_context *ctx, fz_stream *stm); + +/** + Open a block of memory as a stream. + + data: Pointer to start of data block. Ownership of the data + block is NOT passed in. + + len: Number of bytes in data block. + + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. +*/ +fz_stream *fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len); + +/** + Open a buffer as a stream. + + buf: The buffer to open. Ownership of the buffer is NOT passed + in (this function takes its own reference). + + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. +*/ +fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf); + +/** + Attach a filter to a stream that will store any + characters read from the stream into the supplied buffer. + + chain: The underlying stream to leech from. + + buf: The buffer into which the read data should be appended. + The buffer will be resized as required. + + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. +*/ +fz_stream *fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buf); + +/** + Increments the reference count for a stream. Returns the same + pointer. + + Never throws exceptions. +*/ +fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm); + +/** + Decrements the reference count for a stream. + + When the reference count for the stream hits zero, frees the + storage used for the fz_stream itself, and (usually) + releases the underlying resources that the stream is based upon + (depends on the method used to open the stream initially). +*/ +void fz_drop_stream(fz_context *ctx, fz_stream *stm); + +/** + return the current reading position within a stream +*/ +int64_t fz_tell(fz_context *ctx, fz_stream *stm); + +/** + Seek within a stream. + + stm: The stream to seek within. + + offset: The offset to seek to. + + whence: From where the offset is measured (see fseek). + SEEK_SET - start of stream. + SEEK_CUR - current position. + SEEK_END - end of stream. + +*/ +void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence); + +/** + Read from a stream into a given data block. + + stm: The stream to read from. + + data: The data block to read into. + + len: The length of the data block (in bytes). + + Returns the number of bytes read. May throw exceptions. +*/ +size_t fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, size_t len); + +/** + Read from a stream discarding data. + + stm: The stream to read from. + + len: The number of bytes to read. + + Returns the number of bytes read. May throw exceptions. +*/ +size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len); + +/** + Read all of a stream into a buffer. + + stm: The stream to read from + + initial: Suggested initial size for the buffer. + + Returns a buffer created from reading from the stream. May throw + exceptions on failure to allocate. +*/ +fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, size_t initial); + +/** + Read all the contents of a file into a buffer. +*/ +fz_buffer *fz_read_file(fz_context *ctx, const char *filename); + +/** + Read all the contents of a file into a buffer. + + Returns NULL if the file does not exist, otherwise + behaves exactly as fz_read_file. +*/ +fz_buffer *fz_try_read_file(fz_context *ctx, const char *filename); + +/** + fz_read_[u]int(16|24|32|64)(_le)? + + Read a 16/32/64 bit signed/unsigned integer from stream, + in big or little-endian byte orders. + + Throws an exception if EOF is encountered. +*/ +uint16_t fz_read_uint16(fz_context *ctx, fz_stream *stm); +uint32_t fz_read_uint24(fz_context *ctx, fz_stream *stm); +uint32_t fz_read_uint32(fz_context *ctx, fz_stream *stm); +uint64_t fz_read_uint64(fz_context *ctx, fz_stream *stm); + +uint16_t fz_read_uint16_le(fz_context *ctx, fz_stream *stm); +uint32_t fz_read_uint24_le(fz_context *ctx, fz_stream *stm); +uint32_t fz_read_uint32_le(fz_context *ctx, fz_stream *stm); +uint64_t fz_read_uint64_le(fz_context *ctx, fz_stream *stm); + +int16_t fz_read_int16(fz_context *ctx, fz_stream *stm); +int32_t fz_read_int32(fz_context *ctx, fz_stream *stm); +int64_t fz_read_int64(fz_context *ctx, fz_stream *stm); + +int16_t fz_read_int16_le(fz_context *ctx, fz_stream *stm); +int32_t fz_read_int32_le(fz_context *ctx, fz_stream *stm); +int64_t fz_read_int64_le(fz_context *ctx, fz_stream *stm); + +float fz_read_float_le(fz_context *ctx, fz_stream *stm); +float fz_read_float(fz_context *ctx, fz_stream *stm); + +/** + Read a null terminated string from the stream into + a buffer of a given length. The buffer will be null terminated. + Throws on failure (including the failure to fit the entire + string including the terminator into the buffer). +*/ +void fz_read_string(fz_context *ctx, fz_stream *stm, char *buffer, int len); + +/** + Read a utf-8 rune from a stream. + + In the event of encountering badly formatted utf-8 codes + (such as a leading code with an unexpected number of following + codes) no error/exception is given, but undefined values may be + returned. +*/ +int fz_read_rune(fz_context *ctx, fz_stream *in); + +/** + Read a utf-16 rune from a stream. (little endian and + big endian respectively). + + In the event of encountering badly formatted utf-16 codes + (mismatched surrogates) no error/exception is given, but + undefined values may be returned. +*/ +int fz_read_utf16_le(fz_context *ctx, fz_stream *stm); +int fz_read_utf16_be(fz_context *ctx, fz_stream *stm); + +/** + A function type for use when implementing + fz_streams. The supplied function of this type is called + whenever data is required, and the current buffer is empty. + + stm: The stream to operate on. + + max: a hint as to the maximum number of bytes that the caller + needs to be ready immediately. Can safely be ignored. + + Returns -1 if there is no more data in the stream. Otherwise, + the function should find its internal state using stm->state, + refill its buffer, update stm->rp and stm->wp to point to the + start and end of the new data respectively, and then + "return *stm->rp++". +*/ +typedef int (fz_stream_next_fn)(fz_context *ctx, fz_stream *stm, size_t max); + +/** + A function type for use when implementing + fz_streams. The supplied function of this type is called + when the stream is dropped, to release the stream specific + state information. + + state: The stream state to release. +*/ +typedef void (fz_stream_drop_fn)(fz_context *ctx, void *state); + +/** + A function type for use when implementing + fz_streams. The supplied function of this type is called when + fz_seek is requested, and the arguments are as defined for + fz_seek. + + The stream can find it's private state in stm->state. +*/ +typedef void (fz_stream_seek_fn)(fz_context *ctx, fz_stream *stm, int64_t offset, int whence); + +struct fz_stream +{ + int refs; + int error; + int eof; + int progressive; + int64_t pos; + int avail; + int bits; + unsigned char *rp, *wp; + void *state; + fz_stream_next_fn *next; + fz_stream_drop_fn *drop; + fz_stream_seek_fn *seek; +}; + +/** + Create a new stream object with the given + internal state and function pointers. + + state: Internal state (opaque to everything but implementation). + + next: Should provide the next set of bytes (up to max) of stream + data. Return the number of bytes read, or EOF when there is no + more data. + + drop: Should clean up and free the internal state. May not + throw exceptions. +*/ +fz_stream *fz_new_stream(fz_context *ctx, void *state, fz_stream_next_fn *next, fz_stream_drop_fn *drop); + +/** + Attempt to read a stream into a buffer. If truncated + is NULL behaves as fz_read_all, sets a truncated flag in case of + error. + + stm: The stream to read from. + + initial: Suggested initial size for the buffer. + + truncated: Flag to store success/failure indication in. + + worst_case: 0 for unknown, otherwise an upper bound for the + size of the stream. + + Returns a buffer created from reading from the stream. +*/ +fz_buffer *fz_read_best(fz_context *ctx, fz_stream *stm, size_t initial, int *truncated, size_t worst_case); + +/** + Read a line from stream into the buffer until either a + terminating newline or EOF, which it replaces with a null byte + ('\0'). + + Returns buf on success, and NULL when end of file occurs while + no characters have been read. +*/ +char *fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, size_t max); + +/** + Skip over a given string in a stream. Return 0 if successfully + skipped, non-zero otherwise. As many characters will be skipped + over as matched in the string. +*/ +int fz_skip_string(fz_context *ctx, fz_stream *stm, const char *str); + +/** + Skip over whitespace (bytes <= 32) in a stream. +*/ +void fz_skip_space(fz_context *ctx, fz_stream *stm); + +/** + Ask how many bytes are available immediately from + a given stream. + + stm: The stream to read from. + + max: A hint for the underlying stream; the maximum number of + bytes that we are sure we will want to read. If you do not know + this number, give 1. + + Returns the number of bytes immediately available between the + read and write pointers. This number is guaranteed only to be 0 + if we have hit EOF. The number of bytes returned here need have + no relation to max (could be larger, could be smaller). +*/ +static inline size_t fz_available(fz_context *ctx, fz_stream *stm, size_t max) +{ + size_t len = stm->wp - stm->rp; + int c = EOF; + + if (len) + return len; + if (stm->eof) + return 0; + + fz_try(ctx) + c = stm->next(ctx, stm, max); + fz_catch(ctx) + { + fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_report_error(ctx); + fz_warn(ctx, "read error; treating as end of file"); + stm->error = 1; + c = EOF; + } + if (c == EOF) + { + stm->eof = 1; + return 0; + } + stm->rp--; + return stm->wp - stm->rp; +} + +/** + Read the next byte from a stream. + + stm: The stream t read from. + + Returns -1 for end of stream, or the next byte. May + throw exceptions. +*/ +static inline int fz_read_byte(fz_context *ctx, fz_stream *stm) +{ + int c = EOF; + + if (stm->rp != stm->wp) + return *stm->rp++; + if (stm->eof) + return EOF; + fz_try(ctx) + c = stm->next(ctx, stm, 1); + fz_catch(ctx) + { + fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_report_error(ctx); + fz_warn(ctx, "read error; treating as end of file"); + stm->error = 1; + c = EOF; + } + if (c == EOF) + stm->eof = 1; + return c; +} + +/** + Peek at the next byte in a stream. + + stm: The stream to peek at. + + Returns -1 for EOF, or the next byte that will be read. +*/ +static inline int fz_peek_byte(fz_context *ctx, fz_stream *stm) +{ + int c = EOF; + + if (stm->rp != stm->wp) + return *stm->rp; + if (stm->eof) + return EOF; + + fz_try(ctx) + { + c = stm->next(ctx, stm, 1); + if (c != EOF) + stm->rp--; + } + fz_catch(ctx) + { + fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_report_error(ctx); + fz_warn(ctx, "read error; treating as end of file"); + stm->error = 1; + c = EOF; + } + if (c == EOF) + stm->eof = 1; + return c; +} + +/** + Unread the single last byte successfully + read from a stream. Do not call this without having + successfully read a byte. + + stm: The stream to operate upon. +*/ +static inline void fz_unread_byte(fz_context *ctx FZ_UNUSED, fz_stream *stm) +{ + stm->rp--; +} + +/** + Query if the stream has reached EOF (during normal bytewise + reading). + + See fz_is_eof_bits for the equivalent function for bitwise + reading. +*/ +static inline int fz_is_eof(fz_context *ctx, fz_stream *stm) +{ + if (stm->rp == stm->wp) + { + if (stm->eof) + return 1; + return fz_peek_byte(ctx, stm) == EOF; + } + return 0; +} + +/** + Read the next n bits from a stream (assumed to + be packed most significant bit first). + + stm: The stream to read from. + + n: The number of bits to read, between 1 and 8*sizeof(int) + inclusive. + + Returns -1 for EOF, or the required number of bits. +*/ +static inline unsigned int fz_read_bits(fz_context *ctx, fz_stream *stm, int n) +{ + int x; + + if (n <= stm->avail) + { + stm->avail -= n; + x = (stm->bits >> stm->avail) & ((1 << n) - 1); + } + else + { + x = stm->bits & ((1 << stm->avail) - 1); + n -= stm->avail; + stm->avail = 0; + + while (n > 8) + { + x = (x << 8) | fz_read_byte(ctx, stm); + n -= 8; + } + + if (n > 0) + { + stm->bits = fz_read_byte(ctx, stm); + stm->avail = 8 - n; + x = (x << n) | (stm->bits >> stm->avail); + } + } + + return x; +} + +/** + Read the next n bits from a stream (assumed to + be packed least significant bit first). + + stm: The stream to read from. + + n: The number of bits to read, between 1 and 8*sizeof(int) + inclusive. + + Returns (unsigned int)-1 for EOF, or the required number of bits. +*/ +static inline unsigned int fz_read_rbits(fz_context *ctx, fz_stream *stm, int n) +{ + int x; + + if (n <= stm->avail) + { + x = stm->bits & ((1 << n) - 1); + stm->avail -= n; + stm->bits = stm->bits >> n; + } + else + { + unsigned int used = 0; + + x = stm->bits & ((1 << stm->avail) - 1); + n -= stm->avail; + used = stm->avail; + stm->avail = 0; + + while (n > 8) + { + x = (fz_read_byte(ctx, stm) << used) | x; + n -= 8; + used += 8; + } + + if (n > 0) + { + stm->bits = fz_read_byte(ctx, stm); + x = ((stm->bits & ((1 << n) - 1)) << used) | x; + stm->avail = 8 - n; + stm->bits = stm->bits >> n; + } + } + + return x; +} + +/** + Called after reading bits to tell the stream + that we are about to return to reading bytewise. Resyncs + the stream to whole byte boundaries. +*/ +static inline void fz_sync_bits(fz_context *ctx FZ_UNUSED, fz_stream *stm) +{ + stm->avail = 0; +} + +/** + Query if the stream has reached EOF (during bitwise + reading). + + See fz_is_eof for the equivalent function for bytewise + reading. +*/ +static inline int fz_is_eof_bits(fz_context *ctx, fz_stream *stm) +{ + return fz_is_eof(ctx, stm) && (stm->avail == 0 || stm->bits == EOF); +} + +/* Implementation details: subject to change. */ + +/** + Create a stream from a FILE * that will not be closed + when the stream is dropped. +*/ +fz_stream *fz_open_file_ptr_no_close(fz_context *ctx, FILE *file); + +#endif
