void pdf_dropimage(fz_image *fzimg) { #ifndef PSP printf("DI\n"); #endif pdf_image *img = (pdf_image*)fzimg; fz_dropbuffer(img->samples); if (img->mask) fz_dropimage(img->mask); }
static void dropitem(pdf_itemkind kind, void *val) { switch (kind) { case PDF_KCOLORSPACE: fz_dropcolorspace(val); break; case PDF_KFUNCTION: pdf_dropfunction(val); break; case PDF_KXOBJECT: pdf_dropxobject(val); break; case PDF_KIMAGE: fz_dropimage(val); break; case PDF_KPATTERN: pdf_droppattern(val); break; case PDF_KSHADE: fz_dropshade(val); break; case PDF_KCMAP: pdf_dropcmap(val); break; case PDF_KFONT: pdf_dropfont(val); break; } }
static void saveimage(fz_obj *obj, int num, int gen) { pdf_image *img = nil; fz_obj *ref; fz_error error; fz_pixmap *pix; char name[1024]; FILE *f; int bpc; int w; int h; int n; int x; int y; error = fz_newindirect(&ref, num, gen, xref); if (error) die(error); error = pdf_newstore(&xref->store); if (error) die(error); error = pdf_loadimage(&img, xref, ref); if (error) die(error); n = img->super.n; w = img->super.w; h = img->super.h; bpc = img->bpc; error = fz_newpixmap(&pix, 0, 0, w, h, n + 1); if (error) die(error); error = img->super.loadtile(&img->super, pix); if (error) die(error); if (bpc == 1 && n == 0) { fz_pixmap *temp; error = fz_newpixmap(&temp, pix->x, pix->y, pix->w, pix->h, pdf_devicergb->n + 1); if (error) die(error); for (y = 0; y < pix->h; y++) for (x = 0; x < pix->w; x++) { int pixel = y * pix->w + x; temp->samples[pixel * temp->n + 0] = 255; temp->samples[pixel * temp->n + 1] = pix->samples[pixel]; temp->samples[pixel * temp->n + 2] = pix->samples[pixel]; temp->samples[pixel * temp->n + 3] = pix->samples[pixel]; } fz_droppixmap(pix); pix = temp; } if (img->super.cs && strcmp(img->super.cs->name, "DeviceRGB")) { fz_pixmap *temp; error = fz_newpixmap(&temp, pix->x, pix->y, pix->w, pix->h, pdf_devicergb->n + 1); if (error) die(error); fz_convertpixmap(img->super.cs, pix, pdf_devicergb, temp); fz_droppixmap(pix); pix = temp; } sprintf(name, "img-%04d.pnm", num); f = fopen(name, "wb"); if (f == NULL) die(fz_throw("Error creating image file")); fprintf(f, "P6\n%d %d\n%d\n", w, h, 255); for (y = 0; y < pix->h; y++) for (x = 0; x < pix->w; x++) { fz_sample *sample = &pix->samples[(y * pix->w + x) * (pdf_devicergb->n + 1)]; unsigned char r = sample[1]; unsigned char g = sample[2]; unsigned char b = sample[3]; fprintf(f, "%c%c%c", r, g, b); } if (fclose(f) < 0) die(fz_throw("Error closing image file")); fz_droppixmap(pix); pdf_dropstore(xref->store); xref->store = nil; fz_dropimage(&img->super); fz_dropobj(ref); }
void fz_dropimagenode(fz_imagenode *node) { fz_dropimage(node->image); }
/* 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; }