summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/page.h9
-rw-r--r--mupdf/nametree.c21
-rw-r--r--mupdf/outline.c78
-rw-r--r--test/pdfrip.c12
4 files changed, 85 insertions, 35 deletions
diff --git a/include/mupdf/page.h b/include/mupdf/page.h
index b136b99e..d4b4bcb0 100644
--- a/include/mupdf/page.h
+++ b/include/mupdf/page.h
@@ -2,13 +2,13 @@
* Page tree, pages and related objects
*/
-typedef struct pdf_outlines_s pdf_outlines;
+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;
-struct pdf_outlines_s
+struct pdf_outlinetree_s
{
pdf_outline *first;
int count;
@@ -51,8 +51,9 @@ struct pdf_page_s
};
/* outline.c */
-fz_error *pdf_loadoutlines(pdf_outlines **oo, pdf_xref *xref);
-void pdf_freeoutlines(pdf_outlines *outlines);
+fz_error *pdf_loadoutlinetree(pdf_outlinetree **oo, pdf_xref *xref);
+void pdf_debugoutlinetree(pdf_outlinetree *outlinetree);
+void pdf_freeoutlinetree(pdf_outlinetree *outlinetree);
/* nametree.c */
fz_error *pdf_loadnametree(pdf_nametree **ntp, pdf_xref *xref, char *key);
diff --git a/mupdf/nametree.c b/mupdf/nametree.c
index d8179cd7..f1898c0e 100644
--- a/mupdf/nametree.c
+++ b/mupdf/nametree.c
@@ -48,6 +48,7 @@ loadnametree(pdf_nametree *nt, pdf_xref *xref, fz_obj *root)
fz_obj *names = nil;
fz_obj *kids = nil;
fz_obj *key = nil;
+// please dont use _ in variable names:
fz_obj *ref_val = nil;
fz_obj *ref = nil;
int i, len;
@@ -71,6 +72,7 @@ loadnametree(pdf_nametree *nt, pdf_xref *xref, fz_obj *root)
len = fz_arraylen(names);
if (len % 2)
+// with null error object?
goto cleanup;
len /= 2;
@@ -88,10 +90,12 @@ loadnametree(pdf_nametree *nt, pdf_xref *xref, fz_obj *root)
}
nametreepush(nt, key, ref_val);
+// check error!
fz_dropobj(key);
key = nil;
}
+// you leak names
}
/* Intermediate node */
@@ -112,6 +116,7 @@ loadnametree(pdf_nametree *nt, pdf_xref *xref, fz_obj *root)
for (i = 0; i < len; ++i) {
ref = fz_arrayget(kids, i);
loadnametree(nt, xref, ref);
+// check error!
}
}
else {
@@ -119,11 +124,13 @@ loadnametree(pdf_nametree *nt, pdf_xref *xref, fz_obj *root)
error = fz_throw("invalid nametree node: there's no Names and Kids key");
goto cleanup;
}
+// you leak kids
}
return nil;
cleanup:
+// i dont like BIG_FAT_MACROS, use: if (obj) fz_dropobj(obj)
SAFE_FREE_OBJ(localroot);
SAFE_FREE_OBJ(names);
SAFE_FREE_OBJ(kids);
@@ -171,11 +178,14 @@ pdf_loadnametree(pdf_nametree **pnt, pdf_xref *xref, char* key)
error = pdf_loadindirect(&catalog, xref, ref);
if (error) goto cleanup;
+// create empty nametree instead of failing
names = fz_dictgets(catalog, "Names");
+// never resolve something that can be null
error = pdf_resolve(&names, xref);
if (error) goto cleanup;
root = fz_dictgets(names, key);
+// never resolve something that can be null
error = pdf_resolve(&root, xref);
if (error) goto cleanup;
@@ -195,9 +205,14 @@ pdf_loadnametree(pdf_nametree **pnt, pdf_xref *xref, char* key)
error = loadnametree(nt, xref, root);
if (error) goto cleanup;
+// not necessary. tree is sorted when you load it.
sortnametree(nt);
+// please have separate cleanup and okay cases...
+// return nil; here
+
cleanup:
+// no BIG_FAT_MACROS, please :)
SAFE_FREE_OBJ(root);
SAFE_FREE_OBJ(names);
if (catalog) fz_dropobj(catalog);
@@ -240,6 +255,7 @@ pdf_lookupname(pdf_nametree *nt, fz_obj *name)
if (fz_isstring(name)) {
item.k = name;
item.v = nil;
+// bsearch is non-standard. please dont use it.
found = bsearch(&item, nt->items, nt->len, sizeof(nt->items[0]), compare);
return found->v;
}
@@ -252,8 +268,13 @@ pdf_lookupnames(pdf_nametree *nt, char *name)
fz_obj *key;
fz_obj *ref;
int len = strlen(name);
+// please dont create a new string just to do a lookup.
+// change this to be the "standard" function and call it from
+// pdf_lookupname instead. compare name with the fz_tostringbuf() & co
+// return values.
fz_newstring(&key, name, len);
ref = pdf_lookupname(nt, key);
fz_dropobj(key);
return ref;
}
+
diff --git a/mupdf/outline.c b/mupdf/outline.c
index 5fb6738e..54cab1d0 100644
--- a/mupdf/outline.c
+++ b/mupdf/outline.c
@@ -2,8 +2,9 @@
#include <mupdf.h>
static fz_error *
-loadoutlines(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
+loadoutlinetree(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
{
+// please call this 'error'
fz_error *err;
fz_obj *first;
fz_obj *next;
@@ -13,7 +14,9 @@ loadoutlines(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
int i;
t = fz_dictgets(obj, "Title");
+// check for failure after each malloc
outline->title = fz_malloc(sizeof(char) * fz_tostringlen(t) + 1);
+// use strlcpy instead. strncpy does not null terminate.
strncpy(outline->title, fz_tostringbuf(t), fz_tostringlen(t));
outline->title[fz_tostringlen(t)] = 0;
@@ -46,9 +49,11 @@ loadoutlines(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
if (err) return err;
o = fz_malloc(sizeof(pdf_outline));
+// you leak ref
if (!o) { err = fz_outofmem; return err; }
- loadoutlines(xref, o, ref);
+ loadoutlinetree(xref, o, ref);
+// check error return
outline->first = o;
@@ -63,9 +68,11 @@ loadoutlines(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
if (err) return err;
o = fz_malloc(sizeof(pdf_outline));
+// you leak ref
if (!o) { err = fz_outofmem; return err; }
- loadoutlines(xref, o, ref);
+ loadoutlinetree(xref, o, ref);
+// check error return?
outline->next = o;
@@ -77,28 +84,12 @@ loadoutlines(pdf_xref *xref, pdf_outline *outline, fz_obj *obj)
return nil;
}
-void
-pdf_debugoutlines(pdf_outlines *outlines)
-{
- /*
- int i;
- printf("<<\n /Type /Outlines\n /Count %d\n /Kids [\n", outlines->count);
- for (i = 0; i < pages->count; i++) {
- printf(" ");
- fz_debugobj(pages->pref[i]);
- printf("\t%% page %d\n", i + 1);
- //fz_debugobj(stdout, pages->pobj[i]);
- //printf("\n");
- }
- printf(" ]\n>>\n");
- */
-}
-
fz_error *
-pdf_loadoutlines(pdf_outlines **oo, pdf_xref *xref)
+pdf_loadoutlinetree(pdf_outlinetree **oo, pdf_xref *xref)
{
+// please rename to 'error'
fz_error *err;
- pdf_outlines *o = nil;
+ pdf_outlinetree *o = nil;
fz_obj *outline = nil;
fz_obj *catalog = nil;
fz_obj *outlines = nil;
@@ -112,6 +103,7 @@ pdf_loadoutlines(pdf_outlines **oo, pdf_xref *xref)
err = pdf_loadindirect(&catalog, xref, ref);
if (err) goto error;
+// 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);
@@ -120,7 +112,7 @@ pdf_loadoutlines(pdf_outlines **oo, pdf_xref *xref)
ref = fz_dictgets(outlines, "Count");
count = fz_toint(ref);
- o = *oo = fz_malloc(sizeof(pdf_outlines));
+ o = *oo = fz_malloc(sizeof(pdf_outlinetree));
if (!o) { err = fz_outofmem; goto error; }
o->count = count;
@@ -129,7 +121,8 @@ pdf_loadoutlines(pdf_outlines **oo, pdf_xref *xref)
ref = fz_dictgets(outlines, "First");
err = pdf_loadindirect(&outline, xref, ref);
- err = loadoutlines(xref, o->first, outline);
+// check error
+ err = loadoutlinetree(xref, o->first, outline);
if (err) goto error;
fz_dropobj(outline);
@@ -140,9 +133,7 @@ pdf_loadoutlines(pdf_outlines **oo, pdf_xref *xref)
error:
if (outlines) fz_dropobj(outlines);
if (catalog) fz_dropobj(catalog);
- if (o) {
- fz_free(o);
- }
+ if (o) fz_free(o);
return nil;
}
@@ -163,10 +154,35 @@ pdf_freeoutline(pdf_outline *outline)
}
void
-pdf_freeoutlines(pdf_outlines *outlines)
+pdf_freeoutlinetree(pdf_outlinetree *outlinetree)
+{
+ if (outlinetree->first)
+ pdf_freeoutline(outlinetree->first);
+ fz_free(outlinetree);
+}
+
+static void
+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);
+ printf("\n");
+ if (outline->first)
+ debugoutline(outline->first, level + 2);
+ outline = outline->next;
+ }
+}
+
+void
+pdf_debugoutlinetree(pdf_outlinetree *outlinetree)
{
- if (outlines->first)
- pdf_freeoutline(outlines->first);
- fz_free(outlines);
+ debugoutline(outlinetree->first, 0);
}
diff --git a/test/pdfrip.c b/test/pdfrip.c
index 57eba80a..986e61a9 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -82,6 +82,7 @@ int main(int argc, char **argv)
char *filename;
pdf_xref *xref;
pdf_pagetree *pages;
+ pdf_outlinetree *outlines;
int c;
char *password = "";
@@ -119,11 +120,22 @@ int main(int argc, char **argv)
error = pdf_loadpagetree(&pages, xref);
if (error) fz_abort(error);
+ outlines = nil;
+ error = pdf_loadoutlinetree(&outlines, xref);
+ if (error) { fz_warn(error->msg); fz_freeerror(error); }
+
if (optind == argc)
{
printf("pagetree\n");
pdf_debugpagetree(pages);
printf("\n");
+
+ if (outlines)
+ {
+ printf("outlines\n");
+ pdf_debugoutlinetree(outlines);
+ printf("\n");
+ }
}
for ( ; optind < argc; optind++)