Example #1
0
static fz_document *
epub_init(fz_context *ctx, fz_archive *zip)
{
	epub_document *doc;

	doc = fz_new_document(ctx, epub_document);
	doc->zip = zip;
	doc->set = fz_new_html_font_set(ctx);

	doc->super.drop_document = epub_drop_document;
	doc->super.layout = epub_layout;
	doc->super.load_outline = epub_load_outline;
	doc->super.resolve_link = epub_resolve_link;
	doc->super.count_pages = epub_count_pages;
	doc->super.load_page = epub_load_page;
	doc->super.lookup_metadata = epub_lookup_metadata;
	doc->super.is_reflowable = 1;

	fz_try(ctx)
	{
		epub_parse_header(ctx, doc);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, &doc->super);
		fz_rethrow(ctx);
	}

	return (fz_document*)doc;
}
Example #2
0
static tiff_document *
tiff_open_document_with_stream(fz_context *ctx, fz_stream *file)
{
	tiff_document *doc;

	doc = fz_new_document(ctx, tiff_document);

	doc->super.drop_document = (fz_document_drop_fn *)tiff_drop_document;
	doc->super.count_pages = (fz_document_count_pages_fn *)tiff_count_pages;
	doc->super.load_page = (fz_document_load_page_fn *)tiff_load_page;
	doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)tiff_lookup_metadata;

	fz_try(ctx)
	{
		size_t len;
		unsigned char *data;
		doc->buffer = fz_read_all(ctx, file, 1024);
		len = fz_buffer_storage(ctx, doc->buffer, &data);
		doc->page_count = fz_load_tiff_subimage_count(ctx, data, len);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, &doc->super);
		fz_rethrow(ctx);
	}

	return doc;
}
Example #3
0
static void reload(void)
{
    fz_drop_outline(ctx, outline);
    fz_drop_document(ctx, doc);

    doc = fz_open_document(ctx, filename);
    if (fz_needs_password(ctx, doc))
    {
        if (!fz_authenticate_password(ctx, doc, password))
        {
            fprintf(stderr, "Invalid password.\n");
            exit(1);
        }
    }

    fz_layout_document(ctx, doc, layout_w, layout_h, layout_em);

    fz_try(ctx)
    outline = fz_load_outline(ctx, doc);
    fz_catch(ctx)
    outline = NULL;

    pdf = pdf_specifics(ctx, doc);
    if (pdf)
        pdf_enable_js(ctx, pdf);

    currentpage = fz_clampi(currentpage, 0, fz_count_pages(ctx, doc) - 1);

    render_page();
    update_title();
}
Example #4
0
void
xps_drop_page_imp(fz_context *ctx, xps_page *page)
{
	if (page == NULL)
		return;
	fz_drop_document(ctx, &page->doc->super);
	fz_drop_xml(ctx, page->root);
}
MupdfBackend::~MupdfBackend() {
  if (m_doc) {
    fz_drop_document(m_ctx, m_doc);
    m_doc = 0;
  }

  if (m_ctx) {
    fz_drop_document_handler_context(m_ctx); // TODO: is this needed?
    fz_drop_context(m_ctx);
    m_ctx = 0;
  }
}
Example #6
0
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);
    }
}
Example #7
0
static int make_fake_doc(pdfapp_t *app)
{
	fz_context *ctx = app->ctx;
	pdf_document *pdf = NULL;
	fz_buffer *contents = NULL;
	pdf_obj *page_obj = NULL;

	fz_var(contents);
	fz_var(page_obj);

	fz_try(ctx)
	{
		fz_rect mediabox = { 0, 0, app->winw, app->winh };
		int i;

		pdf = pdf_create_document(ctx);


		contents = fz_new_buffer(ctx, 100);
		fz_append_printf(ctx, contents, "1 0 0 RG %g w 0 0 m %g %g l 0 %g m %g 0 l s\n",
			fz_min(mediabox.x1, mediabox.y1) / 20,
			mediabox.x1, mediabox.y1,
			mediabox.y1, mediabox.x1);

		/* Create enough copies of our blank(ish) page so that the
		 * page number is preserved if and when a subsequent load
		 * works. */
		page_obj = pdf_add_page(ctx, pdf, &mediabox, 0, NULL, contents);
		for (i = 0; i < app->pagecount; i++)
			pdf_insert_page(ctx, pdf, -1, page_obj);
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, page_obj);
		fz_drop_buffer(ctx, contents);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, (fz_document *) pdf);
		return 1;
	}

	app->doc = (fz_document*)pdf;
	return 0;
}
Example #8
0
fz_display_list *
fz_new_display_list_from_svg(fz_context *ctx, fz_buffer *buf, float *w, float *h)
{
	fz_document *doc;
	fz_display_list *list;

	doc = svg_open_document_with_buffer(ctx, buf);
	fz_try(ctx)
	{
		list = fz_new_display_list_from_page_number(ctx, doc, 0);
		*w = ((svg_document*)doc)->width;
		*h = ((svg_document*)doc)->height;
	}
	fz_always(ctx)
		fz_drop_document(ctx, doc);
	fz_catch(ctx)
		fz_rethrow(ctx);

	return list;
}
Example #9
0
fz_document *
xps_open_document_with_stream(fz_context *ctx, fz_stream *file)
{
	xps_document *doc;

	doc = fz_malloc_struct(ctx, xps_document);
	xps_init_document(ctx, doc);

	fz_try(ctx)
	{
		doc->zip = fz_open_zip_archive_with_stream(ctx, file);
		xps_read_page_list(ctx, doc);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, &doc->super);
		fz_rethrow(ctx);
	}

	return (fz_document*)doc;
}
Example #10
0
static fz_document *
xps_open_document_with_directory(fz_context *ctx, const char *directory)
{
	xps_document *doc;

	doc = fz_malloc_struct(ctx, xps_document);
	xps_init_document(ctx, doc);

	fz_try(ctx)
	{
		doc->zip = fz_open_directory(ctx, directory);
		xps_read_page_list(ctx, doc);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, &doc->super);
		fz_rethrow(ctx);
	}

	return (fz_document*)doc;
}
Example #11
0
static fz_document *
cbz_open_document_with_stream(fz_context *ctx, fz_stream *file)
{
	cbz_document *doc;

	doc = fz_new_derived_document(ctx, cbz_document);

	doc->super.drop_document = cbz_drop_document;
	doc->super.count_pages = cbz_count_pages;
	doc->super.load_page = cbz_load_page;
	doc->super.lookup_metadata = cbz_lookup_metadata;

	fz_try(ctx)
	{
		doc->arch = fz_open_archive_with_stream(ctx, file);
		cbz_create_page_list(ctx, doc);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, (fz_document*)doc);
		fz_rethrow(ctx);
	}
	return (fz_document*)doc;
}
Example #12
0
int main(int argc, char **argv)
{
	char *password = "";
	fz_document *doc = NULL;
	fz_context *ctx;
	int c;

	fz_var(ctx, doc);

	while ((c = fz_getopt(argc, argv, "p:")) != -1)
	{
		switch (c)
		{
		default: usage(); break;
		case 'p': password = fz_optarg; break;
		}
	}

	if (fz_optind + 2 != argc)
		usage();

	filename = argv[fz_optind];
	mujstest_filename = argv[fz_optind+1];

	if (strcmp(mujstest_filename, "-") == 0)
		mujstest_file = stdout;
	else
		mujstest_file = fopen(mujstest_filename, "wb");

	ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
	if (!ctx)
	{
		fprintf(stderr, "cannot initialise context\n");
		exit(1);
	}

	fz_register_document_handlers(ctx);

	fz_try(ctx)
	{
		doc = fz_open_document(ctx, filename);

		if (fz_needs_password(doc))
		{
			if (!fz_authenticate_password(ctx, doc, password))
				fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", filename);
			fprintf(mujstest_file, "PASSWORD %s\n", password);
		}

		fprintf(mujstest_file, "OPEN %s\n", filename);

		processpages(ctx, doc);

		fz_drop_document(ctx, doc);
	}
	fz_catch(ctx)
	{
		fprintf(stderr, "mjsgen: cannot process document: %s\n", filename);
		return 1;
	}

	fclose(mujstest_file);
	fz_drop_context(ctx);
	return 0;
}
Example #13
0
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;
}
Example #14
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;
}
Example #15
0
int muconvert_main(int argc, char **argv)
{
	int i, c;

	while ((c = fz_getopt(argc, argv, "p:A:W:H:S:U:o:F:O:")) != -1)
	{
		switch (c)
		{
		default: usage(); break;

		case 'p': password = fz_optarg; break;
		case 'A': alphabits = atoi(fz_optarg); break;
		case 'W': layout_w = atof(fz_optarg); break;
		case 'H': layout_h = atof(fz_optarg); break;
		case 'S': layout_em = atof(fz_optarg); break;
		case 'U': layout_css = fz_optarg; break;

		case 'o': output = fz_optarg; break;
		case 'F': format = fz_optarg; break;
		case 'O': options = fz_optarg; break;
		}
	}

	if (fz_optind == argc || (!format && !output))
		usage();

	/* Create a context to hold the exception stack and various caches. */
	ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
	if (!ctx)
	{
		fprintf(stderr, "cannot create mupdf context\n");
		return EXIT_FAILURE;
	}

	/* Register the default file types to handle. */
	fz_try(ctx)
		fz_register_document_handlers(ctx);
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot register document handlers: %s\n", fz_caught_message(ctx));
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	fz_set_aa_level(ctx, alphabits);

	if (layout_css)
	{
		fz_buffer *buf = fz_read_file(ctx, layout_css);
		fz_write_buffer_byte(ctx, buf, 0);
		fz_set_user_css(ctx, (char*)buf->data);
		fz_drop_buffer(ctx, buf);
	}

	/* Open the output document. */
	fz_try(ctx)
		out = fz_new_document_writer(ctx, output, format, options);
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot create document: %s\n", fz_caught_message(ctx));
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	for (i = fz_optind; i < argc; ++i)
	{
		doc = fz_open_document(ctx, argv[i]);
		if (fz_needs_password(ctx, doc))
			if (!fz_authenticate_password(ctx, doc, password))
				fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", argv[i]);
		fz_layout_document(ctx, doc, layout_w, layout_h, layout_em);
		count = fz_count_pages(ctx, doc);

		if (i+1 < argc && fz_is_page_range(ctx, argv[i+1]))
			runrange(argv[++i]);
		else
			runrange("1-N");

		fz_drop_document(ctx, doc);
	}

	fz_drop_document_writer(ctx, out);
	fz_drop_context(ctx);
	return EXIT_SUCCESS;
}
Example #16
0
int main(int argc, char **argv)
{
	char *input;
	float zoom, rotate;
	int page_number, page_count;
	fz_context *ctx;
	fz_document *doc;
	fz_pixmap *pix;
	fz_matrix ctm;
	int x, y;

	if (argc < 3)
	{
		fprintf(stderr, "usage: example input-file page-number [ zoom [ rotate ] ]\n");
		fprintf(stderr, "\tinput-file: path of PDF, XPS, CBZ or EPUB document to open\n");
		fprintf(stderr, "\tPage numbering starts from one.\n");
		fprintf(stderr, "\tZoom level is in percent (100 percent is 72 dpi).\n");
		fprintf(stderr, "\tRotation is in degrees clockwise.\n");
		return EXIT_FAILURE;
	}

	input = argv[1];
	page_number = atoi(argv[2]) - 1;
	zoom = argc > 3 ? atof(argv[3]) : 100;
	rotate = argc > 4 ? atof(argv[4]) : 0;

	/* Create a context to hold the exception stack and various caches. */
	ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
	if (!ctx)
	{
		fprintf(stderr, "cannot create mupdf context\n");
		return EXIT_FAILURE;
	}

	/* Register the default file types to handle. */
	fz_try(ctx)
		fz_register_document_handlers(ctx);
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot register document handlers: %s\n", fz_caught_message(ctx));
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	/* Open the document. */
	fz_try(ctx)
		doc = fz_open_document(ctx, input);
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot open document: %s\n", fz_caught_message(ctx));
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	/* Count the number of pages. */
	fz_try(ctx)
		page_count = fz_count_pages(ctx, doc);
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot count number of pages: %s\n", fz_caught_message(ctx));
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	if (page_number < 0 || page_number >= page_count)
	{
		fprintf(stderr, "page number out of range: %d (page count %d)\n", page_number + 1, page_count);
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	/* Compute a transformation matrix for the zoom and rotation desired. */
	/* The default resolution without scaling is 72 dpi. */
	fz_scale(&ctm, zoom / 100, zoom / 100);
	fz_pre_rotate(&ctm, rotate);

	/* Render page to an RGB pixmap. */
	fz_try(ctx)
		pix = fz_new_pixmap_from_page_number(ctx, doc, page_number, &ctm, fz_device_rgb(ctx), 0);
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot render page: %s\n", fz_caught_message(ctx));
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return EXIT_FAILURE;
	}

	/* Print image data in ascii PPM format. */
	printf("P3\n");
	printf("%d %d\n", pix->w, pix->h);
	printf("255\n");
	for (y = 0; y < pix->h; ++y)
	{
		unsigned char *p = &pix->samples[y * pix->stride];
		for (x = 0; x < pix->w; ++x)
		{
			if (x > 0)
				printf("  ");
			printf("%3d %3d %3d", p[0], p[1], p[2]);
			p += pix->n;
		}
		printf("\n");
	}

	/* Clean up. */
	fz_drop_pixmap(ctx, pix);
	fz_drop_document(ctx, doc);
	fz_drop_context(ctx);
	return EXIT_SUCCESS;
}