diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2017-03-09 17:16:22 +0000 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2017-03-11 10:16:54 -0600 |
commit | d032461524ee064a0025ea38e4dfc913408b7db3 (patch) | |
tree | 83855773b2d35cdb3d8cd7e352987842e128253f | |
parent | ea00b61c7ccd14422bef33282e18fa8b4660fe74 (diff) | |
download | mupdf-d032461524ee064a0025ea38e4dfc913408b7db3.tar.xz |
Improve API documentation for fz_output.
Move implementation to be more in line with fz_streams. Much
closer parallels now.
-rw-r--r-- | include/mupdf/fitz/output.h | 219 | ||||
-rw-r--r-- | source/fitz/output-tga.c | 42 | ||||
-rw-r--r-- | source/fitz/output.c | 45 |
3 files changed, 252 insertions, 54 deletions
diff --git a/include/mupdf/fitz/output.h b/include/mupdf/fitz/output.h index 5bc0fc44..aae56528 100644 --- a/include/mupdf/fitz/output.h +++ b/include/mupdf/fitz/output.h @@ -12,54 +12,170 @@ */ typedef struct fz_output_s fz_output; +/* + fz_output_write_fn: A function type for use when implementing + fz_outputs. The supplied function of this type is called + whenever data is written to the output. + + state: The state for the output stream. + + data: a pointer to a buffer of data to write. + + n: The number of bytes of data to write. +*/ +typedef void (fz_output_write_fn)(fz_context *ctx, void *state, const void *data, size_t n); + +/* + fz_output_seek_fn: A function type for use when implementing + fz_outputs. The supplied function of this type is called when + fz_seek_output is requested. + + state: The output stream state to seek within. + + offset, whence: as defined for fs_seek_output. +*/ +typedef void (fz_output_seek_fn)(fz_context *ctx, void *state, fz_off_t offset, int whence); + +/* + fz_output_tell_fn: A function type for use when implementing + fz_outputs. The supplied function of this type is called when + fz_tell_output is requested. + + state: The output stream state to report on. + + Returns the offset within the output stream. +*/ +typedef fz_off_t (fz_output_tell_fn)(fz_context *ctx, void *state); + +/* + fz_output_close_fn: A function type for use when implementing + fz_outputs. The supplied function of this type is called + when the output stream is closed, to release the stream specific + state information. + + state: The output stream state to release. +*/ +typedef void (fz_output_close_fn)(fz_context *ctx, void *state); + struct fz_output_s { - void *opaque; - void (*write)(fz_context *, void *opaque, const void *, size_t n); - void (*seek)(fz_context *, void *opaque, fz_off_t off, int whence); - fz_off_t (*tell)(fz_context *, void *opaque); - void (*close)(fz_context *, void *opaque); + void *state; + fz_output_write_fn *write; + fz_output_seek_fn *seek; + fz_output_tell_fn *tell; + fz_output_close_fn *close; }; /* - fz_new_output_with_file: Open an output stream that writes to a FILE *. - fz_new_output_with_path: Open an output stream that writes to a file. - fz_new_output_with_buffer: Open an output stream that writes into a buffer. + fz_new_output: Create a new output object with the given + internal state and function pointers. + + state: Internal state (opaque to everything but implementation). + + write: Function to output a given buffer. + + close: Cleanup function to destroy state when output closed. + May permissibly be null. +*/ +fz_output *fz_new_output(fz_context *ctx, void *state, fz_output_write_fn *write, fz_output_close_fn *close); + +/* + fz_new_output_with_file: Open an output stream that writes to a + FILE *. + + file: The file to write to. + + close: non-zero if we should close the file when the fz_output + is closed. +*/ +fz_output *fz_new_output_with_file_ptr(fz_context *ctx, FILE *file, int close); + +/* + fz_new_output_with_path: Open an output stream that writes to a + given path. + + filename: The filename to write to (specified in UTF-8). + + append: non-zero if we should append to the file, rather than + overwriting it. */ -fz_output *fz_new_output_with_file_ptr(fz_context *, FILE *, int close); fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append); -fz_output *fz_new_output_with_buffer(fz_context *, fz_buffer *); /* - fz_stdout: The standard out output stream. - fz_stderr: The standard error output stream. - fz_set_stdout: Replace default standard output stream with a new stream. - fz_set_stderr: Replace default standard error stream with a new stream. + fz_new_output_with_buffer: Open an output stream that appends + to a buffer. + + buf: The buffer to append to. +*/ +fz_output *fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf); + +/* + fz_stdout: The standard out output stream. By default + this stream writes to stdout. This may be overridden + using fz_set_stdout. +*/ +fz_output *fz_stdout(fz_context *ctx); + +/* + fz_stderr: The standard error output stream. By default + this stream writes to stderr. This may be overridden + using fz_set_stderr. +*/ +fz_output *fz_stderr(fz_context *ctx); + +/* + fz_set_stdout: Replace default standard output stream + with a given stream. + + out: The new stream to use. */ -fz_output *fz_stdout(fz_context *); -fz_output *fz_stderr(fz_context *); void fz_set_stdout(fz_context *ctx, fz_output *out); + +/* + fz_set_stderr: Replace default standard error stream + with a given stream. + + err: The new stream to use. +*/ void fz_set_stderr(fz_context *ctx, fz_output *err); /* - fz_write: fwrite equivalent for output streams. fz_printf: fprintf equivalent for output streams. See fz_snprintf. - fz_vprintf: vfprintf equivalent for output streams. See fz_vsnprintf. - fz_puts: fputs equivalent for output streams. - fz_putc: fputc equivalent for output streams. - fz_putrune: fputrune equivalent for output streams. */ void fz_printf(fz_context *ctx, fz_output *out, const char *fmt, ...); + +/* + fz_vprintf: vfprintf equivalent for output streams. See fz_vsnprintf. +*/ void fz_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list ap); -#define fz_puts(C,O,S) fz_write(C, O, (S), strlen(S)) + +/* + fz_putc: fputc equivalent for output streams. +*/ #define fz_putc(C,O,B) fz_write_byte(C, O, B) + +/* + fz_puts: fputs equivalent for output streams. +*/ +#define fz_puts(C,O,S) fz_write(C, O, (S), strlen(S)) + +/* + fz_putrune: fz_putc equivalent for utf-8 output. +*/ #define fz_putrune(C,O,R) fz_write_rune(C, O, R) /* - fz_seek_output: Seek to the specified file position. Throw an error on unseekable outputs. - fz_tell_output: Return the current file position. Throw an error on unseekable outputs. + fz_seek_output: Seek to the specified file position. See fseek + for arguments. + + Throw an error on unseekable outputs. */ void fz_seek_output(fz_context *ctx, fz_output *out, fz_off_t off, int whence); + +/* + fz_tell_output: Return the current file position. Throw an error + on untellable outputs. +*/ fz_off_t fz_tell_output(fz_context *ctx, fz_output *out); /* @@ -68,22 +184,24 @@ fz_off_t fz_tell_output(fz_context *ctx, fz_output *out); void fz_drop_output(fz_context *, fz_output *); /* - fz_write: Write data to output. -*/ + fz_write: Write data to output. Designed to parallel + fwrite. + out: Output stream to write to. + + data: Pointer to data to write. + + size: Length of data to write. +*/ static inline void fz_write(fz_context *ctx, fz_output *out, const void *data, size_t size) { if (out) - out->write(ctx, out->opaque, data, size); + out->write(ctx, out->state, data, size); } /* - fz_write_int32be: Write a big-endian 32-bit binary integer. - fz_write_int32le: Write a little-endian 32-bit binary integer. - fz_write_byte: Write a single byte. - fz_write_rune: Write a UTF-8 encoded unicode character. + fz_write_int32_be: Write a big-endian 32-bit binary integer. */ - static inline void fz_write_int32_be(fz_context *ctx, fz_output *out, int x) { char data[4]; @@ -96,6 +214,9 @@ static inline void fz_write_int32_be(fz_context *ctx, fz_output *out, int x) fz_write(ctx, out, data, 4); } +/* + fz_write_int32_le: Write a little-endian 32-bit binary integer. +*/ static inline void fz_write_int32_le(fz_context *ctx, fz_output *out, int x) { char data[4]; @@ -108,6 +229,22 @@ static inline void fz_write_int32_le(fz_context *ctx, fz_output *out, int x) fz_write(ctx, out, data, 4); } +/* + fz_write_int16_be: Write a big-endian 16-bit binary integer. +*/ +static inline void fz_write_int16_be(fz_context *ctx, fz_output *out, int x) +{ + char data[2]; + + data[0] = x>>8; + data[1] = x; + + fz_write(ctx, out, data, 2); +} + +/* + fz_write_int16_le: Write a little-endian 16-bit binary integer. +*/ static inline void fz_write_int16_le(fz_context *ctx, fz_output *out, int x) { char data[2]; @@ -118,11 +255,25 @@ static inline void fz_write_int16_le(fz_context *ctx, fz_output *out, int x) fz_write(ctx, out, data, 2); } +/* + fz_write_byte: Write a single byte. + + out: stream to write to. + + x: value to write +*/ static inline void fz_write_byte(fz_context *ctx, fz_output *out, unsigned char x) { fz_write(ctx, out, &x, 1); } +/* + fz_write_rune: Write a UTF-8 encoded unicode character. + + out: stream to write to. + + x: value to write +*/ static inline void fz_write_rune(fz_context *ctx, fz_output *out, int rune) { char data[10]; @@ -142,6 +293,10 @@ static inline void fz_write_rune(fz_context *ctx, fz_output *out, int rune) %Z{d,u,x} indicates that the value is a fz_off_t. */ size_t fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args); + +/* + fz_snprintf: The non va_list equivalent of fz_vsnprintf. +*/ size_t fz_snprintf(char *buffer, size_t space, const char *fmt, ...); /* diff --git a/source/fitz/output-tga.c b/source/fitz/output-tga.c index b5e594b6..8a595265 100644 --- a/source/fitz/output-tga.c +++ b/source/fitz/output-tga.c @@ -6,21 +6,45 @@ static inline void tga_put_pixel(fz_context *ctx, fz_output *out, unsigned char *data, int n, int is_bgr) { - if (n >= 3 && !is_bgr) + switch(n) { - fz_putc(ctx, out, data[2]); + case 4: /* RGBA or BGRA */ + if (!is_bgr) { + fz_putc(ctx, out, data[2]); + fz_putc(ctx, out, data[1]); + fz_putc(ctx, out, data[0]); + } else { + fz_putc(ctx, out, data[0]); + fz_putc(ctx, out, data[1]); + fz_putc(ctx, out, data[2]); + } + fz_putc(ctx, out, data[3]); + break; + case 3: /* RGB or BGR */ + if (!is_bgr) { + fz_putc(ctx, out, data[2]); + fz_putc(ctx, out, data[1]); + fz_putc(ctx, out, data[0]); + } else { + fz_putc(ctx, out, data[0]); + fz_putc(ctx, out, data[1]); + fz_putc(ctx, out, data[2]); + } + fz_putc(ctx, out, 255); + break; + case 2: /* GA */ + fz_putc(ctx, out, data[0]); + fz_putc(ctx, out, data[0]); + fz_putc(ctx, out, data[0]); fz_putc(ctx, out, data[1]); + break; + case 1: /* GA */ fz_putc(ctx, out, data[0]); - if (n == 4) - fz_putc(ctx, out, data[3]); - return; - } - if (n == 2) - { fz_putc(ctx, out, data[0]); fz_putc(ctx, out, data[0]); + fz_putc(ctx, out, 255); + break; } - fz_write(ctx, out, data, n); } void diff --git a/source/fitz/output.c b/source/fitz/output.c index a93ecc97..27495b34 100644 --- a/source/fitz/output.c +++ b/source/fitz/output.c @@ -140,14 +140,32 @@ file_close(fz_context *ctx, void *opaque) } fz_output * +fz_new_output(fz_context *ctx, void *state, fz_output_write_fn *write, fz_output_close_fn *close) +{ + fz_output *out; + + fz_try(ctx) + { + out = fz_malloc_struct(ctx, fz_output); + out->state = state; + out->write = write; + out->close = close; + } + fz_catch(ctx) + { + if (close) + close(ctx, state); + fz_rethrow(ctx); + } + return out; +} + +fz_output * fz_new_output_with_file_ptr(fz_context *ctx, FILE *file, int close) { - fz_output *out = fz_malloc_struct(ctx, fz_output); - out->opaque = file; - out->write = file_write; + fz_output *out = fz_new_output(ctx, file, file_write, close ? file_close : NULL); out->seek = file_seek; out->tell = file_tell; - out->close = close ? file_close : NULL; return out; } @@ -214,12 +232,9 @@ buffer_close(fz_context *ctx, void *opaque) fz_output * fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf) { - fz_output *out = fz_malloc_struct(ctx, fz_output); - out->opaque = fz_keep_buffer(ctx, buf); - out->write = buffer_write; + fz_output *out = fz_new_output(ctx, fz_keep_buffer(ctx, buf), buffer_write, buffer_close); out->seek = buffer_seek; out->tell = buffer_tell; - out->close = buffer_close; return out; } @@ -228,8 +243,8 @@ fz_drop_output(fz_context *ctx, fz_output *out) { if (!out) return; if (out->close) - out->close(ctx, out->opaque); - if (out->opaque != &fz_stdout_global && out->opaque != &fz_stderr_global) + out->close(ctx, out->state); + if (out->state != &fz_stdout_global && out->state != &fz_stderr_global) fz_free(ctx, out); } @@ -237,14 +252,18 @@ void fz_seek_output(fz_context *ctx, fz_output *out, fz_off_t off, int whence) { if (!out) return; - out->seek(ctx, out->opaque, off, whence); + if (out->seek == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot seek in unseekable output stream\n"); + out->seek(ctx, out->state, off, whence); } fz_off_t fz_tell_output(fz_context *ctx, fz_output *out) { if (!out) return 0; - return out->tell(ctx, out->opaque); + if (out->tell == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot tell in untellable output stream\n"); + return out->tell(ctx, out->state); } void @@ -271,7 +290,7 @@ fz_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list old_args) } fz_try(ctx) - out->write(ctx, out->opaque, p, len); + out->write(ctx, out->state, p, len); fz_always(ctx) if (p != buffer) fz_free(ctx, p); |