5 * Check if an object is a stream or not.
8 pdf_isstream(pdf_xref
*xref
, int oid
, int gen
)
12 if (oid
< 0 || oid
>= xref
->len
)
15 error
= pdf_cacheobject(xref
, oid
, gen
);
17 fz_warn("%s", error
->msg
);
22 return xref
->table
[oid
].stmbuf
|| xref
->table
[oid
].stmofs
;
26 * Create a filter given a name and param dictionary.
29 buildonefilter(fz_filter
**fp
, fz_obj
*f
, fz_obj
*p
)
31 fz_filter
*decompress
;
38 if (!strcmp(s
, "ASCIIHexDecode") || !strcmp(s
, "AHx"))
39 return fz_newahxd(fp
, p
);
41 if (!strcmp(s
, "ASCII85Decode") || !strcmp(s
, "A85"))
42 return fz_newa85d(fp
, p
);
44 if (!strcmp(s
, "CCITTFaxDecode") || !strcmp(s
, "CCF"))
45 return fz_newfaxd(fp
, p
);
47 if (!strcmp(s
, "DCTDecode") || !strcmp(s
, "DCT"))
48 return fz_newdctd(fp
, p
);
50 if (!strcmp(s
, "RunLengthDecode") || !strcmp(s
, "RL"))
51 return fz_newrld(fp
, p
);
53 if (!strcmp(s
, "FlateDecode") || !strcmp(s
, "Fl"))
57 fz_obj
*obj
= fz_dictgets(p
, "Predictor");
60 error
= fz_newflated(&decompress
, p
);
64 error
= fz_newpredictd(&predict
, p
);
67 fz_dropfilter(decompress
);
71 error
= fz_newpipeline(fp
, decompress
, predict
);
72 fz_dropfilter(decompress
);
73 fz_dropfilter(predict
);
77 return fz_newflated(fp
, p
);
80 if (!strcmp(s
, "LZWDecode") || !strcmp(s
, "LZW"))
84 fz_obj
*obj
= fz_dictgets(p
, "Predictor");
87 error
= fz_newlzwd(&decompress
, p
);
91 error
= fz_newpredictd(&predict
, p
);
94 fz_dropfilter(decompress
);
98 error
= fz_newpipeline(fp
, decompress
, predict
);
99 fz_dropfilter(decompress
);
100 fz_dropfilter(predict
);
104 return fz_newlzwd(fp
, p
);
108 if (!strcmp(s
, "JBIG2Decode"))
110 /* TODO: extract and feed JBIG2Global */
111 return fz_newjbig2d(fp
, p
);
116 if (!strcmp(s
, "JPXDecode"))
117 return fz_newjpxd(fp
, p
);
120 return fz_throw("syntaxerror: unknown filter: %s", s
);
124 * Build a chain of filters given filter names and param dicts.
125 * If head is given, start filter chain with it.
126 * Assume ownership of head.
129 buildfilterchain(fz_filter
**filterp
, fz_filter
*head
, fz_obj
*fs
, fz_obj
*ps
)
138 for (i
= 0; i
< fz_arraylen(fs
); i
++)
140 f
= fz_arrayget(fs
, i
);
142 p
= fz_arrayget(ps
, i
);
146 error
= buildonefilter(&tail
, f
, p
);
152 error
= fz_newpipeline(&newhead
, head
, tail
);
157 fz_dropfilter(newhead
);
171 * Build a filter for reading raw stream data.
172 * This is a null filter to constrain reading to the
173 * stream length, followed by a decryption filter.
176 buildrawfilter(fz_filter
**filterp
, pdf_xref
*xref
, fz_obj
*stmobj
, int oid
, int gen
)
183 stmlen
= fz_dictgets(stmobj
, "Length");
184 error
= pdf_resolve(&stmlen
, xref
);
187 len
= fz_toint(stmlen
);
190 error
= fz_newnullfilter(&base
, len
);
199 error
= pdf_cryptstream(&crypt
, xref
->crypt
, oid
, gen
);
206 error
= fz_newpipeline(&pipe
, base
, crypt
);
208 fz_dropfilter(crypt
);
223 * Construct a filter to decode a stream, without
224 * constraining to stream length, and without decryption.
227 pdf_buildinlinefilter(fz_filter
**filterp
, fz_obj
*stmobj
)
232 filters
= fz_dictgetsa(stmobj
, "Filter", "F");
233 params
= fz_dictgetsa(stmobj
, "DecodeParms", "DP");
239 if (fz_isname(filters
))
240 return buildonefilter(filterp
, filters
, params
);
241 else if (fz_arraylen(filters
) > 0)
242 return buildfilterchain(filterp
, nil
, filters
, params
);
245 /* uh oh, no filter */
251 * Construct a filter to decode a stream, constraining
252 * to stream length and decrypting.
255 pdf_buildfilter(fz_filter
**filterp
, pdf_xref
*xref
, fz_obj
*stmobj
, int oid
, int gen
)
258 fz_filter
*base
, *pipe
, *tmp
;
262 error
= buildrawfilter(&base
, xref
, stmobj
, oid
, gen
);
266 filters
= fz_dictgetsa(stmobj
, "Filter", "F");
267 params
= fz_dictgetsa(stmobj
, "DecodeParms", "DP");
271 error
= pdf_resolve(&filters
, xref
);
277 error
= pdf_resolve(¶ms
, xref
);
282 if (fz_isname(filters
))
284 error
= buildonefilter(&tmp
, filters
, params
);
288 error
= fz_newpipeline(&pipe
, base
, tmp
);
296 error
= buildfilterchain(&pipe
, base
, filters
, params
);
326 * Open a stream for reading the raw (compressed but decrypted) data.
327 * Using xref->file while this is open is a bad idea.
330 pdf_openrawstream(fz_stream
**stmp
, pdf_xref
*xref
, int oid
, int gen
)
337 if (oid
< 0 || oid
>= xref
->len
)
338 return fz_throw("rangecheck: object id out of range");
340 x
= xref
->table
+ oid
;
342 error
= pdf_cacheobject(xref
, oid
, gen
);
348 return fz_openrbuffer(stmp
, x
->stmbuf
);
353 error
= buildrawfilter(&filter
, xref
, x
->obj
, oid
, gen
);
357 n
= fz_seek(xref
->file
, x
->stmofs
, 0);
360 fz_dropfilter(filter
);
361 return fz_ioerror(xref
->file
);
364 error
= fz_openrfilter(stmp
, filter
, xref
->file
);
366 fz_dropfilter(filter
);
374 return fz_throw("syntaxerror: object is not a stream");
378 * Open a stream for reading uncompressed data.
379 * Put the opened file in xref->stream.
380 * Using xref->file while a stream is open is a Bad idea.
383 pdf_openstream(fz_stream
**stmp
, pdf_xref
*xref
, int oid
, int gen
)
391 if (oid
< 0 || oid
>= xref
->len
)
392 return fz_throw("rangecheck: object id out of range");
394 x
= xref
->table
+ oid
;
396 error
= pdf_cacheobject(xref
, oid
, gen
);
402 error
= pdf_buildfilter(&filter
, xref
, x
->obj
, oid
, gen
);
406 error
= fz_openrbuffer(&rawstm
, x
->stmbuf
);
409 fz_dropfilter(filter
);
413 error
= fz_openrfilter(stmp
, filter
, rawstm
);
414 fz_dropfilter(filter
);
415 fz_dropstream(rawstm
);
421 error
= pdf_buildfilter(&filter
, xref
, x
->obj
, oid
, gen
);
425 n
= fz_seek(xref
->file
, x
->stmofs
, 0);
428 fz_dropfilter(filter
);
429 return fz_ioerror(xref
->file
);
432 error
= fz_openrfilter(stmp
, filter
, xref
->file
);
433 fz_dropfilter(filter
);
440 return fz_throw("syntaxerror: object is not a stream");
444 * Load raw (compressed but decrypted) contents of a stream into buf.
447 pdf_loadrawstream(fz_buffer
**bufp
, pdf_xref
*xref
, int oid
, int gen
)
453 error
= pdf_openrawstream(&stm
, xref
, oid
, gen
);
457 n
= fz_readall(bufp
, stm
);
459 error
= fz_ioerror(stm
);
469 * Load uncompressed contents of a stream into buf.
472 pdf_loadstream(fz_buffer
**bufp
, pdf_xref
*xref
, int oid
, int gen
)
478 error
= pdf_openstream(&stm
, xref
, oid
, gen
);
482 n
= fz_readall(bufp
, stm
);
484 error
= fz_ioerror(stm
);