summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/output.h19
-rw-r--r--source/fitz/fitz-imp.h4
-rw-r--r--source/fitz/output.c22
-rw-r--r--source/fitz/stream-open.c8
4 files changed, 51 insertions, 2 deletions
diff --git a/include/mupdf/fitz/output.h b/include/mupdf/fitz/output.h
index 0425e353..2530be47 100644
--- a/include/mupdf/fitz/output.h
+++ b/include/mupdf/fitz/output.h
@@ -5,6 +5,7 @@
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/string-util.h"
+#include "mupdf/fitz/stream.h"
/*
Generic output streams - generalise between outputting to a file,
@@ -62,6 +63,13 @@ typedef void (fz_output_close_fn)(fz_context *ctx, void *state);
*/
typedef void (fz_output_drop_fn)(fz_context *ctx, void *state);
+/*
+ fz_stream_from_output_fn: A function type for use when implementing
+ fz_outputs. The supplied function of this type is called
+ when the fz_stream_from_output is called.
+*/
+typedef fz_stream *(fz_stream_from_output_fn)(fz_context *ctx, void *state);
+
struct fz_output_s
{
@@ -71,6 +79,7 @@ struct fz_output_s
fz_output_tell_fn *tell;
fz_output_close_fn *close;
fz_output_drop_fn *drop;
+ fz_stream_from_output_fn *as_stream;
};
/*
@@ -172,6 +181,16 @@ void fz_close_output(fz_context *, fz_output *);
void fz_drop_output(fz_context *, fz_output *);
/*
+ fz_stream_from_output: obtain the fz_output in the form of a fz_stream
+
+ This allows data to be read back from some forms of fz_output object.
+ When finished reading, the fz_stream should be released by calling
+ fz_drop_stream. Until the fz_stream is dropped, no further operations
+ should be performed on the fz_output object.
+*/
+fz_stream *fz_stream_from_output(fz_context *, fz_output *);
+
+/*
fz_write_data: Write data to output.
data: Pointer to data to write.
diff --git a/source/fitz/fitz-imp.h b/source/fitz/fitz-imp.h
index 41c905e4..9740213d 100644
--- a/source/fitz/fitz-imp.h
+++ b/source/fitz/fitz-imp.h
@@ -3,6 +3,8 @@
#include "mupdf/fitz.h"
+#include <stdio.h>
+
struct fz_buffer_s
{
int refs;
@@ -91,6 +93,8 @@ void fz_new_output_context(fz_context *ctx);
void fz_drop_output_context(fz_context *ctx);
fz_output_context *fz_keep_output_context(fz_context *ctx);
+fz_stream *fz_open_file_ptr_no_close(fz_context *ctx, FILE *file);
+
#if defined(MEMENTO) || !defined(NDEBUG)
#define FITZ_DEBUG_LOCKING
#endif
diff --git a/source/fitz/output.c b/source/fitz/output.c
index 4c6aa6b4..18791603 100644
--- a/source/fitz/output.c
+++ b/source/fitz/output.c
@@ -158,6 +158,14 @@ file_drop(fz_context *ctx, void *opaque)
fz_warn(ctx, "cannot fclose: %s", strerror(errno));
}
+static fz_stream *
+file_as_stream(fz_context *ctx, void *opaque)
+{
+ FILE *file = opaque;
+ fflush(file);
+ return fz_open_file_ptr_no_close(ctx, file);
+};
+
fz_output *
fz_new_output(fz_context *ctx, void *state, fz_output_write_fn *write, fz_output_close_fn *close, fz_output_drop_fn *drop)
{
@@ -197,7 +205,7 @@ fz_new_output_with_path(fz_context *ctx, const char *filename, int append)
if (errno != ENOENT)
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot remove file '%s': %s", filename, strerror(errno));
}
- file = fz_fopen_utf8(filename, append ? "ab" : "wb");
+ file = fz_fopen_utf8(filename, "rb+");
#else
/* Ensure we create a brand new file. We don't want to clobber our old file. */
if (!append)
@@ -206,7 +214,7 @@ fz_new_output_with_path(fz_context *ctx, const char *filename, int append)
if (errno != ENOENT)
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot remove file '%s': %s", filename, strerror(errno));
}
- file = fopen(filename, append ? "ab" : "wb");
+ file = fopen(filename, "rb+");
#endif
if (!file)
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));
@@ -214,6 +222,7 @@ fz_new_output_with_path(fz_context *ctx, const char *filename, int append)
out = fz_new_output(ctx, file, file_write, NULL, file_drop);
out->seek = file_seek;
out->tell = file_tell;
+ out->as_stream = file_as_stream;
return out;
}
@@ -293,6 +302,15 @@ fz_tell_output(fz_context *ctx, fz_output *out)
return out->tell(ctx, out->state);
}
+fz_stream *
+fz_stream_from_output(fz_context *ctx, fz_output *out)
+{
+ if (!out) return 0;
+ if (out->as_stream == NULL)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot derive input stream from output stream");
+ return out->as_stream(ctx, out->state);
+}
+
static void
fz_write_emit(fz_context *ctx, void *out, int c)
{
diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c
index ffd61b66..1a99ad52 100644
--- a/source/fitz/stream-open.c
+++ b/source/fitz/stream-open.c
@@ -144,6 +144,14 @@ fz_open_file_ptr(fz_context *ctx, FILE *file)
return stm;
}
+fz_stream *fz_open_file_ptr_no_close(fz_context *ctx, FILE *file)
+{
+ fz_stream *stm = fz_open_file_ptr(ctx, file);
+ /* We don't own the file ptr. Ensure we don't close it */
+ stm->close = NULL;
+ return stm;
+}
+
fz_stream *
fz_open_file(fz_context *ctx, const char *name)
{