summaryrefslogtreecommitdiff
path: root/fitz/filt_predict.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-29 23:17:46 +0000
committerTor Andersson <tor@ghostscript.com>2010-07-29 23:17:46 +0000
commitd797d4707564bd9c0e1536d1d6355945aa1be740 (patch)
treeb6aef992de0ce2aa306c4dd330512852c1a63ede /fitz/filt_predict.c
parent0b954421d7908c8b835d96b4a945418c2ae08de7 (diff)
downloadmupdf-d797d4707564bd9c0e1536d1d6355945aa1be740.tar.xz
Use chained reader like interface for filters instead of process interface.
Diffstat (limited to 'fitz/filt_predict.c')
-rw-r--r--fitz/filt_predict.c236
1 files changed, 107 insertions, 129 deletions
diff --git a/fitz/filt_predict.c b/fitz/filt_predict.c
index 78bd19b2..b0ef8d3c 100644
--- a/fitz/filt_predict.c
+++ b/fitz/filt_predict.c
@@ -8,7 +8,7 @@ typedef struct fz_predict_s fz_predict;
struct fz_predict_s
{
- fz_filter super;
+ fz_stream *chain;
int predictor;
int columns;
@@ -17,71 +17,12 @@ struct fz_predict_s
int stride;
int bpp;
- unsigned char *refbuf;
+ unsigned char *in;
+ unsigned char *out;
unsigned char *ref;
+ int outlen, outidx;
};
-fz_filter *
-fz_newpredictd(fz_obj *params)
-{
- fz_obj *obj;
-
- FZ_NEWFILTER(fz_predict, p, predict);
-
- p->predictor = 1;
- p->columns = 1;
- p->colors = 1;
- p->bpc = 8;
-
- obj = fz_dictgets(params, "Predictor");
- if (obj)
- p->predictor = fz_toint(obj);
-
- if (p->predictor != 1 && p->predictor != 2 &&
- p->predictor != 10 && p->predictor != 11 &&
- p->predictor != 12 && p->predictor != 13 &&
- p->predictor != 14 && p->predictor != 15)
- {
- fz_warn("invalid predictor: %d", p->predictor);
- p->predictor = 1;
- }
-
- obj = fz_dictgets(params, "Columns");
- if (obj)
- p->columns = fz_toint(obj);
-
- obj = fz_dictgets(params, "Colors");
- if (obj)
- p->colors = fz_toint(obj);
-
- obj = fz_dictgets(params, "BitsPerComponent");
- if (obj)
- p->bpc = fz_toint(obj);
-
- p->stride = (p->bpc * p->colors * p->columns + 7) / 8;
- p->bpp = (p->bpc * p->colors + 7) / 8;
-
- if (p->predictor >= 10)
- {
- p->refbuf = fz_malloc(p->stride);
- memset(p->refbuf, 0, p->stride);
- }
- else
- {
- p->refbuf = nil;
- }
- p->ref = nil;
-
- return (fz_filter*)p;
-}
-
-void
-fz_droppredict(fz_filter *filter)
-{
- fz_predict *p = (fz_predict*)filter;
- fz_free(p->refbuf);
-}
-
static inline int
getcomponent(unsigned char *buf, int x, int bpc)
{
@@ -118,40 +59,34 @@ paeth(int a, int b, int c)
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
}
-static inline void
-fz_predictnone(fz_predict *p, unsigned char *in, int len, unsigned char *out)
-{
- memcpy(out, in, len);
-}
-
static void
-fz_predicttiff(fz_predict *p, unsigned char *in, int len, unsigned char *out)
+fz_predicttiff(fz_predict *state, unsigned char *out, unsigned char *in, int len)
{
int left[MAXC];
int i, k;
- for (k = 0; k < p->colors; k++)
+ for (k = 0; k < state->colors; k++)
left[k] = 0;
- for (i = 0; i < p->columns; i++)
+ for (i = 0; i < state->columns; i++)
{
- for (k = 0; k < p->colors; k++)
+ for (k = 0; k < state->colors; k++)
{
- int a = getcomponent(in, i * p->colors + k, p->bpc);
+ int a = getcomponent(in, i * state->colors + k, state->bpc);
int b = a + left[k];
- int c = b % (1 << p->bpc);
- putcomponent(out, i * p->colors + k, p->bpc, c);
+ int c = b % (1 << state->bpc);
+ putcomponent(out, i * state->colors + k, state->bpc, c);
left[k] = c;
}
}
}
static void
-fz_predictpng(fz_predict *p, unsigned char *in, int len, unsigned char *out, int predictor)
+fz_predictpng(fz_predict *state, unsigned char *out, unsigned char *in, int len, int predictor)
{
- int bpp = p->bpp;
+ int bpp = state->bpp;
int i;
- unsigned char *ref = p->ref;
+ unsigned char *ref = state->ref;
switch (predictor)
{
@@ -186,7 +121,7 @@ fz_predictpng(fz_predict *p, unsigned char *in, int len, unsigned char *out, int
}
for (i = len - bpp; i > 0; i--)
{
- *out = *in++ + (out[-bpp] + *ref++)/2;
+ *out = *in++ + (out[-bpp] + *ref++) / 2;
out++;
}
break;
@@ -205,62 +140,105 @@ fz_predictpng(fz_predict *p, unsigned char *in, int len, unsigned char *out, int
}
}
-fz_error
-fz_processpredict(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+static int
+readpredict(fz_stream *stm, unsigned char *buf, int len)
{
- fz_predict *dec = (fz_predict*)filter;
- int remaining, toconsume, toproduce;
- int ispng = dec->predictor >= 10;
+ fz_predict *state = stm->state;
+ unsigned char *p = buf;
+ int ispng = state->predictor >= 10;
+ int n;
- dec->ref = dec->refbuf;
- while (1)
- {
- remaining = in->wp - in->rp;
- toconsume = MIN(remaining, dec->stride + ispng);
- toproduce = MIN(remaining - ispng, dec->stride);
+ while (state->outidx < state->outlen && p < buf + len)
+ *p++ = state->out[state->outidx++];
- if (remaining < dec->stride + ispng && !in->eof)
+ while (p < buf + len)
+ {
+ n = fz_read(state->chain, state->in, state->stride + ispng);
+ if (n < 0)
+ return fz_rethrow(n, "read error in prediction filter");
+ if (n == 0)
+ return p - buf;
+
+ if (state->predictor == 1)
+ memcpy(state->out, state->in, n);
+ else if (state->predictor == 2)
+ fz_predicttiff(state, state->out, state->in, n);
+ else
{
- return fz_ioneedin;
+ fz_predictpng(state, state->out, state->in + 1, n - 1, state->in[0]);
+ memcpy(state->ref, state->out, state->stride);
}
- if (out->wp + toproduce > out->ep)
- {
- return fz_ioneedout;
- }
+ state->outlen = n - ispng;
+ state->outidx = 0;
- if (toconsume > 0)
- {
- if (dec->predictor == 1)
- {
- fz_predictnone(dec, in->rp, toconsume, out->wp);
- }
- else if (dec->predictor == 2)
- {
- if (dec->bpc != 8)
- memset(out->wp, 0, toconsume);
- fz_predicttiff(dec, in->rp, toconsume, out->wp);
- }
- else
- {
- int predictor = *in->rp++;
- toconsume -= ispng;
- fz_predictpng(dec, in->rp, toconsume, out->wp, predictor);
- }
-
- if (dec->refbuf)
- {
- memcpy(dec->refbuf, out->wp, toproduce);
- dec->ref = dec->refbuf;
- }
-
- in->rp += toconsume;
- out->wp += toproduce;
- }
+ while (state->outidx < state->outlen && p < buf + len)
+ *p++ = state->out[state->outidx++];
+ }
- if (in->eof && (in->wp - in->rp <= 0))
- {
- return fz_iodone;
- }
+ return p - buf;
+}
+
+static void
+closepredict(fz_stream *stm)
+{
+ fz_predict *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state->in);
+ fz_free(state->out);
+ fz_free(state->ref);
+ fz_free(state);
+}
+
+fz_stream *
+fz_openpredict(fz_stream *chain, fz_obj *params)
+{
+ fz_predict *state;
+ fz_obj *obj;
+
+ state = fz_malloc(sizeof(fz_predict));
+ state->chain = chain;
+
+ state->predictor = 1;
+ state->columns = 1;
+ state->colors = 1;
+ state->bpc = 8;
+
+ obj = fz_dictgets(params, "Predictor");
+ if (obj)
+ state->predictor = fz_toint(obj);
+
+ if (state->predictor != 1 && state->predictor != 2 &&
+ state->predictor != 10 && state->predictor != 11 &&
+ state->predictor != 12 && state->predictor != 13 &&
+ state->predictor != 14 && state->predictor != 15)
+ {
+ fz_warn("invalid predictor: %d", state->predictor);
+ state->predictor = 1;
}
+
+ obj = fz_dictgets(params, "Columns");
+ if (obj)
+ state->columns = fz_toint(obj);
+
+ obj = fz_dictgets(params, "Colors");
+ if (obj)
+ state->colors = fz_toint(obj);
+
+ obj = fz_dictgets(params, "BitsPerComponent");
+ if (obj)
+ state->bpc = fz_toint(obj);
+
+ state->stride = (state->bpc * state->colors * state->columns + 7) / 8;
+ state->bpp = (state->bpc * state->colors + 7) / 8;
+
+ state->in = fz_malloc(state->stride + 1);
+ state->out = fz_malloc(state->stride);
+ state->ref = fz_malloc(state->stride);
+ state->outlen = 0;
+ state->outidx = 0;
+
+ memset(state->ref, 0, state->stride);
+
+ return fz_newstream(state, readpredict, closepredict);
}