summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-12-01 06:52:32 +0100
committerTor Andersson <tor@ghostscript.com>2004-12-01 06:52:32 +0100
commit615d27315a131bea0df699c3daa1102289b433c6 (patch)
treeabf1a1f17ff332db226ed48606f26fd5f0d7e8c3
parent4e4e30e57fb4170f3a9dd0a9c23da78c2b46a69f (diff)
downloadmupdf-615d27315a131bea0df699c3daa1102289b433c6.tar.xz
refactor resource loading and item store
-rw-r--r--Jamfile18
-rw-r--r--TODO3
-rw-r--r--include/mupdf/rsrc.h35
-rw-r--r--include/mupdf/xref.h9
-rw-r--r--mupdf/cmap.c11
-rw-r--r--mupdf/colorspace1.c8
-rw-r--r--mupdf/font.c43
-rw-r--r--mupdf/function.c27
-rw-r--r--mupdf/image.c33
-rw-r--r--mupdf/interpret.c17
-rw-r--r--mupdf/open.c6
-rw-r--r--mupdf/repair.c4
-rw-r--r--mupdf/resources.c187
-rw-r--r--mupdf/shade.c2
-rw-r--r--mupdf/store.c81
-rw-r--r--mupdf/type3.c4
-rw-r--r--mupdf/xobject.c13
-rw-r--r--mupdf/xref.c11
-rw-r--r--render/rastshade.c1
19 files changed, 282 insertions, 231 deletions
diff --git a/Jamfile b/Jamfile
index a8c24719..df98e735 100644
--- a/Jamfile
+++ b/Jamfile
@@ -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
diff --git a/TODO b/TODO
index 6722d6f9..29504752 100644
--- a/TODO
+++ b/TODO
@@ -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)