comparison mupdf-source/source/tools/pdfshow.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 // Copyright (C) 2004-2025 Artifex Software, Inc.
2 //
3 // This file is part of MuPDF.
4 //
5 // MuPDF is free software: you can redistribute it and/or modify it under the
6 // terms of the GNU Affero General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17 //
18 // Alternative licensing terms are available from the licensor.
19 // For commercial licensing, see <https://www.artifex.com/> or contact
20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21 // CA 94129, USA, for further information.
22
23 /*
24 * pdfshow -- the ultimate pdf debugging tool
25 */
26
27 #include "mupdf/fitz.h"
28 #include "mupdf/pdf.h"
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 static pdf_document *doc = NULL;
35 static fz_output *out = NULL;
36 static pdf_object_labels *labels = NULL;
37 static int showbinary = 0;
38 static int showdecode = 1;
39 static int do_tight = 0;
40 static int do_repair = 0;
41 static int do_label = 0;
42 static int showcolumn;
43
44 static int usage(void)
45 {
46 fprintf(stderr,
47 "usage: mutool show [options] file.pdf ( trailer | xref | pages | grep | outline | js | form | <path> ) *\n"
48 "\t-p -\tpassword\n"
49 "\t-o -\toutput file\n"
50 "\t-e\tleave stream contents in their original form\n"
51 "\t-b\tprint only stream contents, as raw binary data\n"
52 "\t-g\tprint only object, one line per object, suitable for grep\n"
53 "\t-r\tforce repair before showing any objects\n"
54 "\t-L\tshow object labels\n"
55 "\tpath: path to an object, starting with either an object number,\n"
56 "\t\t'pages', 'trailer', or a property in the trailer;\n"
57 "\t\tpath elements separated by '.' or '/'. Path elements must be\n"
58 "\t\tarray index numbers, dictionary property names, or '*'.\n"
59 );
60 return 1;
61 }
62
63 static void showtrailer(fz_context *ctx)
64 {
65 if (do_tight)
66 fz_write_printf(ctx, out, "trailer ");
67 else
68 fz_write_printf(ctx, out, "trailer\n");
69 pdf_print_obj(ctx, out, pdf_trailer(ctx, doc), do_tight, 1);
70 fz_write_printf(ctx, out, "\n");
71 }
72
73 static void showxref(fz_context *ctx)
74 {
75 int i;
76 int xref_len = pdf_xref_len(ctx, doc);
77 fz_write_printf(ctx, out, "xref\n0 %d\n", xref_len);
78 for (i = 0; i < xref_len; i++)
79 {
80 pdf_xref_entry *entry = pdf_get_xref_entry_no_null(ctx, doc, i);
81 fz_write_printf(ctx, out, "%05d: %010d %05d %c \n",
82 i,
83 (int)entry->ofs,
84 entry->gen,
85 entry->type ? entry->type : '-');
86 }
87 }
88
89 static void showpages(fz_context *ctx)
90 {
91 pdf_obj *ref;
92 int i, n = pdf_count_pages(ctx, doc);
93 for (i = 0; i < n; ++i)
94 {
95 ref = pdf_lookup_page_obj(ctx, doc, i);
96 fz_write_printf(ctx, out, "page %d = %d 0 R\n", i + 1, pdf_to_num(ctx, ref));
97 }
98 }
99
100 static void showsafe(unsigned char *buf, size_t n)
101 {
102 size_t i;
103 for (i = 0; i < n; i++) {
104 if (buf[i] == '\r' || buf[i] == '\n') {
105 putchar('\n');
106 showcolumn = 0;
107 }
108 else if (buf[i] < 32 || buf[i] > 126) {
109 putchar('.');
110 showcolumn ++;
111 }
112 else {
113 putchar(buf[i]);
114 showcolumn ++;
115 }
116 if (showcolumn == 79) {
117 putchar('\n');
118 showcolumn = 0;
119 }
120 }
121 }
122
123 static void showstream(fz_context *ctx, int num)
124 {
125 fz_stream *stm;
126 unsigned char buf[2048];
127 size_t n;
128
129 showcolumn = 0;
130
131 if (showdecode)
132 stm = pdf_open_stream_number(ctx, doc, num);
133 else
134 stm = pdf_open_raw_stream_number(ctx, doc, num);
135
136 while (1)
137 {
138 n = fz_read(ctx, stm, buf, sizeof buf);
139 if (n == 0)
140 break;
141 if (showbinary)
142 fz_write_data(ctx, out, buf, n);
143 else
144 showsafe(buf, n);
145 }
146
147 fz_drop_stream(ctx, stm);
148 }
149
150 static void showlabel(fz_context *ctx, void *arg, const char *label)
151 {
152 fz_write_printf(ctx, arg, "%% %s\n", label);
153 }
154
155 static void showobject(fz_context *ctx, pdf_obj *ref)
156 {
157 pdf_obj *obj = pdf_resolve_indirect(ctx, ref);
158 int num = pdf_to_num(ctx, ref);
159 if (pdf_is_stream(ctx, ref))
160 {
161 if (showbinary)
162 {
163 showstream(ctx, num);
164 }
165 else
166 {
167 if (do_label)
168 pdf_label_object(ctx, labels, num, showlabel, out);
169 if (do_tight)
170 {
171 fz_write_printf(ctx, out, "%d 0 obj ", num);
172 pdf_print_obj(ctx, out, obj, 1, 1);
173 fz_write_printf(ctx, out, " stream\n");
174 }
175 else
176 {
177 fz_write_printf(ctx, out, "%d 0 obj\n", num);
178 pdf_print_obj(ctx, out, obj, 0, 1);
179 fz_write_printf(ctx, out, "\nstream\n");
180 showstream(ctx, num);
181 fz_write_printf(ctx, out, "endstream\n");
182 fz_write_printf(ctx, out, "endobj\n");
183 }
184 }
185 }
186 else
187 {
188 if (do_label)
189 pdf_label_object(ctx, labels, num, showlabel, out);
190 if (do_tight)
191 {
192 fz_write_printf(ctx, out, "%d 0 obj ", num);
193 pdf_print_obj(ctx, out, obj, 1, 1);
194 fz_write_printf(ctx, out, "\n");
195 }
196 else
197 {
198 fz_write_printf(ctx, out, "%d 0 obj\n", num);
199 pdf_print_obj(ctx, out, obj, 0, 1);
200 fz_write_printf(ctx, out, "\nendobj\n");
201 }
202 }
203 }
204
205 static void showgrep(fz_context *ctx)
206 {
207 pdf_obj *ref, *obj;
208 int i, len;
209
210 len = pdf_count_objects(ctx, doc);
211 for (i = 0; i < len; i++)
212 {
213 pdf_xref_entry *entry = pdf_get_xref_entry_no_null(ctx, doc, i);
214 if (entry->type == 'n' || entry->type == 'o')
215 {
216 fz_try(ctx)
217 {
218 ref = pdf_new_indirect(ctx, doc, i, 0);
219 obj = pdf_resolve_indirect(ctx, ref);
220 }
221 fz_catch(ctx)
222 {
223 pdf_drop_obj(ctx, ref);
224 fz_warn(ctx, "skipping object (%d 0 R)", i);
225 continue;
226 }
227
228 pdf_sort_dict(ctx, obj);
229
230 fz_write_printf(ctx, out, "%d 0 obj ", i);
231 pdf_print_obj(ctx, out, obj, 1, 1);
232 if (pdf_is_stream(ctx, ref))
233 fz_write_printf(ctx, out, " stream");
234 fz_write_printf(ctx, out, "\n");
235
236 pdf_drop_obj(ctx, ref);
237 }
238 }
239
240 fz_write_printf(ctx, out, "trailer ");
241 pdf_print_obj(ctx, out, pdf_trailer(ctx, doc), 1, 1);
242 fz_write_printf(ctx, out, "\n");
243 }
244
245 static void
246 print_outline(fz_context *ctx, fz_outline *outline, int level)
247 {
248 int i;
249 while (outline)
250 {
251 if (outline->down)
252 fz_write_byte(ctx, out, outline->is_open ? '-' : '+');
253 else
254 fz_write_byte(ctx, out, '|');
255
256 for (i = 0; i < level; i++)
257 fz_write_byte(ctx, out, '\t');
258 fz_write_printf(ctx, out, "%Q\t%s\n", outline->title, outline->uri);
259 if (outline->down)
260 print_outline(ctx, outline->down, level + 1);
261 outline = outline->next;
262 }
263 }
264
265 static void showoutline(fz_context *ctx)
266 {
267 fz_outline *outline = fz_load_outline(ctx, (fz_document*)doc);
268 fz_try(ctx)
269 print_outline(ctx, outline, 1);
270 fz_always(ctx)
271 fz_drop_outline(ctx, outline);
272 fz_catch(ctx)
273 fz_rethrow(ctx);
274 }
275
276 static void showtext(fz_context *ctx, char *buf, int indent)
277 {
278 int bol = 1;
279 int c = *buf;
280 while (*buf)
281 {
282 c = *buf++;
283 if (c == '\r')
284 {
285 if (*buf == '\n')
286 ++buf;
287 c = '\n';
288 }
289 if (indent && bol)
290 fz_write_byte(ctx, out, '\t');
291 fz_write_byte(ctx, out, c);
292 bol = (c == '\n');
293 }
294 if (!bol)
295 fz_write_byte(ctx, out, '\n');
296 }
297
298 static void showjs(fz_context *ctx)
299 {
300 pdf_obj *tree;
301 int i;
302
303 tree = pdf_load_name_tree(ctx, doc, PDF_NAME(JavaScript));
304 for (i = 0; i < pdf_dict_len(ctx, tree); ++i)
305 {
306 pdf_obj *name = pdf_dict_get_key(ctx, tree, i);
307 pdf_obj *action = pdf_dict_get_val(ctx, tree, i);
308 pdf_obj *js = pdf_dict_get(ctx, action, PDF_NAME(JS));
309 char *src = pdf_load_stream_or_string_as_utf8(ctx, js);
310 fz_write_printf(ctx, out, "// %s\n", pdf_to_name(ctx, name));
311 showtext(ctx, src, 0);
312 fz_free(ctx, src);
313 }
314 }
315
316 static void showaction(fz_context *ctx, pdf_obj *action, const char *name)
317 {
318 if (action)
319 {
320 pdf_obj *js = pdf_dict_get(ctx, action, PDF_NAME(JS));
321 if (js)
322 {
323 char *src = pdf_load_stream_or_string_as_utf8(ctx, js);
324 fz_write_printf(ctx, out, " %s: {\n", name);
325 showtext(ctx, src, 1);
326 fz_write_printf(ctx, out, " }\n", name);
327 fz_free(ctx, src);
328 }
329 else
330 {
331 fz_write_printf(ctx, out, " %s: ", name);
332 if (pdf_is_indirect(ctx, action))
333 action = pdf_resolve_indirect(ctx, action);
334 pdf_print_obj(ctx, out, action, 1, 1);
335 fz_write_printf(ctx, out, "\n");
336 }
337 }
338 }
339
340 static void showfield(fz_context *ctx, pdf_obj *field)
341 {
342 pdf_obj *kids, *ft, *parent;
343 const char *tu;
344 char *t;
345 int ff;
346 int i, n;
347
348 t = pdf_load_field_name(ctx, field);
349 tu = pdf_dict_get_text_string(ctx, field, PDF_NAME(TU));
350 ft = pdf_dict_get_inheritable(ctx, field, PDF_NAME(FT));
351 ff = pdf_field_flags(ctx, field);
352 parent = pdf_dict_get(ctx, field, PDF_NAME(Parent));
353
354 fz_write_printf(ctx, out, "field %d\n", pdf_to_num(ctx, field));
355 fz_write_printf(ctx, out, " Type: %s\n", pdf_to_name(ctx, ft));
356 if (ff)
357 {
358 fz_write_printf(ctx, out, " Flags:");
359 if (ff & PDF_FIELD_IS_READ_ONLY) fz_write_string(ctx, out, " readonly");
360 if (ff & PDF_FIELD_IS_REQUIRED) fz_write_string(ctx, out, " required");
361 if (ff & PDF_FIELD_IS_NO_EXPORT) fz_write_string(ctx, out, " noExport");
362 if (ft == PDF_NAME(Btn))
363 {
364 if (ff & PDF_BTN_FIELD_IS_NO_TOGGLE_TO_OFF) fz_write_string(ctx, out, " noToggleToOff");
365 if (ff & PDF_BTN_FIELD_IS_RADIO) fz_write_string(ctx, out, " radio");
366 if (ff & PDF_BTN_FIELD_IS_PUSHBUTTON) fz_write_string(ctx, out, " pushButton");
367 if (ff & PDF_BTN_FIELD_IS_RADIOS_IN_UNISON) fz_write_string(ctx, out, " radiosInUnison");
368 }
369 if (ft == PDF_NAME(Tx))
370 {
371 if (ff & PDF_TX_FIELD_IS_MULTILINE) fz_write_string(ctx, out, " multiline");
372 if (ff & PDF_TX_FIELD_IS_PASSWORD) fz_write_string(ctx, out, " password");
373 if (ff & PDF_TX_FIELD_IS_FILE_SELECT) fz_write_string(ctx, out, " fileSelect");
374 if (ff & PDF_TX_FIELD_IS_DO_NOT_SPELL_CHECK) fz_write_string(ctx, out, " dontSpellCheck");
375 if (ff & PDF_TX_FIELD_IS_DO_NOT_SCROLL) fz_write_string(ctx, out, " dontScroll");
376 if (ff & PDF_TX_FIELD_IS_COMB) fz_write_string(ctx, out, " comb");
377 if (ff & PDF_TX_FIELD_IS_RICH_TEXT) fz_write_string(ctx, out, " richText");
378 }
379 if (ft == PDF_NAME(Ch))
380 {
381 if (ff & PDF_CH_FIELD_IS_COMBO) fz_write_string(ctx, out, " combo");
382 if (ff & PDF_CH_FIELD_IS_EDIT) fz_write_string(ctx, out, " edit");
383 if (ff & PDF_CH_FIELD_IS_SORT) fz_write_string(ctx, out, " sort");
384 if (ff & PDF_CH_FIELD_IS_MULTI_SELECT) fz_write_string(ctx, out, " multiSelect");
385 if (ff & PDF_CH_FIELD_IS_DO_NOT_SPELL_CHECK) fz_write_string(ctx, out, " dontSpellCheck");
386 if (ff & PDF_CH_FIELD_IS_COMMIT_ON_SEL_CHANGE) fz_write_string(ctx, out, " commitOnSelChange");
387 }
388 fz_write_string(ctx, out, "\n");
389 }
390 fz_write_printf(ctx, out, " Name: %(\n", t);
391 fz_free(ctx, t);
392 if (*tu)
393 fz_write_printf(ctx, out, " Label: %q\n", tu);
394 if (parent)
395 fz_write_printf(ctx, out, " Parent: %d\n", pdf_to_num(ctx, parent));
396
397 showaction(ctx, pdf_dict_getp(ctx, field, "A"), "Action");
398
399 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/K"), "Keystroke");
400 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/V"), "Validate");
401 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/F"), "Format");
402 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/C"), "Calculate");
403
404 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/E"), "Enter");
405 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/X"), "Exit");
406 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/D"), "Down");
407 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/U"), "Up");
408 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/Fo"), "Focus");
409 showaction(ctx, pdf_dict_getp_inheritable(ctx, field, "AA/Bl"), "Blur");
410
411 fz_write_string(ctx, out, "\n");
412
413 kids = pdf_dict_get(ctx, field, PDF_NAME(Kids));
414 n = pdf_array_len(ctx, kids);
415 for (i = 0; i < n; ++i)
416 showfield(ctx, pdf_array_get(ctx, kids, i));
417 }
418
419 static void showform(fz_context *ctx)
420 {
421 pdf_obj *fields;
422 int i, n;
423
424 fields = pdf_dict_getp(ctx, pdf_trailer(ctx, doc), "Root/AcroForm/Fields");
425 n = pdf_array_len(ctx, fields);
426 for (i = 0; i < n; ++i)
427 showfield(ctx, pdf_array_get(ctx, fields, i));
428 }
429
430 #define SEP ".[]/"
431
432 static int isnumber(char *s)
433 {
434 if (*s == '-')
435 s++;
436 while (*s)
437 {
438 if (*s < '0' || *s > '9')
439 return 0;
440 ++s;
441 }
442 return 1;
443 }
444
445 static void showpath(fz_context *ctx, char *path, pdf_obj *obj)
446 {
447 if (path && path[0])
448 {
449 char *part = fz_strsep(&path, SEP);
450 if (part && part[0])
451 {
452 if (!strcmp(part, "*"))
453 {
454 int i, n;
455 char buf[1000];
456 if (pdf_is_array(ctx, obj))
457 {
458 n = pdf_array_len(ctx, obj);
459 for (i = 0; i < n; ++i)
460 {
461 if (path)
462 {
463 fz_strlcpy(buf, path, sizeof buf);
464 showpath(ctx, buf, pdf_array_get(ctx, obj, i));
465 }
466 else
467 showpath(ctx, NULL, pdf_array_get(ctx, obj, i));
468 }
469 }
470 else if (pdf_is_dict(ctx, obj))
471 {
472 n = pdf_dict_len(ctx, obj);
473 for (i = 0; i < n; ++i)
474 {
475 if (path)
476 {
477 fz_strlcpy(buf, path, sizeof buf);
478 showpath(ctx, buf, pdf_dict_get_val(ctx, obj, i));
479 }
480 else
481 showpath(ctx, NULL, pdf_dict_get_val(ctx, obj, i));
482 }
483 }
484 else
485 {
486 fz_write_string(ctx, out, "null\n");
487 }
488 }
489 else if (isnumber(part) && pdf_is_array(ctx, obj))
490 {
491 int num = atoi(part);
492 num = num < 0 ? pdf_array_len(ctx, obj) + num : num - 1;
493 showpath(ctx, path, pdf_array_get(ctx, obj, num));
494 }
495 else
496 showpath(ctx, path, pdf_dict_gets(ctx, obj, part));
497 }
498 else
499 fz_write_string(ctx, out, "null\n");
500 }
501 else
502 {
503 if (pdf_is_indirect(ctx, obj))
504 showobject(ctx, obj);
505 else
506 {
507 pdf_print_obj(ctx, out, obj, do_tight, 0);
508 fz_write_string(ctx, out, "\n");
509 }
510 }
511 }
512
513 static void showpathpage(fz_context *ctx, char *path)
514 {
515 if (path)
516 {
517 char *part = fz_strsep(&path, SEP);
518 if (part && part[0])
519 {
520 if (!strcmp(part, "*"))
521 {
522 int i, n;
523 char buf[1000];
524 n = pdf_count_pages(ctx, doc);
525 for (i = 0; i < n; ++i)
526 {
527 if (path)
528 {
529 fz_strlcpy(buf, path, sizeof buf);
530 showpath(ctx, buf, pdf_lookup_page_obj(ctx, doc, i));
531 }
532 else
533 showpath(ctx, NULL, pdf_lookup_page_obj(ctx, doc, i));
534 }
535 }
536 else if (isnumber(part))
537 {
538 int num = atoi(part);
539 num = num < 0 ? pdf_count_pages(ctx, doc) + num : num - 1;
540 showpath(ctx, path, pdf_lookup_page_obj(ctx, doc, num));
541 }
542 else
543 fz_write_string(ctx, out, "null\n");
544 }
545 else
546 fz_write_string(ctx, out, "null\n");
547 }
548 else
549 {
550 showpages(ctx);
551 }
552 }
553
554 static void showpathroot(fz_context *ctx, char *path)
555 {
556 char buf[2000], *list = buf, *part;
557 fz_strlcpy(buf, path, sizeof buf);
558 part = fz_strsep(&list, SEP);
559 if (part && part[0])
560 {
561 if (!strcmp(part, "trailer"))
562 showpath(ctx, list, pdf_trailer(ctx, doc));
563 else if (!strcmp(part, "pages"))
564 showpathpage(ctx, list);
565 else if (isnumber(part))
566 {
567 pdf_obj *obj;
568 int num = atoi(part);
569 num = num < 0 ? pdf_xref_len(ctx, doc) + num : num;
570 obj = pdf_new_indirect(ctx, doc, num, 0);
571 fz_try(ctx)
572 showpath(ctx, list, obj);
573 fz_always(ctx)
574 pdf_drop_obj(ctx, obj);
575 fz_catch(ctx)
576 ;
577 }
578 else
579 showpath(ctx, list, pdf_dict_gets(ctx, pdf_trailer(ctx, doc), part));
580 }
581 else
582 fz_write_string(ctx, out, "null\n");
583 }
584
585 static void show(fz_context *ctx, char *sel)
586 {
587 if (!strcmp(sel, "trailer"))
588 showtrailer(ctx);
589 else if (!strcmp(sel, "xref"))
590 showxref(ctx);
591 else if (!strcmp(sel, "pages"))
592 showpages(ctx);
593 else if (!strcmp(sel, "grep"))
594 showgrep(ctx);
595 else if (!strcmp(sel, "outline"))
596 showoutline(ctx);
597 else if (!strcmp(sel, "js"))
598 showjs(ctx);
599 else if (!strcmp(sel, "form"))
600 showform(ctx);
601 else
602 showpathroot(ctx, sel);
603 }
604
605 int pdfshow_main(int argc, char **argv)
606 {
607 char *password = NULL; /* don't throw errors if encrypted */
608 char *filename = NULL;
609 char *output = NULL;
610 int c;
611 int errored = 0;
612
613 fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
614 if (!ctx)
615 {
616 fprintf(stderr, "cannot initialise context\n");
617 exit(1);
618 }
619
620 while ((c = fz_getopt(argc, argv, "p:o:begrL")) != -1)
621 {
622 switch (c)
623 {
624 case 'p': password = fz_optarg; break;
625 case 'o': output = fz_optpath(fz_optarg); break;
626 case 'b': showbinary = 1; break;
627 case 'e': showdecode = 0; break;
628 case 'g': do_tight = 1; break;
629 case 'r': do_repair = 1; break;
630 case 'L': do_label = 1; break;
631 default: return usage();
632 }
633 }
634
635 if (fz_optind == argc)
636 return usage();
637
638 filename = argv[fz_optind++];
639
640 if (output)
641 out = fz_new_output_with_path(ctx, output, 0);
642 else
643 out = fz_stdout(ctx);
644
645 fz_var(doc);
646 fz_var(labels);
647 fz_try(ctx)
648 {
649 doc = pdf_open_document(ctx, filename);
650 if (pdf_needs_password(ctx, doc))
651 if (!pdf_authenticate_password(ctx, doc, password))
652 fz_warn(ctx, "cannot authenticate password: %s", filename);
653
654 if (do_repair)
655 {
656 fz_try(ctx)
657 {
658 pdf_repair_xref(ctx, doc);
659 }
660 fz_catch(ctx)
661 {
662 fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
663 fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
664 fz_rethrow_if(ctx, FZ_ERROR_REPAIRED);
665 fz_report_error(ctx);
666 }
667 }
668
669 if (do_label)
670 labels = pdf_load_object_labels(ctx, doc);
671
672 if (fz_optind == argc)
673 showtrailer(ctx);
674
675 while (fz_optind < argc)
676 show(ctx, argv[fz_optind++]);
677 }
678 fz_always(ctx)
679 {
680 fz_close_output(ctx, out);
681 fz_drop_output(ctx, out);
682 pdf_drop_object_labels(ctx, labels);
683 pdf_drop_document(ctx, doc);
684 }
685 fz_catch(ctx)
686 {
687 fz_report_error(ctx);
688 errored = 1;
689 }
690
691 fz_drop_context(ctx);
692 return errored;
693 }