static void expandstream(fz_obj *obj, int num, int gen) { fz_error error; fz_buffer *buf, *tmp; fz_obj *newlen; error = pdf_loadstream(&buf, xref, num, gen); if (error) die(error); fz_dictdels(obj, "Filter"); fz_dictdels(obj, "DecodeParms"); if (doascii && isbinarystream(buf)) { tmp = hexbuf(buf->data, buf->len); fz_dropbuffer(buf); buf = tmp; addhexfilter(obj); } newlen = fz_newint(buf->len); fz_dictputs(obj, "Length", newlen); fz_dropobj(newlen); fprintf(out, "%d %d obj\n", num, gen); fz_fprintobj(out, obj, !doexpand); fprintf(out, "stream\n"); fwrite(buf->data, 1, buf->len, out); fprintf(out, "endstream\nendobj\n\n"); fz_dropbuffer(buf); }
void fz_dropstream(fz_stream *stm) { stm->refs --; if (stm->refs == 0) { if (stm->error) { fz_catch(stm->error, "dropped unhandled ioerror"); stm->error = fz_okay; } switch (stm->kind) { case FZ_SFILE: close(stm->file); break; case FZ_SFILTER: fz_dropfilter(stm->filter); fz_dropstream(stm->chain); break; case FZ_SBUFFER: break; } fz_dropbuffer(stm->buffer); fz_free(stm); } }
fz_error * pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref) { fz_error *error; int fterr; FT_Face face; fz_buffer *buf; error = initfontlibs(); if (error) return fz_rethrow(error, "cannot init font libraries"); pdf_logfont("load embedded font\n"); error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) return fz_rethrow(error, "cannot load font stream"); fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face); if (fterr) { fz_dropbuffer(buf); return fz_throw("freetype: cannot load embedded font: %s", ft_errstr(fterr)); } font->ftface = face; font->fontdata = buf; return fz_okay; }
static fz_error * openfile(fz_stream **stmp, char *path, int mode, int realmode) { fz_error *error; fz_stream *stm; stm = newstm(FZ_SFILE, mode); if (!stm) return fz_throw("outofmem: stream struct"); error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE); if (error) { fz_free(stm); return fz_rethrow(error, "cannot create buffer"); } stm->file = open(path, realmode, 0666); if (stm->file < 0) { fz_dropbuffer(stm->buffer); fz_free(stm); return fz_throw("syserr: open '%s': %s", path, strerror(errno)); } *stmp = stm; return fz_okay; }
fz_error fz_openrfile(fz_stream **stmp, char *path) { fz_error error; fz_stream *stm; stm = newstm(FZ_SFILE); if (!stm) return fz_rethrow(-1, "out of memory: stream struct"); error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE); if (error) { fz_free(stm); return fz_rethrow(error, "cannot create buffer"); } stm->file = open(path, O_BINARY | O_RDONLY, 0666); if (stm->file < 0) { fz_dropbuffer(stm->buffer); fz_free(stm); return fz_throw("syserr: open '%s': %s", path, strerror(errno)); } *stmp = stm; return fz_okay; }
void fz_dropfont(fz_font *font) { int fterr; int i; if (font && --font->refs == 0) { if (font->t3procs) { if (font->t3resources) fz_dropobj(font->t3resources); for (i = 0; i < 256; i++) if (font->t3procs[i]) fz_dropbuffer(font->t3procs[i]); fz_free(font->t3procs); fz_free(font->t3widths); } if (font->ftface) { fterr = FT_Done_Face((FT_Face)font->ftface); if (fterr) fz_warn("freetype finalizing face: %s", ft_errorstring(fterr)); fz_finalizefreetype(); } if (font->widthtable) fz_free(font->widthtable); fz_free(font); } }
fz_error pdf_loadembeddedfont(pdf_fontdesc *fontdesc, pdf_xref *xref, fz_obj *stmref) { fz_error error; fz_buffer *buf; pdf_logfont("load embedded font\n"); error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) return fz_rethrow(error, "cannot load font stream (%d %d R)", fz_tonum(stmref), fz_togen(stmref)); error = fz_newfontfrombuffer(&fontdesc->font, buf->data, buf->len, 0); if (error) { fz_dropbuffer(buf); return fz_rethrow(error, "cannot load embedded font (%d %d R)", fz_tonum(stmref), fz_togen(stmref)); } /* save the buffer so we can free it later */ fontdesc->font->ftdata = buf->data; fontdesc->font->ftsize = buf->len; fz_free(buf); /* only free the fz_buffer struct, not the contained data */ fontdesc->isembedded = 1; return fz_okay; }
void fz_droppipeline(fz_filter *filter) { fz_pipeline *p = (fz_pipeline*)filter; fz_dropfilter(p->head); fz_dropfilter(p->tail); fz_dropbuffer(p->buffer); }
void pdf_dropxobject(pdf_xobject *xobj) { if (--xobj->refs == 0) { if (xobj->contents) fz_dropbuffer(xobj->contents); if (xobj->resources) fz_dropobj(xobj->resources); fz_free(xobj); } }
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); }
fz_error * fz_openrmemory(fz_stream **stmp, unsigned char *mem, int len) { fz_error *error; fz_buffer *buf; error = fz_newbufferwithmemory(&buf, mem, len); if (error) return fz_rethrow(error, "cannot create memory buffer"); error = fz_openrbuffer(stmp, buf); if (error) { fz_dropbuffer(buf); return fz_rethrow(error, "cannot open memory buffer stream"); } fz_dropbuffer(buf); return fz_okay; }
void pdf_droppattern(pdf_pattern *pat) { if (pat && --pat->refs == 0) { if (pat->resources) fz_dropobj(pat->resources); if (pat->contents) fz_dropbuffer(pat->contents); fz_free(pat); } }
static fz_error pdf_loadpagecontentsarray(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list) { fz_error error; fz_buffer *big; fz_buffer *one; int i; pdf_logpage("multiple content streams: %d\n", fz_arraylen(list)); /* TODO: openstream, read, close into big buffer at once */ big = fz_newbuffer(32 * 1024); for (i = 0; i < fz_arraylen(list); i++) { fz_obj *stm = fz_arrayget(list, i); error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm)); if (error) { fz_dropbuffer(big); return fz_rethrow(error, "cannot load content stream part %d/%d (%d %d R)", i + 1, fz_arraylen(list), fz_tonum(stm), fz_togen(stm)); } if (big->len + one->len + 1 > big->cap) fz_resizebuffer(big, big->len + one->len + 1); memcpy(big->data + big->len, one->data, one->len); big->data[big->len + one->len] = ' '; big->len += one->len + 1; fz_dropbuffer(one); } *bigbufp = big; return fz_okay; }
static void ftdropfont(fz_font *font) { pdf_font *pfont = (pdf_font*)font; if (pfont->encoding) pdf_dropcmap(pfont->encoding); if (pfont->tottfcmap) pdf_dropcmap(pfont->tottfcmap); if (pfont->tounicode) pdf_dropcmap(pfont->tounicode); fz_free(pfont->cidtogid); fz_free(pfont->cidtoucs); if (pfont->ftface) FT_Done_Face((FT_Face)pfont->ftface); if (pfont->fontdata) fz_dropbuffer(pfont->fontdata); }
void pdf_freepage(pdf_page *page) { pdf_logpage("drop page %p\n", page); if (page->resources) fz_dropobj(page->resources); if (page->contents) fz_dropbuffer(page->contents); if (page->list) fz_freedisplaylist(page->list); if (page->text) fz_freetextspan(page->text); if (page->links) pdf_freelink(page->links); if (page->annots) pdf_freeannot(page->annots); fz_free(page); }
void fz_dropstream(fz_stream *stm) { stm->refs --; if (stm->refs == 0) { if (stm->error) { fflush(stdout); fz_printerror(stm->error); fz_droperror(stm->error); fflush(stderr); fz_warn("dropped unhandled ioerror"); } if (stm->mode == FZ_SWRITE) { stm->buffer->eof = 1; fz_flush(stm); } switch (stm->kind) { case FZ_SFILE: close(stm->file); break; case FZ_SFILTER: fz_dropfilter(stm->filter); fz_dropstream(stm->chain); break; case FZ_SBUFFER: break; } fz_dropbuffer(stm->buffer); fz_free(stm); } }
fz_error * pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) { fz_error *error; fz_obj *obj; int bpcoord; int bpcomp; int bpflag; int ncomp; float x0, x1, y0, y1; float c0[FZ_MAXCOLORS]; float c1[FZ_MAXCOLORS]; int i, z; int bitspervertex; int bytepervertex; fz_buffer *buf; int n; int j; float cval[16]; int flag; unsigned int t; float x, y; error = nil; ncomp = shade->cs->n; bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); obj = fz_dictgets(shading, "Decode"); if (fz_isarray(obj)) { pdf_logshade("decode array\n"); x0 = fz_toreal(fz_arrayget(obj, 0)); x1 = fz_toreal(fz_arrayget(obj, 1)); y0 = fz_toreal(fz_arrayget(obj, 2)); y1 = fz_toreal(fz_arrayget(obj, 3)); for (i=0; i < fz_arraylen(obj) / 2; ++i) { c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); } } else { error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); goto cleanup; } obj = fz_dictgets(shading, "Function"); if (obj) { ncomp = 1; pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); } bitspervertex = bpflag + bpcoord * 2 + bpcomp * ncomp; bytepervertex = (bitspervertex+7) / 8; error = pdf_loadstream(&buf, xref, fz_tonum(ref), fz_togen(ref)); if (error) goto cleanup; shade->usefunction = 0; n = 2 + shade->cs->n; j = 0; for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z) { flag = *buf->rp++; t = *buf->rp++; t = (t << 8) + *buf->rp++; t = (t << 8) + *buf->rp++; x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1)); t = *buf->rp++; t = (t << 8) + *buf->rp++; t = (t << 8) + *buf->rp++; y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1)); for (i=0; i < ncomp; ++i) { t = *buf->rp++; t = (t << 8) + *buf->rp++; } if (flag == 0) { j += n; } if (flag == 1 || flag == 2) { j += 3 * n; } } buf->rp = buf->bp; shade->mesh = (float*) malloc(sizeof(float) * j); /* 8, 24, 16 only */ j = 0; for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z) { flag = *buf->rp++; t = *buf->rp++; t = (t << 8) + *buf->rp++; t = (t << 8) + *buf->rp++; x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1)); t = *buf->rp++; t = (t << 8) + *buf->rp++; t = (t << 8) + *buf->rp++; y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1)); for (i=0; i < ncomp; ++i) { t = *buf->rp++; t = (t << 8) + *buf->rp++; cval[i] = t / (double)(pow(2, 16) - 1); } if (flag == 0) { shade->mesh[j++] = x; shade->mesh[j++] = y; for (i=0; i < ncomp; ++i) { shade->mesh[j++] = cval[i]; } } if (flag == 1) { memcpy(&(shade->mesh[j]), &(shade->mesh[j - 2 * n]), n * sizeof(float)); memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float)); j+= 2 * n; shade->mesh[j++] = x; shade->mesh[j++] = y; for (i=0; i < ncomp; ++i) { shade->mesh[j++] = cval[i]; } } if (flag == 2) { memcpy(&(shade->mesh[j]), &(shade->mesh[j - 3 * n]), n * sizeof(float)); memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float)); j+= 2 * n; shade->mesh[j++] = x; shade->mesh[j++] = y; for (i=0; i < ncomp; ++i) { shade->mesh[j++] = cval[i]; } } } shade->meshlen = j / n / 3; fz_dropbuffer(buf); cleanup: return nil; }
/* 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; }
static fz_error loadcidfont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz_obj *tounicode) { fz_error error; fz_obj *widths; fz_obj *descriptor; pdf_fontdesc *fontdesc; FT_Face face; fz_bbox bbox; int kind; char collection[256]; char *basefont; int i, k, fterr; fz_obj *obj; int dw; /* Get font name and CID collection */ basefont = fz_toname(fz_dictgets(dict, "BaseFont")); { fz_obj *cidinfo; char tmpstr[64]; int tmplen; cidinfo = fz_dictgets(dict, "CIDSystemInfo"); if (!cidinfo) return fz_throw("cid font is missing info"); obj = fz_dictgets(cidinfo, "Registry"); tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj)); memcpy(tmpstr, fz_tostrbuf(obj), tmplen); tmpstr[tmplen] = '\0'; fz_strlcpy(collection, tmpstr, sizeof collection); fz_strlcat(collection, "-", sizeof collection); obj = fz_dictgets(cidinfo, "Ordering"); tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj)); memcpy(tmpstr, fz_tostrbuf(obj), tmplen); tmpstr[tmplen] = '\0'; fz_strlcat(collection, tmpstr, sizeof collection); } /* Load font file */ fontdesc = pdf_newfontdesc(); pdf_logfont("load cid font (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), fontdesc); pdf_logfont("basefont %s\n", basefont); pdf_logfont("collection %s\n", collection); descriptor = fz_dictgets(dict, "FontDescriptor"); if (descriptor) error = pdf_loadfontdescriptor(fontdesc, xref, descriptor, collection, basefont); else error = fz_throw("syntaxerror: missing font descriptor"); if (error) goto cleanup; face = fontdesc->font->ftface; kind = ftkind(face); bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM; bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM; bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM; bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM; pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); if (bbox.x0 == bbox.x1) fz_setfontbbox(fontdesc->font, -1000, -1000, 2000, 2000); else fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); /* Encoding */ error = fz_okay; if (fz_isname(encoding)) { pdf_logfont("encoding /%s\n", fz_toname(encoding)); if (!strcmp(fz_toname(encoding), "Identity-H")) fontdesc->encoding = pdf_newidentitycmap(0, 2); else if (!strcmp(fz_toname(encoding), "Identity-V")) fontdesc->encoding = pdf_newidentitycmap(1, 2); else error = pdf_loadsystemcmap(&fontdesc->encoding, fz_toname(encoding)); } else if (fz_isindirect(encoding)) { pdf_logfont("encoding %d %d R\n", fz_tonum(encoding), fz_togen(encoding)); error = pdf_loadembeddedcmap(&fontdesc->encoding, xref, encoding); } else { error = fz_throw("syntaxerror: font missing encoding"); } if (error) goto cleanup; pdf_setfontwmode(fontdesc, pdf_getwmode(fontdesc->encoding)); pdf_logfont("wmode %d\n", pdf_getwmode(fontdesc->encoding)); if (kind == TRUETYPE) { fz_obj *cidtogidmap; cidtogidmap = fz_dictgets(dict, "CIDToGIDMap"); if (fz_isindirect(cidtogidmap)) { fz_buffer *buf; pdf_logfont("cidtogidmap stream\n"); error = pdf_loadstream(&buf, xref, fz_tonum(cidtogidmap), fz_togen(cidtogidmap)); if (error) goto cleanup; fontdesc->ncidtogid = (buf->len) / 2; fontdesc->cidtogid = fz_malloc(fontdesc->ncidtogid * sizeof(unsigned short)); for (i = 0; i < fontdesc->ncidtogid; i++) fontdesc->cidtogid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1]; fz_dropbuffer(buf); } /* if truetype font is external, cidtogidmap should not be identity */ /* so we map from cid to unicode and then map that through the (3 1) */ /* unicode cmap to get a glyph id */ else if (fontdesc->font->ftsubstitute) { pdf_logfont("emulate ttf cidfont\n"); fterr = FT_Select_Charmap(face, ft_encoding_unicode); if (fterr) { error = fz_throw("fonterror: no unicode cmap when emulating CID font: %s", ft_errorstring(fterr)); goto cleanup; } if (!strcmp(collection, "Adobe-CNS1")) error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-CNS1-UCS2"); else if (!strcmp(collection, "Adobe-GB1")) error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-GB1-UCS2"); else if (!strcmp(collection, "Adobe-Japan1")) error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Japan1-UCS2"); else if (!strcmp(collection, "Adobe-Japan2")) error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Japan2-UCS2"); else if (!strcmp(collection, "Adobe-Korea1")) error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Korea1-UCS2"); else error = fz_okay; if (error) { error = fz_rethrow(error, "cannot load system cmap %s", collection); goto cleanup; } } } error = pdf_loadtounicode(fontdesc, xref, nil, collection, tounicode); if (error) goto cleanup; /* Horizontal */ dw = 1000; obj = fz_dictgets(dict, "DW"); if (obj) dw = fz_toint(obj); pdf_setdefaulthmtx(fontdesc, dw); widths = fz_dictgets(dict, "W"); if (widths) { int c0, c1, w; for (i = 0; i < fz_arraylen(widths); ) { c0 = fz_toint(fz_arrayget(widths, i)); obj = fz_arrayget(widths, i + 1); if (fz_isarray(obj)) { for (k = 0; k < fz_arraylen(obj); k++) { w = fz_toint(fz_arrayget(obj, k)); pdf_addhmtx(fontdesc, c0 + k, c0 + k, w); } i += 2; } else { c1 = fz_toint(obj); w = fz_toint(fz_arrayget(widths, i + 2)); pdf_addhmtx(fontdesc, c0, c1, w); i += 3; } } } pdf_endhmtx(fontdesc); /* Vertical */ if (pdf_getwmode(fontdesc->encoding) == 1) { int dw2y = 880; int dw2w = -1000; obj = fz_dictgets(dict, "DW2"); if (obj) { dw2y = fz_toint(fz_arrayget(obj, 0)); dw2w = fz_toint(fz_arrayget(obj, 1)); } pdf_setdefaultvmtx(fontdesc, dw2y, dw2w); widths = fz_dictgets(dict, "W2"); if (widths) { int c0, c1, w, x, y; for (i = 0; i < fz_arraylen(widths); ) { c0 = fz_toint(fz_arrayget(widths, i)); obj = fz_arrayget(widths, i + 1); if (fz_isarray(obj)) { for (k = 0; k < fz_arraylen(obj); k += 3) { w = fz_toint(fz_arrayget(obj, k + 0)); x = fz_toint(fz_arrayget(obj, k + 1)); y = fz_toint(fz_arrayget(obj, k + 2)); pdf_addvmtx(fontdesc, c0 + k, c0 + k, x, y, w); } i += 2; } else { c1 = fz_toint(obj); w = fz_toint(fz_arrayget(widths, i + 2)); x = fz_toint(fz_arrayget(widths, i + 3)); y = fz_toint(fz_arrayget(widths, i + 4)); pdf_addvmtx(fontdesc, c0, c1, x, y, w); i += 5; } } } pdf_endvmtx(fontdesc); } pdf_logfont("}\n"); *fontdescp = fontdesc; return fz_okay; cleanup: pdf_dropfont(fontdesc); return fz_rethrow(error, "cannot load cid font (%d %d R)", fz_tonum(dict), fz_togen(dict)); }
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 void closebuffer(fz_stream *stm) { fz_dropbuffer(stm->state); }
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 void savefont(fz_obj *dict, int num, int gen) { fz_error error; char name[1024]; char *subtype; fz_buffer *buf; fz_obj *stream = nil; fz_obj *obj; char *ext = ""; FILE *f; unsigned char *p; char *fontname = "font"; obj = fz_dictgets(dict, "FontName"); if (obj) fontname = fz_toname(obj); obj = fz_dictgets(dict, "FontFile"); if (obj) { stream = obj; ext = "pfa"; } obj = fz_dictgets(dict, "FontFile2"); if (obj) { stream = obj; ext = "ttf"; } obj = fz_dictgets(dict, "FontFile3"); if (obj) { stream = obj; obj = fz_dictgets(obj, "Subtype"); if (obj && !fz_isname(obj)) die(fz_throw("Invalid font descriptor subtype")); subtype = fz_toname(obj); if (!strcmp(subtype, "Type1C")) ext = "cff"; else if (!strcmp(subtype, "CIDFontType0C")) ext = "cid"; else die(fz_throw("Unhandled font type '%s'", subtype)); } if (!stream) { fz_warn("Unhandled font type"); return; } error = fz_newbuffer(&buf, 0); if (error) die(error); error = pdf_loadstream(&buf, xref, fz_tonum(stream), fz_togen(stream)); if (error) die(error); sprintf(name, "%s-%04d.%s", fontname, num, ext); f = fopen(name, "wb"); if (f == NULL) die(fz_throw("Error creating image file")); for (p = buf->rp; p < buf->wp; p ++) fprintf(f, "%c", *p); if (fclose(f) < 0) die(fz_throw("Error closing image file")); fz_dropbuffer(buf); }
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; }