static fz_error * loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) { fz_error *error; struct separation *cs; fz_obj *nameobj = fz_arrayget(array, 1); fz_obj *baseobj = fz_arrayget(array, 2); fz_obj *tintobj = fz_arrayget(array, 3); fz_colorspace *base; pdf_function *tint; int n; pdf_logrsrc("load Separation {\n"); if (fz_isarray(nameobj)) n = fz_arraylen(nameobj); else n = 1; pdf_logrsrc("n = %d\n", n); error = pdf_resolve(&baseobj, xref); if (error) return error; error = pdf_loadcolorspace(&base, xref, baseobj); fz_dropobj(baseobj); if (error) return error; error = pdf_loadfunction(&tint, xref, tintobj); if (error) { fz_dropcolorspace(base); return error; } cs = fz_malloc(sizeof(struct separation)); if (!cs) { pdf_dropfunction(tint); fz_dropcolorspace(base); return fz_outofmem; } initcs((fz_colorspace*)cs, n == 1 ? "Separation" : "DeviceN", n, separationtoxyz, nil, dropseparation); cs->base = base; cs->tint = tint; pdf_logrsrc("}\n"); *csp = (fz_colorspace*)cs; return nil; }
static fz_error loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) { fz_error error; struct separation *cs; fz_obj *nameobj = fz_arrayget(array, 1); fz_obj *baseobj = fz_arrayget(array, 2); fz_obj *tintobj = fz_arrayget(array, 3); fz_colorspace *base; pdf_function *tint; int n; pdf_logrsrc("load Separation {\n"); if (fz_isarray(nameobj)) n = fz_arraylen(nameobj); else n = 1; if (n > FZ_MAXCOLORS) return fz_throw("too many components in colorspace"); pdf_logrsrc("n = %d\n", n); error = pdf_loadcolorspace(&base, xref, baseobj); if (error) return fz_rethrow(error, "cannot load base colorspace"); error = pdf_loadfunction(&tint, xref, tintobj); if (error) { fz_dropcolorspace(base); return fz_rethrow(error, "cannot load tint function"); } cs = fz_malloc(sizeof(struct separation)); initcs((fz_colorspace*)cs, n == 1 ? "Separation" : "DeviceN", n, separationtoxyz, nil, freeseparation); cs->base = fz_keepcolorspace(base); cs->tint = pdf_keepfunction(tint); fz_dropcolorspace(base); pdf_dropfunction(tint); pdf_logrsrc("}\n"); *csp = (fz_colorspace*)cs; return fz_okay; }
static fz_error * loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_matrix matrix) { fz_error *error; fz_shade *shade; fz_obj *obj; int type; int i; pdf_logshade("load shade dict %d %d {\n", fz_tonum(ref), fz_togen(ref)); shade = fz_malloc(sizeof(fz_shade)); if (!shade) return fz_outofmem; shade->refs = 1; shade->usebackground = 0; shade->usefunction = 0; shade->matrix = matrix; shade->bbox = fz_infiniterect; shade->meshlen = 0; shade->meshcap = 0; shade->mesh = nil; obj = fz_dictgets(dict, "ShadingType"); type = fz_toint(obj); pdf_logshade("type %d\n", type); /* TODO: flatten indexed... */ obj = fz_dictgets(dict, "ColorSpace"); if (obj) { shade->cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); if (shade->cs) fz_keepcolorspace(shade->cs); else { error = pdf_resolve(&obj, xref); if (error) return error; error = pdf_loadcolorspace(&shade->cs, xref, obj); if (error) return error; fz_dropobj(obj); } } pdf_logshade("colorspace %s\n", shade->cs->name); obj = fz_dictgets(dict, "Background"); if (obj) { pdf_logshade("background\n"); shade->usebackground = 1; for (i = 0; i < shade->cs->n; i++) shade->background[i] = fz_toreal(fz_arrayget(obj, i)); } obj = fz_dictgets(dict, "BBox"); if (fz_isarray(obj)) { shade->bbox = pdf_torect(obj); pdf_logshade("bbox [%g %g %g %g]\n", shade->bbox.x0, shade->bbox.y0, shade->bbox.x1, shade->bbox.y1); } switch(type) { case 1: error = pdf_loadtype1shade(shade, xref, dict, ref); if (error) goto cleanup; break; case 2: error = pdf_loadtype2shade(shade, xref, dict, ref); if (error) goto cleanup; break; case 3: error = pdf_loadtype3shade(shade, xref, dict, ref); if (error) goto cleanup; break; case 4: error = pdf_loadtype4shade(shade, xref, dict, ref); if (error) goto cleanup; break; case 5: error = pdf_loadtype5shade(shade, xref, dict, ref); if (error) goto cleanup; break; case 6: error = pdf_loadtype6shade(shade, xref, dict, ref); if (error) goto cleanup; break; case 7: error = pdf_loadtype7shade(shade, xref, dict, ref); if (error) goto cleanup; break; default: fz_warn("syntaxerror: unknown shading type: %d", type); break; }; pdf_logshade("}\n"); *shadep = shade; return nil; cleanup: fz_dropshade(shade); return error; }
static fz_error pdf_loadcolorspaceimp(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj) { if (fz_isname(obj)) { if (!strcmp(fz_toname(obj), "DeviceGray")) *csp = pdf_devicegray; else if (!strcmp(fz_toname(obj), "DeviceRGB")) *csp = pdf_devicergb; else if (!strcmp(fz_toname(obj), "DeviceCMYK")) *csp = pdf_devicecmyk; else if (!strcmp(fz_toname(obj), "G")) *csp = pdf_devicegray; else if (!strcmp(fz_toname(obj), "RGB")) *csp = pdf_devicergb; else if (!strcmp(fz_toname(obj), "CMYK")) *csp = pdf_devicecmyk; else if (!strcmp(fz_toname(obj), "Pattern")) *csp = pdf_devicepattern; else return fz_throw("unknown colorspace: %s", fz_toname(obj)); return fz_okay; } else if (fz_isarray(obj)) { fz_obj *name = fz_arrayget(obj, 0); if (fz_isname(name)) { if (!strcmp(fz_toname(name), "CalCMYK")) *csp = pdf_devicecmyk; #ifdef USECAL else if (!strcmp(fz_toname(name), "CalGray")) *csp = loadcalgray(xref, fz_arrayget(obj, 1)); else if (!strcmp(fz_toname(name), "CalRGB")) *csp = loadcalrgb(xref, fz_arrayget(obj, 1)); else if (!strcmp(fz_toname(name), "Lab")) *csp = loadlab(xref, fz_arrayget(obj, 1)); #else else if (!strcmp(fz_toname(name), "CalGray")) *csp = pdf_devicegray; else if (!strcmp(fz_toname(name), "CalRGB")) *csp = pdf_devicergb; else if (!strcmp(fz_toname(name), "Lab")) *csp = pdf_devicelab; #endif else if (!strcmp(fz_toname(name), "ICCBased")) return loadiccbased(csp, xref, fz_arrayget(obj, 1)); else if (!strcmp(fz_toname(name), "Indexed")) return loadindexed(csp, xref, obj); else if (!strcmp(fz_toname(name), "I")) return loadindexed(csp, xref, obj); else if (!strcmp(fz_toname(name), "Separation")) return loadseparation(csp, xref, obj); else if (!strcmp(fz_toname(name), "DeviceN")) return loadseparation(csp, xref, obj); /* load base colorspace instead */ else if (!strcmp(fz_toname(name), "Pattern")) { fz_error error; obj = fz_arrayget(obj, 1); if (!obj) { *csp = pdf_devicepattern; return fz_okay; } error = pdf_loadcolorspace(csp, xref, obj); if (error) return fz_rethrow(error, "cannot load pattern"); } else if (!strcmp(fz_toname(name), "DeviceGray")) *csp = pdf_devicegray; else if (!strcmp(fz_toname(name), "DeviceRGB")) *csp = pdf_devicergb; else if (!strcmp(fz_toname(name), "DeviceCMYK")) *csp = pdf_devicecmyk; else if (!strcmp(fz_toname(name), "G")) *csp = pdf_devicegray; else if (!strcmp(fz_toname(name), "RGB")) *csp = pdf_devicergb; else if (!strcmp(fz_toname(name), "CMYK")) *csp = pdf_devicecmyk; else return fz_throw("syntaxerror: unknown colorspace %s", fz_toname(name)); return fz_okay; } } return fz_throw("syntaxerror: could not parse color space"); }
static fz_error loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) { fz_error error; pdf_indexed *cs; fz_obj *baseobj = fz_arrayget(array, 1); fz_obj *highobj = fz_arrayget(array, 2); fz_obj *lookup = fz_arrayget(array, 3); fz_colorspace *base; int n; pdf_logrsrc("load Indexed {\n"); error = pdf_loadcolorspace(&base, xref, baseobj); if (error) return fz_rethrow(error, "cannot load base colorspace"); pdf_logrsrc("base %s\n", base->name); cs = fz_malloc(sizeof(pdf_indexed)); initcs((fz_colorspace*)cs, "Indexed", 1, nil, nil, freeindexed); cs->base = fz_keepcolorspace(base); cs->high = fz_toint(highobj); fz_dropcolorspace(base); n = base->n * (cs->high + 1); cs->lookup = fz_malloc(n); if (fz_isstring(lookup) && fz_tostrlen(lookup) == n) { unsigned char *buf; int i; pdf_logrsrc("string lookup\n"); buf = (unsigned char *) fz_tostrbuf(lookup); for (i = 0; i < n; i++) cs->lookup[i] = buf[i]; } else if (fz_isindirect(lookup)) { fz_buffer *buf; int i; pdf_logrsrc("stream lookup\n"); error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup)); if (error) { fz_dropcolorspace((fz_colorspace*)cs); return fz_rethrow(error, "cannot load colorpsace lookup table"); } for (i = 0; i < n && i < (buf->wp - buf->rp); i++) cs->lookup[i] = buf->rp[i]; fz_dropbuffer(buf); } else return fz_throw("cannot parse colorspace lookup table"); pdf_logrsrc("}\n"); *csp = (fz_colorspace*)cs; return fz_okay; }
static fz_error * loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) { fz_error *error; pdf_indexed *cs; fz_obj *baseobj = fz_arrayget(array, 1); fz_obj *highobj = fz_arrayget(array, 2); fz_obj *lookup = fz_arrayget(array, 3); fz_colorspace *base; int n; pdf_logrsrc("load Indexed {\n"); error = pdf_resolve(&baseobj, xref); if (error) return error; error = pdf_loadcolorspace(&base, xref, baseobj); fz_dropobj(baseobj); if (error) return error; pdf_logrsrc("base %s\n", base->name); cs = fz_malloc(sizeof(pdf_indexed)); if (!cs) { fz_dropcolorspace(base); return fz_outofmem; } initcs((fz_colorspace*)cs, "Indexed", 1, nil, nil, dropindexed); cs->base = base; cs->high = fz_toint(highobj); n = base->n * (cs->high + 1); cs->lookup = fz_malloc(n); if (!cs->lookup) { fz_dropcolorspace((fz_colorspace*)cs); return fz_outofmem; } if (fz_isstring(lookup) && fz_tostrlen(lookup) == n) { unsigned char *buf; int i; pdf_logrsrc("string lookup\n"); buf = fz_tostrbuf(lookup); for (i = 0; i < n; i++) cs->lookup[i] = buf[i]; } if (fz_isindirect(lookup)) { fz_buffer *buf; int i; pdf_logrsrc("stream lookup\n"); error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup)); if (error) { fz_dropcolorspace((fz_colorspace*)cs); return error; } for (i = 0; i < n && i < (buf->wp - buf->rp); i++) cs->lookup[i] = buf->rp[i]; fz_dropbuffer(buf); } pdf_logrsrc("}\n"); *csp = (fz_colorspace*)cs; return nil; }
static fz_error pdf_loadjpximage(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict) { fz_error error; fz_buffer *buf; fz_pixmap *img; fz_obj *obj; pdf_logimage("jpeg2000\n"); error = pdf_loadstream(&buf, xref, fz_tonum(dict), fz_togen(dict)); if (error) return fz_rethrow(error, "cannot load jpx image data"); error = fz_loadjpximage(&img, buf->data, buf->len); if (error) { fz_dropbuffer(buf); return fz_rethrow(error, "cannot load jpx image"); } fz_dropbuffer(buf); obj = fz_dictgetsa(dict, "SMask", "Mask"); if (fz_isdict(obj)) { error = pdf_loadimageimp(&img->mask, xref, nil, obj, nil, 1); if (error) { fz_droppixmap(img); return fz_rethrow(error, "cannot load image mask/softmask"); } } obj = fz_dictgets(dict, "ColorSpace"); if (obj) { fz_colorspace *original = img->colorspace; img->colorspace = nil; error = pdf_loadcolorspace(&img->colorspace, xref, obj); if (error) { fz_dropcolorspace(original); return fz_rethrow(error, "cannot load image colorspace"); } if (original->n != img->colorspace->n) { fz_warn("jpeg-2000 colorspace (%s) does not match promised colorspace (%s)", original->name, img->colorspace->name); fz_dropcolorspace(img->colorspace); img->colorspace = original; } else fz_dropcolorspace(original); if (!strcmp(img->colorspace->name, "Indexed")) { fz_pixmap *conv; conv = pdf_expandindexedpixmap(img); fz_droppixmap(img); img = conv; } } *imgp = img; return fz_okay; }
static fz_error pdf_loadimageimp(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm, int forcemask) { fz_stream *stm; fz_pixmap *tile; fz_obj *obj, *res; fz_error error; int w, h, bpc, n; int imagemask; int interpolate; int indexed; fz_colorspace *colorspace; fz_pixmap *mask; /* explicit mask/softmask image */ int usecolorkey; int colorkey[FZ_MAXCOLORS * 2]; float decode[FZ_MAXCOLORS * 2]; int scale; int stride; unsigned char *samples; int i, len; /* special case for JPEG2000 images */ if (pdf_isjpximage(dict)) { tile = nil; error = pdf_loadjpximage(&tile, xref, dict); if (error) return fz_rethrow(error, "cannot load jpx image"); if (forcemask) { if (tile->n != 2) { fz_droppixmap(tile); return fz_throw("softmask must be grayscale"); } mask = fz_alphafromgray(tile, 1); fz_droppixmap(tile); *imgp = mask; return fz_okay; } *imgp = tile; return fz_okay; } w = fz_toint(fz_dictgetsa(dict, "Width", "W")); h = fz_toint(fz_dictgetsa(dict, "Height", "H")); bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC")); imagemask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM")); interpolate = fz_tobool(fz_dictgetsa(dict, "Interpolate", "I")); indexed = 0; usecolorkey = 0; colorspace = nil; mask = nil; if (imagemask) bpc = 1; if (w == 0) return fz_throw("image width is zero"); if (h == 0) return fz_throw("image height is zero"); if (bpc == 0) return fz_throw("image depth is zero"); if (w > (1 << 16)) return fz_throw("image is too wide"); if (h > (1 << 16)) return fz_throw("image is too high"); obj = fz_dictgetsa(dict, "ColorSpace", "CS"); if (obj && !imagemask && !forcemask) { /* colorspace resource lookup is only done for inline images */ if (fz_isname(obj)) { res = fz_dictget(fz_dictgets(rdb, "ColorSpace"), obj); if (res) obj = res; } error = pdf_loadcolorspace(&colorspace, xref, obj); if (error) return fz_rethrow(error, "cannot load image colorspace"); if (!strcmp(colorspace->name, "Indexed")) indexed = 1; n = colorspace->n; } else { n = 1; } obj = fz_dictgetsa(dict, "Decode", "D"); if (obj) { for (i = 0; i < n * 2; i++) decode[i] = fz_toreal(fz_arrayget(obj, i)); } else { float maxval = indexed ? (1 << bpc) - 1 : 1; for (i = 0; i < n * 2; i++) decode[i] = i & 1 ? maxval : 0; } obj = fz_dictgetsa(dict, "SMask", "Mask"); if (fz_isdict(obj)) { /* Not allowed for inline images */ if (!cstm) { error = pdf_loadimageimp(&mask, xref, rdb, obj, nil, 1); if (error) { if (colorspace) fz_dropcolorspace(colorspace); return fz_rethrow(error, "cannot load image mask/softmask"); } } } else if (fz_isarray(obj)) { usecolorkey = 1; for (i = 0; i < n * 2; i++) colorkey[i] = fz_toint(fz_arrayget(obj, i)); } stride = (w * n * bpc + 7) / 8; samples = fz_calloc(h, stride); if (cstm) { stm = pdf_openinlinestream(cstm, xref, dict, stride * h); } else { error = pdf_openstream(&stm, xref, fz_tonum(dict), fz_togen(dict)); if (error) { if (colorspace) fz_dropcolorspace(colorspace); if (mask) fz_droppixmap(mask); return fz_rethrow(error, "cannot open image data stream (%d 0 R)", fz_tonum(dict)); } } len = fz_read(stm, samples, h * stride); if (len < 0) { fz_close(stm); if (colorspace) fz_dropcolorspace(colorspace); if (mask) fz_droppixmap(mask); return fz_rethrow(len, "cannot read image data"); } /* Make sure we read the EOF marker (for inline images only) */ if (cstm) { unsigned char tbuf[512]; int tlen = fz_read(stm, tbuf, sizeof tbuf); if (tlen < 0) fz_catch(tlen, "ignoring error at end of image"); if (tlen > 0) fz_warn("ignoring garbage at end of image"); } fz_close(stm); /* Pad truncated images */ if (len < stride * h) { fz_warn("padding truncated image (%d 0 R)", fz_tonum(dict)); memset(samples + len, 0, stride * h - len); } /* Invert 1-bit image masks */ if (imagemask) { /* 0=opaque and 1=transparent so we need to invert */ unsigned char *p = samples; len = h * stride; for (i = 0; i < len; i++) p[i] = ~p[i]; } pdf_logimage("size %dx%d n=%d bpc=%d imagemask=%d indexed=%d\n", w, h, n, bpc, imagemask, indexed); /* Unpack samples into pixmap */ tile = fz_newpixmap(colorspace, 0, 0, w, h); scale = 1; if (!indexed) { switch (bpc) { case 1: scale = 255; break; case 2: scale = 85; break; case 4: scale = 17; break; } } fz_unpacktile(tile, samples, n, bpc, stride, scale); if (usecolorkey) pdf_maskcolorkey(tile, n, colorkey); if (indexed) { fz_pixmap *conv; fz_decodeindexedtile(tile, decode, (1 << bpc) - 1); conv = pdf_expandindexedpixmap(tile); fz_droppixmap(tile); tile = conv; } else { fz_decodetile(tile, decode); } if (colorspace) fz_dropcolorspace(colorspace); tile->mask = mask; tile->interpolate = interpolate; fz_free(samples); *imgp = tile; return fz_okay; }
/* TODO error cleanup */ fz_error * pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) { fz_error *error; pdf_image *img; pdf_image *mask; int ismask; fz_obj *obj; fz_obj *sub; int i; int w, h, bpc; int n = 0; int a = 0; int usecolorkey = 0; fz_colorspace *cs = nil; pdf_indexed *indexed = nil; int stride; #ifndef PSP printf("LI\n"); #endif if ((*imgp = pdf_finditem(xref->store, PDF_KIMAGE, ref))) { fz_keepimage((fz_image*)*imgp); return nil; } img = fz_malloc(sizeof(pdf_image)); if (!img) return fz_outofmem; img->super.refs = 0; pdf_logimage("load image %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), img); /* * Dimensions, BPC and ColorSpace */ w = fz_toint(fz_dictgets(dict, "Width")); h = fz_toint(fz_dictgets(dict, "Height")); bpc = fz_toint(fz_dictgets(dict, "BitsPerComponent")); pdf_logimage("size %dx%d %d\n", w, h, bpc); cs = nil; obj = fz_dictgets(dict, "ColorSpace"); if (obj) { cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); if (cs) fz_keepcolorspace(cs); else { error = pdf_resolve(&obj, xref); if (error) return error; error = pdf_loadcolorspace(&cs, xref, obj); if (error) return error; fz_dropobj(obj); } if (!strcmp(cs->name, "Indexed")) { pdf_logimage("indexed\n"); indexed = (pdf_indexed*)cs; cs = indexed->base; } n = cs->n; a = 0; pdf_logimage("colorspace %s\n", cs->name); } /* * ImageMask, Mask and SoftMask */ mask = nil; ismask = fz_tobool(fz_dictgets(dict, "ImageMask")); if (ismask) { pdf_logimage("is mask\n"); bpc = 1; n = 0; a = 1; } obj = fz_dictgets(dict, "SMask"); if (fz_isindirect(obj)) { pdf_logimage("has soft mask\n"); error = pdf_loadindirect(&sub, xref, obj); if (error) return error; error = pdf_loadimage(&mask, xref, sub, obj); if (error) return error; if (mask->super.cs != pdf_devicegray) return fz_throw("syntaxerror: SMask must be DeviceGray"); mask->super.cs = 0; mask->super.n = 0; mask->super.a = 1; fz_dropobj(sub); } obj = fz_dictgets(dict, "Mask"); if (fz_isindirect(obj)) { error = pdf_loadindirect(&sub, xref, obj); if (error) return error; if (fz_isarray(sub)) { usecolorkey = 1; loadcolorkey(img->colorkey, bpc, indexed != nil, sub); } else { pdf_logimage("has mask\n"); error = pdf_loadimage(&mask, xref, sub, obj); if (error) return error; } fz_dropobj(sub); } else if (fz_isarray(obj)) { usecolorkey = 1; loadcolorkey(img->colorkey, bpc, indexed != nil, obj); } /* * Decode */ obj = fz_dictgets(dict, "Decode"); if (fz_isarray(obj)) { pdf_logimage("decode array\n"); if (indexed) for (i = 0; i < 2; i++) img->decode[i] = fz_toreal(fz_arrayget(obj, i)); else for (i = 0; i < (n + a) * 2; i++) img->decode[i] = fz_toreal(fz_arrayget(obj, i)); } else { if (indexed) for (i = 0; i < 2; i++) img->decode[i] = i & 1 ? (1 << bpc) - 1 : 0; else for (i = 0; i < (n + a) * 2; i++) img->decode[i] = i & 1; } /* * Load samples */ if (indexed) stride = (w * bpc + 7) / 8; else stride = (w * (n + a) * bpc + 7) / 8; // ccm // do not load images larger than 2MB uncompressed int early_reject = 0; if (h * stride <= 2*1024*1024) { error = pdf_loadstream(&img->samples, xref, fz_tonum(ref), fz_togen(ref)); if (error) { /* TODO: colorspace? */ fz_free(img); return error; } if (img->samples->wp - img->samples->bp < stride * h) { /* TODO: colorspace? */ fz_dropbuffer(img->samples); fz_free(img); return fz_throw("syntaxerror: truncated image data"); } /* 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; } } else { #ifndef PSP printf("LI - %p - early reject\n", img); #endif img->samples = nil; early_reject = 1; } /* * Create image object */ img->super.loadtile = pdf_loadtile; img->super.drop = pdf_dropimage; img->super.cs = cs; img->super.w = w; img->super.h = h; img->super.n = n; img->super.a = a; img->indexed = indexed; img->stride = stride; img->bpc = bpc; img->mask = (fz_image*)mask; img->usecolorkey = usecolorkey; if (img->mask) fz_keepimage(img->mask); // ccm #if 1 int bs = 0; if (img->samples) bs = (int)(img->samples->wp) - (int)(img->samples->rp); if (early_reject || (image_buffers_size + bs >= image_buffers_size_max)) { #ifndef PSP printf("LI - %p - optimized out\n", img); #endif if (img->samples) fz_dropbuffer(img->samples); if (img->mask) fz_dropimage(img->mask); fz_newbuffer(&img->samples, 8); img->super.w = 1; img->super.h = 1; img->super.n = 3; img->super.a = 0; img->super.refs = 0; unsigned char *p; for (p = img->samples->bp; p < img->samples->ep; p++) *p = 0x7f; img->indexed = 0; img->stride = (1 * (3 + 0) * 8 + 7) / 8; //(w * (n + a) * bpc + 7) / 8; img->super.cs = cs; img->super.loadtile = fakeImageTile; img->bpc = 8; img->mask = NULL; img->usecolorkey = 0; } else { image_buffers_size += bs; } #endif pdf_logimage("}\n"); error = pdf_storeitem(xref->store, PDF_KIMAGE, ref, img); if (error) { fz_dropimage((fz_image*)img); return error; } *imgp = img; return nil; }
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; }