From 4ebd84900f7f5d0afda14e09c518e614d9fde60d Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Sun, 5 Jul 2009 12:01:17 +0200 Subject: Refactor xref opening and closing to a common file for all pdf tools. --- apps/Jamfile | 13 ++-- apps/common/pdftool.c | 101 ++++++++++++++++++++++++++ apps/pdfclean.c | 56 +-------------- apps/pdfdraw.c | 99 +++++++------------------ apps/pdfextract.c | 60 +--------------- apps/pdfinfo.c | 196 +++++++++++++++++++++----------------------------- apps/pdfshow.c | 60 +--------------- apps/pdftool.h | 14 ++++ 8 files changed, 239 insertions(+), 360 deletions(-) create mode 100644 apps/common/pdftool.c create mode 100644 apps/pdftool.h diff --git a/apps/Jamfile b/apps/Jamfile index f2f36e5d..c0c364d1 100644 --- a/apps/Jamfile +++ b/apps/Jamfile @@ -5,23 +5,26 @@ FITZLIBS = libmupdf libfitz libfitzdraw libfonts libcmaps ; SubDir TOP apps ; Main pdfshow : pdfshow.c ; -LinkLibraries pdfshow : $(FITZLIBS) ; +LinkLibraries pdfshow : libpdftool $(FITZLIBS) ; Main pdfclean : pdfclean.c ; -LinkLibraries pdfclean : $(FITZLIBS) ; +LinkLibraries pdfclean : libpdftool $(FITZLIBS) ; Main pdfdraw : pdfdraw.c ; -LinkLibraries pdfdraw : $(FITZLIBS) ; +LinkLibraries pdfdraw : libpdftool $(FITZLIBS) ; Main pdfinfo : pdfinfo.c ; -LinkLibraries pdfinfo : $(FITZLIBS) ; +LinkLibraries pdfinfo : libpdftool $(FITZLIBS) ; Main pdfextract : pdfextract.c ; -LinkLibraries pdfextract : $(FITZLIBS) ; +LinkLibraries pdfextract : libpdftool $(FITZLIBS) ; SubDir TOP apps common ; Library libpdfapp : pdfapp.c ; +SubDir TOP apps common ; +Library libpdftool : pdftool.c ; + if $(BUILD_WINAPP) { SubDir TOP apps windows ; diff --git a/apps/common/pdftool.c b/apps/common/pdftool.c new file mode 100644 index 00000000..fecfac8c --- /dev/null +++ b/apps/common/pdftool.c @@ -0,0 +1,101 @@ +#include "pdftool.h" + +char *basename = nil; +pdf_xref *xref = nil; +pdf_pagetree *pagetree = nil; +void (*cleanup)(void) = nil; + +void closexref(void); + +void die(fz_error error) +{ + fz_catch(error, "aborting"); + if (cleanup) + cleanup(); + closexref(); + exit(1); +} + +void setcleanup(void (*func)(void)) +{ + cleanup = func; +} + +void openxref(char *filename, char *password, int dieonbadpass) +{ + fz_error error; + fz_obj *obj; + int okay; + + basename = strrchr(filename, '/'); + if (!basename) + basename = filename; + else + basename++; + + error = pdf_newxref(&xref); + if (error) + die(error); + + error = pdf_loadxref(xref, filename); + if (error) + { + fz_catch(error, "trying to repair"); + error = pdf_repairxref(xref, filename); + if (error) + die(error); + } + + error = pdf_decryptxref(xref); + if (error) + die(error); + + if (xref->crypt) + { + okay = pdf_setpassword(xref->crypt, password); + if (!okay && !dieonbadpass) + fz_warn("invalid password, attempting to continue."); + else if (!okay && dieonbadpass) + die(fz_throw("invalid password")); + } + + obj = fz_dictgets(xref->trailer, "Root"); + xref->root = fz_resolveindirect(obj); + if (xref->root) + fz_keepobj(xref->root); + + obj = fz_dictgets(xref->trailer, "Info"); + xref->info = fz_resolveindirect(obj); + if (xref->info) + fz_keepobj(xref->info); +} + +void closexref(void) +{ + if (cleanup) + cleanup(); + + if (pagetree) + { + pdf_droppagetree(pagetree); + pagetree = nil; + } + + if (xref) + { + pdf_closexref(xref); + xref = nil; + } + + basename = nil; +} + +void loadpagetree(void) +{ + fz_error error; + + error = pdf_loadpagetree(&pagetree, xref); + if (error) + die(error); +} + diff --git a/apps/pdfclean.c b/apps/pdfclean.c index f008992f..588a7ac7 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -7,10 +7,8 @@ * Encrypt output. */ -#include "fitz.h" -#include "mupdf.h" +#include "pdftool.h" -static pdf_xref *xref = NULL; static fz_obj *id = NULL; static pdf_crypt *outcrypt = NULL; @@ -24,53 +22,6 @@ int doencrypt = 0; int dogarbage = 0; int doexpand = 0; -void die(fz_error error) -{ - fz_catch(error, "aborting"); - exit(1); -} - -void openxref(char *filename, char *password) -{ - fz_error error; - fz_obj *obj; - - error = pdf_newxref(&xref); - if (error) - die(error); - - error = pdf_loadxref(xref, filename); - if (error) - { - fz_catch(error, "trying to repair"); - error = pdf_repairxref(xref, filename); - if (error) - die(error); - } - - error = pdf_decryptxref(xref); - if (error) - die(error); - - if (xref->crypt) - { - int okay = pdf_setpassword(xref->crypt, password); - if (!okay) - die(fz_throw("invalid password")); - } - - /* TODO: move into mupdf lib, see pdfapp_open in pdfapp.c */ - obj = fz_dictgets(xref->trailer, "Root"); - xref->root = fz_resolveindirect(obj); - if (xref->root) - fz_keepobj(xref->root); - - obj = fz_dictgets(xref->trailer, "Info"); - xref->info = fz_resolveindirect(obj); - if (xref->info) - fz_keepobj(xref->info); -} - /* * Garbage collect objects not reachable from the trailer. */ @@ -356,7 +307,6 @@ int main(int argc, char **argv) int c, oid; int lastfree; - while ((c = fz_getopt(argc, argv, "d:egn:o:p:u:x")) != -1) { switch (c) @@ -391,7 +341,7 @@ int main(int argc, char **argv) if (argc - fz_optind > 0) outfile = argv[fz_optind++]; - openxref(infile, password); + openxref(infile, password, 0); id = fz_dictgets(xref->trailer, "ID"); if (!id) @@ -485,6 +435,6 @@ int main(int argc, char **argv) savexref(); - pdf_closexref(xref); + closexref(); } diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c index 1c1dcf74..913363f7 100644 --- a/apps/pdfdraw.c +++ b/apps/pdfdraw.c @@ -6,8 +6,7 @@ * Benchmark rendering speed. */ -#include "fitz.h" -#include "mupdf.h" +#include "pdftool.h" #ifdef _MSC_VER #include @@ -17,72 +16,6 @@ fz_renderer *drawgc = nil; -char *basename; -pdf_xref *xref = nil; -pdf_pagetree *pagetree = nil; - -void die(fz_error eo) -{ - fz_catch(eo, "aborting"); - if (drawgc) - fz_droprenderer(drawgc); - exit(1); -} - -void openxref(char *filename, char *password) -{ - fz_error error; - fz_obj *obj; - - basename = strrchr(filename, '/'); - if (!basename) - basename = filename; - else - basename ++; - - error = pdf_newxref(&xref); - if (error) - die(error); - - error = pdf_loadxref(xref, filename); - if (error) - { - fz_catch(error, "trying to repair"); - error = pdf_repairxref(xref, filename); - if (error) - die(error); - } - - error = pdf_decryptxref(xref); - if (error) - die(error); - - if (xref->crypt) - { - int okay = pdf_setpassword(xref->crypt, password); - if (!okay) - die(fz_throw("invalid password")); - } - - error = pdf_loadpagetree(&pagetree, xref); - if (error) - die(error); - - /* TODO: move into mupdf lib, see pdfapp_open in pdfapp.c */ - obj = fz_dictgets(xref->trailer, "Root"); - xref->root = fz_resolveindirect(obj); - if (xref->root) - fz_keepobj(xref->root); - - obj = fz_dictgets(xref->trailer, "Info"); - xref->info = fz_resolveindirect(obj); - if (xref->info) - fz_keepobj(xref->info); -} - -/* - */ - enum { DRAWPNM, DRAWTXT, DRAWXML }; struct benchmark @@ -104,6 +37,21 @@ int drawbands = 1; int drawcount = 0; int benchmark = 0; +void local_cleanup(void) +{ + if (xref && xref->store) + { + pdf_dropstore(xref->store); + xref->store = nil; + } + + if (drawgc) + { + fz_droprenderer(drawgc); + drawgc = nil; + } +} + void drawusage(void) { fprintf(stderr, @@ -447,9 +395,7 @@ int main(int argc, char **argv) if (fz_optind == argc) drawusage(); - error = fz_newrenderer(&drawgc, pdf_devicergb, 0, 1024 * 512); - if (error) - die(error); + setcleanup(local_cleanup); state = NO_FILE_OPENED; while (fz_optind < argc) @@ -459,7 +405,14 @@ int main(int argc, char **argv) if (state == NO_PAGES_DRAWN) drawpages("1-"); - openxref(argv[fz_optind], password); + closexref(); + + error = fz_newrenderer(&drawgc, pdf_devicergb, 0, 1024 * 512); + if (error) + die(error); + + openxref(argv[fz_optind], password, 0); + loadpagetree(); state = NO_PAGES_DRAWN; } else @@ -473,6 +426,6 @@ int main(int argc, char **argv) if (state == NO_PAGES_DRAWN) drawpages("1-"); - fz_droprenderer(drawgc); + closexref(); } diff --git a/apps/pdfextract.c b/apps/pdfextract.c index 21d665af..a1023f5f 100644 --- a/apps/pdfextract.c +++ b/apps/pdfextract.c @@ -2,63 +2,7 @@ * pdfextract -- the ultimate way to extract images and fonts from pdfs */ -#include "fitz.h" -#include "mupdf.h" - -pdf_xref *xref = NULL; - -void die(fz_error eo) -{ - fz_catch(eo, "aborting"); - exit(1); -} - -void openxref(char *filename, char *password) -{ - fz_error error; - fz_obj *obj; - - error = pdf_newxref(&xref); - if (error) - die(error); - - error = pdf_loadxref(xref, filename); - if (error) - { - fz_catch(error, "trying to repair"); - error = pdf_repairxref(xref, filename); - if (error) - die(error); - } - - error = pdf_decryptxref(xref); - if (error) - die(error); - - if (xref->crypt) - { - int okay = pdf_setpassword(xref->crypt, password); - if (!okay) - die(fz_throw("invalid password")); - } - - /* TODO: move into mupdf lib, see pdfapp_open in pdfapp.c */ - obj = fz_dictgets(xref->trailer, "Root"); - xref->root = fz_resolveindirect(obj); - if (xref->root) - fz_keepobj(xref->root); - - obj = fz_dictgets(xref->trailer, "Info"); - xref->info = fz_resolveindirect(obj); - if (xref->info) - fz_keepobj(xref->info); -} - -void closexref() -{ - pdf_closexref(xref); - xref = nil; -} +#include "pdftool.h" int showcolumn; @@ -304,7 +248,7 @@ int main(int argc, char **argv) if (fz_optind == argc) showusage(); - openxref(argv[fz_optind++], password); + openxref(argv[fz_optind++], password, 0); if (fz_optind == argc) for (o = 0; o < xref->len; o++) diff --git a/apps/pdfinfo.c b/apps/pdfinfo.c index 751079ab..3a0c86e6 100644 --- a/apps/pdfinfo.c +++ b/apps/pdfinfo.c @@ -3,115 +3,7 @@ * Print information about the input pdf. */ -#include "fitz.h" -#include "mupdf.h" - -/* put these up here so we can clean up in die() */ -fz_renderer *drawgc = nil; -void closexref(void); - -/* - * Common operations. - * Parse page selectors. - * Load and decrypt a PDF file. - * Select pages. - */ - -char *basename; -pdf_xref *xref = nil; -pdf_pagetree *pagetree = nil; - -void die(fz_error eo) -{ - fz_catch(eo, "aborting"); - if (drawgc) - fz_droprenderer(drawgc); - closexref(); - exit(-1); -} - -void closexref(void) -{ - if (pagetree) - { - pdf_droppagetree(pagetree); - pagetree = nil; - } - - if (xref) - { - if (xref->store) - { - pdf_dropstore(xref->store); - xref->store = nil; - } - pdf_closexref(xref); - xref = nil; - } - - basename = nil; -} - -void openxref(char *filename, char *password, int loadpages) -{ - fz_error error; - fz_obj *obj; - - closexref(); - - basename = strrchr(filename, '/'); - if (!basename) - basename = filename; - else - basename++; - printf("%s:\n", basename); - - error = pdf_newxref(&xref); - if (error) - die(error); - - error = pdf_loadxref(xref, filename); - if (error) - { - fz_catch(error, "trying to repair"); - error = pdf_repairxref(xref, filename); - if (error) - die(error); - } - - error = pdf_decryptxref(xref); - if (error) - die(error); - - if (xref->crypt) - { - int okay = pdf_setpassword(xref->crypt, password); - if (!okay) - fz_warn("invalid password, attemping to continue."); - } - - if (loadpages) - { - error = pdf_loadpagetree(&pagetree, xref); - if (error) - die(error); - } - - /* TODO: move into mupdf lib, see pdfapp_open in pdfapp.c */ - obj = fz_dictgets(xref->trailer, "Root"); - xref->root = fz_resolveindirect(obj); - if (xref->root) - fz_keepobj(xref->root); - - obj = fz_dictgets(xref->trailer, "Info"); - xref->info = fz_resolveindirect(obj); - if (xref->info) - fz_keepobj(xref->info); - - error = pdf_loadnametrees(xref); - if (error) - die(error); -} +#include "pdftool.h" enum { @@ -183,6 +75,79 @@ int forms = 0; struct info **psobj = nil; int psobjs = 0; +void local_cleanup(void) +{ + int i; + + if (info) + { + free(info); + info = nil; + } + + if (dim) + { + for (i = 0; i < dims; i++) + free(dim[i]); + free(dim); + dim = nil; + } + + if (font) + { + for (i = 0; i < fonts; i++) + free(font[i]); + free(font); + font = nil; + } + + if (image) + { + for (i = 0; i < images; i++) + free(image[i]); + free(image); + image = nil; + } + + if (shading) + { + for (i = 0; i < shadings; i++) + free(shading[i]); + free(shading); + shading = nil; + } + + if (pattern) + { + for (i = 0; i < patterns; i++) + free(pattern[i]); + free(pattern); + pattern = nil; + } + + if (form) + { + for (i = 0; i < forms; i++) + free(form[i]); + free(form); + form = nil; + } + + if (psobj) + { + for (i = 0; i < psobjs; i++) + free(psobj[i]); + free(psobj); + psobj = nil; + } + + if (xref && xref->store) + { + pdf_dropstore(xref->store); + xref->store = nil; + } +} + void infousage(void) { @@ -851,8 +816,8 @@ printinfo(char *filename, int show, int page) } else if (image[i]->u.image.filter) printf("%s", fz_toname(image[i]->u.image.filter)); - else - printf("Raw"); + else + printf("Raw"); printf(" ] %dx%d %dbpc %s%s%s (%d %d R)\n", fz_toint(image[i]->u.image.width), @@ -1078,6 +1043,8 @@ int main(int argc, char **argv) if (fz_optind == argc) infousage(); + setcleanup(local_cleanup); + state = NO_FILE_OPENED; while (fz_optind < argc) { @@ -1087,17 +1054,20 @@ int main(int argc, char **argv) { printglobalinfo(); showinfo(filename, show, "1-"); + closexref(); } + closexref(); filename = argv[fz_optind]; - openxref(filename, password, 1); + openxref(filename, password, 0); + loadpagetree(); gatherglobalinfo(); state = NO_INFO_GATHERED; } else { if (state == NO_INFO_GATHERED) - printglobalinfo(); + printglobalinfo(); showinfo(filename, show, argv[fz_optind]); state = INFO_SHOWN; } diff --git a/apps/pdfshow.c b/apps/pdfshow.c index 44d50774..164daca0 100644 --- a/apps/pdfshow.c +++ b/apps/pdfshow.c @@ -2,63 +2,7 @@ * pdfshow -- the ultimate pdf debugging tool */ -#include "fitz.h" -#include "mupdf.h" - -pdf_xref *xref = NULL; - -void die(fz_error eo) -{ - fz_catch(eo, "aborting"); - exit(1); -} - -void openxref(char *filename, char *password) -{ - fz_error error; - fz_obj *obj; - - error = pdf_newxref(&xref); - if (error) - die(error); - - error = pdf_loadxref(xref, filename); - if (error) - { - fz_catch(error, "trying to repair"); - error = pdf_repairxref(xref, filename); - if (error) - die(error); - } - - error = pdf_decryptxref(xref); - if (error) - die(error); - - if (xref->crypt) - { - int okay = pdf_setpassword(xref->crypt, password); - if (!okay) - fz_warn("invalid password, attempting to continue."); - } - - /* TODO: move into mupdf lib, see pdfapp_open in pdfapp.c */ - obj = fz_dictgets(xref->trailer, "Root"); - xref->root = fz_resolveindirect(obj); - if (xref->root) - fz_keepobj(xref->root); - - obj = fz_dictgets(xref->trailer, "Info"); - xref->info = fz_resolveindirect(obj); - if (xref->info) - fz_keepobj(xref->info); -} - -void closexref() -{ - pdf_closexref(xref); - xref = nil; -} +#include "pdftool.h" int showbinary = 0; int showdecode = 0; @@ -197,7 +141,7 @@ int main(int argc, char **argv) if (fz_optind == argc) showusage(); - openxref(argv[fz_optind++], password); + openxref(argv[fz_optind++], password, 0); if (fz_optind == argc) showtrailer(); diff --git a/apps/pdftool.h b/apps/pdftool.h new file mode 100644 index 00000000..44e9e361 --- /dev/null +++ b/apps/pdftool.h @@ -0,0 +1,14 @@ +#include "fitz.h" +#include "mupdf.h" + +extern char *basename; +extern pdf_xref *xref; +extern pdf_pagetree *pagetree; + +void die(fz_error error); +void setcleanup(void (*cleanup)(void)); + +void openxref(char *filename, char *password, int dieonbadpass); +void closexref(void); + +void loadpagetree(void); -- cgit v1.2.3