diff options
author | Tor Andersson <tor@ghostscript.com> | 2004-12-01 06:52:32 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2004-12-01 06:52:32 +0100 |
commit | 615d27315a131bea0df699c3daa1102289b433c6 (patch) | |
tree | abf1a1f17ff332db226ed48606f26fd5f0d7e8c3 | |
parent | 4e4e30e57fb4170f3a9dd0a9c23da78c2b46a69f (diff) | |
download | mupdf-615d27315a131bea0df699c3daa1102289b433c6.tar.xz |
refactor resource loading and item store
-rw-r--r-- | Jamfile | 18 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | include/mupdf/rsrc.h | 35 | ||||
-rw-r--r-- | include/mupdf/xref.h | 9 | ||||
-rw-r--r-- | mupdf/cmap.c | 11 | ||||
-rw-r--r-- | mupdf/colorspace1.c | 8 | ||||
-rw-r--r-- | mupdf/font.c | 43 | ||||
-rw-r--r-- | mupdf/function.c | 27 | ||||
-rw-r--r-- | mupdf/image.c | 33 | ||||
-rw-r--r-- | mupdf/interpret.c | 17 | ||||
-rw-r--r-- | mupdf/open.c | 6 | ||||
-rw-r--r-- | mupdf/repair.c | 4 | ||||
-rw-r--r-- | mupdf/resources.c | 187 | ||||
-rw-r--r-- | mupdf/shade.c | 2 | ||||
-rw-r--r-- | mupdf/store.c | 81 | ||||
-rw-r--r-- | mupdf/type3.c | 4 | ||||
-rw-r--r-- | mupdf/xobject.c | 13 | ||||
-rw-r--r-- | mupdf/xref.c | 11 | ||||
-rw-r--r-- | render/rastshade.c | 1 |
19 files changed, 282 insertions, 231 deletions
@@ -118,23 +118,25 @@ Library libmupdf : mupdf/outline.c mupdf/pagetree.c + mupdf/store.c + mupdf/resources.c mupdf/function.c + mupdf/colorspace1.c + mupdf/colorspace2.c + mupdf/xobject.c + mupdf/image.c + mupdf/pattern.c + mupdf/shade.c mupdf/cmap.c + mupdf/unicode.c mupdf/fontagl.c mupdf/fontenc.c mupdf/fontfile.c # mupdf/fontfilefc.c # mupdf/fontfilems.c - mupdf/unicode.c mupdf/font.c mupdf/type3.c - mupdf/colorspace1.c - mupdf/colorspace2.c - mupdf/image.c - mupdf/xobject.c - mupdf/pattern.c - mupdf/shade.c - mupdf/resources.c + mupdf/page.c mupdf/build.c mupdf/interpret.c @@ -1,4 +1,6 @@ immediate plan: + - fast parsed object store (scrap r* cache) + - global font/cmap cache - image color key transparency - text fill + clip mode - pdf logging @@ -8,7 +10,6 @@ immediate plan: - page labels + dests + outline + annots - design gui for editor - go through spec and check all features! - - global font/cmap cache - font and cmap config (where to load cmap and which cid fonts) - talk to keithp about fontconfig cid-font + cmap support diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h index 8298a3d2..0e69621b 100644 --- a/include/mupdf/rsrc.h +++ b/include/mupdf/rsrc.h @@ -1,16 +1,25 @@ /* - * Resource registry and dictionaries + * Resource store */ -struct pdf_rsrc_s +typedef enum pdf_itemkind_e { - fz_obj *key; - void *val; - pdf_rsrc *next; -}; + PDF_KCOLORSPACE, + PDF_KFUNCTION, + PDF_KXOBJECT, + PDF_KIMAGE, + PDF_KPATTERN, + PDF_KSHADE, + PDF_KCMAP, + PDF_KFONT +} pdf_itemkind; + +fz_error *pdf_newstore(pdf_store **storep); +fz_error *pdf_storeitem(pdf_store *store, pdf_itemkind tag, fz_obj *key, void *val); +void *pdf_finditem(pdf_store *store, pdf_itemkind tag, fz_obj *key); +void pdf_dropstore(pdf_store *store); fz_error *pdf_loadresources(fz_obj **rdb, pdf_xref *xref, fz_obj *orig); -void *pdf_findresource(pdf_rsrc *list, fz_obj *key); /* * Functions @@ -18,7 +27,7 @@ void *pdf_findresource(pdf_rsrc *list, fz_obj *key); typedef struct pdf_function_s pdf_function; -fz_error *pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj); +fz_error *pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *ref); fz_error *pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outlen); void pdf_dropfunction(pdf_function *func); @@ -103,7 +112,7 @@ struct pdf_image_s }; fz_error *pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_file *file); -fz_error *pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *obj, fz_obj *stm); +fz_error *pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); fz_error *pdf_loadtile(fz_image *image, fz_pixmap *tile); /* @@ -164,9 +173,9 @@ struct pdf_font_s /* cmap.c */ fz_error *pdf_parsecmap(fz_cmap **cmapp, fz_file *file); -fz_error *pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref); +fz_error *pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *ref); fz_error *pdf_loadsystemcmap(fz_cmap **cmapp, char *name); -fz_error *pdf_makeidentitycmap(fz_cmap **cmapp, int wmode, int bytes); +fz_error *pdf_makeidentitycmap(fz_cmap **cmapp, int wmode, int bytes); // XXX /* unicode.c */ fz_error *pdf_loadtounicode(pdf_font *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm); @@ -178,10 +187,10 @@ fz_error *pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection); fz_error *pdf_loadsubstitutefont(pdf_font *font, int fdflags, char *collection); /* type3.c */ -fz_error *pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *font); +fz_error *pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); /* font.c */ fz_error *pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection); -fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *font); +fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); void pdf_dropfont(pdf_font *font); diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h index f1cf79c0..7ad417da 100644 --- a/include/mupdf/xref.h +++ b/include/mupdf/xref.h @@ -2,7 +2,7 @@ * xref and object / stream api */ -typedef struct pdf_rsrc_s pdf_rsrc; /* parsed resource registry */ +typedef struct pdf_store_s pdf_store; /* parsed resource store */ typedef struct pdf_xrefentry_s pdf_xrefentry; typedef struct pdf_xref_s pdf_xref; @@ -20,12 +20,7 @@ struct pdf_xref_s int cap; pdf_xrefentry *table; - pdf_rsrc *rfont; - pdf_rsrc *rimage; - pdf_rsrc *rxobject; - pdf_rsrc *rpattern; - pdf_rsrc *rshade; - pdf_rsrc *rcolorspace; + pdf_store *store; }; struct pdf_xrefentry_s diff --git a/mupdf/cmap.c b/mupdf/cmap.c index 55ae0e2b..0a53b28f 100644 --- a/mupdf/cmap.c +++ b/mupdf/cmap.c @@ -382,6 +382,9 @@ pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref) fz_obj *wmode; fz_obj *obj; + if ((*cmapp = pdf_finditem(xref->store, PDF_KCMAP, stmref))) + return nil; + pdf_logfont("load embedded cmap %d %d {\n", fz_tonum(stmref), fz_togen(stmref)); error = pdf_resolve(&stmobj, xref); @@ -425,10 +428,14 @@ pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref) fz_dropcmap(usecmap); } - fz_dropobj(stmobj); - pdf_logfont("}\n"); + error = pdf_storeitem(xref->store, PDF_KCMAP, stmref, cmap); + if (error) + goto cleanup; + + fz_dropobj(stmobj); + *cmapp = cmap; return nil; diff --git a/mupdf/colorspace1.c b/mupdf/colorspace1.c index dcd6dc1f..3be2c6be 100644 --- a/mupdf/colorspace1.c +++ b/mupdf/colorspace1.c @@ -548,8 +548,8 @@ static void dropindexed(fz_colorspace *fzcs) { pdf_indexed *cs = (pdf_indexed *)fzcs; - fz_dropcolorspace(cs->base); - fz_free(cs->lookup); + if (cs->base) fz_dropcolorspace(cs->base); + if (cs->lookup) fz_free(cs->lookup); } static fz_error * @@ -592,7 +592,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) cs->lookup = fz_malloc(n); if (!cs->lookup) { - dropindexed((fz_colorspace*)cs); + fz_dropcolorspace((fz_colorspace*)cs); return fz_outofmem; } @@ -618,7 +618,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup)); if (error) { - dropindexed((fz_colorspace*)cs); + fz_dropcolorspace((fz_colorspace*)cs); return error; } diff --git a/mupdf/font.c b/mupdf/font.c index e3a494b1..6f146b51 100644 --- a/mupdf/font.c +++ b/mupdf/font.c @@ -284,7 +284,7 @@ pdf_newfont(char *name) */ static fz_error * -loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) +loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) { fz_error *error; fz_obj *descriptor = nil; @@ -313,7 +313,7 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) if (!font) return fz_outofmem; - pdf_logfont("load simple font %p {\n", font); + pdf_logfont("load simple font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font); pdf_logfont("basefont0 %s\n", basefont); pdf_logfont("basefont1 %s\n", fontname); @@ -570,7 +570,7 @@ cleanup: */ static fz_error * -loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz_obj *tounicode) +loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj *encoding, fz_obj *tounicode) { fz_error *error; fz_obj *widths = nil; @@ -625,7 +625,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz if (!font) return fz_outofmem; - pdf_logfont("load cid font %p {\n", font); + pdf_logfont("load cid font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font); pdf_logfont("basefont %s\n", basefont); pdf_logfont("collection %s\n", collection); @@ -878,7 +878,7 @@ cleanup: } static fz_error * -loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) +loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) { fz_error *error; fz_obj *dfonts; @@ -902,9 +902,9 @@ loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) tounicode = fz_dictgets(dict, "ToUnicode"); if (!strcmp(fz_toname(subtype), "CIDFontType0")) - error = loadcidfont(fontp, xref, dfont, encoding, tounicode); + error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode); else if (!strcmp(fz_toname(subtype), "CIDFontType2")) - error = loadcidfont(fontp, xref, dfont, encoding, tounicode); + error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode); else error = fz_throw("syntaxerror: unknown cid font type"); @@ -978,18 +978,33 @@ cleanup: } fz_error * -pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) +pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) { - char *subtype = fz_toname(fz_dictgets(dict, "Subtype")); + fz_error *error; + char *subtype; + + if ((*fontp = pdf_finditem(xref->store, PDF_KFONT, ref))) + return nil; + + subtype = fz_toname(fz_dictgets(dict, "Subtype")); if (!strcmp(subtype, "Type0")) - return loadtype0(fontp, xref, dict); + error = loadtype0(fontp, xref, dict, ref); if (!strcmp(subtype, "Type1") || !strcmp(subtype, "MMType1")) - return loadsimplefont(fontp, xref, dict); + error = loadsimplefont(fontp, xref, dict, ref); else if (!strcmp(subtype, "TrueType")) - return loadsimplefont(fontp, xref, dict); + error = loadsimplefont(fontp, xref, dict, ref); else if (!strcmp(subtype, "Type3")) - return pdf_loadtype3font(fontp, xref, dict); + error = pdf_loadtype3font(fontp, xref, dict, ref); else - return fz_throw("unimplemented: %s fonts", subtype); + error = fz_throw("unimplemented: %s fonts", subtype); + + if (error) + return error; + + error = pdf_storeitem(xref->store, PDF_KFONT, ref, *fontp); + if (error) + return error; + + return nil; } diff --git a/mupdf/function.c b/mupdf/function.c index eb246a12..c300b89e 100644 --- a/mupdf/function.c +++ b/mupdf/function.c @@ -1443,7 +1443,7 @@ pdf_dropfunction(pdf_function *func) } fz_error * -pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj) +pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *ref) { fz_error *error = nil; fz_obj *objfunc = nil; @@ -1452,12 +1452,15 @@ pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj) int tmp; int i; float min,max; - + + if ((*func = pdf_finditem(xref->store, PDF_KFUNCTION, ref))) + return nil; + newfunc = fz_malloc(sizeof(pdf_function)); if(!newfunc) return fz_outofmem; memset(newfunc,0,sizeof(pdf_function)); - objfunc = obj; + objfunc = ref; error = pdf_resolve(&objfunc,xref); if(error) { objfunc = nil; goto cleanup; } @@ -1514,12 +1517,12 @@ pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj) switch(newfunc->type) { case PDF_FUNC_SAMPLE: - if(!fz_isindirect(obj)) + if(!fz_isindirect(ref)) goto cleanup; - if(!pdf_isstream(xref, fz_tonum(obj), fz_togen(obj))) + if(!pdf_isstream(xref, fz_tonum(ref), fz_togen(ref))) goto cleanup; error = loadsamplefunc(newfunc, xref, objfunc, - fz_tonum(obj), fz_togen(obj)); + fz_tonum(ref), fz_togen(ref)); if(error) goto cleanup; break; case PDF_FUNC_EXPONENTIAL: @@ -1531,12 +1534,12 @@ pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj) if(error) goto cleanup; break; case PDF_FUNC_POSTSCRIPT: - if(!fz_isindirect(obj)) + if(!fz_isindirect(ref)) goto cleanup; - if(!pdf_isstream(xref, fz_tonum(obj), fz_togen(obj))) + if(!pdf_isstream(xref, fz_tonum(ref), fz_togen(ref))) goto cleanup; error = loadpostscriptfunc(newfunc, xref, objfunc, - fz_tonum(obj), fz_togen(obj)); + fz_tonum(ref), fz_togen(ref)); if(error) goto cleanup; break; default: @@ -1544,9 +1547,11 @@ pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj) } fz_dropobj(objfunc); - + + error = pdf_storeitem(xref->store, PDF_KFUNCTION, ref, newfunc); + if (error) goto cleanup; + *func = newfunc; - return nil; cleanup: diff --git a/mupdf/image.c b/mupdf/image.c index 8fbb04e5..94168d68 100644 --- a/mupdf/image.c +++ b/mupdf/image.c @@ -62,12 +62,13 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, if (csd) { fz_obj *cso = fz_dictget(csd, cs); - img->super.cs = pdf_findresource(xref->rcolorspace, cso); + img->super.cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, cso); } } if (!img->super.cs) { + /* XXX danger! danger! does this resolve? */ error = pdf_loadcolorspace(&img->super.cs, xref, cs); if (error) return error; @@ -177,6 +178,9 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) pdf_indexed *indexed = nil; int stride; + if ((*imgp = pdf_finditem(xref->store, PDF_KIMAGE, ref))) + return nil; + img = fz_malloc(sizeof(pdf_image)); if (!img) return fz_outofmem; @@ -197,13 +201,19 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) obj = fz_dictgets(dict, "ColorSpace"); if (obj) { - error = pdf_resolve(&obj, xref); - if (error) - return error; + cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); + if (!cs) + { + error = pdf_resolve(&obj, xref); + if (error) + return error; - error = pdf_loadcolorspace(&cs, xref, obj); - if (error) - return error; + error = pdf_loadcolorspace(&cs, xref, obj); + if (error) + return error; + + fz_dropobj(obj); + } if (!strcmp(cs->name, "Indexed")) { @@ -215,8 +225,6 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) a = 0; pdf_logimage("colorspace %s\n", cs->name); - - fz_dropobj(obj); } /* @@ -359,6 +367,13 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) 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; } diff --git a/mupdf/interpret.c b/mupdf/interpret.c index c45c63e3..910e5f6f 100644 --- a/mupdf/interpret.c +++ b/mupdf/interpret.c @@ -180,7 +180,7 @@ runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate) { if (fz_isarray(val) && fz_arraylen(val) == 2) { - gstate->font = pdf_findresource(xref->rfont, fz_arrayget(val, 0)); + gstate->font = pdf_finditem(xref->store, PDF_KFONT, fz_arrayget(val, 0)); if (!gstate->font) return fz_throw("syntaxerror: missing font resource"); gstate->size = fz_toreal(fz_arrayget(val, 1)); @@ -433,7 +433,8 @@ Lsetcolorspace: obj = fz_dictget(dict, obj); if (!obj) return fz_throw("syntaxerror: missing colorspace resource"); - cs = pdf_findresource(xref->rcolorspace, obj); + + cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj); if (!cs) return fz_throw("syntaxerror: missing colorspace resource"); } @@ -500,14 +501,14 @@ Lsetcolor: if (!obj) return fz_throw("syntaxerror: missing pattern resource"); - pat = pdf_findresource(xref->rpattern, obj); + pat = pdf_finditem(xref->store, PDF_KPATTERN, obj); if (pat) { error = pdf_setpattern(csi, what, pat, csi->top == 1 ? nil : v); if (error) return error; } - shd = pdf_findresource(xref->rshade, obj); + shd = pdf_finditem(xref->store, PDF_KSHADE, obj); if (shd) { error = pdf_setshade(csi, what, shd); @@ -627,7 +628,7 @@ Lsetcolor: if (!obj) return fz_throw("syntaxerror: missing font resource"); - gstate->font = pdf_findresource(xref->rfont, obj); + gstate->font = pdf_finditem(xref->store, PDF_KFONT, obj); if (!gstate->font) return fz_throw("syntaxerror: missing font resource"); @@ -730,8 +731,8 @@ fz_debugobj(rdb); if (!obj) return fz_throw("syntaxerror: missing xobject resource"); - img = pdf_findresource(xref->rimage, obj); - xobj = pdf_findresource(xref->rxobject, obj); + img = pdf_finditem(xref->store, PDF_KIMAGE, obj); + xobj = pdf_finditem(xref->store, PDF_KXOBJECT, obj); if (!img && !xobj) return fz_throw("syntaxerror: missing xobject resource"); @@ -769,7 +770,7 @@ fz_debugobj(rdb); if (!obj) return fz_throw("syntaxerror: missing shading resource"); - shd = pdf_findresource(xref->rshade, obj); + shd = pdf_finditem(xref->store, PDF_KSHADE, obj); if (!shd) return fz_throw("syntaxerror: missing shading resource"); diff --git a/mupdf/open.c b/mupdf/open.c index 46e56802..0dcd1d62 100644 --- a/mupdf/open.c +++ b/mupdf/open.c @@ -534,7 +534,11 @@ pdf_openpdf(pdf_xref **xrefp, char *filename) error = readxrefsections(xref, xref->startxref, buf, sizeof buf); if (error) - return error; + goto cleanup; + + error = pdf_newstore(&xref->store); + if (error) + goto cleanup; *xrefp = xref; return nil; diff --git a/mupdf/repair.c b/mupdf/repair.c index d5ce6584..f342b083 100644 --- a/mupdf/repair.c +++ b/mupdf/repair.c @@ -294,6 +294,10 @@ pdf_repairpdf(pdf_xref **xrefp, char *filename) fz_free(list); + error = pdf_newstore(&xref->store); + if (error) + goto cleanup; + *xrefp = xref; return nil; diff --git a/mupdf/resources.c b/mupdf/resources.c index 2b83e714..73d7cc8a 100644 --- a/mupdf/resources.c +++ b/mupdf/resources.c @@ -1,27 +1,19 @@ #include <fitz.h> #include <mupdf.h> -/* TODO: use binary search ... realizm.pdf */ - -void * -pdf_findresource(pdf_rsrc *rsrc, fz_obj *key) -{ - if (key == nil) - return nil; - while (rsrc) - { - if (!fz_cmpobj(rsrc->key, key)) - return rsrc->val; - rsrc = rsrc->next; - } - return nil; -} - /* -Load resources: Go through resource dictionary and resolve some levels of -indirect references so we end up with a stylized structure: +indirect references so we end up with a stylized structure. +The resources referenced are all pre-loaded which inserts +them into the resource store for later lookup when interpreting +content streams. + +All resources except colorspaces are automatically inserted +in the resource store when they are parsed. For colorspaces +named in resource dictionaries, we have to insert them ourselves +since we cannot take the risk of having to resolve objects +while in the middle of parsing a content stream. << /Font << @@ -51,9 +43,6 @@ indirect references so we end up with a stylized structure: >> >> -Then all references to actual resources will get -parsed and inserted into the pdf_xref resource lists. - */ static fz_error * @@ -61,33 +50,28 @@ preloadcolorspace(pdf_xref *xref, fz_obj *ref) { fz_error *error; fz_colorspace *colorspace; - pdf_rsrc *rsrc; fz_obj *obj = ref; - if (pdf_findresource(xref->rcolorspace, ref)) + if (pdf_finditem(xref->store, PDF_KCOLORSPACE, ref)) return nil; - if (!fz_isindirect(ref)) - pdf_logrsrc("inline colorspace resource\n"); - - rsrc = fz_malloc(sizeof(pdf_rsrc)); - if (!rsrc) - return fz_outofmem; - error = pdf_resolve(&obj, xref); if (error) return error; error = pdf_loadcolorspace(&colorspace, xref, obj); fz_dropobj(obj); - if (error) { - fz_free(rsrc); + if (error) + return error; + + pdf_logrsrc("rsrc colorspace %s\n", colorspace->name); + + error = pdf_storeitem(xref->store, PDF_KCOLORSPACE, ref, colorspace); + if (error) + { + fz_dropcolorspace(colorspace); return error; } - rsrc->key = fz_keepobj(ref); - rsrc->val = colorspace; - rsrc->next = xref->rcolorspace; - xref->rcolorspace = rsrc; return nil; } @@ -95,22 +79,11 @@ static fz_error * preloadpattern(pdf_xref *xref, fz_obj *ref) { fz_error *error; - pdf_rsrc *rsrc; + pdf_pattern *pattern; + fz_shade *shade; fz_obj *type; fz_obj *obj = ref; - if (pdf_findresource(xref->rpattern, ref)) - return nil; - if (pdf_findresource(xref->rshade, ref)) - return nil; - - if (!fz_isindirect(ref)) - pdf_logrsrc("inline pattern resource\n"); - - rsrc = fz_malloc(sizeof(pdf_rsrc)); - if (!rsrc) - return fz_outofmem; - error = pdf_resolve(&obj, xref); if (error) return error; @@ -119,36 +92,21 @@ preloadpattern(pdf_xref *xref, fz_obj *ref) if (fz_toint(type) == 1) { - error = pdf_loadpattern((pdf_pattern**)&rsrc->val, xref, obj, ref); + error = pdf_loadpattern(&pattern, xref, obj, ref); fz_dropobj(obj); - if (error) { - fz_free(rsrc); - return error; - } - rsrc->key = fz_keepobj(ref); - rsrc->next = xref->rpattern; - xref->rpattern = rsrc; - return nil; + return error; } else if (fz_toint(type) == 2) { - error = pdf_loadshade((fz_shade**)&rsrc->val, xref, obj, ref); + error = pdf_loadshade(&shade, xref, obj, ref); fz_dropobj(obj); - if (error) { - fz_free(rsrc); - return error; - } - rsrc->key = fz_keepobj(ref); - rsrc->next = xref->rshade; - xref->rshade = rsrc; - return nil; + return error; } else { fz_dropobj(obj); - fz_free(rsrc); return fz_throw("syntaxerror: unknown Pattern type"); } } @@ -157,56 +115,24 @@ static fz_error * preloadshading(pdf_xref *xref, fz_obj *ref) { fz_error *error; - pdf_rsrc *rsrc; + fz_shade *shade; fz_obj *obj = ref; - - if (pdf_findresource(xref->rshade, ref)) - return nil; - - if (!fz_isindirect(ref)) - pdf_logrsrc("inline shading resource\n"); - - rsrc = fz_malloc(sizeof(pdf_rsrc)); - if (!rsrc) - return fz_outofmem; - error = pdf_resolve(&obj, xref); - if (error) - return error; - - error = pdf_loadshade((fz_shade**)&rsrc->val, xref, obj, ref); + if (error) return error; + error = pdf_loadshade(&shade, xref, obj, ref); fz_dropobj(obj); - if (error) { - fz_free(rsrc); - return error; - } - - rsrc->key = fz_keepobj(ref); - rsrc->next = xref->rshade; - xref->rshade = rsrc; - return nil; + return error; } static fz_error * preloadxobject(pdf_xref *xref, fz_obj *ref) { fz_error *error; - pdf_rsrc *rsrc; + pdf_xobject *xobject; + pdf_image *image; fz_obj *obj = ref; fz_obj *subtype; - if (pdf_findresource(xref->rxobject, ref)) - return nil; - if (pdf_findresource(xref->rimage, ref)) - return nil; - - if (!fz_isindirect(ref)) - pdf_logrsrc("inline xobject resource\n"); - - rsrc = fz_malloc(sizeof(pdf_rsrc)); - if (!rsrc) - return fz_outofmem; - error = pdf_resolve(&obj, xref); if (error) return error; @@ -215,36 +141,21 @@ preloadxobject(pdf_xref *xref, fz_obj *ref) if (!strcmp(fz_toname(subtype), "Form")) { - error = pdf_loadxobject((pdf_xobject**)&rsrc->val, xref, obj, ref); + error = pdf_loadxobject(&xobject, xref, obj, ref); fz_dropobj(obj); - if (error) { - fz_free(rsrc); - return error; - } - rsrc->key = fz_keepobj(ref); - rsrc->next = xref->rxobject; - xref->rxobject = rsrc; - return nil; + return error; } else if (!strcmp(fz_toname(subtype), "Image")) { - error = pdf_loadimage((pdf_image**)&rsrc->val, xref, obj, ref); + error = pdf_loadimage(&image, xref, obj, ref); fz_dropobj(obj); - if (error) { - fz_free(rsrc); - return error; - } - rsrc->key = fz_keepobj(ref); - rsrc->next = xref->rimage; - xref->rimage = rsrc; - return nil; + return error; } else { fz_dropobj(obj); - fz_free(rsrc); return fz_throw("syntaxerror: unknown XObject subtype"); } } @@ -254,34 +165,12 @@ preloadfont(pdf_xref *xref, fz_obj *ref) { fz_error *error; pdf_font *font; - pdf_rsrc *rsrc; fz_obj *obj = ref; - - if (pdf_findresource(xref->rfont, ref)) - return nil; - - if (!fz_isindirect(ref)) - pdf_logrsrc("inline font resource\n"); - - rsrc = fz_malloc(sizeof(pdf_rsrc)); - if (!rsrc) - return fz_outofmem; - error = pdf_resolve(&obj, xref); if (error) return error; - error = pdf_loadfont(&font, xref, obj); - fz_dropobj(obj); - if (error) { - fz_free(rsrc); - return error; - } - - rsrc->key = fz_keepobj(ref); - rsrc->val = font; - rsrc->next = xref->rfont; - xref->rfont = rsrc; - return nil; + error = pdf_loadfont(&font, xref, obj, ref); + return error; } static fz_error * diff --git a/mupdf/shade.c b/mupdf/shade.c index 472390bc..0473e33f 100644 --- a/mupdf/shade.c +++ b/mupdf/shade.c @@ -89,7 +89,7 @@ cleanup: fz_error * pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *obj, fz_obj *ref) { - fz_error *error; + fz_error *error = fz_throw("NYI"); fz_shade *shade; fz_obj *shading; diff --git a/mupdf/store.c b/mupdf/store.c new file mode 100644 index 00000000..03dee670 --- /dev/null +++ b/mupdf/store.c @@ -0,0 +1,81 @@ +#include <fitz.h> +#include <mupdf.h> + +typedef struct pdf_item_s pdf_item; + +struct pdf_item_s +{ + pdf_itemkind kind; + fz_obj *key; + void *val; + pdf_item *next; +}; + +struct pdf_store_s +{ + int len; + int cap; + pdf_item *root; +}; + +fz_error * +pdf_newstore(pdf_store **storep) +{ + pdf_store *store; + + store = fz_malloc(sizeof(pdf_store)); + if (!store) + return fz_outofmem; + + store->root = nil; + + *storep = store; + return nil; +} + +void +pdf_dropstore(pdf_store *store) +{ + /* TODO */ +} + +fz_error * +pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val) +{ + pdf_item *item; + + item = fz_malloc(sizeof(pdf_item)); + if (!item) + return fz_outofmem; + + pdf_logrsrc("store item %d: %p\n", kind, val); + + item->kind = kind; + item->key = fz_keepobj(key); + item->val = val; /* heh. should do *keep() here */ + + item->next = store->root; + store->root = item; + return nil; +} + +void * +pdf_finditem(pdf_store *store, pdf_itemkind kind, fz_obj *key) +{ + pdf_item *item; + + if (key == nil) + return nil; + + for (item = store->root; item; item = item->next) + { + if (item->kind == kind && !fz_cmpobj(item->key, key)) + { + pdf_logrsrc("find item %d: %p\n", kind, item->val); + return item->val; + } + } + + return nil; +} + diff --git a/mupdf/type3.c b/mupdf/type3.c index 9999c07c..5927b8ba 100644 --- a/mupdf/type3.c +++ b/mupdf/type3.c @@ -86,7 +86,7 @@ loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) } fz_error * -pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) +pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) { fz_error *error; char buf[256]; @@ -111,7 +111,7 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) if (!font) return fz_outofmem; - pdf_logfont("load type3 font %p {\n", font); + pdf_logfont("load type3 font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font); pdf_logfont("name %s\n", buf); font->super.render = t3render; diff --git a/mupdf/xobject.c b/mupdf/xobject.c index bd17235b..e0e1fd2f 100644 --- a/mupdf/xobject.c +++ b/mupdf/xobject.c @@ -8,6 +8,9 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) pdf_xobject *form; fz_obj *obj; + if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, ref))) + return nil; + form = fz_malloc(sizeof(pdf_xobject)); if (!form) return fz_outofmem; @@ -54,6 +57,7 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) fz_dropobj(obj); } + form->contents = nil; error = pdf_loadstream(&form->contents, xref, fz_tonum(ref), fz_togen(ref)); if (error) { @@ -66,6 +70,15 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) pdf_logrsrc("}\n"); + error = pdf_storeitem(xref->store, PDF_KXOBJECT, ref, form); + if (error) + { + fz_dropbuffer(form->contents); + fz_dropobj(form->resources); + fz_free(form); + return error; + } + *formp = form; return nil; } diff --git a/mupdf/xref.c b/mupdf/xref.c index c1ed230e..a4be93f2 100644 --- a/mupdf/xref.c +++ b/mupdf/xref.c @@ -8,6 +8,7 @@ fz_error * pdf_newpdf(pdf_xref **xrefp) { + fz_error *error; pdf_xref *xref; xref = fz_malloc(sizeof(pdf_xref)); @@ -39,6 +40,13 @@ pdf_newpdf(pdf_xref **xrefp) xref->table[0].stmofs = 0; xref->table[0].obj = nil; + error = pdf_newstore(&xref->store); + if (error) + { + pdf_closepdf(xref); + return error; + } + *xrefp = xref; return nil; } @@ -82,6 +90,9 @@ pdf_closepdf(pdf_xref *xref) pdf_logxref("closexref %p\n", xref); + if (xref->store) + pdf_dropstore(xref->store); + if (xref->table) { for (i = 0; i < xref->len; i++) diff --git a/render/rastshade.c b/render/rastshade.c index 89a06f40..4affae36 100644 --- a/render/rastshade.c +++ b/render/rastshade.c @@ -1,5 +1,4 @@ #include <fitz.h> -#include <mupdf.h> fz_error * fz_rendershade1(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp, int over) |