/* * Open a stream for reading the raw (compressed but decrypted) data. * Using xref->file while this is open is a bad idea. */ fz_error * pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) { pdf_xrefentry *x; fz_error *error; fz_filter *filter; if (oid < 0 || oid >= xref->len) return fz_throw("object id out of range (%d)", oid); x = xref->table + oid; error = pdf_cacheobject(xref, oid, gen); if (error) return fz_rethrow(error, "cannot load stream object (%d)", oid); if (x->stmbuf) { error = fz_openrbuffer(stmp, x->stmbuf); if (error) return fz_rethrow(error, "cannot open stream from buffer"); return fz_okay; } if (x->stmofs) { error = buildrawfilter(&filter, xref, x->obj, oid, gen); if (error) return fz_rethrow(error, "cannot create raw filter"); error = fz_seek(xref->file, x->stmofs, 0); if (error) { fz_dropfilter(filter); return fz_rethrow(error, "cannot seek to stream"); } error = fz_openrfilter(stmp, filter, xref->file); fz_dropfilter(filter); if (error) return fz_rethrow(error, "cannot open filter stream"); return fz_okay; } return fz_throw("object is not a stream"); }
static fz_error * writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) { fz_error *error; fz_stream *dststm; fz_stream *srcstm; unsigned char buf[4096]; fz_filter *ef; int n; fz_print(out, "stream\n"); if (encrypt) { error = pdf_cryptstream(&ef, encrypt, oid, gen); if (error) return error; error = fz_openrfilter(&dststm, ef, out); fz_dropfilter(ef); if (error) return error; } else { dststm = fz_keepstream(out); } error = pdf_openrawstream(&srcstm, xref, oid, gen); if (error) goto cleanupdst; while (1) { n = fz_read(srcstm, buf, sizeof buf); if (n == 0) break; if (n < 0) { error = fz_ioerror(srcstm); goto cleanupsrc; } n = fz_write(dststm, buf, n); if (n < 0) { error = fz_ioerror(dststm); goto cleanupsrc; } } fz_dropstream(srcstm); fz_dropstream(dststm); fz_print(out, "endstream\n"); return nil; cleanupsrc: fz_dropstream(srcstm); cleanupdst: fz_dropstream(dststm); return error; }
fz_error * pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file) { fz_error *error; pdf_image *img; fz_filter *filter; fz_obj *f; fz_obj *cs; fz_obj *d; int ismask; int i; img = fz_malloc(sizeof(pdf_image)); if (!img) return fz_outofmem; pdf_logimage("load inline image %p {\n", img); img->super.loadtile = pdf_loadtile; img->super.drop = pdf_dropimage; img->super.n = 0; img->super.a = 0; img->super.refs = 0; img->indexed = nil; img->usecolorkey = 0; img->mask = nil; img->super.w = fz_toint(fz_dictgetsa(dict, "Width", "W")); img->super.h = fz_toint(fz_dictgetsa(dict, "Height", "H")); img->bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC")); ismask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM")); d = fz_dictgetsa(dict, "Decode", "D"); cs = fz_dictgetsa(dict, "ColorSpace", "CS"); pdf_logimage("size %dx%d %d\n", img->super.w, img->super.h, img->bpc); if (ismask) { pdf_logimage("is mask\n"); img->super.cs = nil; img->super.n = 0; img->super.a = 1; img->bpc = 1; } if (cs) { img->super.cs = nil; if (fz_isname(cs)) { fz_obj *csd = fz_dictgets(rdb, "ColorSpace"); if (csd) { fz_obj *cso = fz_dictget(csd, cs); img->super.cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, cso); if (img->super.cs) fz_keepcolorspace(img->super.cs); } } if (!img->super.cs) { /* XXX danger! danger! does this resolve? */ error = pdf_loadcolorspace(&img->super.cs, xref, cs); if (error) return error; } if (!strcmp(img->super.cs->name, "Indexed")) { pdf_logimage("indexed\n"); img->indexed = (pdf_indexed*)img->super.cs; img->super.cs = img->indexed->base; } pdf_logimage("colorspace %s\n", img->super.cs->name); img->super.n = img->super.cs->n; img->super.a = 0; } if (fz_isarray(d)) { pdf_logimage("decode array\n"); if (img->indexed) for (i = 0; i < 2; i++) img->decode[i] = fz_toreal(fz_arrayget(d, i)); else for (i = 0; i < (img->super.n + img->super.a) * 2; i++) img->decode[i] = fz_toreal(fz_arrayget(d, i)); } else { if (img->indexed) for (i = 0; i < 2; i++) img->decode[i] = i & 1 ? (1 << img->bpc) - 1 : 0; else for (i = 0; i < (img->super.n + img->super.a) * 2; i++) img->decode[i] = i & 1; } if (img->indexed) img->stride = (img->super.w * img->bpc + 7) / 8; else img->stride = (img->super.w * (img->super.n + img->super.a) * img->bpc + 7) / 8; /* load image data */ f = fz_dictgetsa(dict, "Filter", "F"); if (f) { fz_stream *tempfile; error = pdf_buildinlinefilter(&filter, dict); if (error) return error; error = fz_openrfilter(&tempfile, filter, file); if (error) return error; i = fz_readall(&img->samples, tempfile); if (i < 0) return fz_ioerror(tempfile); fz_dropfilter(filter); fz_dropstream(tempfile); } else { error = fz_newbuffer(&img->samples, img->super.h * img->stride); if (error) return error; i = fz_read(file, img->samples->bp, img->super.h * img->stride); if (i < 0) return fz_ioerror(file); img->samples->wp += img->super.h * img->stride; } /* 0 means opaque and 1 means transparent, so we invert to get alpha */ if (ismask) { unsigned char *p; for (p = img->samples->bp; p < img->samples->ep; p++) *p = ~*p; } pdf_logimage("}\n"); *imgp = img; return nil; }