summaryrefslogtreecommitdiff
path: root/apps/pdfshow.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2012-10-02 16:52:45 +0200
committerRobin Watts <robin.watts@artifex.com>2012-10-05 15:54:56 +0100
commitae5749c4139982079bd35698a3c3c23e4ec9147e (patch)
tree6c03bc26152ee69122d8a1535283a180d5db3b52 /apps/pdfshow.c
parent8aa48c0f5766a0d62489cb42225cd03f3d1a2a62 (diff)
downloadmupdf-ae5749c4139982079bd35698a3c3c23e4ec9147e.tar.xz
Rename mubusy to mutool.
Diffstat (limited to 'apps/pdfshow.c')
-rw-r--r--apps/pdfshow.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/apps/pdfshow.c b/apps/pdfshow.c
new file mode 100644
index 00000000..655493f9
--- /dev/null
+++ b/apps/pdfshow.c
@@ -0,0 +1,235 @@
+/*
+ * pdfshow -- the ultimate pdf debugging tool
+ */
+
+#include "mupdf-internal.h"
+
+static pdf_document *doc = NULL;
+static fz_context *ctx = NULL;
+static int showbinary = 0;
+static int showdecode = 1;
+static int showcolumn;
+
+static void usage(void)
+{
+ fprintf(stderr, "usage: mutool show [options] file.pdf [grepable] [xref] [trailer] [pagetree] [object numbers]\n");
+ fprintf(stderr, "\t-b\tprint streams as binary data\n");
+ fprintf(stderr, "\t-e\tprint encoded streams (don't decode)\n");
+ fprintf(stderr, "\t-p\tpassword\n");
+ exit(1);
+}
+
+static void showtrailer(void)
+{
+ if (!doc)
+ fz_throw(ctx, "no file specified");
+ printf("trailer\n");
+ pdf_fprint_obj(stdout, doc->trailer, 0);
+ printf("\n");
+}
+
+static void showxref(void)
+{
+ if (!doc)
+ fz_throw(ctx, "no file specified");
+ pdf_print_xref(doc);
+ printf("\n");
+}
+
+static void showpagetree(void)
+{
+ pdf_obj *ref;
+ int count;
+ int i;
+
+ if (!doc)
+ fz_throw(ctx, "no file specified");
+
+ count = pdf_count_pages(doc);
+ for (i = 0; i < count; i++)
+ {
+ ref = doc->page_refs[i];
+ printf("page %d = %d %d R\n", i + 1, pdf_to_num(ref), pdf_to_gen(ref));
+ }
+ printf("\n");
+}
+
+static 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;
+ }
+ }
+}
+
+static void showstream(int num, int gen)
+{
+ fz_stream *stm;
+ unsigned char buf[2048];
+ int n;
+
+ showcolumn = 0;
+
+ if (showdecode)
+ stm = pdf_open_stream(doc, num, gen);
+ else
+ stm = pdf_open_raw_stream(doc, num, gen);
+
+ while (1)
+ {
+ n = fz_read(stm, buf, sizeof buf);
+ if (n == 0)
+ break;
+ if (showbinary)
+ fwrite(buf, 1, n, stdout);
+ else
+ showsafe(buf, n);
+ }
+
+ fz_close(stm);
+}
+
+static void showobject(int num, int gen)
+{
+ pdf_obj *obj;
+
+ if (!doc)
+ fz_throw(ctx, "no file specified");
+
+ obj = pdf_load_object(doc, num, gen);
+
+ if (pdf_is_stream(doc, num, gen))
+ {
+ if (showbinary)
+ {
+ showstream(num, gen);
+ }
+ else
+ {
+ printf("%d %d obj\n", num, gen);
+ pdf_fprint_obj(stdout, obj, 0);
+ printf("stream\n");
+ showstream(num, gen);
+ printf("endstream\n");
+ printf("endobj\n\n");
+ }
+ }
+ else
+ {
+ printf("%d %d obj\n", num, gen);
+ pdf_fprint_obj(stdout, obj, 0);
+ printf("endobj\n\n");
+ }
+
+ pdf_drop_obj(obj);
+}
+
+static void showgrep(char *filename)
+{
+ pdf_obj *obj;
+ int i, len;
+
+ len = pdf_count_objects(doc);
+ for (i = 0; i < len; i++)
+ {
+ if (doc->table[i].type == 'n' || doc->table[i].type == 'o')
+ {
+ fz_try(ctx)
+ {
+ obj = pdf_load_object(doc, i, 0);
+ }
+ fz_catch(ctx)
+ {
+ fz_warn(ctx, "skipping object (%d 0 R)", i);
+ continue;
+ }
+
+ pdf_sort_dict(obj);
+
+ printf("%s:%d: ", filename, i);
+ pdf_fprint_obj(stdout, obj, 1);
+
+ pdf_drop_obj(obj);
+ }
+ }
+
+ printf("%s:trailer: ", filename);
+ pdf_fprint_obj(stdout, doc->trailer, 1);
+}
+
+int pdfshow_main(int argc, char **argv)
+{
+ char *password = NULL; /* don't throw errors if encrypted */
+ char *filename;
+ int c;
+
+ while ((c = fz_getopt(argc, argv, "p:be")) != -1)
+ {
+ switch (c)
+ {
+ case 'p': password = fz_optarg; break;
+ case 'b': showbinary = 1; break;
+ case 'e': showdecode = 0; break;
+ default: usage(); break;
+ }
+ }
+
+ if (fz_optind == argc)
+ usage();
+
+ filename = argv[fz_optind++];
+
+ ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
+ if (!ctx)
+ {
+ fprintf(stderr, "cannot initialise context\n");
+ exit(1);
+ }
+
+ fz_var(doc);
+ fz_try(ctx)
+ {
+ doc = pdf_open_document_no_run(ctx, filename);
+ if (pdf_needs_password(doc))
+ if (!pdf_authenticate_password(doc, password))
+ fz_warn(ctx, "cannot authenticate password: %s", filename);
+
+ if (fz_optind == argc)
+ showtrailer();
+
+ while (fz_optind < argc)
+ {
+ switch (argv[fz_optind][0])
+ {
+ case 't': showtrailer(); break;
+ case 'x': showxref(); break;
+ case 'p': showpagetree(); break;
+ case 'g': showgrep(filename); break;
+ default: showobject(atoi(argv[fz_optind]), 0); break;
+ }
+ fz_optind++;
+ }
+ }
+ fz_catch(ctx)
+ {
+ }
+
+ pdf_close_document(doc);
+ fz_free_context(ctx);
+ return 0;
+}