Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 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 | }>>>>>> |