1 #include "mupdf/fitz.h"
3 /* TODO: check if this works with 16bpp images */
5 typedef struct fz_predict_s fz_predict;
21 unsigned char *rp, *wp;
23 unsigned char buffer[4096];
26 static inline int getcomponent(unsigned char *line, int x, int bpc)
30 case 1: return (line[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
31 case 2: return (line[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3;
32 case 4: return (line[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 15;
33 case 8: return line[x];
34 case 16: return (line[x<<1]<<8)+line[(x<<1)+1];
39 static inline void putcomponent(unsigned char *buf, int x, int bpc, int value)
43 case 1: buf[x >> 3] |= value << (7 - (x & 7)); break;
44 case 2: buf[x >> 2] |= value << ((3 - (x & 3)) << 1); break;
45 case 4: buf[x >> 1] |= value << ((1 - (x & 1)) << 2); break;
46 case 8: buf[x] = value; break;
47 case 16: buf[x<<1] = value>>8; buf[(x<<1)+1] = value; break;
51 static inline int paeth(int a, int b, int c)
53 /* The definitions of ac and bc are correct, not a typo. */
54 int ac = b - c, bc = a - c, abcc = ac + bc;
57 int pc = fz_absi(abcc);
58 return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
62 fz_predict_tiff(fz_predict *state, unsigned char *out, unsigned char *in, int len)
64 int left[FZ_MAX_COLORS];
66 const int mask = (1 << state->bpc)-1;
68 for (k = 0; k < state->colors; k++)
71 /* special fast case */
74 for (i = 0; i < state->columns; i++)
75 for (k = 0; k < state->colors; k++)
76 *out++ = left[k] = (*in++ + left[k]) & 0xFF;
80 /* putcomponent assumes zeroed memory for bpc < 8 */
82 memset(out, 0, state->stride);
84 for (i = 0; i < state->columns; i++)
86 for (k = 0; k < state->colors; k++)
88 int a = getcomponent(in, i * state->colors + k, state->bpc);
91 putcomponent(out, i * state->colors + k, state->bpc, c);
98 fz_predict_png(fz_predict *state, unsigned char *out, unsigned char *in, int len, int predictor)
100 int bpp = state->bpp;
102 unsigned char *ref = state->ref;
110 memcpy(out, in, len);
113 for (i = bpp; i > 0; i--)
117 for (i = len - bpp; i > 0; i--)
119 *out = *in++ + out[-bpp];
124 for (i = bpp; i > 0; i--)
126 *out++ = *in++ + *ref++;
128 for (i = len - bpp; i > 0; i--)
130 *out++ = *in++ + *ref++;
134 for (i = bpp; i > 0; i--)
136 *out++ = *in++ + (*ref++) / 2;
138 for (i = len - bpp; i > 0; i--)
140 *out = *in++ + (out[-bpp] + *ref++) / 2;
145 for (i = bpp; i > 0; i--)
147 *out++ = *in++ + paeth(0, *ref++, 0);
149 for (i = len - bpp; i > 0; i --)
151 *out = *in++ + paeth(out[-bpp], *ref, ref[-bpp]);
160 next_predict(fz_stream *stm, int len)
162 fz_predict *state = stm->state;
163 unsigned char *buf = state->buffer;
164 unsigned char *p = buf;
166 int ispng = state->predictor >= 10;
169 if (len >= sizeof(state->buffer))
170 len = sizeof(state->buffer);
173 while (state->rp < state->wp && p < ep)
178 n = fz_read(state->chain, state->in, state->stride + ispng);
182 if (state->predictor == 1)
183 memcpy(state->out, state->in, n);
184 else if (state->predictor == 2)
185 fz_predict_tiff(state, state->out, state->in, n);
188 fz_predict_png(state, state->out, state->in + 1, n - 1, state->in[0]);
189 memcpy(state->ref, state->out, state->stride);
192 state->rp = state->out;
193 state->wp = state->out + n - ispng;
195 while (state->rp < state->wp && p < ep)
201 if (stm->rp == stm->wp)
209 close_predict(fz_context *ctx, void *state_)
211 fz_predict *state = (fz_predict *)state_;
212 fz_close(state->chain);
213 fz_free(ctx, state->in);
214 fz_free(ctx, state->out);
215 fz_free(ctx, state->ref);
220 rebind_predict(fz_stream *s)
222 fz_predict *state = s->state;
226 /* Default values: predictor = 1, columns = 1, colors = 1, bpc = 8 */
228 fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc)
230 fz_context *ctx = chain->ctx;
231 fz_predict *state = NULL;
246 if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16)
247 fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of bits per component: %d", bpc);
248 if (colors > FZ_MAX_COLORS)
249 fz_throw(ctx, FZ_ERROR_GENERIC, "too many color components (%d > %d)", colors, FZ_MAX_COLORS);
250 if (columns >= INT_MAX / (bpc * colors))
251 fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns);
253 state = fz_malloc_struct(ctx, fz_predict);
256 state->chain = chain;
258 state->predictor = predictor;
259 state->columns = columns;
260 state->colors = colors;
263 if (state->predictor != 1 && state->predictor != 2 &&
264 state->predictor != 10 && state->predictor != 11 &&
265 state->predictor != 12 && state->predictor != 13 &&
266 state->predictor != 14 && state->predictor != 15)
268 fz_warn(ctx, "invalid predictor: %d", state->predictor);
269 state->predictor = 1;
272 state->stride = (state->bpc * state->colors * state->columns + 7) / 8;
273 state->bpp = (state->bpc * state->colors + 7) / 8;
275 state->in = fz_malloc(ctx, state->stride + 1);
276 state->out = fz_malloc(ctx, state->stride);
277 state->ref = fz_malloc(ctx, state->stride);
278 state->rp = state->out;
279 state->wp = state->out;
281 memset(state->ref, 0, state->stride);
287 fz_free(ctx, state->in);
288 fz_free(ctx, state->out);
295 return fz_new_stream(ctx, state, next_predict, close_predict, rebind_predict);