diff options
Diffstat (limited to 'test/mupdf.c')
-rw-r--r-- | test/mupdf.c | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/test/mupdf.c b/test/mupdf.c new file mode 100644 index 00000000..b51eb43d --- /dev/null +++ b/test/mupdf.c @@ -0,0 +1,337 @@ +#include <fitz.h> +#include <mupdf.h> + +static char *password = ""; +static int dodecode = 0; +static int dorepair = 0; +static int doprintxref = 0; +static int doprintpages = 0; + +void usage() +{ + fprintf(stderr, "usage: mupdf [-drxp] [-u password] file.pdf\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, fz_obj *stream, int oid, int gid, int ofs) +{ + fz_error *error; + unsigned char buf[512]; + + safecol = 0; + + error = pdf_openstream0(xref, stream, oid, gid, ofs); + if (error) fz_abort(error); + + while (1) + { + int n = fz_read(xref->file, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + fz_abort(fz_ferror(xref->file)); + printsafe(buf, n); + } + + pdf_closestream(xref); +} + +void copystream(pdf_xref *xref, fz_obj *stream, int ofs) +{ + fz_error *error; + unsigned char buf[512]; + fz_filter *filter; + fz_obj *obj; + int len; + + safecol = 0; + + obj = fz_dictgets(stream, "Length"); + error = pdf_resolve(&obj, xref); + if (error) fz_abort(error); + len = fz_toint(obj); + fz_dropobj(obj); + + error = fz_newnullfilter(&filter, len); + if (error) fz_abort(error); + + fz_seek(xref->file, ofs); + + error = fz_pushfilter(xref->file, filter); + if (error) fz_abort(error); + + while (1) + { + int n = fz_read(xref->file, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + fz_abort(fz_ferror(xref->file)); + printsafe(buf, n); + } + + fz_popfilter(xref->file); +} + +void printobject(pdf_xref *xref, int oid, int gid) +{ + fz_error *error; + int stmofs; + fz_obj *obj; + + error = pdf_loadobject0(&obj, xref, oid, gid, &stmofs); + if (error) fz_abort(error); + + printf("%d %d obj\n", oid, gid); + fz_fprintobj(stdout, obj); + printf("\n"); + if (stmofs != -1) { + printf("stream\n"); + if (dodecode) + decodestream(xref, obj, oid, gid, stmofs); + else + copystream(xref, obj, stmofs); + printf("endstream\n"); + } + printf("endobj\n"); + + fz_dropobj(obj); +} + +/* + * Draw page + */ + +void runcsi(pdf_xref *xref, pdf_csi *csi, pdf_resources *rdb, fz_obj *stmref) +{ + fz_error *error; + + error = pdf_openstream(xref, stmref); + if (error) fz_abort(error); + + error = pdf_runcsi(csi, rdb, xref->file); + if (error) fz_abort(error); + + pdf_closestream(xref); +} + +void showpage(pdf_xref *xref, fz_obj *page) +{ + fz_error *error; + pdf_csi *csi; + pdf_resources *rdb = nil; + fz_obj *resources; + fz_obj *contents; + int i; + + fz_fprintobj(stdout, page); + printf("\n"); + + resources = fz_dictgets(page, "Resources"); + if (resources) + { + error = pdf_resolve(&resources, xref); + if (error) fz_abort(error); + + error = pdf_loadresources(&rdb, xref, resources); + if (error) fz_abort(error); + + // parse resources into native res dict + fz_dropobj(resources); + } + else + fz_abort(fz_throw("syntaxerror: missing resource dictionary")); + +printf("resources:\n"); +printf(" font:\n"); +fz_fprintobj(stdout, rdb->font); +printf("\n extgstate:\n"); +fz_fprintobj(stdout, rdb->extgstate); +printf("\nfitz tree:\n"); + + error = pdf_newcsi(&csi); + if (error) fz_abort(error); + + contents = fz_dictgets(page, "Contents"); + if (contents) + { + if (fz_isarray(contents)) + { + for (i = 0; i < fz_arraylen(contents); i++) + { + runcsi(xref, csi, rdb, fz_arrayget(contents, i)); + } + } + else + { + // XXX resolve and check if it is an array + runcsi(xref, csi, rdb, contents); + } + } + + fz_debugtree(csi->tree); + + { + fz_pixmap *pix; + fz_renderer *gc; + fz_matrix ctm; + +#define W 612 +#define H 792 + +#define xW 1106 +#define xH 1548 + + fz_newrenderer(&gc); + fz_newpixmap(&pix, 0, 0, W, H, 1, 0); + ctm = fz_concat(fz_translate(0, -H), fz_scale(1,-1)); + + memset(pix->samples, 0x00, pix->stride * pix->h * 2); + +printf("rendering!\n"); + fz_rendernode(gc, csi->tree->root, ctm, pix); +printf("done!\n"); + fz_debugpixmap(pix); + + fz_freepixmap(pix); + fz_freerenderer(gc); + } + + pdf_freecsi(csi); +} + +int main(int argc, char **argv) +{ + fz_error *error; + char *filename; + pdf_xref *xref; + pdf_pagetree *pages; + int c; + + while ((c = getopt(argc, argv, "drxopu:")) != -1) + { + switch (c) + { + case 'd': + dodecode ++; + break; + case 'r': + dorepair ++; + break; + case 'x': + doprintxref ++; + break; + case 'p': + doprintpages ++; + 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); + + if (dorepair) + error = pdf_repairxref(xref, filename); + else + error = pdf_openxref(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 (doprintxref) + pdf_debugxref(xref); + + if (doprintpages) + { + error = pdf_loadpagetree(&pages, xref); + if (error) fz_abort(error); + + if (optind == argc) + { + printf("pagetree\n"); + pdf_debugpagetree(pages); + printf("\n"); + } + else + { + for ( ; optind < argc; optind++) + { + int page = atoi(argv[optind]); + if (page < 1 || page > pages->count) + fprintf(stderr, "page out of bounds: %d\n", page); + printf("page %d\n", page); + showpage(xref, pages->pobj[page - 1]); + } + } + } + + else + { + if (optind == argc) + { + printf("trailer\n"); + fz_fprintobj(stdout, xref->trailer); + printf("\n"); + } + + for ( ; optind < argc; optind++) + { + printobject(xref, atoi(argv[optind]), 0); + printf("\n"); + } + } + + pdf_closexref(xref); + + return 0; +} + |