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; }
void render_page(void) { fz_annot *annot; fz_pixmap *pix; fz_scale(&page_ctm, currentzoom / 72, currentzoom / 72); fz_pre_rotate(&page_ctm, -currentrotate); fz_invert_matrix(&page_inv_ctm, &page_ctm); fz_drop_page(ctx, page); page = fz_load_page(ctx, doc, currentpage); fz_drop_link(ctx, links); links = NULL; links = fz_load_links(ctx, page); pix = fz_new_pixmap_from_page_contents(ctx, page, &page_ctm, fz_device_rgb(ctx), 0); texture_from_pixmap(&page_tex, pix); fz_drop_pixmap(ctx, pix); annot_count = 0; for (annot = fz_first_annot(ctx, page); annot; annot = fz_next_annot(ctx, annot)) { pix = fz_new_pixmap_from_annot(ctx, annot, &page_ctm, fz_device_rgb(ctx), 1); texture_from_pixmap(&annot_tex[annot_count++], pix); fz_drop_pixmap(ctx, pix); if (annot_count >= nelem(annot_tex)) { fz_warn(ctx, "too many annotations to display!"); break; } } }
~MupdfPage() { clear(); fz_drop_page(m_ctx, m_page); m_page = 0; m_ctx = 0; }
static void runpage(int number) { fz_rect mediabox; fz_page *page; fz_device *dev; page = fz_load_page(ctx, doc, number - 1); fz_bound_page(ctx, page, &mediabox); dev = fz_begin_page(ctx, out, &mediabox); fz_run_page(ctx, page, dev, &fz_identity, NULL); fz_end_page(ctx, out, dev); fz_drop_page(ctx, page); }
fz_buffer * fz_new_buffer_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_rect *sel, int crlf) { fz_page *page; fz_buffer *buf; page = fz_load_page(ctx, doc, number); fz_try(ctx) buf = fz_new_buffer_from_page(ctx, page, sel, crlf); fz_always(ctx) fz_drop_page(ctx, page); fz_catch(ctx) fz_rethrow(ctx); return buf; }
int fz_search_page_number(fz_context *ctx, fz_document *doc, int number, const char *needle, fz_rect *hit_bbox, int hit_max) { fz_page *page; int count; page = fz_load_page(ctx, doc, number); fz_try(ctx) count = fz_search_page(ctx, page, needle, hit_bbox, hit_max); fz_always(ctx) fz_drop_page(ctx, page); fz_catch(ctx) fz_rethrow(ctx); return count; }
fz_stext_page * fz_new_stext_page_from_page_number(fz_context *ctx, fz_document *doc, int number, fz_stext_sheet *sheet) { fz_page *page; fz_stext_page *text; page = fz_load_page(ctx, doc, number); fz_try(ctx) text = fz_new_stext_page_from_page(ctx, page, sheet); fz_always(ctx) fz_drop_page(ctx, page); fz_catch(ctx) fz_rethrow(ctx); return text; }
fz_display_list * fz_new_display_list_from_page_number(fz_context *ctx, fz_document *doc, int number) { fz_page *page; fz_display_list *list; page = fz_load_page(ctx, doc, number); fz_try(ctx) list = fz_new_display_list_from_page(ctx, page); fz_always(ctx) fz_drop_page(ctx, page); fz_catch(ctx) fz_rethrow(ctx); return list; }
fz_pixmap * fz_new_pixmap_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_matrix *ctm, fz_colorspace *cs, int alpha) { fz_page *page; fz_pixmap *pix; page = fz_load_page(ctx, doc, number); fz_try(ctx) pix = fz_new_pixmap_from_page(ctx, page, ctm, cs, alpha); fz_always(ctx) fz_drop_page(ctx, page); fz_catch(ctx) fz_rethrow(ctx); return pix; }
Viewer::~Viewer() { if (dev) { fz_drop_device(ctx, dev); } if (pix) { fz_drop_pixmap(ctx, pix); } if (page) { fz_drop_page(ctx, page); } if (doc) { fz_drop_document(ctx, doc); } if (ctx) { fz_drop_context(ctx); } }
static fz_page * cbz_load_page(fz_context *ctx, fz_document *doc_, int number) { cbz_document *doc = (cbz_document*)doc_; cbz_page *page = NULL; fz_buffer *buf = NULL; if (number < 0 || number >= doc->page_count) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load page %d", number); fz_var(page); if (doc->arch) buf = fz_read_archive_entry(ctx, doc->arch, doc->page[number]); if (!buf) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load cbz page"); fz_try(ctx) { page = fz_new_derived_page(ctx, cbz_page); page->super.bound_page = cbz_bound_page; page->super.run_page_contents = cbz_run_page; page->super.drop_page = cbz_drop_page; page->image = fz_new_image_from_buffer(ctx, buf); } fz_always(ctx) { fz_drop_buffer(ctx, buf); } fz_catch(ctx) { fz_drop_page(ctx, (fz_page*)page); fz_rethrow(ctx); } return (fz_page*)page; }
int main(int argc, char **argv) { char *filename = argc >= 2 ? argv[1] : ""; pthread_t *thread = NULL; fz_locks_context locks; pthread_mutex_t mutex[FZ_LOCK_MAX]; fz_context *ctx; fz_document *doc; int threads; int i; // Initialize FZ_LOCK_MAX number of non-recursive mutexes. for (i = 0; i < FZ_LOCK_MAX; i++) { if (pthread_mutex_init(&mutex[i], NULL) != 0) fail("pthread_mutex_init()"); } // Initialize the locking structure with function pointers to // the locking functions and to the user data. In this case // the user data is a pointer to the array of mutexes so the // locking functions can find the relevant lock to change when // they are called. This way we avoid global variables. locks.user = mutex; locks.lock = lock_mutex; locks.unlock = unlock_mutex; // This is the main threads context function, so supply the // locking structure. This context will be used to parse all // the pages from the document. ctx = fz_new_context(NULL, &locks, FZ_STORE_UNLIMITED); // Register default file types. fz_register_document_handlers(ctx); // Open the PDF, XPS or CBZ document. Note, this binds doc to ctx. // You must only ever use doc with ctx - never a clone of it! doc = fz_open_document(ctx, filename); // Retrieve the number of pages, which translates to the // number of threads used for rendering pages. threads = fz_count_pages(ctx, doc); fprintf(stderr, "spawning %d threads, one per page...\n", threads); thread = malloc(threads * sizeof (pthread_t)); for (i = 0; i < threads; i++) { fz_page *page; fz_rect bbox; fz_irect rbox; fz_display_list *list; fz_device *dev; fz_pixmap *pix; struct data *data; // Load the relevant page for each thread. Note, that this // cannot be done on the worker threads, as each use of doc // uses ctx, and only one thread can be using ctx at a time. page = fz_load_page(ctx, doc, i); // Compute the bounding box for each page. fz_bound_page(ctx, page, &bbox); // Create a display list that will hold the drawing // commands for the page. Once we have the display list // this can safely be used on any other thread as it is // not bound to a given context. list = fz_new_display_list(ctx, &bbox); // Run the loaded page through a display list device // to populate the page's display list. dev = fz_new_list_device(ctx, list); fz_run_page(ctx, page, dev, &fz_identity, NULL); fz_close_device(ctx, dev); fz_drop_device(ctx, dev); // The page is no longer needed, all drawing commands // are now in the display list. fz_drop_page(ctx, page); // Create a white pixmap using the correct dimensions. pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), fz_round_rect(&rbox, &bbox), 0); fz_clear_pixmap_with_value(ctx, pix, 0xff); // Populate the data structure to be sent to the // rendering thread for this page. data = malloc(sizeof (struct data)); data->pagenumber = i + 1; data->ctx = ctx; data->list = list; data->bbox = bbox; data->pix = pix; // Create the thread and pass it the data structure. if (pthread_create(&thread[i], NULL, renderer, data) != 0) fail("pthread_create()"); } // Now each thread is rendering pages, so wait for each thread // to complete its rendering. fprintf(stderr, "joining %d threads...\n", threads); for (i = threads - 1; i >= 0; i--) { char filename[42]; struct data *data; if (pthread_join(thread[i], (void **) &data) != 0) fail("pthread_join"); sprintf(filename, "out%04d.png", i); fprintf(stderr, "\tSaving %s...\n", filename); // Write the rendered image to a PNG file fz_save_pixmap_as_png(ctx, data->pix, filename); // Free the thread's pixmap and display list since // they were allocated by the main thread above. fz_drop_pixmap(ctx, data->pix); fz_drop_display_list(ctx, data->list); // Free the data structured passed back and forth // between the main thread and rendering thread. free(data); } fprintf(stderr, "finally!\n"); fflush(NULL); free(thread); // Finally the document is closed and the main thread's // context is freed. fz_drop_document(ctx, doc); fz_drop_context(ctx); return 0; }
int main(int argc, char **argv) #endif { const GLFWvidmode *video_mode; int c; while ((c = fz_getopt(argc, argv, "p:r:W:H:S:U:X")) != -1) { switch (c) { default: usage(argv[0]); break; case 'p': password = fz_optarg; break; case 'r': currentzoom = fz_atof(fz_optarg); break; case 'W': layout_w = fz_atof(fz_optarg); break; case 'H': layout_h = fz_atof(fz_optarg); break; case 'S': layout_em = fz_atof(fz_optarg); break; case 'U': layout_css = fz_optarg; break; case 'X': layout_use_doc_css = 0; break; } } if (fz_optind < argc) { fz_strlcpy(filename, argv[fz_optind], sizeof filename); } else { #ifdef _WIN32 win_install(); if (!win_open_file(filename, sizeof filename)) exit(0); #else usage(argv[0]); #endif } title = strrchr(filename, '/'); if (!title) title = strrchr(filename, '\\'); if (title) ++title; else title = filename; memset(&ui, 0, sizeof ui); search_input.p = search_input.text; search_input.q = search_input.p; search_input.end = search_input.p; glfwSetErrorCallback(on_error); if (!glfwInit()) { fprintf(stderr, "cannot initialize glfw\n"); exit(1); } video_mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); screen_w = video_mode->width; screen_h = video_mode->height; window = glfwCreateWindow(DEFAULT_WINDOW_W, DEFAULT_WINDOW_H, filename, NULL, NULL); if (!window) { fprintf(stderr, "cannot create glfw window\n"); exit(1); } glfwMakeContextCurrent(window); ctx = fz_new_context(NULL, NULL, 0); fz_register_document_handlers(ctx); if (layout_css) { fz_buffer *buf = fz_read_file(ctx, layout_css); fz_set_user_css(ctx, fz_string_from_buffer(ctx, buf)); fz_drop_buffer(ctx, buf); } fz_set_use_document_css(ctx, layout_use_doc_css); has_ARB_texture_non_power_of_two = glfwExtensionSupported("GL_ARB_texture_non_power_of_two"); if (!has_ARB_texture_non_power_of_two) fz_warn(ctx, "OpenGL implementation does not support non-power of two texture sizes"); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); ui.fontsize = DEFAULT_UI_FONTSIZE; ui.baseline = DEFAULT_UI_BASELINE; ui.lineheight = DEFAULT_UI_LINEHEIGHT; ui_init_fonts(ctx, ui.fontsize); reload(); shrinkwrap(); glfwSetFramebufferSizeCallback(window, on_reshape); glfwSetCursorPosCallback(window, on_mouse_motion); glfwSetMouseButtonCallback(window, on_mouse_button); glfwSetScrollCallback(window, on_scroll); glfwSetCharModsCallback(window, on_char); glfwSetKeyCallback(window, on_key); glfwSetWindowRefreshCallback(window, on_display); glfwGetFramebufferSize(window, &window_w, &window_h); ui_needs_update = 1; while (!glfwWindowShouldClose(window)) { glfwWaitEvents(); if (ui_needs_update) run_main_loop(); } ui_finish_fonts(ctx); fz_drop_link(ctx, links); fz_drop_page(ctx, page); fz_drop_outline(ctx, outline); fz_drop_document(ctx, doc); fz_drop_context(ctx); glfwTerminate(); return 0; }
void fz_save_gproof(fz_context *ctx, const char *pdf_file, fz_document *doc, const char *filename, int res, const char *print_profile, const char *display_profile) { int i; int num_pages = fz_count_pages(ctx, doc); fz_output *out; fz_page *page = NULL; fz_var(page); if (num_pages <= 0) fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot write a 0 page GProof skeleton file"); out = fz_new_output_with_path(ctx, filename, 0); fz_try(ctx) { /* File Signature: GPRO */ fz_write_int32_le(ctx, out, 0x4f525047); /* Version = 1 */ fz_write_byte(ctx, out, 1); fz_write_byte(ctx, out, 0); /* Resolution */ fz_write_int32_le(ctx, out, res); /* Num Pages */ fz_write_int32_le(ctx, out, num_pages); for (i = 0; i < num_pages; i++) { fz_rect rect; int w, h; page = fz_load_page(ctx, doc, i); fz_bound_page(ctx, page, &rect); fz_drop_page(ctx, page); page = NULL; /* Same lack of rounding as gs uses */ w = (int)((rect.x1 - rect.x0) * res / 72.0); h = (int)((rect.y1 - rect.y0) * res / 72.0); fz_write_int32_le(ctx, out, w); fz_write_int32_le(ctx, out, h); } /* Filenames */ fz_write(ctx, out, pdf_file, strlen(pdf_file)+1); fz_write(ctx, out, print_profile, strlen(print_profile) + 1); fz_write(ctx, out, display_profile, strlen(display_profile) + 1); } fz_always(ctx) { fz_drop_page(ctx, page); fz_drop_output(ctx, out); } fz_catch(ctx) { fz_rethrow(ctx); } }