diff options
-rw-r--r-- | Jamrules | 2 | ||||
-rw-r--r-- | apps/Jamfile | 6 | ||||
-rw-r--r-- | apps/pdfclean.c | 184 | ||||
-rw-r--r-- | apps/pdfdebug.c | 190 | ||||
-rw-r--r-- | apps/pdfmerge.c | 224 | ||||
-rw-r--r-- | apps/pdfrip.c | 290 | ||||
-rw-r--r-- | apps/pdfselect.c | 299 | ||||
-rw-r--r-- | apps/pdftool.c | 874 | ||||
-rw-r--r-- | apps/samshow.c | 30 | ||||
-rw-r--r-- | base/base_error.c | 16 | ||||
-rw-r--r-- | include/fitz/base_runtime.h | 1 |
11 files changed, 901 insertions, 1215 deletions
@@ -43,7 +43,7 @@ switch $(OS) NEED_STRLCAT = yes ; NEED_STRSEP = yes ; FLAG_CCALL += -std=gnu99 -DHAVE_C99 ; - FLAG_LDALL += -L/usr/X11R6/lib ; + FLAG_LDALL += -L/opt/local/lib -L/usr/X11R6/lib ; switch $(CC)-$(OSPLAT) { diff --git a/apps/Jamfile b/apps/Jamfile index 4accf75a..672b8671 100644 --- a/apps/Jamfile +++ b/apps/Jamfile @@ -6,11 +6,7 @@ SubDir TOP apps ; APPLIST = - pdfrip - pdfclean - pdfdebug - pdfmerge - pdfselect + pdftool samshow ; diff --git a/apps/pdfclean.c b/apps/pdfclean.c deleted file mode 100644 index 05bef10f..00000000 --- a/apps/pdfclean.c +++ /dev/null @@ -1,184 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -void usage() -{ - fprintf(stderr, - "usage: pdfclean [options] infile.pdf outfile.pdf\n" - " -d -\tpassword for decryption\n" - " -g \tgarbage collect unused objects\n" - " -r \trebuild xref table\n" - " -x \texpand compressed streams\n" - " -e \tencrypt outfile\n" - " -u -\tset user password for encryption\n" - " -o -\tset owner password\n" - " -p -\tset permissions (combine letters 'pmca')\n" - " -n -\tkey length in bits: 40 <= n <= 128\n" - ); - exit(1); -} - -void preloadobjstms(pdf_xref *xref) -{ - fz_error *error; - fz_obj *obj; - int i; - - for (i = 0; i < xref->len; i++) - { - if (xref->table[i].type == 'o') - { - error = pdf_loadobject(&obj, xref, i, 0); - if (error) fz_abort(error); - fz_dropobj(obj); - } - } -} - -void expandstreams(pdf_xref *xref) -{ - fz_error *error; - fz_obj *stmobj; - fz_buffer *buf; - fz_obj *stmlen; - int i, gen; - - for (i = 0; i < xref->len; i++) - { - if (xref->table[i].type == 'n') - { - gen = xref->table[i].gen; - - if (pdf_isstream(xref, i, gen)) - { - error = pdf_loadobject(&stmobj, xref, i, gen); - if (error) fz_abort(error); - - error = pdf_loadstream(&buf, xref, i, gen); - if (error) fz_abort(error); - - fz_dictdels(stmobj, "Filter"); - fz_dictdels(stmobj, "DecodeParms"); - - error = fz_newint(&stmlen, buf->wp - buf->rp); - if (error) fz_abort(error); - error = fz_dictputs(stmobj, "Length", stmlen); - if (error) fz_abort(error); - fz_dropobj(stmlen); - - pdf_updateobject(xref, i, gen, stmobj); - pdf_updatestream(xref, i, gen, buf); - - fz_dropobj(stmobj); - } - } - } -} - -int main(int argc, char **argv) -{ - fz_error *error; - char *infile; - char *outfile; - pdf_xref *xref; - int c; - - pdf_crypt *encrypt = 0; - int doencrypt = 0; - int dorepair = 0; - int doexpand = 0; - int dogc = 0; - - char *userpw = ""; - char *ownerpw = ""; - unsigned perms = 0xfffff0c0; /* nothing allowed */ - int keylen = 40; - char *password = ""; - - while ((c = getopt(argc, argv, "rgxd:eu:o:p:n:")) != -1) - { - switch (c) - { - case 'r': ++ dorepair; break; - case 'x': ++ doexpand; break; - case 'g': ++ dogc; break; - case 'e': ++ doencrypt; break; - case 'u': userpw = optarg; break; - case 'o': ownerpw = optarg; break; - case 'p': - /* see TABLE 3.15 User access permissions */ - perms = 0xfffff0c0; - if (strchr(optarg, 'p')) /* print */ - perms |= (1 << 2) | (1 << 11); - if (strchr(optarg, 'm')) /* modify */ - perms |= (1 << 3) | (1 << 10); - if (strchr(optarg, 'c')) /* copy */ - perms |= (1 << 4) | (1 << 9); - if (strchr(optarg, 'a')) /* annotate / forms */ - perms |= (1 << 5) | (1 << 8); - break; - case 'n': keylen = atoi(optarg); break; - case 'd': password = optarg; break; - default: usage(); - } - } - - if (argc - optind < 2) - usage(); - - infile = argv[optind++]; - outfile = argv[optind++]; - - error = pdf_newxref(&xref); - - if (dorepair) - error = pdf_repairxref(xref, infile); - else - error = pdf_loadxref(xref, infile); - if (error) - fz_abort(error); - - error = pdf_decryptxref(xref); - if (error) - fz_abort(error); - - if (xref->crypt) - { - error = pdf_setpassword(xref->crypt, password); - if (error) fz_abort(error); - } - - if (doencrypt) - { - fz_obj *id = fz_dictgets(xref->trailer, "ID"); - if (!id) - fz_packobj(&id, "[(ABCDEFGHIJKLMNOP)(ABCDEFGHIJKLMNOP)]"); - else - fz_keepobj(id); - error = pdf_newencrypt(&encrypt, userpw, ownerpw, perms, keylen, id); - if (error) - fz_abort(error); - fz_dropobj(id); - } - - if (doexpand) - expandstreams(xref); - - if (dogc) - { - preloadobjstms(xref); - pdf_garbagecollect(xref); - } - - error = pdf_savexref(xref, outfile, encrypt); - if (error) - fz_abort(error); - - if (encrypt) - pdf_dropcrypt(encrypt); - - pdf_closexref(xref); - - return 0; -} - diff --git a/apps/pdfdebug.c b/apps/pdfdebug.c deleted file mode 100644 index 3a3f8321..00000000 --- a/apps/pdfdebug.c +++ /dev/null @@ -1,190 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -static char *password = ""; -static int dodecode = 0; -static int doprintxref = 0; - -void usage() -{ - fprintf(stderr, "usage: pdfdebug [-dx] [-u password] file.pdf [oid ...]\n"); - exit(1); -} - -/* - * Debug-print stream contents - */ - -static int safecol = 0; - -void printsafe(unsigned char *buf, int n) -{ - int i; - for (i = 0; i < n; i++) { - if (buf[i] == '\r' || buf[i] == '\n') { - printf("\n"); - safecol = 0; - } - else if (buf[i] < 32 || buf[i] > 126) { - printf("."); - safecol ++; - } - else { - printf("%c", buf[i]); - safecol ++; - } - if (safecol == 79) { - printf("\n"); - safecol = 0; - } - } -} - -void decodestream(pdf_xref *xref, int oid, int gid) -{ - fz_error *error; - fz_stream *stm; - unsigned char buf[512]; - - safecol = 0; - - error = pdf_openstream(&stm, xref, oid, gid); - if (error) fz_abort(error); - - while (1) - { - int n = fz_read(stm, buf, sizeof buf); - if (n == 0) - break; - if (n < 0) - fz_abort(fz_ioerror(stm)); - printsafe(buf, n); - } - - fz_dropstream(stm); -} - -void copystream(pdf_xref *xref, int oid, int gid) -{ - fz_error *error; - fz_stream *stm; - unsigned char buf[512]; - - safecol = 0; - - error = pdf_openrawstream(&stm, xref, oid, gid); - if (error) fz_abort(error); - - while (1) - { - int n = fz_read(stm, buf, sizeof buf); - if (n == 0) - break; - if (n < 0) - fz_abort(fz_ioerror(stm)); - printsafe(buf, n); - } - - fz_dropstream(stm); -} - -void printobject(pdf_xref *xref, int oid, int gid) -{ - fz_error *error; - fz_obj *obj; - - error = pdf_loadobject(&obj, xref, oid, gid); - if (error) fz_abort(error); - - printf("%d %d obj\n", oid, gid); - fz_debugobj(obj); - printf("\n"); - - if (xref->table[oid].stmofs) { - printf("stream\n"); - if (dodecode) - decodestream(xref, oid, gid); - else - copystream(xref, oid, gid); - printf("endstream\n"); - } - - printf("endobj\n"); - - fz_dropobj(obj); -} - -int main(int argc, char **argv) -{ - fz_error *error; - char *filename; - pdf_xref *xref; - int c; - - while ((c = getopt(argc, argv, "dxu:")) != -1) - { - switch (c) - { - case 'd': - dodecode ++; - break; - case 'x': - doprintxref ++; - break; - case 'u': - password = optarg; - break; - default: - usage(); - } - } - - if (argc - optind == 0) - usage(); - - filename = argv[optind++]; - - error = pdf_newxref(&xref); - if (error) - fz_abort(error); - - 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); - - if (xref->crypt) - { - error = pdf_setpassword(xref->crypt, password); - if (error) fz_abort(error); - } - - if (optind == argc) - { - printf("trailer\n"); - fz_debugobj(xref->trailer); - printf("\n"); - } - - for ( ; optind < argc; optind++) - { - printobject(xref, atoi(argv[optind]), 0); - printf("\n"); - } - - if (doprintxref) - pdf_debugxref(xref); - - pdf_closexref(xref); - - return 0; -} - diff --git a/apps/pdfmerge.c b/apps/pdfmerge.c deleted file mode 100644 index 8c431308..00000000 --- a/apps/pdfmerge.c +++ /dev/null @@ -1,224 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -void usage() -{ - fprintf(stderr, - "usage: pdfmerge [options] file1.pdf file2.pdf ...\n" - " -d -\tpassword for decryption\n" - " -o -\toutput file name (default out.pdf)\n" - " -v \tverbose\n" - ); - exit(1); -} - -int main(int argc, char **argv) -{ - fz_error *error; - char *savename = "out.pdf"; - pdf_pagetree *srcpages; - fz_obj *srcrefs; - fz_obj *newsrcrefs; - fz_obj *dstrefs; - pdf_xref *dst; - pdf_xref *src; - int rootoid; - int rootgid; - int pagesoid; - int pagesgid; - fz_obj *pagesref; - fz_obj *obj; - int i, k; - int c; - - int verbose = 0; - char *password = ""; - - while ((c = getopt(argc, argv, "vo:d:")) != -1) - { - switch (c) - { - case 'v': ++ verbose; break; - case 'o': savename = optarg; break; - case 'd': password = optarg; break; - default: usage(); - } - } - - if (argc - optind < 1) - usage(); - - /* - * Create new blank xref table - */ - - error = pdf_newxref(&dst); - if (error) - fz_abort(error); - - error = pdf_initxref(dst); - if (error) - fz_abort(error); - - error = fz_newarray(&dstrefs, 100); - if (error) - fz_abort(error); - - /* - * Copy pages saving refs in dstrefs - */ - - for (i = optind; i < argc; i++) - { - if (verbose) - { - printf("loading pdf '%s' ", argv[i]); - fflush(stdout); - } - - error = pdf_newxref(&src); - if (error) - fz_abort(error); - - error = pdf_loadxref(src, argv[i]); - if (error) - fz_abort(error); - - error = pdf_decryptxref(src); - if (error) - fz_abort(error); - - if (src->crypt) - { - error = pdf_setpassword(src->crypt, password); - if (error) - fz_abort(error); - } - - error = pdf_loadpagetree(&srcpages, src); - if (error) - fz_abort(error); - - error = fz_newarray(&srcrefs, 100); - if (error) - fz_abort(error); - - if (verbose) - printf("(%d pages)\n", srcpages->count); - - for (k = 0; k < srcpages->count; k++) - { - fz_dictdels(srcpages->pobj[k], "Parent"); - fz_dictdels(srcpages->pobj[k], "B"); - fz_dictdels(srcpages->pobj[k], "PieceInfo"); - fz_dictdels(srcpages->pobj[k], "Metadata"); - fz_dictdels(srcpages->pobj[k], "Annots"); - fz_dictdels(srcpages->pobj[k], "Tabs"); - - pdf_updateobject(src, - fz_tonum(srcpages->pref[k]), - fz_togen(srcpages->pref[k]), - srcpages->pobj[k]); - error = fz_arraypush(srcrefs, srcpages->pref[k]); - if (error) - fz_abort(error); - } - - error = pdf_transplant(dst, src, &newsrcrefs, srcrefs); - if (error) - fz_abort(error); - - for (k = 0; k < fz_arraylen(newsrcrefs); k++) - { - error = fz_arraypush(dstrefs, fz_arrayget(newsrcrefs, k)); - if (error) - fz_abort(error); - } - - fz_dropobj(srcrefs); - fz_dropobj(newsrcrefs); - - pdf_droppagetree(srcpages); - - pdf_closexref(src); - } - - /* - * Create and relink Pages object - */ - - if (verbose) - printf("creating pdf '%s' (%d pages)\n", - savename, fz_arraylen(dstrefs)); - - error = pdf_allocobject(dst, &pagesoid, &pagesgid); - if (error) - fz_abort(error); - - error = fz_packobj(&obj, - "<</Type/Pages/Count %i/Kids %o>>", - fz_arraylen(dstrefs), - dstrefs); - if (error) - fz_abort(error); - - pdf_updateobject(dst, pagesoid, pagesgid, obj); - - fz_dropobj(obj); - - error = fz_newindirect(&pagesref, pagesoid, pagesgid); - if (error) - fz_abort(error); - - for (i = 0; i < fz_arraylen(dstrefs); i++) - { - int oid = fz_tonum(fz_arrayget(dstrefs, i)); - int gid = fz_togen(fz_arrayget(dstrefs, i)); - error = pdf_loadobject(&obj, dst, oid, gid); - if (error) - fz_abort(error); - error = fz_dictputs(obj, "Parent", pagesref); - if (error) - fz_abort(error); - pdf_updateobject(dst, oid, gid, obj); - fz_dropobj(obj); - } - - fz_dropobj(pagesref); - - /* - * Create Catalog and trailer - */ - - error = pdf_allocobject(dst, &rootoid, &rootgid); - if (error) - fz_abort(error); - - error = fz_packobj(&obj, - "<</Type/Catalog/Pages %r>>", - pagesoid, pagesgid); - if (error) - fz_abort(error); - - pdf_updateobject(dst, rootoid, rootgid, obj); - - fz_dropobj(obj); - - error = fz_packobj(&dst->trailer, "<</Root %r>>", rootoid, rootgid); - if (error) - fz_abort(error); - - /* - * Write out the new PDF - */ - - error = pdf_savexref(dst, savename, nil); - if (error) - fz_abort(error); - - fz_dropobj(dstrefs); - pdf_closexref(dst); - - return 0; -} - diff --git a/apps/pdfrip.c b/apps/pdfrip.c deleted file mode 100644 index 59d0fa48..00000000 --- a/apps/pdfrip.c +++ /dev/null @@ -1,290 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -int showtree = 0; -float zoom = 1.0; -char *namefmt = nil; -fz_renderer *gc; -int nbands = 1; -int verbose = 0; -int textonly = 0; - -void usage() -{ - fprintf(stderr, -"usage: pdfrip [options] file.pdf pageranges\n" -" -b -\trender page in N bands (default 1)\n" -" -d -\tpassword for decryption\n" -" -g \tshow display tree -- debug\n" -" -o -\toutput filename format (default out-%%03d.ppm)\n" -" -t \tprint text on stdout instead of rendering\n" -" -v \tverbose\n" -" -z -\tzoom factor (default 1.0 = 72 dpi)\n" - ); - exit(1); -} - -/* - * Draw page - */ - -void showpage(pdf_xref *xref, fz_obj *pageobj, int pagenum) -{ - fz_error *error; - pdf_page *page; - char namebuf[256]; - char buf[128]; - fz_pixmap *pix; - fz_matrix ctm; - fz_irect bbox; - int fd; - int x, y; - int w, h; - int b, bh; - - if (verbose) - printf("page %d\n", pagenum); - - sprintf(namebuf, namefmt, pagenum); - - error = pdf_loadpage(&page, xref, pageobj); - if (error) - fz_abort(error); - - if (showtree) - { - fz_debugobj(pageobj); - printf("\n"); - - printf("page\n"); - printf(" mediabox [ %g %g %g %g ]\n", - page->mediabox.x0, page->mediabox.y0, - page->mediabox.x1, page->mediabox.y1); - printf(" rotate %d\n", page->rotate); - - printf(" resources\n"); - fz_debugobj(page->resources); - printf("\n"); - - printf("tree\n"); - fz_debugtree(page->tree); - printf("endtree\n"); - } - - ctm = fz_concat(fz_translate(0, -page->mediabox.y1), - fz_scale(zoom, -zoom)); - - if (textonly) - { - pdf_textline *line; - - error = pdf_loadtextfromtree(&line, page->tree, ctm); - if (error) - fz_abort(error); - pdf_debugtextline(line); - pdf_droptextline(line); - pdf_droppage(page); - - printf("\n\f\n"); - - return; - } - - bbox = fz_roundrect(page->mediabox); - bbox.x0 = bbox.x0 * zoom; - bbox.y0 = bbox.y0 * zoom; - bbox.x1 = bbox.x1 * zoom; - bbox.y1 = bbox.y1 * zoom; - w = bbox.x1 - bbox.x0; - h = bbox.y1 - bbox.y0; - bh = h / nbands; - - fd = open(namebuf, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666); - if (fd < 0) - fz_abort(fz_throw("open %s failed: %s", namebuf, strerror(errno))); - sprintf(buf, "P6\n%d %d\n255\n", w, bh * nbands); - write(fd, buf, strlen(buf)); - - error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4); - if (error) - fz_abort(error); - - for (b = 0; b < nbands; b++) - { - if (verbose) - printf("render band %d of %d\n", b + 1, nbands); - - memset(pix->samples, 0xff, pix->w * pix->h * 4); - - error = fz_rendertreeover(gc, pix, page->tree, ctm); - if (error) - fz_abort(error); - - for (y = 0; y < pix->h; y++) - { - unsigned char *src = pix->samples + y * pix->w * 4; - unsigned char *dst = src; - - for (x = 0; x < pix->w; x++) - { - dst[x * 3 + 0] = src[x * 4 + 1]; - dst[x * 3 + 1] = src[x * 4 + 2]; - dst[x * 3 + 2] = src[x * 4 + 3]; - } - - write(fd, dst, pix->w * 3); - } - - pix->y += bh; - } - - fz_droppixmap(pix); - - close(fd); - - pdf_droppage(page); -} - -int main(int argc, char **argv) -{ - fz_error *error; - char *filename; - pdf_xref *xref; - pdf_pagetree *pages; - int c; - - char *password = ""; - - fz_cpudetect(); - fz_accelerate(); - - while ((c = getopt(argc, argv, "Vgtvz:d:o:b:")) != -1) - { - switch (c) - { - case 'g': ++showtree; break; - case 't': ++textonly; break; - case 'v': ++verbose; break; - case 'd': password = optarg; break; - case 'z': zoom = atof(optarg); break; - case 'o': namefmt = optarg; break; - case 'b': nbands = atoi(optarg); break; - default: usage(); - } - } - - if (argc - optind == 0) - usage(); - - filename = argv[optind++]; - - if (!namefmt) - { -#if 1 - namefmt = "out-%03d.ppm"; -#else - char namebuf[256]; - char *s; - s = strrchr(filename, '/'); - if (!s) - s = filename; - else - s ++; - strcpy(namebuf, s); - s = strrchr(namebuf, '.'); - if (s) - strcpy(s, "-%03d.ppm"); - else - strcat(namebuf, "-%03d.ppm"); - namefmt = namebuf; -#endif - } - - if (verbose) - printf("loading pdf: '%s'\n", filename); - - error = pdf_newxref(&xref); - if (error) - fz_abort(error); - - error = pdf_loadxref(xref, filename); - if (error) - fz_abort(error); - - error = pdf_decryptxref(xref); - if (error) - fz_abort(error); - - if (xref->crypt) - { - error = pdf_setpassword(xref->crypt, password); - if (error) - fz_abort(error); - } - - error = pdf_loadpagetree(&pages, xref); - if (error) - fz_abort(error); - - if (verbose) - pdf_debugpagetree(pages); - - if (optind == argc) - { - printf("%d pages\n", pdf_getpagecount(pages)); - return 0; - } - - if (textonly) - { - puts("Content-Type: text/plain; charset=UTF-8"); - puts(""); - } - - error = fz_newrenderer(&gc, pdf_devicergb, 0, 1024 * 512); - if (error) - fz_abort(error); - - for ( ; optind < argc; optind++) - { - int spage, epage, page; - char *spec = argv[optind]; - char *dash = strchr(spec, '-'); - - if (dash == spec) - spage = epage = 1; - else - spage = epage = atoi(spec); - - if (dash) - { - if (strlen(dash) > 1) - epage = atoi(dash+1); - else - epage = pdf_getpagecount(pages); - } - - if (spage > epage) - page = spage, spage = epage, epage = page; - - for (page = spage; page <= epage; page++) - { - if (page < 1 || page > pdf_getpagecount(pages)) - fprintf(stderr, "page out of bounds: %d\n", page); - else - { - showpage(xref, pdf_getpageobject(pages, page - 1), page); - } - } - } - - fz_droprenderer(gc); - - pdf_dropstore(xref->store); - xref->store = nil; - - pdf_closexref(xref); - - return 0; -} - diff --git a/apps/pdfselect.c b/apps/pdfselect.c deleted file mode 100644 index f2381f94..00000000 --- a/apps/pdfselect.c +++ /dev/null @@ -1,299 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -void usage() -{ - fprintf(stderr, - "usage: pdfselect [options] infile.pdf outfile.pdf pageranges\n" - " -d -\tpassword for decryption\n" - " -e \tselect only even pages\n" - " -o \tselect only odd pages\n" - " -r \toutput in reverse order\n" - " -v \tverbose\n" - ); - exit(1); -} - -void preloadobjstms(pdf_xref *xref) -{ - fz_error *error; - fz_obj *obj; - int i; - - for (i = 0; i < xref->len; i++) - { - if (xref->table[i].type == 'o') - { - error = pdf_loadobject(&obj, xref, i, 0); - if (error) fz_abort(error); - fz_dropobj(obj); - } - } -} - -int main(int argc, char **argv) -{ - fz_error *error; - char *password = ""; - char *infile; - char *outfile; - pdf_xref *xref; - pdf_pagetree *pages; - fz_obj *pagesref; - fz_obj *kids; - int i, k; - int c; - int page; - int rootoid; - int rootgid; - int kidsoid; - int kidsgid; - int pagesoid; - int pagesgid; - fz_obj *obj; - - int verbose = 0; - int even = 0; - int odd = 0; - int reverse = 0; - int all = 0; - - while ((c = getopt(argc, argv, "d:eorv")) != -1) - { - switch (c) - { - case 'd': password = optarg; break; - case 'e': ++ even; break; - case 'o': ++ odd; break; - case 'r': ++ reverse; break; - case 'v': ++ verbose; break; - default: usage(); - } - } - - if (argc - optind < 2) - usage(); - - if (argc - optind < 3 && !even && !odd && !reverse) - usage(); - - if (argc - optind == 2) - all = 1; - - infile = argv[optind++]; - outfile = argv[optind++]; - - if (verbose) - printf("loading pdf '%s'\n", infile); - - error = pdf_newxref(&xref); - if (error) - fz_abort(error); - - error = pdf_loadxref(xref, infile); - if (error) - fz_abort(error); - - error = pdf_decryptxref(xref); - if (error) - fz_abort(error); - - if (xref->crypt) - { - error = pdf_setpassword(xref->crypt, password); - if (error) - fz_abort(error); - } - - error = pdf_loadpagetree(&pages, xref); - if (error) - fz_abort(error); - - /* - * Kill annotations on all pages - */ - - if (verbose) - printf("killing time\n"); - - for (k = 0; k < pages->count; k++) - { - fz_dictdels(pages->pobj[k], "Parent"); - fz_dictdels(pages->pobj[k], "B"); - fz_dictdels(pages->pobj[k], "PieceInfo"); - fz_dictdels(pages->pobj[k], "Metadata"); - fz_dictdels(pages->pobj[k], "Annots"); - fz_dictdels(pages->pobj[k], "Tabs"); - pdf_updateobject(xref, - fz_tonum(pages->pref[k]), - fz_togen(pages->pref[k]), - pages->pobj[k]); - } - - /* - * Save the pages we want to keep, in the order specified - */ - - error = fz_newarray(&kids, 100); - if (error) - fz_abort(error); - - for ( ; optind < argc; optind++) - { - int spage, epage; - char *spec = argv[optind]; - char *dash = strchr(spec, '-'); - - if (dash == spec) - spage = epage = 1; - else - spage = epage = atoi(spec); - - if (dash) - { - if (strlen(dash) > 1) - epage = atoi(dash+1); - else - epage = pdf_getpagecount(pages); - } - - if (spage > epage) - page = spage, spage = epage, epage = page; - - for (page = spage; page <= epage; page++) - { - if (page < 1 || page > pdf_getpagecount(pages)) - continue; - if (odd && (page & 1) != 1) - continue; - if (even && (page & 1) != 0) - continue; - error = fz_arraypush(kids, pages->pref[page-1]); - if (error) - fz_abort(error); - } - } - - if (all) - { - for (page = 1; page <= pdf_getpagecount(pages); page++) - { - if (odd && (page & 1) != 1) - continue; - if (even && (page & 1) != 0) - continue; - error = fz_arraypush(kids, pages->pref[page-1]); - if (error) - fz_abort(error); - } - } - - if (reverse) - { - fz_obj *o1, *o2; - int len = fz_arraylen(kids); - for (i = 0; i < len / 2; i++) - { - o1 = fz_keepobj(fz_arrayget(kids, i)); - o2 = fz_keepobj(fz_arrayget(kids, len - i - 1)); - fz_arrayput(kids, i, o2); - fz_arrayput(kids, len - i - 1, o1); - } - } - - /* - * Save the new kids array - */ - - error = pdf_allocobject(xref, &kidsoid, &kidsgid); - if (error) - fz_abort(error); - - pdf_updateobject(xref, kidsoid, kidsgid, kids); - - /* - * Save the new pages object - */ - - error = pdf_allocobject(xref, &pagesoid, &pagesgid); - if (error) - fz_abort(error); - - error = fz_packobj(&obj, - "<</Type/Pages/Count %i/Kids %r>>", - fz_arraylen(kids), kidsoid, kidsgid); - if (error) - fz_abort(error); - - pdf_updateobject(xref, pagesoid, pagesgid, obj); - - fz_dropobj(obj); - - /* - * Relink parents to point to new pages object - */ - - error = fz_newindirect(&pagesref, pagesoid, pagesgid); - if (error) - fz_abort(error); - - for (i = 0; i < fz_arraylen(kids); i++) - { - int oid = fz_tonum(fz_arrayget(kids, i)); - int gid = fz_togen(fz_arrayget(kids, i)); - error = pdf_loadobject(&obj, xref, oid, gid); - if (error) - fz_abort(error); - error = fz_dictputs(obj, "Parent", pagesref); - if (error) - fz_abort(error); - pdf_updateobject(xref, oid, gid, obj); - fz_dropobj(obj); - } - - fz_dropobj(pagesref); - - /* - * Create new catalog and trailer - */ - - error = pdf_allocobject(xref, &rootoid, &rootgid); - if (error) - fz_abort(error); - - error = fz_packobj(&obj, - "<</Type/Catalog/Pages %r>>", - pagesoid, pagesgid); - if (error) - fz_abort(error); - - pdf_updateobject(xref, rootoid, rootgid, obj); - - fz_dropobj(obj); - - error = fz_packobj(&xref->trailer, "<</Root %r>>", rootoid, rootgid); - if (error) - fz_abort(error); - - /* - * Write out the new PDF - */ - - if (verbose) - printf("garbage collecting\n"); - - preloadobjstms(xref); - pdf_garbagecollect(xref); - - if (verbose) - printf("saving pdf '%s'\n", outfile); - - error = pdf_savexref(xref, outfile, nil); - if (error) - fz_abort(error); - - pdf_closexref(xref); - - return 0; -} - diff --git a/apps/pdftool.c b/apps/pdftool.c new file mode 100644 index 00000000..ba721e96 --- /dev/null +++ b/apps/pdftool.c @@ -0,0 +1,874 @@ +/* + * Swiss army knife for manipulating and debugging PDFs. + * + * There are a few major modes of operation: + * + * show -- pretty-print objects and streams + * draw -- render pages to bitmap + * clean -- simple rewrite of pdf file + * edit -- edit pages (impose and copy operations) + */ + +#include "fitz.h" +#include "mupdf.h" + +/* + * Common operations. + * Parse page selectors. + * Load and decrypt a PDF file. + * Select pages. + */ + +pdf_xref *src = nil; +pdf_pagetree *srcpages = nil; + +void die(fz_error *eo) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); + fflush(stderr); + abort(); +} + +void closesrc(void) +{ + if (srcpages) + { + pdf_droppagetree(srcpages); + srcpages = nil; + } + + if (src) + { + if (src->store) + { + pdf_dropstore(src->store); + src->store = nil; + } + pdf_closexref(src); + src = nil; + } +} + +void opensrc(char *filename, char *password, int loadpages) +{ + fz_error *error; + + closesrc(); + + error = pdf_newxref(&src); + if (error) + die(error); + + error = pdf_loadxref(src, filename); + if (error) + { + fz_warn("trying to repair"); + error = pdf_repairxref(src, filename); + if (error) + die(error); + } + + error = pdf_decryptxref(src); + if (error) + die(error); + + if (src->crypt) + { + error = pdf_setpassword(src->crypt, password); + if (error) + die(error); + } + + if (loadpages) + { + error = pdf_loadpagetree(&srcpages, src); + if (error) + die(error); + } +} + +void preloadobjstms(void) +{ + fz_error *error; + fz_obj *obj; + int i; + + for (i = 0; i < src->len; i++) + { + if (src->table[i].type == 'o') + { + error = pdf_loadobject(&obj, src, i, 0); + if (error) die(error); + fz_dropobj(obj); + } + } +} + +/* --------------------------------------------------------------------- */ + +/* + * Debug print parts of the PDF. + */ + +int showbinary = 0; +int showdecode = 0; +int showcolumn; + +void showusage(void) +{ + fprintf(stderr, "usage: pdftool show [-bd] <file> [xref] [trailer] [object numbers]\n"); + fprintf(stderr, " -b \tprint streams as raw binary data\n"); + fprintf(stderr, " -d \tdecode streams\n"); + exit(1); +} + +void showtrailer(void) +{ + if (!src) + die(fz_throw("no file specified")); + printf("trailer\n"); + fz_debugobj(src->trailer); + printf("\n\n"); +} + +void showxref(void) +{ + if (!src) + die(fz_throw("no file specified")); + pdf_debugxref(src); + printf("\n"); +} + +void showsafe(unsigned char *buf, int n) +{ + int i; + for (i = 0; i < n; i++) { + if (buf[i] == '\r' || buf[i] == '\n') { + putchar('\n'); + showcolumn = 0; + } + else if (buf[i] < 32 || buf[i] > 126) { + putchar('.'); + showcolumn ++; + } + else { + putchar(buf[i]); + showcolumn ++; + } + if (showcolumn == 79) { + putchar('\n'); + showcolumn = 0; + } + } +} + +void showstream(int num, int gen) +{ + fz_error *error; + fz_stream *stm; + unsigned char buf[2048]; + int n; + + showcolumn = 0; + + if (showdecode) + error = pdf_openstream(&stm, src, num, gen); + else + error = pdf_openrawstream(&stm, src, num, gen); + if (error) + die(error); + + while (1) + { + n = fz_read(stm, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + die(fz_ioerror(stm)); + + if (showbinary) + fwrite(buf, 1, n, stdout); + else + showsafe(buf, n); + } + + fz_dropstream(stm); +} + +void showobject(int num, int gen) +{ + fz_error *error; + fz_obj *obj; + + if (!src) + die(fz_throw("no file specified")); + + error = pdf_loadobject(&obj, src, num, gen); + if (error) + die(error); + + printf("%d %d obj\n", num, gen); + fz_debugobj(obj); + printf("\n"); + + if (pdf_isstream(src, num, gen)) + { + printf("stream\n"); + showstream(num, gen); + printf("endstream\n"); + } + + printf("endobj\n\n"); + + fz_dropobj(obj); +} + +void +showmain(int argc, char **argv) +{ + int c; + + while ((c = getopt(argc, argv, "bd")) != -1) + { + switch (c) + { + case 'b': showbinary ++; break; + case 'd': showdecode ++; break; + default: + showusage(); + break; + } + } + + if (optind == argc) + showusage(); + + opensrc(argv[optind++], "", 0); + + if (optind == argc) + showtrailer(); + + while (optind < argc) + { + if (!strcmp(argv[optind], "trailer")) + showtrailer(); + else if (!strcmp(argv[optind], "xref")) + showxref(); + else + showobject(atoi(argv[optind]), 0); + optind++; + } +} + +/* --------------------------------------------------------------------- */ + +/* + * Clean tool. + * Rewrite PDF. + * Garbage collect. + * Decompress streams. + * Encrypt or decrypt. + */ + +void +cleanusage(void) +{ + fprintf(stderr, + "usage: pdftool clean [options] input.pdf [outfile.pdf]\n" + " -d -\tpassword for decryption\n" + " -g \tgarbage collect unused objects\n" + " -x \texpand compressed streams\n" + " -e \tencrypt output\n" + " -u -\tset user password for encryption\n" + " -o -\tset owner password\n" + " -p -\tset permissions (combine letters 'pmca')\n" + " -n -\tkey length in bits: 40 <= n <= 128\n"); + exit(1); +} + +void +cleanexpand(void) +{ + fz_error *error; + fz_obj *stmobj; + fz_buffer *buf; + fz_obj *stmlen; + int i, gen; + + for (i = 0; i < src->len; i++) + { + if (src->table[i].type == 'n') + { + gen = src->table[i].gen; + + if (pdf_isstream(src, i, gen)) + { + error = pdf_loadobject(&stmobj, src, i, gen); + if (error) die(error); + + error = pdf_loadstream(&buf, src, i, gen); + if (error) die(error); + + fz_dictdels(stmobj, "Filter"); + fz_dictdels(stmobj, "DecodeParms"); + + error = fz_newint(&stmlen, buf->wp - buf->rp); + if (error) die(error); + error = fz_dictputs(stmobj, "Length", stmlen); + if (error) die(error); + fz_dropobj(stmlen); + + pdf_updateobject(src, i, gen, stmobj); + pdf_updatestream(src, i, gen, buf); + + fz_dropobj(stmobj); + } + } + } +} + +void +cleanmain(int argc, char **argv) +{ + int doencrypt = 0; + int dogarbage = 0; + int doexpand = 0; + pdf_crypt *encrypt = nil; + char *infile; + char *outfile = "out.pdf"; + char *userpw = ""; + char *ownerpw = ""; + unsigned perms = 0xfffff0c0; /* nothing allowed */ + int keylen = 40; + char *password = ""; + fz_error *error; + int c; + + while ((c = getopt(argc, argv, "d:egn:o:p:u:x")) != -1) + { + switch (c) + { + case 'p': + /* see TABLE 3.15 User access permissions */ + perms = 0xfffff0c0; + if (strchr(optarg, 'p')) /* print */ + perms |= (1 << 2) | (1 << 11); + if (strchr(optarg, 'm')) /* modify */ + perms |= (1 << 3) | (1 << 10); + if (strchr(optarg, 'c')) /* copy */ + perms |= (1 << 4) | (1 << 9); + if (strchr(optarg, 'a')) /* annotate / forms */ + perms |= (1 << 5) | (1 << 8); + break; + case 'd': password = optarg; break; + case 'e': doencrypt ++; break; + case 'g': dogarbage ++; break; + case 'n': keylen = atoi(optarg); break; + case 'o': ownerpw = optarg; break; + case 'u': userpw = optarg; break; + case 'x': doexpand ++; break; + default: cleanusage(); break; + } + } + + if (argc - optind < 1) + cleanusage(); + + infile = argv[optind++]; + if (argc - optind > 0) + outfile = argv[optind++]; + + opensrc(infile, password, 0); + + if (doencrypt) + { + fz_obj *id = fz_dictgets(src->trailer, "ID"); + if (!id) + { + error = fz_packobj(&id, "[(ABCDEFGHIJKLMNOP)(ABCDEFGHIJKLMNOP)]"); + if (error) + die(error); + } + else + fz_keepobj(id); + + error = pdf_newencrypt(&encrypt, userpw, ownerpw, perms, keylen, id); + if (error) + die(error); + + fz_dropobj(id); + } + + if (doexpand) + cleanexpand(); + + if (dogarbage) + { + preloadobjstms(); + pdf_garbagecollect(src); + } + + error = pdf_savexref(src, outfile, encrypt); + if (error) + die(error); + + if (encrypt) + pdf_dropcrypt(encrypt); + + pdf_closexref(src); +} + + +/* --------------------------------------------------------------------- */ + +/* + * Draw pages to PPM bitmaps. + */ + +enum { DRAWPNM, DRAWTXT, DRAWXML }; + +fz_renderer *drawgc = nil; +int drawmode = DRAWPNM; +char *drawpattern = "out%0.3d.pnm"; +pdf_page *drawpage = nil; +float drawzoom = 1.0; +int drawrotate = 0; +int drawbands = 1; +int drawcount = 0; + +void +drawusage(void) +{ + fprintf(stderr, + "usage: pdftool draw [options] [file.pdf pages ... ]\n" + " -b -\tdraw page in N bands\n" + " -d -\tpassword for decryption\n" + " -o -\tpattern (%%d for page number) for output file\n" + " -r -\tresolution in dpi\n" + " -t \tutf-8 text output instead of graphics\n" + " -x \txml dump of display tree\n" + " example:\n" + " pdftool draw -o out%%0.3d.pnm a.pdf 1-3,5,9-\n"); + exit(1); +} + +void +drawloadpage(int pagenum) +{ + fz_error *error; + fz_obj *pageobj; + + pageobj = pdf_getpageobject(srcpages, pagenum - 1); + error = pdf_loadpage(&drawpage, src, pageobj); + if (error) + die(error); + + fprintf(stderr, "page %d mediabox [ %g %g %g %g ] rotate %d\n", + pagenum, + drawpage->mediabox.x0, drawpage->mediabox.y0, + drawpage->mediabox.x1, drawpage->mediabox.y1, + drawpage->rotate); +} + +void +drawfreepage(void) +{ + pdf_droppage(drawpage); + drawpage = nil; +} + +void +drawpnm(int pagenum) +{ + fz_error *error; + fz_matrix ctm; + fz_irect bbox; + fz_pixmap *pix; + char namebuf[256]; + char buf[256]; + int x, y, w, h, b, bh; + int fd; + + drawloadpage(pagenum); + + ctm = fz_identity(); + ctm = fz_concat(ctm, fz_translate(0, -drawpage->mediabox.y1)); + ctm = fz_concat(ctm, fz_scale(drawzoom, -drawzoom)); + ctm = fz_concat(ctm, fz_rotate(drawrotate + drawpage->rotate)); + + bbox = fz_roundrect(fz_transformaabb(ctm, drawpage->mediabox)); + w = bbox.x1 - bbox.x0; + h = bbox.y1 - bbox.y0; + bh = h / drawbands; + + if (drawpattern) + { + sprintf(namebuf, drawpattern, drawcount++); + fd = open(namebuf, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (fd < 0) + die(fz_throw("ioerror: could not open file '%s'", namebuf)); + } + else + fd = 1; + + sprintf(buf, "P6\n%d %d\n255\n", w, h); + write(fd, buf, strlen(buf)); + + error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4); + if (error) + die(error); + + memset(pix->samples, 0xff, pix->h * pix->w * pix->n); + + for (b = 0; b < drawbands; b++) + { + if (drawbands > 1) + fprintf(stderr, "drawing band %d / %d\n", b + 1, drawbands); + + error = fz_rendertreeover(drawgc, pix, drawpage->tree, ctm); + if (error) + die(error); + + for (y = 0; y < pix->h; y++) + { + unsigned char *src = pix->samples + y * pix->w * 4; + unsigned char *dst = src; + + for (x = 0; x < pix->w; x++) + { + dst[x * 3 + 0] = src[x * 4 + 1]; + dst[x * 3 + 1] = src[x * 4 + 2]; + dst[x * 3 + 2] = src[x * 4 + 3]; + } + + write(fd, dst, pix->w * 3); + + memset(src, 0xff, pix->w * 4); + } + + pix->y += bh; + if (pix->y + pix->h > bbox.y1) + pix->h = bbox.y1 - pix->y; + } + + fz_droppixmap(pix); + + if (drawpattern) + close(fd); + + drawfreepage(); +} + +void +drawtxt(int pagenum) +{ + fz_error *error; + pdf_textline *line; + fz_matrix ctm; + + drawloadpage(pagenum); + + ctm = fz_concat( + fz_translate(0, -drawpage->mediabox.y1), + fz_scale(drawzoom, -drawzoom)); + + error = pdf_loadtextfromtree(&line, drawpage->tree, ctm); + if (error) + die(error); + + pdf_debugtextline(line); + pdf_droptextline(line); + + drawfreepage(); +} + +void +drawxml(int pagenum) +{ + drawloadpage(pagenum); + fz_debugtree(drawpage->tree); + drawfreepage(); +} + +void +drawpages(char *pagelist) +{ + int page, spage, epage; + char *spec, *dash; + + if (!src) + drawusage(); + + spec = strsep(&pagelist, ","); + while (spec) + { + dash = strchr(spec, '-'); + + if (dash == spec) + spage = epage = 1; + else + spage = epage = atoi(spec); + + if (dash) + { + if (strlen(dash) > 1) + epage = atoi(dash + 1); + else + epage = pdf_getpagecount(srcpages); + } + + if (spage > epage) + page = spage, spage = epage, epage = page; + + for (page = spage; page <= epage; page++) + { + if (page < 1 || page > pdf_getpagecount(srcpages)) + continue; + switch (drawmode) + { + case DRAWPNM: drawpnm(page); break; + case DRAWTXT: drawtxt(page); break; + case DRAWXML: drawxml(page); break; + } + } + + spec = strsep(&pagelist, ","); + } +} + +void +drawmain(int argc, char **argv) +{ + fz_error *error; + char *password = ""; + int c; + + while ((c = getopt(argc, argv, "b:d:o:r:tx")) != -1) + { + switch (c) + { + case 'b': drawbands = atoi(optarg); break; + case 'd': password = optarg; break; + case 'o': drawpattern = optarg; break; + case 'r': drawzoom = atof(optarg) / 72.0; break; + case 't': drawmode = DRAWTXT; break; + case 'x': drawmode = DRAWXML; break; + default: + drawusage(); + break; + } + } + + if (optind == argc) + drawusage(); + + error = fz_newrenderer(&drawgc, pdf_devicergb, 0, 1024 * 512); + if (error) + die(error); + + while (optind < argc) + { + if (strstr(argv[optind], ".pdf")) + opensrc(argv[optind], password, 1); + else + drawpages(argv[optind]); + optind++; + } + + closesrc(); + + fz_droprenderer(drawgc); +} + +/* --------------------------------------------------------------------- */ + +/* + * Edit tool. + * Copy or impose pages from other pdf files into output pdf. + */ + +/* for each source pdf, build a list of objects to transplant. + * for each source pdf, do the transplants at the end of object collecting. + * build a new page tree structure for output. + * change page nodes into xobjects for over and n-up modes. + * create new page nodes. + * create new page tree. + */ + +enum { COPY, OVER, NUP2, NUP4, NUP8 }; + +pdf_xref *editxref = nil; +fz_obj *editkids = nil; +int editmode = COPY; + +void +editusage(void) +{ + fprintf(stderr, "usage: pdftool edit [-o file.pdf] [mode file.pdf pages ... ]\n"); + fprintf(stderr, " mode is one of: copy over 2up 4up 8up\n"); + fprintf(stderr, " pages is a comma separated list of ranges\n"); + fprintf(stderr, " example:\n"); + fprintf(stderr, " pdftool edit -o output.pdf copy one.pdf 1-3,5,9 two.pdf 1-\n"); + exit(1); +} + +void +editcopy(int pagenum) +{ + printf("copy page %d\n", pagenum); +} + +void editover(int pagenum) { } +void edit2up(int pagenum) { } +void edit4up(int pagenum) { } +void edit8up(int pagenum) { } + +void +editpages(char *pagelist) +{ + int page, spage, epage; + char *spec, *dash; + + if (!src) + editusage(); + + spec = strsep(&pagelist, ","); + while (spec) + { + dash = strchr(spec, '-'); + + if (dash == spec) + spage = epage = 1; + else + spage = epage = atoi(spec); + + if (dash) + { + if (strlen(dash) > 1) + epage = atoi(dash + 1); + else + epage = pdf_getpagecount(srcpages); + } + + if (spage > epage) + page = spage, spage = epage, epage = page; + + for (page = spage; page <= epage; page++) + { + if (page < 1 || page > pdf_getpagecount(srcpages)) + continue; + switch (editmode) + { + case COPY: editcopy(page); break; + case OVER: editover(page); break; + case NUP2: edit2up(page); break; + case NUP4: edit4up(page); break; + case NUP8: edit8up(page); break; + } + } + + spec = strsep(&pagelist, ","); + } +} + +void +editmain(int argc, char **argv) +{ + char *outfile = "out.pdf"; + fz_error *error; + int c; + + while ((c = getopt(argc, argv, "o:")) != -1) + { + switch (c) + { + case 'o': + outfile = optarg; + break; + default: + editusage(); + break; + } + } + + if (optind == argc) + editusage(); + + fprintf(stderr, "edit tool is not implemented yet\n"); + exit(1); + + error = pdf_newxref(&editxref); + if (error) + die(error); + + error = pdf_initxref(editxref); + if (error) + die(error); + + while (optind < argc) + { + if (strstr(argv[optind], ".pdf")) + { + opensrc(argv[optind], "", 1); + } + else if (!strcmp(argv[optind], "copy")) + editmode = COPY; + else if (!strcmp(argv[optind], "over")) + editmode = OVER; + else if (!strcmp(argv[optind], "2up")) + editmode = NUP2; + else if (!strcmp(argv[optind], "4up")) + editmode = NUP4; + else if (!strcmp(argv[optind], "8up")) + editmode = NUP8; + else + editpages(argv[optind]); + optind++; + } + + closesrc(); + + error = pdf_savexref(editxref, outfile, nil); + if (error) + die(error); + + pdf_closexref(editxref); +} + +/* --------------------------------------------------------------------- */ + +/* + * Main! + */ + +void +mainusage(void) +{ + fprintf(stderr, "usage: pdftool <command> [options...]\n"); + fprintf(stderr, " command is one of: show, draw, clean, edit\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + if (argc >= 2) + { + optind = 2; + if (!strcmp(argv[1], "show")) + showmain(argc, argv); + else if (!strcmp(argv[1], "draw")) + drawmain(argc, argv); + else if (!strcmp(argv[1], "clean")) + cleanmain(argc, argv); + else if (!strcmp(argv[1], "edit")) + editmain(argc, argv); + else + mainusage(); + } + else + mainusage(); + return 0; +} + diff --git a/apps/samshow.c b/apps/samshow.c index e9ce86f1..a1563c9d 100644 --- a/apps/samshow.c +++ b/apps/samshow.c @@ -1,6 +1,14 @@ #include "fitz.h" #include "samus.h" +void die(fz_error *eo) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); + fflush(stderr); + abort(); +} + void showfixdocseq(sa_package *pack, char *part) { fz_error *error; @@ -8,7 +16,7 @@ void showfixdocseq(sa_package *pack, char *part) error = sa_loadfixdocseq(&seq, pack, part); if (error) - fz_abort(error); + die(error); sa_debugfixdocseq(seq); @@ -38,14 +46,14 @@ int runpack(int argc, char **argv) error = sa_openpackage(&pack, argv[1]); if (error) - fz_abort(error); + die(error); sa_debugpackage(pack); printf("\n"); error = sa_loadrelations(&rels, pack, "/"); if (error) - fz_abort(error); + die(error); sa_debugrelations(rels); printf("\n"); @@ -67,7 +75,7 @@ int runpack(int argc, char **argv) error = sa_loadrelations(&rels, pack, argv[i]); if (error) - fz_abort(error); + die(error); sa_debugrelations(rels); sa_droprelations(rels); @@ -89,7 +97,7 @@ int runzip(int argc, char **argv) error = sa_openzip(&zip, argv[1]); if (error) - fz_abort(error); + die(error); if (argc == 2) sa_debugzip(zip); @@ -98,10 +106,10 @@ int runzip(int argc, char **argv) { error = sa_openzipentry(&stm, zip, argv[i]); if (error) - fz_abort(error); + die(error); n = fz_readall(&buf, stm); if (n < 0) - fz_abort(fz_ioerror(stm)); + die(fz_ioerror(stm)); fz_dropstream(stm); fwrite(buf->rp, 1, buf->wp - buf->rp, stdout); @@ -123,11 +131,11 @@ int runxml(int argc, char **argv) error = fz_openrfile(&file, argv[1]); if (error) - fz_abort(error); + die(error); error = sa_openxml(&parser, file, 0); if (error) - fz_abort(error); + die(error); item = sa_xmlnext(parser); if (item) @@ -148,11 +156,11 @@ int runtiff(int argc, char **argv) error = fz_openrfile(&file, argv[1]); if (error) - fz_abort(error); + die(error); error = sa_readtiff(file); if (error) - fz_abort(error); + die(error); fz_dropstream(file); diff --git a/base/base_error.c b/base/base_error.c index e9823f14..e0bf1567 100644 --- a/base/base_error.c +++ b/base/base_error.c @@ -53,7 +53,12 @@ fz_throw0(const char *func, const char *file, int line, char *fmt, ...) va_end(ap); if (getenv("BOMB")) - fz_abort(eo); + { + fflush(stdout); + fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); + fflush(stderr); + abort(); + } return eo; } @@ -67,12 +72,3 @@ fz_droperror(fz_error *eo) fz_free(eo); } -void -fz_abort(fz_error *eo) -{ - fflush(stdout); - fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg); - fflush(stderr); - abort(); -} - diff --git a/include/fitz/base_runtime.h b/include/fitz/base_runtime.h index feeb7ffc..717b22e9 100644 --- a/include/fitz/base_runtime.h +++ b/include/fitz/base_runtime.h @@ -57,7 +57,6 @@ fz_error *fz_throw0(const char *func, const char *file, int line, char *fmt, ... fz_error *fz_throw1(char *fmt, ...); void fz_warn(char *fmt, ...); -void fz_abort(fz_error *eo); void fz_droperror(fz_error *eo); typedef struct fz_memorycontext_s fz_memorycontext; |