void pdf_clean_file(fz_context *ctx, char *infile, char *outfile, char *password, fz_write_options *opts, char *argv[], int argc) { globals glo = { 0 }; glo.ctx = ctx; fz_try(ctx) { glo.doc = pdf_open_document_no_run(ctx, infile); if (pdf_needs_password(ctx, glo.doc)) if (!pdf_authenticate_password(ctx, glo.doc, password)) fz_throw(glo.ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); /* Only retain the specified subset of the pages */ if (argc) retainpages(ctx, &glo, argc, argv); pdf_write_document(ctx, glo.doc, outfile, opts); } fz_always(ctx) { pdf_close_document(ctx, glo.doc); } fz_catch(ctx) { if (opts && opts->errors) *opts->errors = *opts->errors+1; } }
int pdfsign_main(int argc, char **argv) { fz_context *ctx; pdf_document *doc; char *password = ""; int i, n, c; pdf_page *page = NULL; while ((c = fz_getopt(argc, argv, "p:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; default: usage(); break; } } if (argc - fz_optind < 1) usage(); filename = argv[fz_optind++]; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialize context\n"); exit(1); } fz_var(page); doc = pdf_open_document(ctx, filename); fz_try(ctx) { if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_warn(ctx, "cannot authenticate password: %s", filename); n = pdf_count_pages(ctx, doc); for (i = 0; i < n; ++i) { page = pdf_load_page(ctx, doc, i); verify_page(ctx, doc, i, page); fz_drop_page(ctx, (fz_page*)page); page = NULL; } } fz_always(ctx) pdf_drop_document(ctx, doc); fz_catch(ctx) { fz_drop_page(ctx, (fz_page*)page); fprintf(stderr, "error verify signatures: %s\n", fz_caught_message(ctx)); } fz_flush_warnings(ctx); fz_drop_context(ctx); return 0; }
int pdfextract_main(int argc, char **argv) { char *infile; char *password = ""; int c, o; while ((c = fz_getopt(argc, argv, "p:r")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'r': dorgb++; break; default: usage(); break; } } if (fz_optind == argc) usage(); infile = argv[fz_optind++]; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } doc = pdf_open_document(ctx, infile); if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); if (fz_optind == argc) { int len = pdf_count_objects(ctx, doc); for (o = 1; o < len; o++) showobject(o); } else { while (fz_optind < argc) { showobject(atoi(argv[fz_optind])); fz_optind++; } } pdf_close_document(ctx, doc); fz_flush_warnings(ctx); fz_drop_context(ctx); return 0; }
int pdfposter_main(int argc, char **argv) { char *infile; char *outfile = "out.pdf"; char *password = ""; int c; fz_write_options opts = { 0 }; pdf_document *doc; fz_context *ctx; opts.do_incremental = 0; opts.do_garbage = 0; opts.do_expand = 0; opts.do_ascii = 0; opts.do_linear = 0; while ((c = fz_getopt(argc, argv, "x:y:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'x': x_factor = atoi(fz_optarg); break; case 'y': y_factor = atoi(fz_optarg); break; default: usage(); break; } } if (argc - fz_optind < 1) usage(); infile = argv[fz_optind++]; if (argc - fz_optind > 0 && (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) { outfile = argv[fz_optind++]; } ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } doc = pdf_open_document(ctx, infile); if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); decimatepages(ctx, doc); pdf_write_document(ctx, doc, outfile, &opts); pdf_close_document(ctx, doc); fz_drop_context(ctx); return 0; }
int pdfposter_main(int argc, char **argv) { char *infile; char *outfile = "out.pdf"; char *password = ""; int c; fz_write_options opts; pdf_document *xref; fz_context *ctx; opts.do_garbage = 0; opts.do_expand = 0; opts.do_ascii = 0; while ((c = fz_getopt(argc, argv, "x:y:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'x': x_factor = atoi(fz_optarg); break; case 'y': y_factor = atoi(fz_optarg); break; default: usage(); break; } } if (argc - fz_optind < 1) usage(); infile = argv[fz_optind++]; if (argc - fz_optind > 0 && (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) { outfile = argv[fz_optind++]; } ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } xref = pdf_open_document_no_run(ctx, infile); if (pdf_needs_password(xref)) if (!pdf_authenticate_password(xref, password)) fz_throw(ctx, "cannot authenticate password: %s", infile); /* Only retain the specified subset of the pages */ decimatepages(xref); pdf_write_document(xref, outfile, &opts); pdf_close_document(xref); fz_free_context(ctx); return 0; }
/* ** Get /Info strings, e.g. wmupdf_info_field("myfile.pdf","Author",buf,255); ** Info labels: ** Title Document title ** Author Name of the person who created the doc. ** Subject Subject of the doc ** Keywords Keywords associated with the document. ** Creator If doc was converted to PDF from another format, the name ** of the product that created the original document. ** Producer If doc was converted to PDF from another format, the name ** of the product that converted it to PDF. ** CreationDate Date/Time document was created. ** ModDate Date/Time of most recent mod. */ int wmupdf_info_field(char *infile,char *label,char *buf,int maxlen) { pdf_document *xref; fz_context *ctx; pdf_obj *info,*obj; char *password=""; xref=NULL; buf[0]='\0'; ctx = fz_new_context(NULL,NULL,FZ_STORE_UNLIMITED); if (!ctx) return(-1); fz_try(ctx) { xref=pdf_open_document_no_run(ctx,infile); if (!xref) { fz_free_context(ctx); return(-2); } if (pdf_needs_password(xref) && !pdf_authenticate_password(xref,password)) { pdf_close_document(xref); fz_free_context(ctx); return(-3); } if (xref->trailer!=NULL && (info=pdf_dict_gets(xref->trailer,"Info"))!=NULL && (obj=pdf_dict_gets(info,label))!=NULL && pdf_is_string(obj)) { strncpy(buf,pdf_to_str_buf(obj),maxlen-1); buf[maxlen-1]='\0'; } } fz_always(ctx) { pdf_close_document(xref); } fz_catch(ctx) { } fz_free_context(ctx); return(0); }
static int pdfpages_pages(fz_context *ctx, fz_output *out, char *filename, char *password, char *argv[], int argc) { enum { NO_FILE_OPENED, NO_INFO_GATHERED, INFO_SHOWN } state; int argidx = 0; pdf_document *doc = NULL; int ret = 0; state = NO_FILE_OPENED; while (argidx < argc) { if (state == NO_FILE_OPENED || !fz_is_page_range(ctx, argv[argidx])) { if (state == NO_INFO_GATHERED) { showpages(ctx, doc, out, "1-N"); } pdf_drop_document(ctx, doc); filename = argv[argidx]; fz_printf(ctx, out, "%s:\n", filename); doc = pdf_open_document(ctx, filename); if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", filename); state = NO_INFO_GATHERED; } else { ret |= showpages(ctx, doc, out, argv[argidx]); state = INFO_SHOWN; } argidx++; } if (state == NO_INFO_GATHERED) showpages(ctx, doc, out, "1-N"); pdf_drop_document(ctx, doc); return ret; }
int pdfinfo_main(int argc, char **argv) { enum { NO_FILE_OPENED, NO_INFO_GATHERED, INFO_SHOWN } state; char *filename = ""; char *password = ""; int show = ALL; int c; while ((c = fz_getopt(argc, argv, "mfispxd:")) != -1) { switch (c) { case 'm': if (show == ALL) show = DIMENSIONS; else show |= DIMENSIONS; break; case 'f': if (show == ALL) show = FONTS; else show |= FONTS; break; case 'i': if (show == ALL) show = IMAGES; else show |= IMAGES; break; case 's': if (show == ALL) show = SHADINGS; else show |= SHADINGS; break; case 'p': if (show == ALL) show = PATTERNS; else show |= PATTERNS; break; case 'x': if (show == ALL) show = XOBJS; else show |= XOBJS; break; case 'd': password = fz_optarg; break; default: infousage(); break; } } if (fz_optind == argc) infousage(); ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } state = NO_FILE_OPENED; while (fz_optind < argc) { if (state == NO_FILE_OPENED || !arg_is_page_range(argv[fz_optind])) { if (state == NO_INFO_GATHERED) { showinfo(filename, show, "1-"); } closexref(); filename = argv[fz_optind]; printf("%s:\n", filename); doc = pdf_open_document_no_run(ctx, filename); if (pdf_needs_password(doc)) if (!pdf_authenticate_password(doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", filename); pagecount = pdf_count_pages(doc); showglobalinfo(); state = NO_INFO_GATHERED; } else { showinfo(filename, show, argv[fz_optind]); state = INFO_SHOWN; } fz_optind++; } if (state == NO_INFO_GATHERED) showinfo(filename, show, "1-"); closexref(); fz_free_context(ctx); return 0; }
int pdfportfolio_main(int argc, char **argv) { char *password = ""; char *outfile = NULL; char *outopts = "compress"; char *infile; int exit_code = 0; int do_save = 0; int has_old_file = 0; int c; while ((c = fz_getopt(argc, argv, "p:o:O:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'o': outfile = fz_optarg; break; case 'O': outopts = fz_optarg; break; default: usage(); break; } } if (fz_optind == argc) usage(); infile = argv[fz_optind++]; if (!outfile) outfile = infile; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } if (fz_file_exists(ctx, infile)) { doc = pdf_open_document(ctx, infile); if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); has_old_file = 1; } else { doc = pdf_create_document(ctx); /* add a blank page */ { const char *template = "BT /Tm 16 Tf 50 434 TD (This is a portfolio document.) Tj ET\n"; const unsigned char *data; int size; fz_font *font; pdf_obj *font_obj, *page_obj; pdf_obj *resources; fz_buffer *contents; fz_rect mediabox = { 0, 0, 400, 500 }; data = fz_lookup_base14_font(ctx, "Times-Roman", &size); font = fz_new_font_from_memory(ctx, "Times-Roman", data, size, 0, 0); font_obj = pdf_add_simple_font(ctx, doc, font, PDF_SIMPLE_ENCODING_LATIN); fz_drop_font(ctx, font); resources = pdf_add_new_dict(ctx, doc, 1); pdf_dict_putp_drop(ctx, resources, "Font/Tm", font_obj); contents = fz_new_buffer_from_shared_data(ctx, (const unsigned char *)template, strlen(template));
static void pdfapp_open_pdf(pdfapp_t *app, char *filename, int fd) { fz_error error; fz_stream *file; char *password = ""; fz_obj *obj; fz_obj *info; /* * Open PDF and load xref table */ file = fz_open_fd(fd); error = pdf_open_xref_with_stream(&app->xref, file, NULL); if (error) pdfapp_error(app, fz_rethrow(error, "cannot open document '%s'", filename)); fz_close(file); /* * Handle encrypted PDF files */ if (pdf_needs_password(app->xref)) { int okay = pdf_authenticate_password(app->xref, password); while (!okay) { password = winpassword(app, filename); if (!password) exit(1); okay = pdf_authenticate_password(app->xref, password); if (!okay) pdfapp_warn(app, "Invalid password."); } } /* * Load meta information */ app->outline = pdf_load_outline(app->xref); app->doctitle = filename; if (strrchr(app->doctitle, '\\')) app->doctitle = strrchr(app->doctitle, '\\') + 1; if (strrchr(app->doctitle, '/')) app->doctitle = strrchr(app->doctitle, '/') + 1; info = fz_dict_gets(app->xref->trailer, "Info"); if (info) { obj = fz_dict_gets(info, "Title"); if (obj) app->doctitle = pdf_to_utf8(obj); } /* * Start at first page */ error = pdf_load_page_tree(app->xref); if (error) pdfapp_error(app, fz_rethrow(error, "cannot load page tree")); app->pagecount = pdf_count_pages(app->xref); }
int main(int argc, char **argv) #endif { char *infile; char *outfile = "out.pdf"; char *password = ""; int c, num; int subset; while ((c = fz_getopt(argc, argv, "adfgip:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'g': dogarbage ++; break; case 'd': doexpand ^= expand_all; break; case 'f': doexpand ^= expand_fonts; break; case 'i': doexpand ^= expand_images; break; case 'a': doascii ++; break; default: usage(); break; } } if (argc - fz_optind < 1) usage(); infile = argv[fz_optind++]; if (argc - fz_optind > 0 && (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) { outfile = argv[fz_optind++]; } subset = 0; if (argc - fz_optind > 0) subset = 1; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } xref = pdf_open_document(ctx, infile); if (pdf_needs_password(xref)) if (!pdf_authenticate_password(xref, password)) fz_throw(ctx, "cannot authenticate password: %s\n", infile); out = fopen(outfile, "wb"); if (!out) fz_throw(ctx, "cannot open output file '%s'", outfile); fprintf(out, "%%PDF-%d.%d\n", xref->version / 10, xref->version % 10); fprintf(out, "%%\316\274\341\277\246\n\n"); uselist = fz_malloc_array(ctx, xref->len + 1, sizeof(char)); ofslist = fz_malloc_array(ctx, xref->len + 1, sizeof(int)); genlist = fz_malloc_array(ctx, xref->len + 1, sizeof(int)); renumbermap = fz_malloc_array(ctx, xref->len + 1, sizeof(int)); for (num = 0; num < xref->len; num++) { uselist[num] = 0; ofslist[num] = 0; genlist[num] = 0; renumbermap[num] = num; } /* Make sure any objects hidden in compressed streams have been loaded */ preloadobjstms(); /* Only retain the specified subset of the pages */ if (subset) retainpages(argc, argv); /* Sweep & mark objects from the trailer */ if (dogarbage >= 1) sweepobj(xref->trailer); /* Coalesce and renumber duplicate objects */ if (dogarbage >= 3) removeduplicateobjs(); /* Compact xref by renumbering and removing unused objects */ if (dogarbage >= 2) compactxref(); /* Make renumbering affect all indirect references and update xref */ /* Do not renumber objects if encryption is in use, as the object * numbers are baked into the streams/strings, and we can't currently * cope with moving them. See bug 692627. */ if (dogarbage >= 2 && !xref->crypt) renumberobjs(); writepdf(); if (fclose(out)) fz_throw(ctx, "cannot close output file '%s'", outfile); fz_free(xref->ctx, uselist); fz_free(xref->ctx, ofslist); fz_free(xref->ctx, genlist); fz_free(xref->ctx, renumbermap); pdf_close_document(xref); fz_free_context(ctx); return 0; }
int pdfclean_main(int argc, char **argv) { char *infile; char *outfile = "out.pdf"; char *password = ""; int c; int subset; fz_write_options opts; int write_failed = 0; opts.do_garbage = 0; opts.do_expand = 0; opts.do_ascii = 0; opts.do_linear = 0; while ((c = fz_getopt(argc, argv, "adfgilp:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'g': opts.do_garbage ++; break; case 'd': opts.do_expand ^= fz_expand_all; break; case 'f': opts.do_expand ^= fz_expand_fonts; break; case 'i': opts.do_expand ^= fz_expand_images; break; case 'l': opts.do_linear ++; break; case 'a': opts.do_ascii ++; break; default: usage(); break; } } if (argc - fz_optind < 1) usage(); infile = argv[fz_optind++]; if (argc - fz_optind > 0 && (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) { outfile = argv[fz_optind++]; } subset = 0; if (argc - fz_optind > 0) subset = 1; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } fz_try(ctx) { xref = pdf_open_document_no_run(ctx, infile); if (pdf_needs_password(xref)) if (!pdf_authenticate_password(xref, password)) fz_throw(ctx, "cannot authenticate password: %s", infile); /* Only retain the specified subset of the pages */ if (subset) retainpages(argc, argv); pdf_write_document(xref, outfile, &opts); } fz_always(ctx) { pdf_close_document(xref); } fz_catch(ctx) { write_failed = 1; } fz_free_context(ctx); return write_failed ? 1 : 0; }
/* ** Reconstruct PDF file per the information in pageinfo. ** use_forms==0: Old-style reconstruction where the pages are not turned into XObject Forms. ** use_forms==1: New-style where pages are turned into XObject forms. */ int wmupdf_remake_pdf(char *infile,char *outfile,WPDFPAGEINFO *pageinfo,int use_forms,FILE *out) { pdf_document *xref; fz_context *ctx; fz_write_options fzopts; char *password=""; int status; int write_failed; fzopts.do_garbage=1; /* 2 and 3 don't work for this. */ fzopts.do_expand=0; fzopts.do_ascii=0; fzopts.do_linear=0; write_failed=0; wpdfpageinfo_sort(pageinfo); xref=NULL; /* New context */ ctx = fz_new_context(NULL,NULL,FZ_STORE_UNLIMITED); if (!ctx) { nprintf(out,"wmupdf_remake_pdf: Cannot initialize context.\n"); return(-1); } fz_try(ctx) { xref=pdf_open_document_no_run(ctx,infile); if (!xref) { fz_free_context(ctx); nprintf(out,"wmupdf_remake_pdf: Cannot open PDF file %s.\n",infile); return(-2); } if (pdf_needs_password(xref) && !pdf_authenticate_password(xref,password)) { pdf_close_document(xref); fz_free_context(ctx); nprintf(out,"wmupdf_remake_pdf: Cannot authenticate PDF file %s.\n",infile); return(-3); } status=wmupdf_pdfdoc_newpages(xref,ctx,pageinfo,use_forms,out); if (status<0) { pdf_close_document(xref); fz_free_context(ctx); nprintf(out,"wmupdf_remake_pdf: Error re-paginating PDF file %s.\n",infile); return(status); } info_update(ctx,xref,pageinfo->producer); /* Write output */ pdf_write_document(xref,outfile,&fzopts); } fz_always(ctx) { pdf_close_document(xref); } fz_catch(ctx) { write_failed=1; } fz_free_context(ctx); if (write_failed) { nprintf(out,"wmupdf_remake_pdf: Error writing output PDF file %s.\n",outfile); return(-10); } return(0); }
void pdfapp_open(pdfapp_t *app, char *filename) { #if 0 fz_error error; fz_obj *obj; char *password = ""; #else fz_error error; fz_stream *file; char *password = ""; fz_obj *obj; fz_obj *info; int fd; fd = open(filename, O_BINARY | O_RDONLY, 0666); if (fd < 0) fprintf(stderr, "error, file %s does not exist\n", filename); #endif /* * Open PDF and load xref table */ app->filename = filename; #if 0 app->xref = pdf_newxref(); error = pdf_loadxref(app->xref, filename); if (error) { fz_catch(error, "trying to air"); error = pdf_repairxref(app->xref, filename); if (error) pdfapp_error(app, error); } error = pdf_decryptxref(app->xref); if (error) pdfapp_error(app, error); #else file = fz_open_fd(fd); error = pdf_open_xref_with_stream(&app->xref, file, NULL); if (error) pdfapp_error(app, fz_rethrow(error, "cannot open document '%s'", filename)); fz_close(file); #endif /* * Handle encrypted PDF files */ if (pdf_needs_password(app->xref)) { int okay = pdf_authenticate_password(app->xref, password); while (!okay) { //password = winpassword(app, filename); if (!password) exit(1); okay = pdf_authenticate_password(app->xref, password); if (!okay) pdfapp_warn(app, "Invalid password."); } } /* * Load meta information * TODO: move this into mupdf library */ #if 0 obj = fz_dictgets(app->xref->trailer, "Root"); app->xref->root = fz_resolveindirect(obj); if (!app->xref->root) pdfapp_error(app, fz_throw("syntaxerror: missing Root object")); fz_keepobj(app->xref->root); obj = fz_dictgets(app->xref->trailer, "Info"); app->xref->info = fz_resolveindirect(obj); if (!app->xref->info) pdfapp_warn(app, "Could not load PDF meta information."); if (app->xref->info) fz_keepobj(app->xref->info); /*app->outline = pdf_loadoutline(app->xref);*/ app->doctitle = filename; if (strrchr(app->doctitle, '\\')) app->doctitle = strrchr(app->doctitle, '\\') + 1; if (strrchr(app->doctitle, '/')) app->doctitle = strrchr(app->doctitle, '/') + 1; if (app->xref->info) { obj = fz_dictgets(app->xref->info, "Title"); if (obj) { app->doctitle = pdf_toutf8(obj); } } #else app->outline = pdf_load_outline(app->xref); app->doctitle = filename; if (strrchr(app->doctitle, '\\')) app->doctitle = strrchr(app->doctitle, '\\') + 1; if (strrchr(app->doctitle, '/')) app->doctitle = strrchr(app->doctitle, '/') + 1; info = fz_dict_gets(app->xref->trailer, "Info"); if (info) { obj = fz_dict_gets(info, "Title"); if (obj) app->doctitle = pdf_to_utf8(obj); } #endif /* * Start at first page */ #if 0 app->pagecount = pdf_getpagecount(app->xref); #else error = pdf_load_page_tree(app->xref); if (error) pdfapp_error(app, fz_rethrow(error, "cannot load page tree")); app->pagecount = pdf_count_pages(app->xref); #endif app->rotate = 0; }
fz_error pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) { pdf_xref *xref; fz_error error; fz_obj *encrypt, *id; fz_obj *dict, *obj; int i, repaired = 0; /* install pdf specific callback */ fz_resolve_indirect = pdf_resolve_indirect; xref = fz_malloc(sizeof(pdf_xref)); memset(xref, 0, sizeof(pdf_xref)); xref->file = fz_keep_stream(file); error = pdf_load_xref(xref, xref->scratch, sizeof xref->scratch); if (error) { fz_catch(error, "trying to repair"); if (xref->table) { fz_free(xref->table); xref->table = NULL; xref->len = 0; } if (xref->trailer) { fz_drop_obj(xref->trailer); xref->trailer = NULL; } error = pdf_repair_xref(xref, xref->scratch, sizeof xref->scratch); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "cannot repair document"); } repaired = 1; } encrypt = fz_dict_gets(xref->trailer, "Encrypt"); id = fz_dict_gets(xref->trailer, "ID"); if (fz_is_dict(encrypt)) { error = pdf_new_crypt(&xref->crypt, encrypt, id); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "cannot decrypt document"); } } if (pdf_needs_password(xref)) { /* Only care if we have a password */ if (password) { int okay = pdf_authenticate_password(xref, password); if (!okay) { pdf_free_xref(xref); return fz_throw("invalid password"); } } } if (repaired) { int hasroot, hasinfo; error = pdf_repair_obj_stms(xref); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "cannot repair document"); } hasroot = fz_dict_gets(xref->trailer, "Root") != NULL; hasinfo = fz_dict_gets(xref->trailer, "Info") != NULL; for (i = 1; i < xref->len; i++) { if (xref->table[i].type == 0 || xref->table[i].type == 'f') continue; error = pdf_load_object(&dict, xref, i, 0); if (error) { fz_catch(error, "ignoring broken object (%d 0 R)", i); continue; } if (!hasroot) { obj = fz_dict_gets(dict, "Type"); if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Catalog")) { obj = fz_new_indirect(i, 0, xref); fz_dict_puts(xref->trailer, "Root", obj); fz_drop_obj(obj); } } if (!hasinfo) { if (fz_dict_gets(dict, "Creator") || fz_dict_gets(dict, "Producer")) { obj = fz_new_indirect(i, 0, xref); fz_dict_puts(xref->trailer, "Info", obj); fz_drop_obj(obj); } } fz_drop_obj(dict); } } error = pdf_read_ocg(xref); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "Broken Optional Content"); } *xrefp = xref; return fz_okay; }