From 4220c1656ba6f42621dbd622b77202636a1b666e Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Wed, 14 Jul 2010 15:39:57 +0200 Subject: Refactor pdfclean main() into a set of smaller functions. --- apps/pdfclean.c | 334 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 174 insertions(+), 160 deletions(-) (limited to 'apps/pdfclean.c') diff --git a/apps/pdfclean.c b/apps/pdfclean.c index e033c662..7e81055b 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -336,207 +336,147 @@ static void cleanusage(void) exit(1); } -int main(int argc, char **argv) +static void retainpages(int argc, char **argv) { - char *infile; - char *outfile = "out.pdf"; - char *password = ""; - fz_error error; - int c, num; - int lastfree; - int subset; + fz_obj *root, *pages, *kids; + int count; - while ((c = fz_getopt(argc, argv, "gxp:")) != -1) - { - switch (c) - { - case 'p': password = fz_optarg; break; - case 'g': dogarbage ++; break; - case 'x': doexpand ++; break; - default: cleanusage(); break; - } - } - - if (argc - fz_optind < 1) - cleanusage(); - - infile = argv[fz_optind++]; + /* Snatch pages entry from root dict */ + root = fz_dictgets(xref->trailer, "Root"); + pages = fz_keepobj(fz_dictgets(root, "Pages")); - if (argc - fz_optind > 0 && - (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) + /* Then empty the root dict */ + while (fz_dictlen(root) > 0) { - outfile = argv[fz_optind++]; + fz_obj *key = fz_dictgetkey(root, 0); + fz_dictdel(root, key); } - subset = 0; - if (argc - fz_optind > 0) - subset = 1; - - openxref(infile, password, 0, 1); - - out = fopen(outfile, "wb"); - if (!out) - die(fz_throw("cannot open output file '%s'", outfile)); - - fprintf(out, "%%PDF-%d.%d\n", xref->version / 10, xref->version % 10); - fprintf(out, "%%\342\343\317\323\n\n"); + /* And only retain pages and type entries */ + fz_dictputs(root, "Pages", pages); + fz_dictputs(root, "Type", fz_newname("Catalog")); + fz_dropobj(pages); - uselist = malloc(sizeof (char) * (xref->len + 1)); - ofslist = malloc(sizeof (int) * (xref->len + 1)); - genlist = malloc(sizeof (int) * (xref->len + 1)); + /* Create a new kids array too add into pages dict + * since each element must be replaced to point to + * a retained page */ + kids = fz_newarray(1); + count = 0; - for (num = 0; num < xref->len; num++) + /* Retain pages specified */ + while (argc - fz_optind) { - uselist[num] = 0; - ofslist[num] = 0; - genlist[num] = 0; - } - - /* Make sure any objects hidden in compressed streams have been loaded */ - preloadobjstms(); + int page, spage, epage; + char *spec, *dash; + char *pagelist = argv[fz_optind]; - /* Only retain the specified subset of the pages */ - if (subset) - { - fz_obj *root, *pages, *kids; - int count; - - /* Snatch pages entry from root dict */ - root = fz_dictgets(xref->trailer, "Root"); - pages = fz_keepobj(fz_dictgets(root, "Pages")); - - /* Then empty the root dict */ - while (fz_dictlen(root) > 0) + spec = fz_strsep(&pagelist, ","); + while (spec) { - fz_obj *key = fz_dictgetkey(root, 0); - fz_dictdel(root, key); - } - - /* And only retain pages and type entries */ - fz_dictputs(root, "Pages", pages); - fz_dictputs(root, "Type", fz_newname("Catalog")); - fz_dropobj(pages); + dash = strchr(spec, '-'); - /* Create a new kids array too add into pages dict - * since each element must be replaced to point to - * a retained page */ - kids = fz_newarray(1); - count = 0; + if (dash == spec) + spage = epage = 1; + else + spage = epage = atoi(spec); - /* Retain pages specified */ - while (argc - fz_optind) - { - int page, spage, epage; - char *spec, *dash; - char *pagelist = argv[fz_optind]; - - spec = fz_strsep(&pagelist, ","); - while (spec) + if (dash) { - dash = strchr(spec, '-'); - - if (dash == spec) - spage = epage = 1; + if (strlen(dash) > 1) + epage = atoi(dash + 1); else - spage = epage = atoi(spec); - - if (dash) - { - if (strlen(dash) > 1) - epage = atoi(dash + 1); - else - epage = pagecount; - } - - if (spage > epage) - page = spage, spage = epage, epage = page; - - if (spage < 1) - spage = 1; - if (epage > pagecount) epage = pagecount; + } - for (page = spage; page <= epage; page++) - { - fz_obj *pageobj = pdf_getpageobject(xref, page); - fz_obj *pageref = pdf_getpageref(xref, page); + if (spage > epage) + page = spage, spage = epage, epage = page; - /* Update parent reference */ - fz_dictputs(pageobj, "Parent", pages); + if (spage < 1) + spage = 1; + if (epage > pagecount) + epage = pagecount; - /* Store page object in new kids array */ - fz_arraypush(kids, pageref); - count++; + for (page = spage; page <= epage; page++) + { + fz_obj *pageobj = pdf_getpageobject(xref, page); + fz_obj *pageref = pdf_getpageref(xref, page); - fz_dropobj(pageref); - } + /* Update parent reference */ + fz_dictputs(pageobj, "Parent", pages); - spec = fz_strsep(&pagelist, ","); + /* Store page object in new kids array */ + fz_arraypush(kids, pageref); + count++; + + fz_dropobj(pageref); } - fz_optind++; + spec = fz_strsep(&pagelist, ","); } - /* Update page count and kids array */ - fz_dictputs(pages, "Count", fz_newint(count)); - fz_dictputs(pages, "Kids", kids); + fz_optind++; } - /* Sweep & mark objects from the trailer */ - error = sweepobj(xref->trailer); - if (error) - die(fz_rethrow(error, "cannot mark used objects")); + /* Update page count and kids array */ + fz_dictputs(pages, "Count", fz_newint(count)); + fz_dictputs(pages, "Kids", kids); +} - /* Renumber objects to shorten xref */ - if (dogarbage >= 2) +static void dorenumbering() +{ + int num, newnum; + fz_error error; + + newnumlist = fz_malloc(xref->len * sizeof(int)); + oldxreflist = fz_malloc(xref->len * sizeof(pdf_xrefentry)); + for (num = 0; num < xref->len; num++) { - int newnum; + newnumlist[num] = -1; + oldxreflist[num] = xref->table[num]; + } - newnumlist = fz_malloc(xref->len * sizeof(int)); - oldxreflist = fz_malloc(xref->len * sizeof(pdf_xrefentry)); - for (num = 0; num < xref->len; num++) - { - newnumlist[num] = -1; - oldxreflist[num] = xref->table[num]; - } + newnum = 1; + for (num = 0; num < xref->len; num++) + { + if (xref->table[num].type == 'f') + uselist[num] = 0; - newnum = 1; - for (num = 0; num < xref->len; num++) - { - if (xref->table[num].type == 'f') - uselist[num] = 0; + if (uselist[num]) + newnumlist[num] = newnum++; + } - if (uselist[num]) - newnumlist[num] = newnum++; - } + error = renumberobj(xref->trailer); + if (error) + die(fz_rethrow(error, "cannot renumber used objects")); - error = renumberobj(xref->trailer); + for (num = 0; num < xref->len; num++) + { + error = renumberobj(xref->table[num].obj); if (error) die(fz_rethrow(error, "cannot renumber used objects")); + } - for (num = 0; num < xref->len; num++) - { - error = renumberobj(xref->table[num].obj); - if (error) - die(fz_rethrow(error, "cannot renumber used objects")); - } + for (num = 0; num < xref->len; num++) + uselist[num] = 0; - for (num = 0; num < xref->len; num++) - uselist[num] = 0; + for (num = 0; num < xref->len; num++) + if (newnumlist[num] >= 0) + { + xref->table[newnumlist[num]] = oldxreflist[num]; + uselist[newnumlist[num]] = 1; + } - for (num = 0; num < xref->len; num++) - if (newnumlist[num] >= 0) - { - xref->table[newnumlist[num]] = oldxreflist[num]; - uselist[newnumlist[num]] = 1; - } + fz_free(oldxreflist); + fz_free(newnumlist); - fz_free(oldxreflist); - fz_free(newnumlist); + xref->len = newnum; +} - xref->len = newnum; - } +static void outputpdf() +{ + int lastfree; + int num; for (num = 0; num < xref->len; num++) { @@ -573,6 +513,80 @@ int main(int argc, char **argv) } savexref(); +} + +int main(int argc, char **argv) +{ + char *infile; + char *outfile = "out.pdf"; + char *password = ""; + fz_error error; + int c, num; + int subset; + + while ((c = fz_getopt(argc, argv, "gxp:")) != -1) + { + switch (c) + { + case 'p': password = fz_optarg; break; + case 'g': dogarbage ++; break; + case 'x': doexpand ++; break; + default: cleanusage(); break; + } + } + + if (argc - fz_optind < 1) + cleanusage(); + + infile = argv[fz_optind++]; + + if (argc - fz_optind > 0 && + (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) + { + outfile = argv[fz_optind++]; + } + + subset = 0; + if (argc - fz_optind > 0) + subset = 1; + + openxref(infile, password, 0, 1); + + out = fopen(outfile, "wb"); + if (!out) + die(fz_throw("cannot open output file '%s'", outfile)); + + fprintf(out, "%%PDF-%d.%d\n", xref->version / 10, xref->version % 10); + fprintf(out, "%%\342\343\317\323\n\n"); + + uselist = malloc(sizeof (char) * (xref->len + 1)); + ofslist = malloc(sizeof (int) * (xref->len + 1)); + genlist = malloc(sizeof (int) * (xref->len + 1)); + + for (num = 0; num < xref->len; num++) + { + uselist[num] = 0; + ofslist[num] = 0; + genlist[num] = 0; + } + + /* Make sure any objects hidden in compressed streams have been loaded */ + preloadobjstms(); + + /* Only retain the specified subset of the pages */ + if (subset) + retainpages(argc, argv); + + /* Sweep & mark objects from the trailer */ + error = sweepobj(xref->trailer); + if (error) + die(fz_rethrow(error, "cannot mark used objects")); + + /* Renumber objects to shorten xref */ + if (dogarbage >= 2) + dorenumbering(); + + outputpdf(); closexref(); -- cgit v1.2.3