summaryrefslogtreecommitdiff
path: root/test/mupdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/mupdf.c')
-rw-r--r--test/mupdf.c337
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;
+}
+