diff options
-rw-r--r-- | include/mupdf/page.h | 9 | ||||
-rw-r--r-- | mupdf/nametree.c | 21 | ||||
-rw-r--r-- | mupdf/outline.c | 78 | ||||
-rw-r--r-- | test/pdfrip.c | 12 |
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++) |