Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * pdfshow -- the ultimate pdf debugging tool
  3.  */
  4.  
  5. #include "fitz.h"
  6. #include "mupdf.h"
  7.  
  8. static pdf_xref *xref = NULL;
  9. static int showbinary = 0;
  10. static int showdecode = 1;
  11. static int showcolumn;
  12.  
  13. void die(fz_error error)
  14. {
  15.         fz_catch(error, "aborting");
  16.         if (xref)
  17.                 pdf_free_xref(xref);
  18.         exit(1);
  19. }
  20.  
  21. static void usage(void)
  22. {
  23.         fprintf(stderr, "usage: pdfshow [options] file.pdf [grepable] [xref] [trailer] [pagetree] [object numbers]\n");
  24.         fprintf(stderr, "\t-b\tprint streams as binary data\n");
  25.         fprintf(stderr, "\t-e\tprint encoded streams (don't decode)\n");
  26.         fprintf(stderr, "\t-p\tpassword\n");
  27.         exit(1);
  28. }
  29.  
  30. static void showtrailer(void)
  31. {
  32.         if (!xref)
  33.                 die(fz_throw("no file specified"));
  34.         printf("trailer\n");
  35.         fz_debug_obj(xref->trailer);
  36.         printf("\n");
  37. }
  38.  
  39. static void showxref(void)
  40. {
  41.         if (!xref)
  42.                 die(fz_throw("no file specified"));
  43.         pdf_debug_xref(xref);
  44.         printf("\n");
  45. }
  46.  
  47. static void showpagetree(void)
  48. {
  49.         fz_error error;
  50.         fz_obj *ref;
  51.         int count;
  52.         int i;
  53.  
  54.         if (!xref)
  55.                 die(fz_throw("no file specified"));
  56.  
  57.         if (!xref->page_len)
  58.         {
  59.                 error = pdf_load_page_tree(xref);
  60.                 if (error)
  61.                         die(fz_rethrow(error, "cannot load page tree"));
  62.         }
  63.  
  64.         count = pdf_count_pages(xref);
  65.         for (i = 0; i < count; i++)
  66.         {
  67.                 ref = xref->page_refs[i];
  68.                 printf("page %d = %d %d R\n", i + 1, fz_to_num(ref), fz_to_gen(ref));
  69.         }
  70.         printf("\n");
  71. }
  72.  
  73. static void showsafe(unsigned char *buf, int n)
  74. {
  75.         int i;
  76.         for (i = 0; i < n; i++) {
  77.                 if (buf[i] == '\r' || buf[i] == '\n') {
  78.                         putchar('\n');
  79.                         showcolumn = 0;
  80.                 }
  81.                 else if (buf[i] < 32 || buf[i] > 126) {
  82.                         putchar('.');
  83.                         showcolumn ++;
  84.                 }
  85.                 else {
  86.                         putchar(buf[i]);
  87.                         showcolumn ++;
  88.                 }
  89.                 if (showcolumn == 79) {
  90.                         putchar('\n');
  91.                         showcolumn = 0;
  92.                 }
  93.         }
  94. }
  95.  
  96. static void showstream(int num, int gen)
  97. {
  98.         fz_error error;
  99.         fz_stream *stm;
  100.         unsigned char buf[2048];
  101.         int n;
  102.  
  103.         showcolumn = 0;
  104.  
  105.         if (showdecode)
  106.                 error = pdf_open_stream(&stm, xref, num, gen);
  107.         else
  108.                 error = pdf_open_raw_stream(&stm, xref, num, gen);
  109.         if (error)
  110.                 die(error);
  111.  
  112.         while (1)
  113.         {
  114.                 n = fz_read(stm, buf, sizeof buf);
  115.                 if (n < 0)
  116.                         die(n);
  117.                 if (n == 0)
  118.                         break;
  119.                 if (showbinary)
  120.                         fwrite(buf, 1, n, stdout);
  121.                 else
  122.                         showsafe(buf, n);
  123.         }
  124.  
  125.         fz_close(stm);
  126. }
  127.  
  128. static void showobject(int num, int gen)
  129. {
  130.         fz_error error;
  131.         fz_obj *obj;
  132.  
  133.         if (!xref)
  134.                 die(fz_throw("no file specified"));
  135.  
  136.         error = pdf_load_object(&obj, xref, num, gen);
  137.         if (error)
  138.                 die(error);
  139.  
  140.         if (pdf_is_stream(xref, num, gen))
  141.         {
  142.                 if (showbinary)
  143.                 {
  144.                         showstream(num, gen);
  145.                 }
  146.                 else
  147.                 {
  148.                         printf("%d %d obj\n", num, gen);
  149.                         fz_debug_obj(obj);
  150.                         printf("stream\n");
  151.                         showstream(num, gen);
  152.                         printf("endstream\n");
  153.                         printf("endobj\n\n");
  154.                 }
  155.         }
  156.         else
  157.         {
  158.                 printf("%d %d obj\n", num, gen);
  159.                 fz_debug_obj(obj);
  160.                 printf("endobj\n\n");
  161.         }
  162.  
  163.         fz_drop_obj(obj);
  164. }
  165.  
  166. static void showgrep(char *filename)
  167. {
  168.         fz_error error;
  169.         fz_obj *obj;
  170.         int i;
  171.  
  172.         for (i = 0; i < xref->len; i++)
  173.         {
  174.                 if (xref->table[i].type == 'n' || xref->table[i].type == 'o')
  175.                 {
  176.                         error = pdf_load_object(&obj, xref, i, 0);
  177.                         if (error)
  178.                                 die(error);
  179.  
  180.                         fz_sort_dict(obj);
  181.  
  182.                         printf("%s:%d: ", filename, i);
  183.                         fz_fprint_obj(stdout, obj, 1);
  184.  
  185.                         fz_drop_obj(obj);
  186.                 }
  187.         }
  188.  
  189.         printf("%s:trailer: ", filename);
  190.         fz_fprint_obj(stdout, xref->trailer, 1);
  191. }
  192.  
  193. int main(int argc, char **argv)
  194. {
  195.         char *password = NULL; /* don't throw errors if encrypted */
  196.         char *filename;
  197.         fz_error error;
  198.         int c;
  199.  
  200.         while ((c = fz_getopt(argc, argv, "p:be")) != -1)
  201.         {
  202.                 switch (c)
  203.                 {
  204.                 case 'p': password = fz_optarg; break;
  205.                 case 'b': showbinary = 1; break;
  206.                 case 'e': showdecode = 0; break;
  207.                 default: usage(); break;
  208.                 }
  209.         }
  210.  
  211.         if (fz_optind == argc)
  212.                 usage();
  213.  
  214.         filename = argv[fz_optind++];
  215.         error = pdf_open_xref(&xref, filename, password);
  216.         if (error)
  217.                 die(fz_rethrow(error, "cannot open document: %s", filename));
  218.  
  219.         if (fz_optind == argc)
  220.                 showtrailer();
  221.  
  222.         while (fz_optind < argc)
  223.         {
  224.                 switch (argv[fz_optind][0])
  225.                 {
  226.                 case 't': showtrailer(); break;
  227.                 case 'x': showxref(); break;
  228.                 case 'p': showpagetree(); break;
  229.                 case 'g': showgrep(filename); break;
  230.                 default: showobject(atoi(argv[fz_optind]), 0); break;
  231.                 }
  232.                 fz_optind++;
  233.         }
  234.  
  235.         pdf_free_xref(xref);
  236.  
  237.         fz_flush_warnings();
  238.  
  239.         return 0;
  240. }
  241.