From 651f13408c67a8392ad93adda079c096d8a6118c Mon Sep 17 00:00:00 2001
From: Robin Watts <robin.watts@artifex.com>
Date: Fri, 13 Dec 2013 16:29:18 +0000
Subject: Add rebinding for fz_streams.

---
 source/fitz/filter-basic.c   | 71 +++++++++++++++++++++++++++++++++++++++-----
 source/fitz/filter-dct.c     |  9 +++++-
 source/fitz/filter-fax.c     |  9 +++++-
 source/fitz/filter-flate.c   |  9 +++++-
 source/fitz/filter-jbig2.c   |  9 +++++-
 source/fitz/filter-lzw.c     |  9 +++++-
 source/fitz/filter-predict.c |  9 +++++-
 source/fitz/stream-open.c    | 22 ++++++++++----
 source/fitz/stream-prog.c    |  2 +-
 9 files changed, 130 insertions(+), 19 deletions(-)

(limited to 'source/fitz')

diff --git a/source/fitz/filter-basic.c b/source/fitz/filter-basic.c
index 4e64d016..3a64ee93 100644
--- a/source/fitz/filter-basic.c
+++ b/source/fitz/filter-basic.c
@@ -40,6 +40,13 @@ close_null(fz_context *ctx, void *state_)
 	fz_close(chain);
 }
 
+static fz_stream *
+rebind_null(fz_stream *s)
+{
+	struct null_filter *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_null(fz_stream *chain, int len, int offset)
 {
@@ -61,7 +68,7 @@ fz_open_null(fz_stream *chain, int len, int offset)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_null, close_null);
+	return fz_new_stream(ctx, state, read_null, close_null, rebind_null);
 }
 
 /* Concat filter concatenates several streams into one */
@@ -129,6 +136,21 @@ close_concat(fz_context *ctx, void *state_)
 	fz_free(ctx, state);
 }
 
+static fz_stream *
+rebind_concat(fz_stream *s)
+{
+	struct concat_filter *state = s->state;
+	int i;
+
+	if (state->current >= state->count)
+		return NULL;
+	for (i = state->current; i < state->count-1; i++)
+	{
+		fz_rebind_stream(state->chain[i], s->ctx);
+	}
+	return state->chain[i];
+}
+
 fz_stream *
 fz_open_concat(fz_context *ctx, int len, int pad)
 {
@@ -141,7 +163,7 @@ fz_open_concat(fz_context *ctx, int len, int pad)
 	state->pad = pad;
 	state->ws = 0; /* We never send padding byte at the start */
 
-	return fz_new_stream(ctx, state, read_concat, close_concat);
+	return fz_new_stream(ctx, state, read_concat, close_concat, rebind_concat);
 }
 
 void
@@ -247,6 +269,13 @@ close_ahxd(fz_context *ctx, void *state_)
 	fz_close(chain);
 }
 
+static fz_stream *
+rebind_ahxd(fz_stream *s)
+{
+	fz_ahxd *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_ahxd(fz_stream *chain)
 {
@@ -265,7 +294,7 @@ fz_open_ahxd(fz_stream *chain)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_ahxd, close_ahxd);
+	return fz_new_stream(ctx, state, read_ahxd, close_ahxd, rebind_ahxd);
 }
 
 /* ASCII 85 Decode */
@@ -397,6 +426,13 @@ close_a85d(fz_context *ctx, void *state_)
 	fz_close(chain);
 }
 
+static fz_stream *
+rebind_a85d(fz_stream *s)
+{
+	fz_a85d *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_a85d(fz_stream *chain)
 {
@@ -417,7 +453,7 @@ fz_open_a85d(fz_stream *chain)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_a85d, close_a85d);
+	return fz_new_stream(ctx, state, read_a85d, close_a85d, rebind_a85d);
 }
 
 /* Run Length Decode */
@@ -493,6 +529,13 @@ close_rld(fz_context *ctx, void *state_)
 	fz_close(chain);
 }
 
+static fz_stream *
+rebind_rld(fz_stream *s)
+{
+	fz_rld *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_rld(fz_stream *chain)
 {
@@ -513,7 +556,7 @@ fz_open_rld(fz_stream *chain)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_rld, close_rld);
+	return fz_new_stream(ctx, state, read_rld, close_rld, rebind_rld);
 }
 
 /* RC4 Filter */
@@ -545,6 +588,13 @@ close_arc4(fz_context *ctx, void *state_)
 	fz_close(chain);
 }
 
+static fz_stream *
+rebind_arc4c(fz_stream *s)
+{
+	fz_arc4c *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen)
 {
@@ -563,7 +613,7 @@ fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_arc4, close_arc4);
+	return fz_new_stream(ctx, state, read_arc4, close_arc4, rebind_arc4c);
 }
 
 /* AES Filter */
@@ -636,6 +686,13 @@ close_aesd(fz_context *ctx, void *state_)
 	fz_close(chain);
 }
 
+static fz_stream *
+rebind_aesd(fz_stream *s)
+{
+	fz_aesd *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
 {
@@ -661,5 +718,5 @@ fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_aesd, close_aesd);
+	return fz_new_stream(ctx, state, read_aesd, close_aesd, rebind_aesd);
 }
diff --git a/source/fitz/filter-dct.c b/source/fitz/filter-dct.c
index adc3206c..f53f00cd 100644
--- a/source/fitz/filter-dct.c
+++ b/source/fitz/filter-dct.c
@@ -236,6 +236,13 @@ skip:
 	fz_free(ctx, state);
 }
 
+static fz_stream *
+rebind_dctd(fz_stream *s)
+{
+	fz_dctd *state = s->state;
+	return state->chain;
+}
+
 /* Default: color_transform = -1 (unset), l2factor = 0, jpegtables = NULL */
 fz_stream *
 fz_open_dctd(fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables)
@@ -264,5 +271,5 @@ fz_open_dctd(fz_stream *chain, int color_transform, int l2factor, fz_stream *jpe
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_dctd, close_dctd);
+	return fz_new_stream(ctx, state, read_dctd, close_dctd, rebind_dctd);
 }
diff --git a/source/fitz/filter-fax.c b/source/fitz/filter-fax.c
index 38f948bf..e0aa781d 100644
--- a/source/fitz/filter-fax.c
+++ b/source/fitz/filter-fax.c
@@ -760,6 +760,13 @@ close_faxd(fz_context *ctx, void *state_)
 	fz_free(ctx, fax);
 }
 
+static fz_stream *
+rebind_faxd(fz_stream *s)
+{
+	fz_faxd *state = s->state;
+	return state->chain;
+}
+
 /* Default: columns = 1728, end_of_block = 1, the rest = 0 */
 fz_stream *
 fz_open_faxd(fz_stream *chain,
@@ -818,5 +825,5 @@ fz_open_faxd(fz_stream *chain,
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, fax, read_faxd, close_faxd);
+	return fz_new_stream(ctx, fax, read_faxd, close_faxd, rebind_faxd);
 }
diff --git a/source/fitz/filter-flate.c b/source/fitz/filter-flate.c
index f2abaf6d..022cdb12 100644
--- a/source/fitz/filter-flate.c
+++ b/source/fitz/filter-flate.c
@@ -86,6 +86,13 @@ close_flated(fz_context *ctx, void *state_)
 	fz_free(ctx, state);
 }
 
+static fz_stream *
+rebind_flated(fz_stream *s)
+{
+	fz_flate *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_flated(fz_stream *chain)
 {
@@ -119,5 +126,5 @@ fz_open_flated(fz_stream *chain)
 		fz_close(chain);
 		fz_rethrow(ctx);
 	}
-	return fz_new_stream(ctx, state, read_flated, close_flated);
+	return fz_new_stream(ctx, state, read_flated, close_flated, rebind_flated);
 }
diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c
index 12eb8c3b..d3d5c5fa 100644
--- a/source/fitz/filter-jbig2.c
+++ b/source/fitz/filter-jbig2.c
@@ -63,6 +63,13 @@ read_jbig2d(fz_stream *stm, unsigned char *buf, int len)
 	return p - buf;
 }
 
+static fz_stream *
+rebind_jbig2d(fz_stream *s)
+{
+	fz_jbig2d *state = s->state;
+	return state->chain;
+}
+
 fz_stream *
 fz_open_jbig2d(fz_stream *chain, fz_buffer *globals)
 {
@@ -104,5 +111,5 @@ fz_open_jbig2d(fz_stream *chain, fz_buffer *globals)
 	}
 	fz_drop_buffer(ctx, globals);
 
-	return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d);
+	return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d, rebind_jbig2d);
 }
diff --git a/source/fitz/filter-lzw.c b/source/fitz/filter-lzw.c
index 63d6555b..c78c8c3f 100644
--- a/source/fitz/filter-lzw.c
+++ b/source/fitz/filter-lzw.c
@@ -174,6 +174,13 @@ close_lzwd(fz_context *ctx, void *state_)
 	fz_free(ctx, lzw);
 }
 
+static fz_stream *
+rebind_lzwd(fz_stream *s)
+{
+	fz_lzwd *state = s->state;
+	return state->chain;
+}
+
 /* Default: early_change = 1 */
 fz_stream *
 fz_open_lzwd(fz_stream *chain, int early_change)
@@ -221,5 +228,5 @@ fz_open_lzwd(fz_stream *chain, int early_change)
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, lzw, read_lzwd, close_lzwd);
+	return fz_new_stream(ctx, lzw, read_lzwd, close_lzwd, rebind_lzwd);
 }
diff --git a/source/fitz/filter-predict.c b/source/fitz/filter-predict.c
index c8de290a..6bc75c8e 100644
--- a/source/fitz/filter-predict.c
+++ b/source/fitz/filter-predict.c
@@ -190,6 +190,13 @@ close_predict(fz_context *ctx, void *state_)
 	fz_free(ctx, state);
 }
 
+static fz_stream *
+rebind_predict(fz_stream *s)
+{
+	fz_predict *state = s->state;
+	return state->chain;
+}
+
 /* Default values: predictor = 1, columns = 1, colors = 1, bpc = 8 */
 fz_stream *
 fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc)
@@ -252,5 +259,5 @@ fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bp
 		fz_rethrow(ctx);
 	}
 
-	return fz_new_stream(ctx, state, read_predict, close_predict);
+	return fz_new_stream(ctx, state, read_predict, close_predict, rebind_predict);
 }
diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c
index 9e4dc8d4..f336a4e4 100644
--- a/source/fitz/stream-open.c
+++ b/source/fitz/stream-open.c
@@ -1,9 +1,20 @@
 #include "mupdf/fitz.h"
 
+void fz_rebind_stream(fz_stream *stm, fz_context *ctx)
+{
+	if (stm == NULL || stm->ctx == ctx)
+		return;
+	do {
+		stm->ctx = ctx;
+		stm = (stm->rebind == NULL ? NULL : stm->rebind(stm));
+	} while (stm != NULL);
+}
+
 fz_stream *
 fz_new_stream(fz_context *ctx, void *state,
-	int(*read)(fz_stream *stm, unsigned char *buf, int len),
-	void(*close)(fz_context *ctx, void *state))
+	fz_stream_read_fn *read,
+	fz_stream_close_fn *close,
+	fz_stream_rebind_fn *rebind)
 {
 	fz_stream *stm;
 
@@ -34,6 +45,7 @@ fz_new_stream(fz_context *ctx, void *state,
 	stm->read = read;
 	stm->close = close;
 	stm->seek = NULL;
+	stm->rebind = rebind;
 	stm->ctx = ctx;
 
 	return stm;
@@ -100,7 +112,7 @@ fz_open_fd(fz_context *ctx, int fd)
 
 	fz_try(ctx)
 	{
-		stm = fz_new_stream(ctx, state, read_file, close_file);
+		stm = fz_new_stream(ctx, state, read_file, close_file, NULL);
 	}
 	fz_catch(ctx)
 	{
@@ -178,7 +190,7 @@ fz_open_buffer(fz_context *ctx, fz_buffer *buf)
 	fz_stream *stm;
 
 	fz_keep_buffer(ctx, buf);
-	stm = fz_new_stream(ctx, buf, read_buffer, close_buffer);
+	stm = fz_new_stream(ctx, buf, read_buffer, close_buffer, NULL);
 	stm->seek = seek_buffer;
 
 	stm->bp = buf->data;
@@ -196,7 +208,7 @@ fz_open_memory(fz_context *ctx, unsigned char *data, int len)
 {
 	fz_stream *stm;
 
-	stm = fz_new_stream(ctx, NULL, read_buffer, close_buffer);
+	stm = fz_new_stream(ctx, NULL, read_buffer, close_buffer, NULL);
 	stm->seek = seek_buffer;
 
 	stm->bp = data;
diff --git a/source/fitz/stream-prog.c b/source/fitz/stream-prog.c
index e35a1ac5..5ec23823 100644
--- a/source/fitz/stream-prog.c
+++ b/source/fitz/stream-prog.c
@@ -144,7 +144,7 @@ fz_open_fd_progressive(fz_context *ctx, int fd, int bps)
 
 	fz_try(ctx)
 	{
-		stm = fz_new_stream(ctx, state, read_prog, close_prog);
+		stm = fz_new_stream(ctx, state, read_prog, close_prog, NULL);
 	}
 	fz_catch(ctx)
 	{
-- 
cgit v1.2.3