summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-12-13 09:37:48 +0100
committerTor Andersson <tor@ghostscript.com>2004-12-13 09:37:48 +0100
commit72976993f5b39d9ee1599dc89961288b297cdc62 (patch)
tree131098a8e8c2de04766181aeddc8a13aebb2981d
parent690dabe2db5f440b9bbb4c4eecbeeb77635a22b4 (diff)
downloadmupdf-72976993f5b39d9ee1599dc89961288b297cdc62.tar.xz
clean up nametree and outlines
-rw-r--r--Jamfile6
-rw-r--r--TODO58
-rw-r--r--base/matrix.c2
-rw-r--r--include/fitz/object.h15
-rw-r--r--include/mupdf/annot.h23
-rw-r--r--include/mupdf/page.h42
-rw-r--r--include/mupdf/rsrc.h1
-rw-r--r--include/mupdf/syntax.h1
-rw-r--r--include/mupdf/xref.h28
-rw-r--r--mupdf/annot.c94
-rw-r--r--mupdf/build.c4
-rw-r--r--mupdf/colorspace1.c4
-rw-r--r--mupdf/crypt.c16
-rw-r--r--mupdf/font.c8
-rw-r--r--mupdf/fontenc.c36
-rw-r--r--mupdf/fontfile.c4
-rw-r--r--mupdf/nametree.c147
-rw-r--r--mupdf/open.c46
-rw-r--r--mupdf/outline.c244
-rw-r--r--mupdf/parse.c49
-rw-r--r--mupdf/repair.c36
-rw-r--r--mupdf/save.c4
-rw-r--r--mupdf/store.c2
-rw-r--r--mupdf/xref.c134
-rw-r--r--object/dict.c151
-rw-r--r--object/simple.c26
-rw-r--r--test/pdfclean.c14
-rw-r--r--test/pdfdebug.c26
-rw-r--r--test/x11pdf.c65
29 files changed, 647 insertions, 639 deletions
diff --git a/Jamfile b/Jamfile
index 51c268f5..699e9a3e 100644
--- a/Jamfile
+++ b/Jamfile
@@ -205,9 +205,9 @@ LINKLIBS on x11pdf = -lX11 -lXext $(LINKLIBS) ;
Main pdfclean : test/pdfclean.c ;
Main pdfdebug : test/pdfdebug.c ;
-Main pdfmerge : test/pdfmerge.c ;
-Main pdfrip : test/pdfrip.c ;
-Main pdffunction : test/pdffunction.c ;
+# Main pdfmerge : test/pdfmerge.c ;
+# Main pdfrip : test/pdfrip.c ;
+# Main pdffunction : test/pdffunction.c ;
Main x11pdf : test/x11pdf.c test/ximage.c ;
diff --git a/TODO b/TODO
index 2cb87096..2fbfd259 100644
--- a/TODO
+++ b/TODO
@@ -1,36 +1,34 @@
immediate plan:
- + refactor xref init
- + loadlowlevel
- + loadhighlevel
- - load name trees
- - load page tree
- - load outline
-
- - altivec optimize
- - design gui for editor
- - go through spec and check all features!
- - talk to keithp about fontconfig cid-font + cmap support
+ * design gui for editor
+ * libfontfocus
+ * write mupdf hackers guide
+ * clean up and 'freeze' public api
- * page labels + dests + outline + annots
+ * refactor image loading
+ * refactor xref loading/repair
+ * restructure build.c and interpret.c (ftb vs csi)
+ * fix the colorspace/pattern/shading material mess
+ * font loading:
+ - configuration... where to find system files (asian font archive?)
+ - system fontfile + cmap store
+ - embedded fontfile store
+ - split type3 and ftfont malloc (dont waste t3 charprocs on ft fonts)
+ - make ftfontfile separate struct w/ refcounting
+ - refactor font loading more. simple/cid/type3 have too much in common.
- * libfontfocus
+ * structure low/high level stuff
+ - rewrite outline parser
+ - implement comments
- * font and cmap config (where to load cmap and which cid fonts)
- - global fontfile/cmap cache
- - unify handling of mallocing fonts and images
- - split type3 and ftfont malloc (dont waste t3 charprocs on ft fonts)
- - make ftfontfile separate struct w/ refcounting
- - refactor font loading more. simple/cid/type3 have too much in common.
- fix default .fonts.conf for base14 fonts
- fix default .fonts.conf for asian fonts
- maybe add CMap directory entry to fontconfig?
+ * clean high-level api
- * clean up and 'freeze' public api
+ - go through spec and check all features!
+ - altivec optimize
---
-std rsrc fmt
+std rsrc fmt (v3)
transparency (v2)
- everything!
@@ -47,24 +45,14 @@ image rendering (v2)
- better filter than box
- lazy decoding
-shadings
- - ... jeong ...
-
rendering
- fix glyphcache evictlast
- bbox culling per glyph
- font focus
-
-parser
- - try to clean up colorspace/material handling in interpreter
- - annotations and destinations (for links and outline)
+ - render cache (link-nodes and scaled images and colorspaced shades)
fz_optimizetree()
- error & memory
- concatenate chained transforms
- remove identity transforms
-cache
- global cache for cmaps and fontfiles (emb+sys)
- render cache (link-nodes and scaled images and shades)
-
diff --git a/base/matrix.c b/base/matrix.c
index b0513940..7d7097c4 100644
--- a/base/matrix.c
+++ b/base/matrix.c
@@ -133,8 +133,6 @@ fz_transformaabb(fz_matrix m, fz_rect r)
if (fz_isinfiniterect(r))
return r;
- if (fz_isemptyrect(r))
- return r;
s.x = r.min.x; s.y = r.min.y;
t.x = r.min.x; t.y = r.max.y;
diff --git a/include/fitz/object.h b/include/fitz/object.h
index 015f1e74..34b62f59 100644
--- a/include/fitz/object.h
+++ b/include/fitz/object.h
@@ -1,4 +1,5 @@
typedef struct fz_obj_s fz_obj;
+typedef struct fz_keyval_s fz_keyval;
typedef enum fz_objkind_e
{
@@ -23,7 +24,7 @@ struct fz_keyval_s
struct fz_obj_s
{
unsigned short refs;
- unsigned short kind; /* fz_objkind takes 4 bytes :( */
+ char kind; /* fz_objkind takes 4 bytes :( */
union
{
int b;
@@ -40,9 +41,10 @@ struct fz_obj_s
fz_obj **items;
} a;
struct {
+ char sorted;
int len;
int cap;
- struct fz_keyval_s *items;
+ fz_keyval *items;
} d;
struct {
int oid;
@@ -83,19 +85,21 @@ int fz_isdict(fz_obj *obj);
int fz_isindirect(fz_obj *obj);
int fz_ispointer(fz_obj *obj);
-int fz_cmpobj(fz_obj *a, fz_obj *b);
+int fz_objcmp(fz_obj *a, fz_obj *b);
/* silent failure, no error reporting */
int fz_tobool(fz_obj *obj);
int fz_toint(fz_obj *obj);
float fz_toreal(fz_obj *obj);
char *fz_toname(fz_obj *obj);
-char *fz_tostringbuf(fz_obj *obj);
-int fz_tostringlen(fz_obj *obj);
+char *fz_tostrbuf(fz_obj *obj);
+int fz_tostrlen(fz_obj *obj);
int fz_tonum(fz_obj *obj);
int fz_togen(fz_obj *obj);
void *fz_topointer(fz_obj *obj);
+fz_error *fz_newnamefromstring(fz_obj **op, fz_obj *str);
+
int fz_arraylen(fz_obj *array);
fz_obj *fz_arrayget(fz_obj *array, int i);
fz_error *fz_arrayput(fz_obj *array, int i, fz_obj *obj);
@@ -111,6 +115,7 @@ fz_error *fz_dictput(fz_obj *dict, fz_obj *key, fz_obj *val);
fz_error *fz_dictputs(fz_obj *dict, char *key, fz_obj *val);
fz_error *fz_dictdel(fz_obj *dict, fz_obj *key);
fz_error *fz_dictdels(fz_obj *dict, char *key);
+void fz_sortdict(fz_obj *dict);
int fz_sprintobj(char *s, int n, fz_obj *obj, int tight);
void fz_debugobj(fz_obj *obj);
diff --git a/include/mupdf/annot.h b/include/mupdf/annot.h
index ac017735..47e7a9f8 100644
--- a/include/mupdf/annot.h
+++ b/include/mupdf/annot.h
@@ -5,6 +5,7 @@
typedef struct pdf_link_s pdf_link;
typedef struct pdf_comment_s pdf_comment;
typedef struct pdf_widget_s pdf_widget;
+typedef struct pdf_outline_s pdf_outline;
typedef enum pdf_linkkind_e
{
@@ -16,9 +17,7 @@ struct pdf_link_s
{
pdf_linkkind kind;
fz_rect rect;
- fz_obj *page;
- fz_obj *uri;
- int ismap;
+ fz_obj *dest;
pdf_link *next;
};
@@ -46,8 +45,24 @@ struct pdf_comment_s
pdf_comment *next;
};
-fz_error * pdf_newlink(pdf_link**, fz_rect rect, int ismap, fz_obj *page, fz_obj *uri);
+struct pdf_outline_s
+{
+ char *title;
+ pdf_link *link;
+ pdf_outline *child;
+ pdf_outline *next;
+};
+
+fz_error *pdf_loadnametree(fz_obj **dictp, pdf_xref *xref, fz_obj *root);
+fz_error *pdf_loadnametrees(pdf_xref *xref);
+
+fz_error *pdf_newlink(pdf_link**, fz_rect rect, fz_obj *dest);
+fz_error *pdf_loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict);
void pdf_droplink(pdf_link *link);
+fz_error *pdf_loadoutline(pdf_outline **outlinep, pdf_xref *xref);
+void pdf_debugoutline(pdf_outline *outline, int level);
+void pdf_dropoutline(pdf_outline *outline);
+
fz_error *pdf_loadannots(pdf_comment **, pdf_link **, pdf_xref *, fz_obj *annots);
diff --git a/include/mupdf/page.h b/include/mupdf/page.h
index f027ac89..648fe54d 100644
--- a/include/mupdf/page.h
+++ b/include/mupdf/page.h
@@ -2,40 +2,11 @@
* Page tree, pages and related objects
*/
-typedef struct pdf_outlinetree_s pdf_outlinetree;
-typedef struct pdf_outline_s pdf_outline;
-typedef struct pdf_nametree_s pdf_nametree;
typedef struct pdf_pagetree_s pdf_pagetree;
typedef struct pdf_page_s pdf_page;
typedef struct pdf_textline_s pdf_textline;
typedef struct pdf_textchar_s pdf_textchar;
-struct pdf_outlinetree_s
-{
- pdf_outline *first;
- int count;
-};
-
-struct pdf_outline_s
-{
- char *title;
- pdf_outline *next;
- pdf_outline *first;
- int count;
- fz_obj *dest;
- fz_obj *a;
- fz_obj *se;
- float c[3];
- int f;
-};
-
-struct pdf_nametree_s
-{
- int len;
- int cap;
- struct fz_keyval_s *items;
-};
-
struct pdf_pagetree_s
{
int count;
@@ -67,19 +38,6 @@ struct pdf_textline_s
pdf_textline *next;
};
-/* outline.c */
-fz_error *pdf_loadoutlinetree(pdf_outlinetree **oo, pdf_xref *xref);
-void pdf_debugoutlinetree(pdf_outlinetree *outlinetree);
-void pdf_dropoutlinetree(pdf_outlinetree *outlinetree);
-
-/* nametree.c */
-fz_error *pdf_loadnametrees(pdf_xref *xref);
-fz_error *pdf_loadnametree(pdf_nametree **treep, pdf_xref *xref, fz_obj *root);
-void pdf_dropnametree(pdf_nametree *tree);
-void pdf_debugnametree(pdf_nametree *tree);
-fz_obj *pdf_lookupname(pdf_nametree *tree, fz_obj *name);
-fz_obj *pdf_lookupnames(pdf_nametree *tree, char *name);
-
/* pagetree.c */
fz_error *pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref);
int pdf_getpagecount(pdf_pagetree *pages);
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 29c8fa97..34aefea2 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -150,6 +150,7 @@ extern int pdf_adobeglyphlen;
void pdf_loadencoding(char **estrings, char *encoding);
int pdf_lookupagl(char *name);
+extern unsigned short pdf_docencoding[256];
extern char *pdf_macroman[256];
extern char *pdf_macexpert[256];
extern char *pdf_winansi[256];
diff --git a/include/mupdf/syntax.h b/include/mupdf/syntax.h
index 786147bd..c25dcb01 100644
--- a/include/mupdf/syntax.h
+++ b/include/mupdf/syntax.h
@@ -27,6 +27,7 @@ fz_error *pdf_parseindobj(fz_obj **op, fz_file *f, char *buf, int cap, int *oid,
fz_rect pdf_torect(fz_obj *array);
fz_matrix pdf_tomatrix(fz_obj *array);
+fz_error *pdf_toutf8(char **dstp, fz_obj *src);
/*
* Encryption
diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h
index 3721e09a..98f45a39 100644
--- a/include/mupdf/xref.h
+++ b/include/mupdf/xref.h
@@ -11,15 +11,20 @@ struct pdf_xref_s
fz_file *stream;
float version;
int startxref;
- fz_obj *trailer; /* TODO split this into root/info/encrypt/id */
pdf_crypt *crypt;
+ fz_obj *trailer; /* TODO split this into root/info/encrypt/id */
+ fz_obj *root; /* resolved catalog dict */
+ fz_obj *info; /* resolved info dict */
+ fz_obj *dests; /* flattened dests nametree */
+
int len;
int cap;
pdf_xrefentry *table;
- struct pdf_nametree_s *dests;
struct pdf_store_s *store;
+ struct pdf_pagetree_s *pages;
+ struct pdf_outline_s *outlines;
};
struct pdf_xrefentry_s
@@ -33,16 +38,17 @@ struct pdf_xrefentry_s
fz_obj *obj; /* stored/cached object */
};
-fz_error *pdf_repairpdf(pdf_xref **, char *filename);
-fz_error *pdf_openpdf(pdf_xref **, char *filename);
-fz_error *pdf_newpdf(pdf_xref **);
+fz_error *pdf_newxref(pdf_xref **);
+fz_error *pdf_repairxref(pdf_xref *, char *filename);
+fz_error *pdf_loadxref(pdf_xref *, char *filename);
-fz_error *pdf_updatepdf(pdf_xref *, char *filename);
-fz_error *pdf_savepdf(pdf_xref *, char *filename, pdf_crypt *encrypt);
+fz_error *pdf_openpdf(pdf_xref **, char *filename);
+fz_error *pdf_updatexref(pdf_xref *, char *filename);
+fz_error *pdf_savexref(pdf_xref *, char *filename, pdf_crypt *encrypt);
-void pdf_debugpdf(pdf_xref *);
-void pdf_flushpdf(pdf_xref *, int force);
-void pdf_closepdf(pdf_xref *);
+void pdf_debugxref(pdf_xref *);
+void pdf_flushxref(pdf_xref *, int force);
+void pdf_closexref(pdf_xref *);
fz_error *pdf_allocobject(pdf_xref *, int *oidp, int *genp);
fz_error *pdf_deleteobject(pdf_xref *, int oid, int gen);
@@ -67,5 +73,5 @@ fz_error *pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *ol
/* private */
fz_error *pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap);
-fz_error *pdf_decryptpdf(pdf_xref *xref);
+fz_error *pdf_decryptxref(pdf_xref *xref);
diff --git a/mupdf/annot.c b/mupdf/annot.c
index 0f8acf6f..055dae75 100644
--- a/mupdf/annot.c
+++ b/mupdf/annot.c
@@ -8,7 +8,7 @@ loadcomment(pdf_comment **commentp, pdf_xref *xref, fz_obj *dict)
}
fz_error *
-pdf_newlink(pdf_link **linkp, fz_rect bbox, int ismap, fz_obj *page, fz_obj *uri)
+pdf_newlink(pdf_link **linkp, fz_rect bbox, fz_obj *dest)
{
pdf_link *link;
@@ -17,9 +17,7 @@ pdf_newlink(pdf_link **linkp, fz_rect bbox, int ismap, fz_obj *page, fz_obj *uri
return fz_outofmem;
link->rect = bbox;
- link->ismap = ismap;
- link->page = page ? fz_keepobj(page) : nil;
- link->uri = uri ? fz_keepobj(uri) : nil;
+ link->dest = fz_keepobj(dest);
link->next = nil;
*linkp = link;
@@ -31,27 +29,27 @@ pdf_droplink(pdf_link *link)
{
if (link->next)
pdf_droplink(link->next);
- if (link->page)
- fz_dropobj(link->page);
- if (link->uri)
- fz_dropobj(link->uri);
+ if (link->dest)
+ fz_dropobj(link->dest);
fz_free(link);
}
static fz_obj *
resolvedest(pdf_xref *xref, fz_obj *dest)
{
- if (fz_isname(dest) && xref->dests)
+ if (fz_isname(dest))
{
- dest = pdf_lookupname(xref->dests, dest);
- pdf_resolve(&dest, xref); /* XXX */
+ dest = fz_dictget(xref->dests, dest);
+ if (dest)
+ pdf_resolve(&dest, xref); /* XXX */
return resolvedest(xref, dest);
}
- else if (fz_isstring(dest) && xref->dests)
+ else if (fz_isstring(dest))
{
- dest = pdf_lookupname(xref->dests, dest);
- pdf_resolve(&dest, xref); /* XXX */
+ dest = fz_dictget(xref->dests, dest);
+ if (dest)
+ pdf_resolve(&dest, xref); /* XXX */
return resolvedest(xref, dest);
}
@@ -72,30 +70,31 @@ resolvedest(pdf_xref *xref, fz_obj *dest)
return nil;
}
-static fz_error *
-loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict)
+fz_error *
+pdf_loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict)
{
fz_error *error;
pdf_link *link;
- fz_obj *page;
- fz_obj *uri;
+ fz_obj *dest;
fz_obj *action;
fz_obj *obj;
fz_rect bbox;
- int ismap;
pdf_logpage("load link {\n");
link = nil;
- page = nil;
- uri = nil;
- ismap = 0;
+ dest = nil;
obj = fz_dictgets(dict, "Rect");
- bbox = pdf_torect(obj);
- pdf_logpage("rect [%g %g %g %g]\n",
- bbox.min.x, bbox.min.y,
- bbox.max.x, bbox.max.y);
+ if (obj)
+ {
+ bbox = pdf_torect(obj);
+ pdf_logpage("rect [%g %g %g %g]\n",
+ bbox.min.x, bbox.min.y,
+ bbox.max.x, bbox.max.y);
+ }
+ else
+ bbox = fz_emptyrect;
obj = fz_dictgets(dict, "Dest");
if (obj)
@@ -103,8 +102,8 @@ loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict)
error = pdf_resolve(&obj, xref);
if (error)
return error;
- page = resolvedest(xref, obj);
- pdf_logpage("dest %d %d R\n", fz_tonum(page), fz_togen(page));
+ dest = resolvedest(xref, obj);
+ pdf_logpage("dest %d %d R\n", fz_tonum(dest), fz_togen(dest));
fz_dropobj(obj);
}
@@ -118,14 +117,13 @@ loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict)
obj = fz_dictgets(action, "S");
if (!strcmp(fz_toname(obj), "GoTo"))
{
- page = resolvedest(xref, fz_dictgets(action, "D"));
- pdf_logpage("action goto %d %d R\n", fz_tonum(page), fz_togen(page));
+ dest = resolvedest(xref, fz_dictgets(action, "D"));
+ pdf_logpage("action goto %d %d R\n", fz_tonum(dest), fz_togen(dest));
}
else if (!strcmp(fz_toname(obj), "URI"))
{
- uri = fz_dictgets(action, "URI");
- ismap = fz_tobool(fz_dictgets(action, "IsMap"));
- pdf_logpage("action uri ismap=%d\n", ismap);
+ dest = fz_dictgets(action, "URI");
+ pdf_logpage("action uri %s\n", fz_tostrbuf(dest));
}
else
pdf_logpage("action ... ?\n");
@@ -135,12 +133,11 @@ loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict)
pdf_logpage("}\n");
- if (page || uri)
+ if (dest)
{
- error = pdf_newlink(&link, bbox, ismap, page, uri);
+ error = pdf_newlink(&link, bbox, dest);
if (error)
return error;
- link->next = *linkp;
*linkp = link;
}
@@ -171,14 +168,27 @@ pdf_loadannots(pdf_comment **cp, pdf_link **lp, pdf_xref *xref, fz_obj *annots)
subtype = fz_dictgets(obj, "Subtype");
if (!strcmp(fz_toname(subtype), "Link"))
- error = loadlink(&link, xref, obj);
+ {
+ pdf_link *temp = nil;
+
+ error = pdf_loadlink(&temp, xref, obj);
+ fz_dropobj(obj);
+ if (error)
+ goto cleanup;
+
+ if (temp)
+ {
+ temp->next = link;
+ link = temp;
+ }
+ }
else
+ {
error = loadcomment(&comment, xref, obj);
-
- fz_dropobj(obj);
-
- if (error)
- goto cleanup;
+ fz_dropobj(obj);
+ if (error)
+ goto cleanup;
+ }
}
pdf_logpage("}\n");
diff --git a/mupdf/build.c b/mupdf/build.c
index 93d1a26d..2c56e484 100644
--- a/mupdf/build.c
+++ b/mupdf/build.c
@@ -770,8 +770,8 @@ pdf_showtext(pdf_csi *csi, fz_obj *text)
return nil;
}
- buf = fz_tostringbuf(text);
- len = fz_tostringlen(text);
+ buf = fz_tostrbuf(text);
+ len = fz_tostrlen(text);
end = buf + len;
while (buf < end)
diff --git a/mupdf/colorspace1.c b/mupdf/colorspace1.c
index e9c384b9..e98beaa1 100644
--- a/mupdf/colorspace1.c
+++ b/mupdf/colorspace1.c
@@ -617,14 +617,14 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
return fz_outofmem;
}
- if (fz_isstring(lookup) && fz_tostringlen(lookup) == n)
+ if (fz_isstring(lookup) && fz_tostrlen(lookup) == n)
{
unsigned char *buf;
int i;
pdf_logrsrc("string lookup\n");
- buf = fz_tostringbuf(lookup);
+ buf = fz_tostrbuf(lookup);
for (i = 0; i < n; i++)
cs->lookup[i] = buf[i];
}
diff --git a/mupdf/crypt.c b/mupdf/crypt.c
index 03633c9e..d0cf1084 100644
--- a/mupdf/crypt.c
+++ b/mupdf/crypt.c
@@ -70,14 +70,14 @@ pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
crypt->id = nil;
obj = fz_dictgets(enc, "O");
- if (!fz_isstring(obj) || fz_tostringlen(obj) != 32)
+ if (!fz_isstring(obj) || fz_tostrlen(obj) != 32)
goto cleanup;
- memcpy(crypt->o, fz_tostringbuf(obj), 32);
+ memcpy(crypt->o, fz_tostrbuf(obj), 32);
obj = fz_dictgets(enc, "U");
- if (!fz_isstring(obj) || fz_tostringlen(obj) != 32)
+ if (!fz_isstring(obj) || fz_tostrlen(obj) != 32)
goto cleanup;
- memcpy(crypt->u, fz_tostringbuf(obj), 32);
+ memcpy(crypt->u, fz_tostrbuf(obj), 32);
obj = fz_dictgets(enc, "P");
if (!fz_isint(obj))
@@ -179,7 +179,7 @@ createkey(pdf_crypt *crypt, char *userpw)
fz_md5update(&md5, buf, 4);
/* Step 5 */
- fz_md5update(&md5, fz_tostringbuf(crypt->id), fz_tostringlen(crypt->id));
+ fz_md5update(&md5, fz_tostrbuf(crypt->id), fz_tostrlen(crypt->id));
fz_md5final(&md5, crypt->key);
/* Step 6 (rev 3 only) */
@@ -255,7 +255,7 @@ createuser(pdf_crypt *crypt, char *userpw)
fz_md5update(&md5, padding, 32);
/* Step 3 */
- fz_md5update(&md5, fz_tostringbuf(crypt->id), fz_tostringlen(crypt->id));
+ fz_md5update(&md5, fz_tostrbuf(crypt->id), fz_tostrlen(crypt->id));
fz_md5final(&md5, key);
/* Step 4 */
@@ -349,8 +349,8 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid)
int i, n;
if (fz_isstring(obj)) {
- s = fz_tostringbuf(obj);
- n = fz_tostringlen(obj);
+ s = fz_tostrbuf(obj);
+ n = fz_tostrlen(obj);
createobjkey(crypt, oid, gid, key);
fz_arc4init(&arc4, key, crypt->keylen);
fz_arc4encrypt(&arc4, s, s, n);
diff --git a/mupdf/font.c b/mupdf/font.c
index 5c6aac57..d92ffe50 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -604,16 +604,16 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
return error;
obj = fz_dictgets(cidinfo, "Registry");
- tmplen = MIN(sizeof tmpstr - 1, fz_tostringlen(obj));
- memcpy(tmpstr, fz_tostringbuf(obj), tmplen);
+ tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj));
+ memcpy(tmpstr, fz_tostrbuf(obj), tmplen);
tmpstr[tmplen] = '\0';
strlcpy(collection, tmpstr, sizeof collection);
strlcat(collection, "-", sizeof collection);
obj = fz_dictgets(cidinfo, "Ordering");
- tmplen = MIN(sizeof tmpstr - 1, fz_tostringlen(obj));
- memcpy(tmpstr, fz_tostringbuf(obj), tmplen);
+ tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj));
+ memcpy(tmpstr, fz_tostrbuf(obj), tmplen);
tmpstr[tmplen] = '\0';
strlcat(collection, tmpstr, sizeof collection);
diff --git a/mupdf/fontenc.c b/mupdf/fontenc.c
index cdf082d7..7de7b5e9 100644
--- a/mupdf/fontenc.c
+++ b/mupdf/fontenc.c
@@ -24,6 +24,42 @@ void pdf_loadencoding(char **estrings, char *encoding)
estrings[i] = bstrings[i];
}
+unsigned short pdf_docencoding[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000,
+ 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044,
+ 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
+ 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160,
+ 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000,
+ 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+ 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+};
+
char *pdf_macroman[256] = { _notdef, _notdef,
_notdef, _notdef, _notdef, _notdef, _notdef, _notdef,
_notdef, _notdef, _notdef, _notdef, _notdef, _notdef,
diff --git a/mupdf/fontfile.c b/mupdf/fontfile.c
index e5e4e3a8..5c894c75 100644
--- a/mupdf/fontfile.c
+++ b/mupdf/fontfile.c
@@ -83,10 +83,10 @@ static struct subent fontsubs[] =
{ GB, MINCHO, "mingliu.ttc" },
{ GB, GOTHIC, "mingliu.ttc" },
- { Japan, MINCHO, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\346\230\216\346\234\235 Pro W3.otf" },
- { Japan, GOTHIC, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\350\247\222\343\202\263\343\202\231 Pro W3.otf" },
{ Japan, MINCHO, "kochi-mincho.ttf" },
{ Japan, GOTHIC, "kochi-gothic.ttf" },
+ { Japan, MINCHO, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\346\230\216\346\234\235 Pro W3.otf" },
+ { Japan, GOTHIC, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\350\247\222\343\202\263\343\202\231 Pro W3.otf" },
{ Japan, MINCHO, "msmincho.ttc" },
{ Japan, GOTHIC, "msgothic.ttc" },
diff --git a/mupdf/nametree.c b/mupdf/nametree.c
index b806ec83..1b766e64 100644
--- a/mupdf/nametree.c
+++ b/mupdf/nametree.c
@@ -2,24 +2,7 @@
#include <mupdf.h>
static fz_error *
-grownametree(pdf_nametree *tree, int amount)
-{
- struct fz_keyval_s *newitems;
- int newcap;
-
- newcap = tree->cap + amount;
- newitems = fz_realloc(tree->items, sizeof(struct fz_keyval_s) * newcap);
- if (!newitems)
- return fz_outofmem;
-
- tree->items = newitems;
- tree->cap = newcap;
-
- return nil;
-}
-
-static fz_error *
-loadnametreenode(pdf_nametree *tree, pdf_xref *xref, fz_obj *node)
+loadnametreenode(fz_obj *tree, pdf_xref *xref, fz_obj *node)
{
fz_error *error;
fz_obj *names;
@@ -41,21 +24,16 @@ loadnametreenode(pdf_nametree *tree, pdf_xref *xref, fz_obj *node)
len = fz_arraylen(names) / 2;
- error = grownametree(tree, len);
- if (error)
- {
- fz_dropobj(names);
- goto cleanup;
- }
-
for (i = 0; i < len; ++i)
{
key = fz_arrayget(names, i * 2 + 0);
val = fz_arrayget(names, i * 2 + 1);
-
- tree->items[tree->len].k = fz_keepobj(key);
- tree->items[tree->len].v = fz_keepobj(val);
- tree->len ++;
+ error = fz_dictput(tree, key, val);
+ if (error)
+ {
+ fz_dropobj(names);
+ goto cleanup;
+ }
}
fz_dropobj(names);
@@ -90,130 +68,61 @@ cleanup:
return error;
}
-void
-pdf_dropnametree(pdf_nametree *tree)
-{
- int i;
- for (i = 0; i < tree->len; i++)
- {
- fz_dropobj(tree->items[i].k);
- fz_dropobj(tree->items[i].v);
- }
- fz_free(tree->items);
- fz_free(tree);
-}
-
fz_error *
-pdf_loadnametree(pdf_nametree **treep, pdf_xref *xref, fz_obj *root)
+pdf_loadnametree(fz_obj **dictp, pdf_xref *xref, fz_obj *root)
{
fz_error *error;
- pdf_nametree *tree;
-
- tree = fz_malloc(sizeof(pdf_nametree));
- if (!tree)
- return fz_outofmem;
+ fz_obj *tree;
- tree->len = 0;
- tree->cap = 0;
- tree->items = nil;
+ error = fz_newdict(&tree, 128);
+ if (error)
+ return error;
error = loadnametreenode(tree, xref, root);
if (error)
{
- pdf_dropnametree(tree);
+ fz_dropobj(tree);
return error;
}
- *treep = tree;
- return nil;
-}
-
-void
-pdf_debugnametree(pdf_nametree *tree)
-{
- int i;
- for (i = 0; i < tree->len; i++) {
- printf(" ");
- fz_debugobj(tree->items[i].k);
- printf(" ");
- fz_debugobj(tree->items[i].v);
- printf("\n");
- }
-}
-
-static fz_obj *
-lookup(pdf_nametree *tree, char *namestr, int namelen)
-{
- int l = 0;
- int r = tree->len - 1;
-
- while (l <= r)
- {
- int m = (l + r) >> 1;
- char *keystr = fz_tostringbuf(tree->items[m].k);
- int keylen = fz_tostringlen(tree->items[m].k);
- int cmplen = MIN(namelen, keylen);
- int c = strncmp(namestr, keystr, cmplen);
- if (c < 0)
- r = m - 1;
- else if (c > 0)
- l = m + 1;
- else
- return tree->items[m].v;
- }
+// fz_sortdict(tree);
+ *dictp = tree;
return nil;
}
-fz_obj *
-pdf_lookupname(pdf_nametree *tree, fz_obj *name)
-{
- return lookup(tree, fz_tostringbuf(name), fz_tostringlen(name));
-}
-
-fz_obj *
-pdf_lookupnames(pdf_nametree *tree, char *name)
-{
- return lookup(tree, name, strlen(name));
-}
-
fz_error *
pdf_loadnametrees(pdf_xref *xref)
{
fz_error *error;
- fz_obj *catalog;
fz_obj *names;
fz_obj *dests;
- catalog = fz_dictgets(xref->trailer, "Root");
- error = pdf_resolve(&catalog, xref);
- if (error)
- return error;
+ /* PDF 1.1 */
+ dests = fz_dictgets(xref->root, "Dests");
+ if (dests)
+ {
+ error = pdf_resolve(&dests, xref);
+ if (error)
+ return error;
+ xref->dests = dests;
+ return nil;
+ }
- names = fz_dictgets(catalog, "Names");
+ /* PDF 1.2 */
+ names = fz_dictgets(xref->root, "Names");
if (names)
{
error = pdf_resolve(&names, xref);
if (error)
- {
- fz_dropobj(names);
- fz_dropobj(catalog);
return error;
- }
-
dests = fz_dictgets(names, "Dests");
error = pdf_loadnametree(&xref->dests, xref, dests);
+ fz_dropobj(names);
if (error)
- {
- fz_dropobj(names);
- fz_dropobj(catalog);
return error;
- }
-
- fz_dropobj(names);
}
- fz_dropobj(catalog);
return nil;
}
diff --git a/mupdf/open.c b/mupdf/open.c
index 840690b4..34caa862 100644
--- a/mupdf/open.c
+++ b/mupdf/open.c
@@ -473,51 +473,35 @@ cleanup1:
}
/*
- * open xref in normal mode (as opposed to repair mode)
+ * open and load xref tables from pdf
*/
fz_error *
-pdf_openpdf(pdf_xref **xrefp, char *filename)
+pdf_loadxref(pdf_xref *xref, char *filename)
{
fz_error *error;
- pdf_xref *xref;
fz_obj *size;
int i;
char buf[65536]; /* yeowch! */
- xref = fz_malloc(sizeof(pdf_xref));
- if (!xref)
- return fz_outofmem;
- memset(xref, 0, sizeof(pdf_xref));
-
- xref->file = nil;
- xref->version = 1.0;
- xref->startxref = 0;
- xref->trailer = nil;
- xref->crypt = nil;
-
- xref->len = 0;
- xref->cap = 0;
- xref->table = nil;
-
- pdf_logxref("openxref '%s' %p\n", filename, xref);
+ pdf_logxref("loadxref '%s' %p\n", filename, xref);
error = fz_openfile(&xref->file, filename, FZ_READ);
if (error)
- goto cleanup;
+ return error;
error = loadversion(xref);
if (error)
- goto cleanup;
+ return error;
error = readstartxref(xref);
if (error)
- goto cleanup;
+ return error;
error = readtrailer(xref, buf, sizeof buf);
if (error)
- goto cleanup;
+ return error;
size = fz_dictgets(xref->trailer, "Size");
if (!size)
@@ -525,9 +509,10 @@ pdf_openpdf(pdf_xref **xrefp, char *filename)
pdf_logxref(" size %d\n", fz_toint(size));
+ assert(xref->table == nil);
+
xref->cap = fz_toint(size);
xref->len = fz_toint(size);
-
xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry));
if (!xref->table)
return fz_outofmem;
@@ -545,19 +530,8 @@ pdf_openpdf(pdf_xref **xrefp, char *filename)
error = readxrefsections(xref, xref->startxref, buf, sizeof buf);
if (error)
- goto cleanup;
-
- error = pdf_newstore(&xref->store);
- if (error)
- goto cleanup;
-
- xref->dests = nil;
+ return error;
- *xrefp = xref;
return nil;
-
-cleanup:
- pdf_closepdf(xref);
- return error;
}
diff --git a/mupdf/outline.c b/mupdf/outline.c
index fa8fffed..c41d96f5 100644
--- a/mupdf/outline.c
+++ b/mupdf/outline.c
@@ -2,187 +2,141 @@
#include <mupdf.h>
static fz_error *
-loadoutlinetree(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
+loadoutline(pdf_outline **nodep, pdf_xref *xref, fz_obj *dict)
{
-/*XXX please call this 'error' */
- fz_error *err;
- fz_obj *first;
- fz_obj *next;
- fz_obj *ref;
- fz_obj *t;
- pdf_outline *o;
- int i;
-
- t = fz_dictgets(obj, "Title");
-/*XXX check for failure after each malloc */
- outline->title = fz_malloc(sizeof(char) * fz_tostringlen(t) + 1);
-/*XXX use strlcpy instead. strncpy does not null terminate. */
- strncpy(outline->title, fz_tostringbuf(t), fz_tostringlen(t));
- outline->title[fz_tostringlen(t)] = 0;
-
- t = fz_dictgets(obj, "Count");
- outline->count = fz_toint(t);
-
- outline->dest = fz_dictgets(obj, "Dest");
- if (outline->dest) fz_keepobj(outline->dest);
- outline->a = fz_dictgets(obj, "A");
- if (outline->a) fz_keepobj(outline->a);
- outline->se = fz_dictgets(obj, "SE");
- if (outline->se) fz_keepobj(outline->se);
-
- t = fz_dictgets(obj, "C");
- if (t) {
- for (i = 0; i < 3; i++)
- outline->c[i] = fz_toreal(fz_arrayget(t, i));
- } else {
- for (i = 0; i < 3; i++)
- outline->c[i] = 0.;
- }
-
- t = fz_dictgets(obj, "F");
- if (t)
- outline->f = fz_toint(t);
+ fz_error *error;
+ pdf_outline *node;
+ fz_obj *obj;
- first = fz_dictgets(obj, "First");
- if (first) {
- err = pdf_loadindirect(&ref, xref, first);
- if (err) return err;
+ node = fz_malloc(sizeof(pdf_outline));
+ node->title = "<unknown>";
+ node->link = nil;
+ node->child = nil;
+ node->next = nil;
- o = fz_malloc(sizeof(pdf_outline));
-/*XXX you leak ref */
- if (!o) { err = fz_outofmem; return err; }
+ pdf_logpage("load outline {\n");
- loadoutlinetree(xref, o, ref);
-/*XXX check error return */
-
- outline->first = o;
-
- fz_dropobj(ref);
- } else {
- outline->first = nil;
+ obj = fz_dictgets(dict, "Title");
+ if (obj)
+ {
+ error = pdf_toutf8(&node->title, obj);
+ if (error)
+ return error;
+ pdf_logpage("title %s\n", node->title);
}
- next = fz_dictgets(obj, "Next");
- if (next) {
- err = pdf_loadindirect(&ref, xref, next);
- if (err) return err;
+ if (fz_dictgets(dict, "Dest") || fz_dictgets(dict, "A"))
+ {
+ error = pdf_loadlink(&node->link, xref, dict);
+ if (error)
+ return error;
+ }
- o = fz_malloc(sizeof(pdf_outline));
-/*XXX you leak ref */
- if (!o) { err = fz_outofmem; return err; }
+ obj = fz_dictgets(dict, "First");
+ if (obj)
+ {
+ error = pdf_resolve(&obj, xref);
+ if (error)
+ return error;
+ error = loadoutline(&node->child, xref, obj);
+ fz_dropobj(obj);
+ if (error)
+ return error;
+ }
- loadoutlinetree(xref, o, ref);
-/*XXX check error return? */
-
- outline->next = o;
+ pdf_logpage("}\n");
- fz_dropobj(ref);
- } else {
- outline->next = nil;
+ obj = fz_dictgets(dict, "Next");
+ if (obj)
+ {
+ error = pdf_resolve(&obj, xref);
+ if (error)
+ return error;
+ error = loadoutline(&node->next, xref, obj);
+ fz_dropobj(obj);
+ if (error)
+ return error;
}
+ *nodep = node;
return nil;
}
fz_error *
-pdf_loadoutlinetree(pdf_outlinetree **oo, pdf_xref *xref)
+pdf_loadoutline(pdf_outline **nodep, pdf_xref *xref)
{
-/*XXX please rename to 'error' */
- fz_error *err;
- pdf_outlinetree *o = nil;
- fz_obj *outline = nil;
- fz_obj *catalog = nil;
- fz_obj *outlines = nil;
- fz_obj *trailer;
- fz_obj *ref;
- int count;
-
- trailer = xref->trailer;
-
- ref = fz_dictgets(trailer, "Root");
- err = pdf_loadindirect(&catalog, xref, ref);
- if (err) goto error;
-
-/*XXX create empty tree if no outlines exist instead of failing? */
- ref = fz_dictgets(catalog, "Outlines");
- if (!ref) goto error;
- err = pdf_loadindirect(&outlines, xref, ref);
- if (err) goto error;
-
- ref = fz_dictgets(outlines, "Count");
- count = fz_toint(ref);
-
- o = *oo = fz_malloc(sizeof(pdf_outlinetree));
- if (!o) { err = fz_outofmem; goto error; }
-
- o->count = count;
- o->first = fz_malloc(sizeof(pdf_outline));
- if (!o->first) { err = fz_outofmem; goto error; }
-
- ref = fz_dictgets(outlines, "First");
- err = pdf_loadindirect(&outline, xref, ref);
-/*XXX check error */
- err = loadoutlinetree(xref, o->first, outline);
- if (err) goto error;
-
- fz_dropobj(outline);
- fz_dropobj(outlines);
- fz_dropobj(catalog);
- return nil;
+ fz_error *error;
+ pdf_outline *node;
+ fz_obj *obj;
+ fz_obj *first;
+
+ pdf_logpage("load outlines {\n");
+
+ node = nil;
+
+ obj = fz_dictgets(xref->root, "Outlines");
+ if (obj)
+ {
+ error = pdf_resolve(&obj, xref);
+ if (error)
+ return error;
+
+ first = fz_dictgets(obj, "First");
+ if (first)
+ {
+ error = pdf_resolve(&first, xref);
+ fz_dropobj(obj);
+ if (error)
+ return error;
+ error = loadoutline(&node, xref, first);
+ fz_dropobj(first);
+ if (error)
+ return error;
+ }
+ else
+ fz_dropobj(obj);
+ }
+
+ pdf_logpage("}\n");
-error:
- if (outlines) fz_dropobj(outlines);
- if (catalog) fz_dropobj(catalog);
- if (o) fz_free(o);
+ *nodep = node;
return nil;
}
void
pdf_dropoutline(pdf_outline *outline)
{
- if (outline->first)
- pdf_dropoutline(outline->first);
+ if (outline->child)
+ pdf_dropoutline(outline->child);
if (outline->next)
pdf_dropoutline(outline->next);
-
+ pdf_droplink(outline->link);
fz_free(outline->title);
- if (outline->dest) fz_dropobj(outline->dest);
- if (outline->a) fz_dropobj(outline->a);
- if (outline->se) fz_dropobj(outline->se);
-
fz_free(outline);
}
void
-pdf_dropoutlinetree(pdf_outlinetree *outlinetree)
-{
- if (outlinetree->first)
- pdf_dropoutline(outlinetree->first);
- fz_free(outlinetree);
-}
-
-static void
-debugoutline(pdf_outline *outline, int level)
+pdf_debugoutline(pdf_outline *outline, int level)
{
int i;
while (outline)
{
- for (i = 0; i < level; i++) putchar(' ');
- printf("(%s) ", outline->title);
- if (outline->dest)
- fz_debugobj(outline->dest);
- if (outline->a)
- fz_debugobj(outline->a);
+ for (i = 0; i < level; i++)
+ putchar(' ');
+
+ printf("%s ", outline->title);
+
+ if (outline->link)
+ fz_debugobj(outline->link->dest);
+ else
+ printf("<nil>");
+
printf("\n");
- if (outline->first)
- debugoutline(outline->first, level + 2);
+
+ if (outline->child)
+ pdf_debugoutline(outline->child, level + 2);
+
outline = outline->next;
}
}
-void
-pdf_debugoutlinetree(pdf_outlinetree *outlinetree)
-{
- debugoutline(outlinetree->first, 0);
-}
-
diff --git a/mupdf/parse.c b/mupdf/parse.c
index 32d8b698..ba2fcf2c 100644
--- a/mupdf/parse.c
+++ b/mupdf/parse.c
@@ -28,6 +28,55 @@ fz_matrix pdf_tomatrix(fz_obj *array)
}
fz_error *
+pdf_toutf8(char **dstp, fz_obj *src)
+{
+ unsigned char *srcptr = fz_tostrbuf(src);
+ char *dstptr;
+ int srclen = fz_tostrlen(src);
+ int dstlen = 0;
+ int ucs;
+ int i;
+
+ if (srclen > 2 && srcptr[0] == 254 && srcptr[1] == 255)
+ {
+ for (i = 2; i < srclen; i += 2)
+ {
+ ucs = (srcptr[i] << 8) | srcptr[i+1];
+ dstlen += runelen(srcptr[i]);
+ }
+
+ dstptr = *dstp = fz_malloc(dstlen + 1);
+ if (!dstptr)
+ return fz_outofmem;
+
+ for (i = 2; i < srclen; i += 2)
+ {
+ ucs = (srcptr[i] << 8) | srcptr[i+1];
+ dstptr += runetochar(dstptr, &ucs);
+ }
+ }
+
+ else
+ {
+ for (i = 0; i < srclen; i++)
+ dstlen += runelen(srcptr[i]);
+
+ dstptr = *dstp = fz_malloc(dstlen + 1);
+ if (!dstptr)
+ return fz_outofmem;
+
+ for (i = 0; i < srclen; i++)
+ {
+ ucs = srcptr[i];
+ dstptr += runetochar(dstptr, &ucs);
+ }
+ }
+
+ *dstptr = '\0';
+ return nil;
+}
+
+fz_error *
pdf_parsearray(fz_obj **op, fz_file *file, char *buf, int cap)
{
fz_error *error = nil;
diff --git a/mupdf/repair.c b/mupdf/repair.c
index bd0f6add..e533d826 100644
--- a/mupdf/repair.c
+++ b/mupdf/repair.c
@@ -1,6 +1,10 @@
#include <fitz.h>
#include <mupdf.h>
+/*
+ * open pdf and scan objects to reconstruct xref table
+ */
+
struct entry
{
int oid;
@@ -101,10 +105,9 @@ atobjend:
}
fz_error *
-pdf_repairpdf(pdf_xref **xrefp, char *filename)
+pdf_repairxref(pdf_xref *xref, char *filename)
{
fz_error *error;
- pdf_xref *xref;
fz_file *file;
struct entry *list = nil;
@@ -124,22 +127,11 @@ pdf_repairpdf(pdf_xref **xrefp, char *filename)
int next;
int i;
- xref = fz_malloc(sizeof(pdf_xref));
- if (!xref)
- return fz_outofmem;
- memset(xref, 0, sizeof(pdf_xref));
-
- xref->file = nil;
- xref->version = 0.0;
- xref->startxref = 0;
- xref->trailer = nil;
- xref->crypt = nil;
-
- pdf_logxref("repairxref '%s' %p\n", filename, xref);
-
error = fz_openfile(&file, filename, FZ_READ);
if (error)
- goto cleanup;
+ return error;
+
+ pdf_logxref("repairxref '%s' %p\n", filename, xref);
xref->file = file;
@@ -224,11 +216,11 @@ pdf_repairpdf(pdf_xref **xrefp, char *filename)
if (error)
goto cleanup;
- xref->version = 1.3; /* FIXME */
xref->len = maxoid + 1;
xref->cap = xref->len;
xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry));
- if (!xref->table) {
+ if (!xref->table)
+ {
error = fz_outofmem;
goto cleanup;
}
@@ -300,18 +292,10 @@ pdf_repairpdf(pdf_xref **xrefp, char *filename)
fz_free(list);
- error = pdf_newstore(&xref->store);
- if (error)
- goto cleanup;
-
- xref->dests = nil;
-
- *xrefp = xref;
return nil;
cleanup:
fz_closefile(file);
- fz_free(xref);
fz_free(list);
return error;
}
diff --git a/mupdf/save.c b/mupdf/save.c
index aaa02a75..344d942c 100644
--- a/mupdf/save.c
+++ b/mupdf/save.c
@@ -104,7 +104,7 @@ static int countmodified(pdf_xref *xref, int oid)
}
fz_error *
-pdf_updatepdf(pdf_xref *xref, char *path)
+pdf_updatexref(pdf_xref *xref, char *path)
{
fz_error *error;
fz_file *out;
@@ -207,7 +207,7 @@ cleanup:
}
fz_error *
-pdf_savepdf(pdf_xref *xref, char *path, pdf_crypt *encrypt)
+pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt)
{
fz_error *error;
fz_file *out;
diff --git a/mupdf/store.c b/mupdf/store.c
index bfeb5bff..d46cd628 100644
--- a/mupdf/store.c
+++ b/mupdf/store.c
@@ -172,7 +172,7 @@ pdf_finditem(pdf_store *store, pdf_itemkind kind, fz_obj *key)
else
{
for (item = store->root; item; item = item->next)
- if (item->kind == kind && !fz_cmpobj(item->key, key))
+ if (item->kind == kind && !fz_objcmp(item->key, key))
return item->val;
}
diff --git a/mupdf/xref.c b/mupdf/xref.c
index 29972b8f..2c92bbe6 100644
--- a/mupdf/xref.c
+++ b/mupdf/xref.c
@@ -6,7 +6,7 @@
*/
fz_error *
-pdf_newpdf(pdf_xref **xrefp)
+pdf_newxref(pdf_xref **xrefp)
{
fz_error *error;
pdf_xref *xref;
@@ -19,31 +19,24 @@ pdf_newpdf(pdf_xref **xrefp)
pdf_logxref("newxref %p\n", xref);
xref->file = nil;
- xref->version = 1.3;
+ xref->version = 1.0;
xref->startxref = 0;
- xref->trailer = nil;
xref->crypt = nil;
- xref->cap = 256;
- xref->len = 1;
- xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry));
- if (!xref->table) {
- fz_free(xref);
- return fz_outofmem;
- }
+ xref->trailer = nil;
+ xref->root = nil;
+ xref->info = nil;
+ xref->dests = nil;
+ xref->store = nil;
- xref->table[0].type = 'f';
- xref->table[0].mark = 0;
- xref->table[0].ofs = 0;
- xref->table[0].gen = 65535;
- xref->table[0].stmbuf = nil;
- xref->table[0].stmofs = 0;
- xref->table[0].obj = nil;
+ xref->cap = 0;
+ xref->len = 0;
+ xref->table = nil;
error = pdf_newstore(&xref->store);
if (error)
{
- pdf_closepdf(xref);
+ pdf_closexref(xref);
return error;
}
@@ -51,40 +44,37 @@ pdf_newpdf(pdf_xref **xrefp)
return nil;
}
-fz_error *
-pdf_decryptpdf(pdf_xref *xref)
+void
+pdf_closexref(pdf_xref *xref)
{
- fz_error *error;
- fz_obj *encrypt;
- fz_obj *id;
+ pdf_logxref("closexref %p\n", xref);
- encrypt = fz_dictgets(xref->trailer, "Encrypt");
- id = fz_dictgets(xref->trailer, "ID");
+ if (xref->store)
+ pdf_dropstore(xref->store);
- if (encrypt && id)
+ if (xref->table)
{
- error = pdf_resolve(&encrypt, xref);
- if (error)
- return error;
+ pdf_flushxref(xref, 1);
+ fz_free(xref->table);
+ }
- error = pdf_resolve(&id, xref);
- if (error)
- {
- fz_dropobj(encrypt);
- return error;
- }
+ if (xref->file)
+ fz_closefile(xref->file);
- error = pdf_newdecrypt(&xref->crypt, encrypt, id);
- fz_dropobj(encrypt);
- fz_dropobj(id);
- return error;
- }
+ if (xref->trailer)
+ fz_dropobj(xref->trailer);
+ if (xref->root)
+ fz_dropobj(xref->root);
+ if (xref->info)
+ fz_dropobj(xref->info);
+ if (xref->dests)
+ fz_dropobj(xref->dests);
- return nil;
+ fz_free(xref);
}
void
-pdf_flushpdf(pdf_xref *xref, int force)
+pdf_flushxref(pdf_xref *xref, int force)
{
int i;
@@ -112,7 +102,7 @@ pdf_flushpdf(pdf_xref *xref, int force)
fz_dropbuffer(xref->table[i].stmbuf);
xref->table[i].stmbuf = nil;
}
- if (xref->table[i].obj && xref->table[i].stmbuf->refs == 1)
+ if (xref->table[i].obj && xref->table[i].obj->refs == 1)
{
fz_dropobj(xref->table[i].obj);
xref->table[i].obj = nil;
@@ -122,30 +112,7 @@ pdf_flushpdf(pdf_xref *xref, int force)
}
void
-pdf_closepdf(pdf_xref *xref)
-{
- pdf_logxref("closexref %p\n", xref);
-
- if (xref->store)
- pdf_dropstore(xref->store);
-
- if (xref->table)
- {
- pdf_flushpdf(xref, 1);
- fz_free(xref->table);
- }
-
- if (xref->file)
- fz_closefile(xref->file);
-
- if (xref->trailer)
- fz_dropobj(xref->trailer);
-
- fz_free(xref);
-}
-
-void
-pdf_debugpdf(pdf_xref *xref)
+pdf_debugxref(pdf_xref *xref)
{
int i;
printf("xref\n0 %d\n", xref->len);
@@ -161,6 +128,39 @@ pdf_debugpdf(pdf_xref *xref)
}
}
+/* ICKY! */
+fz_error *
+pdf_decryptxref(pdf_xref *xref)
+{
+ fz_error *error;
+ fz_obj *encrypt;
+ fz_obj *id;
+
+ encrypt = fz_dictgets(xref->trailer, "Encrypt");
+ id = fz_dictgets(xref->trailer, "ID");
+
+ if (encrypt && id)
+ {
+ error = pdf_resolve(&encrypt, xref);
+ if (error)
+ return error;
+
+ error = pdf_resolve(&id, xref);
+ if (error)
+ {
+ fz_dropobj(encrypt);
+ return error;
+ }
+
+ error = pdf_newdecrypt(&xref->crypt, encrypt, id);
+ fz_dropobj(encrypt);
+ fz_dropobj(id);
+ return error;
+ }
+
+ return nil;
+}
+
/*
* mutate objects
*/
diff --git a/object/dict.c b/object/dict.c
index c41dbab1..a0fb6d25 100644
--- a/object/dict.c
+++ b/object/dict.c
@@ -1,6 +1,26 @@
#include <fitz.h>
-void fz_dropdict(fz_obj *obj);
+/* keep either names or strings in the dict. don't mix & match. */
+
+static int keyvalcmp(const void *ap, const void *bp)
+{
+ const fz_keyval *a = ap;
+ const fz_keyval *b = bp;
+ if (fz_isname(a->k))
+ return strcmp(fz_toname(a->k), fz_toname(b->k));
+ if (fz_isstring(a->k))
+ return strcmp(fz_tostrbuf(a->k), fz_tostrbuf(b->k));
+ return -1;
+}
+
+static inline int keystrcmp(fz_obj *key, char *s)
+{
+ if (fz_isname(key))
+ return strcmp(fz_toname(key), s);
+ if (fz_isstring(key))
+ return strcmp(fz_tostrbuf(key), s);
+ return -1;
+}
fz_error *
fz_newdict(fz_obj **op, int initialcap)
@@ -14,10 +34,11 @@ fz_newdict(fz_obj **op, int initialcap)
obj->refs = 1;
obj->kind = FZ_DICT;
+ obj->u.d.sorted = 1;
obj->u.d.len = 0;
obj->u.d.cap = initialcap > 0 ? initialcap : 10;
- obj->u.d.items = fz_malloc(sizeof(struct fz_keyval_s) * obj->u.d.cap);
+ obj->u.d.items = fz_malloc(sizeof(fz_keyval) * obj->u.d.cap);
if (!obj->u.d.items) { fz_free(obj); return fz_outofmem; }
for (i = 0; i < obj->u.d.cap; i++) {
@@ -44,7 +65,7 @@ fz_copydict(fz_obj **op, fz_obj *obj)
for (i = 0; i < fz_dictlen(obj); i++) {
error = fz_dictput(new, fz_dictgetkey(obj, i), fz_dictgetval(obj, i));
- if (error) { fz_dropdict(new); return error; }
+ if (error) { fz_dropobj(new); return error; }
}
return nil;
@@ -71,23 +92,23 @@ fz_deepcopydict(fz_obj **op, fz_obj *obj)
if (fz_isarray(val)) {
error = fz_deepcopyarray(&val, val);
- if (error) { fz_dropdict(new); return error; }
+ if (error) { fz_dropobj(new); return error; }
error = fz_dictput(new, fz_dictgetkey(obj, i), val);
- if (error) { fz_dropobj(val); fz_dropdict(new); return error; }
+ if (error) { fz_dropobj(val); fz_dropobj(new); return error; }
fz_dropobj(val);
}
else if (fz_isdict(val)) {
error = fz_deepcopydict(&val, val);
- if (error) { fz_dropdict(new); return error; }
+ if (error) { fz_dropobj(new); return error; }
error = fz_dictput(new, fz_dictgetkey(obj, i), val);
- if (error) { fz_dropobj(val); fz_dropdict(new); return error; }
+ if (error) { fz_dropobj(val); fz_dropobj(new); return error; }
fz_dropobj(val);
}
else {
error = fz_dictput(new, fz_dictgetkey(obj, i), val);
- if (error) { fz_dropdict(new); return error; }
+ if (error) { fz_dropobj(new); return error; }
}
}
@@ -97,13 +118,13 @@ fz_deepcopydict(fz_obj **op, fz_obj *obj)
static fz_error *
growdict(fz_obj *obj)
{
- struct fz_keyval_s *newitems;
+ fz_keyval *newitems;
int newcap;
int i;
newcap = obj->u.d.cap * 2;
- newitems = fz_realloc(obj->u.d.items, sizeof(struct fz_keyval_s) * newcap);
+ newitems = fz_realloc(obj->u.d.items, sizeof(fz_keyval) * newcap);
if (!newitems) return fz_outofmem;
obj->u.d.items = newitems;
@@ -148,6 +169,36 @@ fz_dictgetval(fz_obj *obj, int i)
return obj->u.d.items[i].v;
}
+static inline int dictfinds(fz_obj *obj, char *key)
+{
+ if (obj->u.d.sorted)
+ {
+ int l = 0;
+ int r = obj->u.d.len - 1;
+ while (l <= r)
+ {
+ int m = (l + r) >> 1;
+ int c = -keystrcmp(obj->u.d.items[m].k, key);
+ if (c < 0)
+ r = m - 1;
+ else if (c > 0)
+ l = m + 1;
+ else
+ return m;
+ }
+ }
+
+ else
+ {
+ int i;
+ for (i = 0; i < obj->u.d.len; i++)
+ if (keystrcmp(obj->u.d.items[i].k, key) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
fz_obj *
fz_dictgets(fz_obj *obj, char *key)
{
@@ -156,9 +207,9 @@ fz_dictgets(fz_obj *obj, char *key)
if (!fz_isdict(obj))
return nil;
- for (i = 0; i < obj->u.d.len; i++)
- if (strcmp(fz_toname(obj->u.d.items[i].k), key) == 0)
- return obj->u.d.items[i].v;
+ i = dictfinds(obj, key);
+ if (i >= 0)
+ return obj->u.d.items[i].v;
return nil;
}
@@ -166,7 +217,11 @@ fz_dictgets(fz_obj *obj, char *key)
fz_obj *
fz_dictget(fz_obj *obj, fz_obj *key)
{
- return fz_dictgets(obj, fz_toname(key));
+ if (fz_isname(key))
+ return fz_dictgets(obj, fz_toname(key));
+ if (fz_isstring(key))
+ return fz_dictgets(obj, fz_tostrbuf(key));
+ return nil;
}
fz_obj *
@@ -183,29 +238,39 @@ fz_error *
fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val)
{
fz_error *error;
- int i;
char *s;
+ int i;
if (!fz_isdict(obj))
return fz_throw("typecheck in dictput");
- if (!fz_isname(key))
- return fz_throw("typecheck in dictput");
- s = fz_toname(key);
+ if (fz_isname(key))
+ s = fz_toname(key);
+ else if (fz_isstring(key))
+ s = fz_tostrbuf(key);
+ else
+ return fz_throw("typecheck in dictput");
- for (i = 0; i < obj->u.d.len; i++) {
- if (strcmp(fz_toname(obj->u.d.items[i].k), s) == 0) {
- fz_dropobj(obj->u.d.items[i].v);
- obj->u.d.items[i].v = fz_keepobj(val);
- return nil;
- }
+ i = dictfinds(obj, s);
+ if (i >= 0)
+ {
+ fz_dropobj(obj->u.d.items[i].v);
+ obj->u.d.items[i].v = fz_keepobj(val);
+ return nil;
}
- if (obj->u.d.len + 1 > obj->u.d.cap) {
+ if (obj->u.d.len + 1 > obj->u.d.cap)
+ {
error = growdict(obj);
- if (error) return error;
+ if (error)
+ return error;
}
+ /* borked! */
+ if (obj->u.d.len)
+ if (keystrcmp(obj->u.d.items[obj->u.d.len - 1].k, s) > 0)
+ obj->u.d.sorted = 0;
+
obj->u.d.items[obj->u.d.len].k = fz_keepobj(key);
obj->u.d.items[obj->u.d.len].v = fz_keepobj(val);
obj->u.d.len ++;
@@ -233,13 +298,14 @@ fz_dictdels(fz_obj *obj, char *key)
if (!fz_isdict(obj))
return fz_throw("typecheck in dictdel");
- for (i = 0; i < obj->u.d.len; i++) {
- if (strcmp(fz_toname(obj->u.d.items[i].k), key) == 0) {
- fz_dropobj(obj->u.d.items[i].k);
- fz_dropobj(obj->u.d.items[i].v);
- obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];
- obj->u.d.len --;
- }
+ i = dictfinds(obj, key);
+ if (i >= 0)
+ {
+ fz_dropobj(obj->u.d.items[i].k);
+ fz_dropobj(obj->u.d.items[i].v);
+ obj->u.d.sorted = 0;
+ obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];
+ obj->u.d.len --;
}
return nil;
@@ -248,7 +314,12 @@ fz_dictdels(fz_obj *obj, char *key)
fz_error *
fz_dictdel(fz_obj *obj, fz_obj *key)
{
- return fz_dictdels(obj, fz_toname(key));
+ if (fz_isname(key))
+ return fz_dictdels(obj, fz_toname(key));
+ else if (fz_isstring(key))
+ return fz_dictdels(obj, fz_tostrbuf(key));
+ else
+ return fz_throw("typecheck in dictdel");
}
void
@@ -270,3 +341,15 @@ fz_dropdict(fz_obj *obj)
fz_free(obj);
}
+void
+fz_sortdict(fz_obj *obj)
+{
+ if (!fz_isdict(obj))
+ return;
+ if (!obj->u.d.sorted)
+ {
+ qsort(obj->u.d.items, obj->u.d.len, sizeof(fz_keyval), keyvalcmp);
+ obj->u.d.sorted = 1;
+ }
+}
+
diff --git a/object/simple.c b/object/simple.c
index d9a0e12e..131e11b4 100644
--- a/object/simple.c
+++ b/object/simple.c
@@ -44,9 +44,10 @@ fz_newreal(fz_obj **op, float f)
fz_error *
fz_newstring(fz_obj **op, char *str, int len)
{
- NEWOBJ(FZ_STRING, offsetof(fz_obj, u.s.buf) + len);
+ NEWOBJ(FZ_STRING, offsetof(fz_obj, u.s.buf) + len + 1);
o->u.s.len = len;
memcpy(o->u.s.buf, str, len);
+ o->u.s.buf[len] = '\0';
return nil;
}
@@ -78,6 +79,7 @@ fz_newpointer(fz_obj **op, void *p)
fz_obj *
fz_keepobj(fz_obj *o)
{
+ assert(o != nil);
o->refs ++;
return o;
}
@@ -85,6 +87,7 @@ fz_keepobj(fz_obj *o)
void
fz_dropobj(fz_obj *o)
{
+ assert(o != nil);
if (--o->refs == 0)
{
if (o->kind == FZ_ARRAY)
@@ -193,7 +196,7 @@ fz_toname(fz_obj *obj)
}
char *
-fz_tostringbuf(fz_obj *obj)
+fz_tostrbuf(fz_obj *obj)
{
if (fz_isstring(obj))
return obj->u.s.buf;
@@ -201,7 +204,7 @@ fz_tostringbuf(fz_obj *obj)
}
int
-fz_tostringlen(fz_obj *obj)
+fz_tostrlen(fz_obj *obj)
{
if (fz_isstring(obj))
return obj->u.s.len;
@@ -232,8 +235,17 @@ fz_topointer(fz_obj *obj)
return nil;
}
+fz_error *
+fz_newnamefromstring(fz_obj **op, fz_obj *str)
+{
+ NEWOBJ(FZ_NAME, offsetof(fz_obj, u.n) + fz_tostrlen(str) + 1);
+ memcpy(o->u.n, fz_tostrbuf(str), fz_tostrlen(str));
+ o->u.n[fz_tostrlen(str)] = '\0';
+ return nil;
+}
+
int
-fz_cmpobj(fz_obj *a, fz_obj *b)
+fz_objcmp(fz_obj *a, fz_obj *b)
{
int i;
@@ -264,7 +276,7 @@ fz_cmpobj(fz_obj *a, fz_obj *b)
if (a->u.a.len != b->u.a.len)
return a->u.a.len - b->u.a.len;
for (i = 0; i < a->u.a.len; i++)
- if (fz_cmpobj(a->u.a.items[i], b->u.a.items[i]))
+ if (fz_objcmp(a->u.a.items[i], b->u.a.items[i]))
return 1;
return 0;
@@ -273,9 +285,9 @@ fz_cmpobj(fz_obj *a, fz_obj *b)
return a->u.d.len - b->u.d.len;
for (i = 0; i < a->u.d.len; i++)
{
- if (fz_cmpobj(a->u.d.items[i].k, b->u.d.items[i].k))
+ if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k))
return 1;
- if (fz_cmpobj(a->u.d.items[i].v, b->u.d.items[i].v))
+ if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v))
return 1;
}
return 0;
diff --git a/test/pdfclean.c b/test/pdfclean.c
index 32acacd9..a55b94ef 100644
--- a/test/pdfclean.c
+++ b/test/pdfclean.c
@@ -5,7 +5,7 @@ void usage()
{
fprintf(stderr,
"usage: pdfclean [options] infile.pdf outfile.pdf\n"
- " -r\treconstruct broken xref table\n"
+ " -r\trebuild xref table\n"
" -g\tgarbage collect unused objects\n"
" -x\texpand compressed streams\n"
" -d -\tset user password for decryption\n"
@@ -118,14 +118,16 @@ int main(int argc, char **argv)
infile = argv[optind++];
outfile = argv[optind++];
+ error = pdf_newxref(&xref);
+
if (dorepair)
- error = pdf_repairpdf(&xref, infile);
+ error = pdf_repairxref(xref, infile);
else
- error = pdf_openpdf(&xref, infile);
+ error = pdf_loadxref(xref, infile);
if (error)
fz_abort(error);
- error = pdf_decryptpdf(xref);
+ error = pdf_decryptxref(xref);
if (error)
fz_abort(error);
@@ -157,14 +159,14 @@ int main(int argc, char **argv)
pdf_garbagecollect(xref);
}
- error = pdf_savepdf(xref, outfile, encrypt);
+ error = pdf_savexref(xref, outfile, encrypt);
if (error)
fz_abort(error);
if (encrypt)
pdf_dropcrypt(encrypt);
- pdf_closepdf(xref);
+ pdf_closexref(xref);
return 0;
}
diff --git a/test/pdfdebug.c b/test/pdfdebug.c
index eefa0a74..2a18ade7 100644
--- a/test/pdfdebug.c
+++ b/test/pdfdebug.c
@@ -3,12 +3,11 @@
static char *password = "";
static int dodecode = 0;
-static int dorepair = 0;
static int doprintxref = 0;
void usage()
{
- fprintf(stderr, "usage: pdfdebug [-drxs] [-u password] file.pdf [oid ...]\n");
+ fprintf(stderr, "usage: pdfdebug [-dxs] [-u password] file.pdf [oid ...]\n");
exit(1);
}
@@ -127,9 +126,6 @@ int main(int argc, char **argv)
case 'd':
dodecode ++;
break;
- case 'r':
- dorepair ++;
- break;
case 'x':
doprintxref ++;
break;
@@ -146,14 +142,20 @@ int main(int argc, char **argv)
filename = argv[optind++];
- if (dorepair)
- error = pdf_repairpdf(&xref, filename);
- else
- error = pdf_openpdf(&xref, filename);
+ error = pdf_newxref(&xref);
if (error)
fz_abort(error);
- error = pdf_decryptpdf(xref);
+ error = pdf_loadxref(xref, filename);
+ if (error)
+ {
+ fz_warn("trying to repair");
+ error = pdf_repairxref(xref, filename);
+ if (error)
+ fz_abort(error);
+ }
+
+ error = pdf_decryptxref(xref);
if (error)
fz_abort(error);
@@ -177,9 +179,9 @@ int main(int argc, char **argv)
}
if (doprintxref)
- pdf_debugpdf(xref);
+ pdf_debugxref(xref);
- pdf_closepdf(xref);
+ pdf_closexref(xref);
return 0;
}
diff --git a/test/x11pdf.c b/test/x11pdf.c
index 3200b893..e35f90a6 100644
--- a/test/x11pdf.c
+++ b/test/x11pdf.c
@@ -24,7 +24,7 @@ static XEvent xevt;
static int mapped = 0;
static Cursor xcarrow, xchand, xcwait;
-static char doctitle[256];
+static char *doctitle = "<untitled>";
static float zoom = 1.0;
static int rotate = 0;
@@ -43,6 +43,7 @@ static int pagebufidx = 0;
static pdf_xref *xref;
static pdf_pagetree *pages;
+static pdf_outline *outline;
static fz_renderer *rast;
static fz_pixmap *image;
@@ -201,17 +202,21 @@ static void pdfopen(char *filename, char *password)
fz_error *error;
fz_obj *obj;
- error = pdf_openpdf(&xref, filename);
+ error = pdf_newxref(&xref);
+ if (error)
+ fz_abort(error);
+
+ error = pdf_loadxref(xref, filename);
if (error)
{
fz_warn(error->msg);
printf("trying to repair...\n");
- error = pdf_repairpdf(&xref, filename);
+ error = pdf_repairxref(xref, filename);
if (error)
fz_abort(error);
}
- error = pdf_decryptpdf(xref);
+ error = pdf_decryptxref(xref);
if (error)
fz_abort(error);
@@ -221,28 +226,44 @@ static void pdfopen(char *filename, char *password)
if (error) fz_abort(error);
}
- error = pdf_loadnametrees(xref);
+ obj = fz_dictgets(xref->trailer, "Root");
+ if (!obj)
+ fz_abort(fz_throw("syntaxerror: missing Root object"));
+ error = pdf_loadindirect(&xref->root, xref, obj);
if (error) fz_abort(error);
- error = pdf_loadpagetree(&pages, xref);
+ obj = fz_dictgets(xref->trailer, "Info");
+ if (obj)
+ {
+ error = pdf_loadindirect(&xref->info, xref, obj);
+ if (error) fz_abort(error);
+ }
+
+ error = pdf_loadnametrees(xref);
if (error) fz_abort(error);
- count = pdf_getpagecount(pages);
+ error = pdf_loadoutline(&outline, xref);
+ if (error) fz_abort(error);
- strlcpy(doctitle, filename, sizeof doctitle);
- obj = fz_dictgets(xref->trailer, "Info");
- if (fz_isindirect(obj))
+ doctitle = filename;
+ if (xref->info)
{
- pdf_resolve(&obj, xref);
- obj = fz_dictgets(obj, "Title");
+ obj = fz_dictgets(xref->info, "Title");
if (obj)
{
- int n = MIN(fz_tostringlen(obj) + 1, sizeof doctitle);
- if (obj)
- strlcpy(doctitle, fz_tostringbuf(obj), n);
+ error = pdf_toutf8(&doctitle, obj);
+ if (error) fz_abort(error);
}
}
+ if (outline)
+ pdf_debugoutline(outline, 0);
+
+ error = pdf_loadpagetree(&pages, xref);
+ if (error) fz_abort(error);
+
+ count = pdf_getpagecount(pages);
+
error = fz_newrenderer(&rast, pdf_devicergb, 0, 1024 * 512);
if (error) fz_abort(error);
@@ -274,8 +295,8 @@ static void gotouri(fz_obj *uri)
fz_debugobj(uri);
printf("\n");
- memcpy(buf, fz_tostringbuf(uri), fz_tostringlen(uri));
- buf[fz_tostringlen(uri)] = 0;
+ memcpy(buf, fz_tostrbuf(uri), fz_tostrlen(uri));
+ buf[fz_tostrlen(uri)] = 0;
if (getenv("BROWSER"))
sprintf(cmd, "$BROWSER %s &", buf);
@@ -477,10 +498,10 @@ static void handlemouse(float x, int y, int btn)
XDefineCursor(xdpy, xwin, xchand);
if (btn)
{
- if (link->uri)
- gotouri(link->uri);
- if (link->page)
- gotopage(link->page);
+ if (fz_isstring(link->dest))
+ gotouri(link->dest);
+ if (fz_isindirect(link->dest))
+ gotopage(link->dest);
}
}
else
@@ -562,7 +583,7 @@ int main(int argc, char **argv)
}
}
- pdf_closepdf(xref);
+ pdf_closexref(xref);
return 0;
}