/* SumatraPDF: make pdf_lookup_inherited_page_item externally available */ pdf_obj * pdf_lookup_inherited_page_item(pdf_document *doc, pdf_obj *node, const char *key) { fz_context *ctx = doc->ctx; pdf_obj *node2 = node; pdf_obj *val; /* fz_var(node); Not required as node passed in */ fz_try(ctx) { do { val = pdf_dict_gets(node, key); if (val) break; if (pdf_mark_obj(node)) fz_throw(ctx, FZ_ERROR_GENERIC, "cycle in page tree (parents)"); node = pdf_dict_gets(node, "Parent"); } while (node); } fz_always(ctx) { do { pdf_unmark_obj(node2); if (node2 == node) break; node2 = pdf_dict_gets(node2, "Parent"); } while (node2); } fz_catch(ctx) { fz_rethrow(ctx); } return val; }
pdf_obj *pdf_new_rect(fz_context *ctx, pdf_document *doc, const fz_rect *rect) { pdf_obj *arr = NULL; pdf_obj *item = NULL; fz_var(arr); fz_var(item); fz_try(ctx) { arr = pdf_new_array(ctx, doc, 4); item = pdf_new_real(ctx, doc, rect->x0); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, rect->y0); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, rect->x1); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, rect->y1); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; } fz_catch(ctx) { pdf_drop_obj(ctx, item); pdf_drop_obj(ctx, arr); fz_rethrow(ctx); } return arr; }
static fz_outline * epub_parse_ncx_imp(fz_context *ctx, epub_document *doc, fz_xml *node, char *base_uri) { char path[2048]; fz_outline *outline, *head, **tailp; head = NULL; tailp = &head; node = fz_xml_find_down(node, "navPoint"); while (node) { char *text = fz_xml_text(fz_xml_down(fz_xml_find_down(fz_xml_find_down(node, "navLabel"), "text"))); char *content = fz_xml_att(fz_xml_find_down(node, "content"), "src"); if (text && content) { fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, content, sizeof path); fz_urldecode(path); fz_cleanname(path); fz_try(ctx) { *tailp = outline = fz_new_outline(ctx); tailp = &(*tailp)->next; outline->title = fz_strdup(ctx, text); outline->uri = fz_strdup(ctx, path); outline->page = -1; outline->down = epub_parse_ncx_imp(ctx, doc, node, base_uri); outline->is_open = 1; } fz_catch(ctx) { fz_drop_outline(ctx, head); fz_rethrow(ctx); } } node = fz_xml_find_next(node, "navPoint"); }
static int make_fake_doc(pdfapp_t *app) { fz_context *ctx = app->ctx; pdf_document *pdf = NULL; fz_buffer *contents = NULL; fz_try(ctx) { fz_rect mediabox = { 0, 0, app->winw, app->winh }; pdf_obj *page_obj; int i; contents = fz_new_buffer(ctx, 100); pdf = pdf_create_document(ctx); app->doc = (fz_document*)pdf; fz_buffer_printf(ctx, contents, "1 0 0 rg %f w 0 0 m %f %f l 0 %f m %f 0 l\n", fz_min(mediabox.x1, mediabox.y1) / 4, 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, contents, NULL); for (i = 0; i < app->pagecount; i++) pdf_insert_page(ctx, pdf, -1, page_obj); pdf_drop_obj(ctx, page_obj); } fz_always(ctx) { fz_drop_buffer(ctx, contents); } fz_catch(ctx) { fz_rethrow(ctx); } return 0; }
pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect rect) { pdf_obj *arr = NULL; pdf_obj *item = NULL; fz_var(arr); fz_var(item); fz_try(ctx) { arr = pdf_new_array(ctx, 4); item = pdf_new_real(ctx, rect.x0); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, rect.y0); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, rect.x1); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, rect.y1); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; } fz_catch(ctx) { pdf_drop_obj(item); pdf_drop_obj(arr); fz_rethrow(ctx); } return arr; }
static unsigned char * pam_binary_read_header(fz_context *ctx, struct info *pnm, unsigned char *p, unsigned char *e) { char *token = fz_strdup(ctx, ""); fz_try(ctx) { while (p < e && strcmp(token, "ENDHDR")) { fz_free(ctx, token); p = pnm_read_string(ctx, p, e, &token); p = pnm_read_white(ctx, p, e, 0); if (!strcmp(token, "WIDTH")) p = pnm_read_number(ctx, p, e, &pnm->width); else if (!strcmp(token, "HEIGHT")) p = pnm_read_number(ctx, p, e, &pnm->height); else if (!strcmp(token, "DEPTH")) p = pnm_read_number(ctx, p, e, &pnm->depth); else if (!strcmp(token, "MAXVAL")) p = pnm_read_number(ctx, p, e, &pnm->maxval); else if (!strcmp(token, "TUPLTYPE")) p = pnm_read_string(ctx, p, e, &pnm->tupletype); else if (strcmp(token, "ENDHDR")) fz_throw(ctx, FZ_ERROR_GENERIC, "unknown header token in pnm image"); if (strcmp(token, "ENDHDR")) p = pnm_read_white(ctx, p, e, 0); } } fz_always(ctx) { fz_free(ctx, token); } fz_catch(ctx) { fz_rethrow(ctx); } return p; }
static cbz_document * cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) { cbz_document *doc = fz_new_document(ctx, sizeof *doc); doc->super.close = (fz_document_close_fn *)cbz_close_document; doc->super.count_pages = (fz_document_count_pages_fn *)cbz_count_pages; doc->super.load_page = (fz_document_load_page_fn *)cbz_load_page; doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)cbz_lookup_metadata; fz_try(ctx) { doc->zip = fz_open_archive_with_stream(ctx, file); cbz_create_page_list(ctx, doc); } fz_catch(ctx) { cbz_close_document(ctx, doc); fz_rethrow(ctx); } return doc; }
static void fz_list_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_display_node *node; fz_context *ctx = dev->ctx; node = fz_new_display_node(ctx, FZ_CMD_STROKE_TEXT, ctm, colorspace, color, alpha); node->item.text = NULL; fz_try(ctx) { node->rect = fz_bound_text(dev->ctx, text, ctm); fz_adjust_rect_for_stroke(&node->rect, stroke, &ctm); node->item.text = fz_clone_text(dev->ctx, text); node->stroke = fz_keep_stroke_state(dev->ctx, stroke); } fz_catch(ctx) { fz_free_display_node(ctx, node); fz_rethrow(ctx); } fz_append_display_node(dev->user, node); }
static void fz_list_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { //PDFLOGI("[dev_list.c] fz_list_fill_path, start \n"); fz_display_node *node; fz_context *ctx = dev->ctx; node = fz_new_display_node(ctx, FZ_CMD_FILL_PATH, ctm, colorspace, color, alpha); fz_try(ctx) { node->rect = fz_bound_path(dev->ctx, path, NULL, ctm); node->item.path = fz_clone_path(dev->ctx, path); node->flag = even_odd; } fz_catch(ctx) { fz_free_display_node(ctx, node); fz_rethrow(ctx); } fz_append_display_node(dev->user, node); }
void fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, const char *filename) { fz_band_writer *writer = NULL; fz_output *out = fz_new_output_with_path(ctx, filename, 0); fz_var(writer); fz_try(ctx) { writer = fz_new_pam_band_writer(ctx, out); fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 0, pixmap->colorspace, pixmap->seps); fz_write_band(ctx, writer, pixmap->stride, pixmap->h, pixmap->samples); } fz_always(ctx) { fz_drop_band_writer(ctx, writer); fz_drop_output(ctx, out); } fz_catch(ctx) fz_rethrow(ctx); }
fz_outline * pdf_load_outline(fz_context *ctx, pdf_document *doc) { pdf_obj *root, *obj, *first; fz_outline *outline = NULL; pdf_load_page_tree(ctx, doc); /* cache page tree for fast link destination lookups */ fz_try(ctx) { root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root); obj = pdf_dict_get(ctx, root, PDF_NAME_Outlines); first = pdf_dict_get(ctx, obj, PDF_NAME_First); if (first) outline = pdf_load_outline_imp(ctx, doc, first); } fz_always(ctx) pdf_drop_page_tree(ctx, doc); fz_catch(ctx) fz_rethrow(ctx); return outline; }
fz_stream * fz_open_fd(fz_context *ctx, int fd) { fz_stream *stm; int *state; state = fz_malloc_struct(ctx, int); *state = fd; fz_try(ctx) { stm = fz_new_stream(ctx, state, read_file, close_file); } fz_catch(ctx) { fz_free(ctx, state); fz_rethrow(ctx); } stm->seek = seek_file; return stm; }
fz_stream * fz_new_stream(fz_context *ctx, void *state, int(*read)(fz_stream *stm, unsigned char *buf, int len), void(*close)(fz_context *ctx, void *state)) { fz_stream *stm; fz_try(ctx) { stm = fz_malloc_struct(ctx, fz_stream); } fz_catch(ctx) { close(ctx, state); fz_rethrow(ctx); } stm->refs = 1; stm->error = 0; stm->eof = 0; stm->pos = 0; stm->bits = 0; stm->avail = 0; stm->locked = 0; stm->bp = stm->buf; stm->rp = stm->bp; stm->wp = stm->bp; stm->ep = stm->buf + sizeof stm->buf; stm->state = state; stm->read = read; stm->close = close; stm->seek = NULL; stm->ctx = ctx; return stm; }
static void fz_list_clip_text(fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate) { fz_display_node *node; fz_context *ctx = dev->ctx; node = fz_new_display_node(ctx, FZ_CMD_CLIP_TEXT, ctm, NULL, NULL, 0); fz_try(ctx) { fz_bound_text(dev->ctx, text, NULL, ctm, &node->rect); node->item.text = fz_clone_text(dev->ctx, text); node->flag = accumulate; /* when accumulating, be conservative about culling */ if (accumulate) node->rect = fz_infinite_rect; } fz_catch(ctx) { fz_free_display_node(ctx, node); fz_rethrow(ctx); } fz_append_display_node(dev->user, node); }
xps_part * xps_new_part(fz_context *ctx, xps_document *doc, char *name, unsigned char *data, int size) { xps_part *part; part = fz_malloc_struct(ctx, xps_part); fz_try(ctx) { part->name = fz_strdup(ctx, name); part->data = data; part->size = size; } fz_catch(ctx) { fz_free(ctx, part->name); fz_free(ctx, part->data); fz_free(ctx, part); fz_rethrow(ctx); } return part; }
fz_stream * fz_new_stream(fz_context *ctx, void *state, fz_stream_next_fn *next, fz_stream_close_fn *close, fz_stream_rebind_fn *rebind) { fz_stream *stm; fz_try(ctx) { stm = fz_malloc_struct(ctx, fz_stream); } fz_catch(ctx) { close(ctx, state); fz_rethrow(ctx); } stm->refs = 1; stm->error = 0; stm->eof = 0; stm->pos = 0; stm->bits = 0; stm->avail = 0; stm->rp = NULL; stm->wp = NULL; stm->state = state; stm->next = next; stm->close = close; stm->seek = NULL; stm->rebind = rebind; stm->reopen = NULL; stm->ctx = ctx; return stm; }
static void xps_read_and_process_metadata_part(fz_context *ctx, xps_document *doc, char *name, xps_fixdoc *fixdoc) { xps_part *part; if (!xps_has_part(ctx, doc, name)) return; part = xps_read_part(ctx, doc, name); fz_try(ctx) { xps_parse_metadata(ctx, doc, part, fixdoc); } fz_always(ctx) { xps_drop_part(ctx, doc, part); } fz_catch(ctx) { fz_rethrow(ctx); } }
fz_path * fz_clone_path(fz_context *ctx, fz_path *old) { fz_path *path; assert(old); path = fz_malloc_struct(ctx, fz_path); fz_try(ctx) { path->len = old->len; path->cap = old->len; path->items = fz_malloc_array(ctx, path->cap, sizeof(fz_path_item)); memcpy(path->items, old->items, sizeof(fz_path_item) * path->len); } fz_catch(ctx) { fz_free(ctx, path); fz_rethrow(ctx); } return path; }
pdf_document *openxref(fz_context *ctx, char *filename) { pdf_document *xref = pdf_open_document(ctx, filename); fz_try(ctx) { if (pdf_needs_password(xref)) { logbench("Warning: password protected document\n"); fz_throw(ctx, "document requires password"); } pdf_count_pages(xref); } fz_catch(ctx) { pdf_close_document(xref); fz_rethrow(ctx); } return xref; }
static int read_jbig2d(fz_stream *stm, unsigned char *buf, int len) { fz_jbig2d *state = stm->state; unsigned char tmp[4096]; unsigned char *p = buf; unsigned char *ep = buf + len; unsigned char *s; int x, w, n; if (!state->page) { while (1) { n = fz_read(state->chain, tmp, sizeof tmp); if (n < 0) return fz_rethrow(n, "read error in jbig2 filter"); if (n == 0) break; jbig2_data_in(state->ctx, tmp, n); } jbig2_complete_page(state->ctx); state->page = jbig2_page_out(state->ctx); if (!state->page) return fz_throw("jbig2_page_out failed"); } s = state->page->data; w = state->page->height * state->page->stride; x = state->idx; while (p < ep && x < w) *p++ = s[x++] ^ 0xff; state->idx = x; return p - buf; }
static tiff_page * tiff_load_page(fz_context *ctx, tiff_document *doc, int number) { fz_pixmap *pixmap = NULL; fz_image *image = NULL; tiff_page *page = NULL; if (number < 0 || number >= doc->page_count) return NULL; fz_var(pixmap); fz_var(image); fz_var(page); fz_try(ctx) { pixmap = fz_load_tiff_subimage(ctx, doc->buffer->data, doc->buffer->len, number); image = fz_new_image_from_pixmap(ctx, pixmap, NULL); page = fz_new_page(ctx, sizeof *page); page->super.bound_page = (fz_page_bound_page_fn *)tiff_bound_page; page->super.run_page_contents = (fz_page_run_page_contents_fn *)tiff_run_page; page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)tiff_drop_page_imp; page->image = fz_keep_image(ctx, image); } fz_always(ctx) { fz_drop_image(ctx, image); fz_drop_pixmap(ctx, pixmap); } fz_catch(ctx) { fz_free(ctx, page); fz_rethrow(ctx); } return page; }
static fz_error parsehexstring(fz_obj **obj, char **sp) { fz_error error; char buf[512]; char *s = *sp; char *p = buf; int a, b; s ++; /* skip '<' */ while (*s && p < buf + sizeof buf) { skipwhite(&s); if (*s == '>') { s ++; break; } a = *s++; if (*s == '\0') break; skipwhite(&s); if (*s == '>') { s ++; break; } b = *s++; *p++ = fromhex(a) * 16 + fromhex(b); } *sp = s; error = fz_newstring(obj, buf, p - buf); if (error) return fz_rethrow(error, "cannot create string"); return fz_okay; }
static void execute_action(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *a) { if (a) { pdf_obj *type = pdf_dict_get(ctx, a, PDF_NAME_S); if (pdf_name_eq(ctx, type, PDF_NAME_JavaScript)) { pdf_obj *js = pdf_dict_get(ctx, a, PDF_NAME_JS); if (js) { char *code = pdf_to_utf8(ctx, doc, js); fz_try(ctx) { pdf_js_execute(doc->js, code); } fz_always(ctx) { fz_free(ctx, code); } fz_catch(ctx) { fz_rethrow(ctx); } } } else if (pdf_name_eq(ctx, type, PDF_NAME_ResetForm)) { reset_form(ctx, doc, pdf_dict_get(ctx, a, PDF_NAME_Fields), pdf_to_int(ctx, pdf_dict_get(ctx, a, PDF_NAME_Flags)) & 1); } else if (pdf_name_eq(ctx, type, PDF_NAME_Named)) { pdf_obj *name = pdf_dict_get(ctx, a, PDF_NAME_N); if (pdf_name_eq(ctx, name, PDF_NAME_Print)) pdf_event_issue_print(ctx, doc); } }
fz_stream * fz_open_null(fz_stream *chain, int len, int offset) { struct null_filter *state; fz_context *ctx = chain->ctx; if (len < 0) len = 0; fz_try(ctx) { state = fz_malloc_struct(ctx, struct null_filter); state->chain = chain; state->remain = len; state->pos = offset; } fz_catch(ctx) { fz_close(chain); fz_rethrow(ctx); } return fz_new_stream(ctx, state, read_null, close_null); }
static fz_error * openfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src, int mode) { fz_error *error; fz_stream *stm; stm = newstm(FZ_SFILTER, mode); if (!stm) return fz_throw("outofmem: stream struct"); error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE); if (error) { fz_free(stm); return fz_rethrow(error, "cannot create buffer"); } stm->chain = fz_keepstream(src); stm->filter = fz_keepfilter(flt); *stmp = stm; return fz_okay; }
fz_error pdf_loadimage(fz_pixmap **pixp, pdf_xref *xref, fz_obj *dict) { fz_error error; if ((*pixp = pdf_finditem(xref->store, fz_droppixmap, dict))) { fz_keeppixmap(*pixp); return fz_okay; } pdf_logimage("load image (%d 0 R) {\n", fz_tonum(dict)); error = pdf_loadimageimp(pixp, xref, nil, dict, nil, 0); if (error) return fz_rethrow(error, "cannot load image (%d 0 R)", fz_tonum(dict)); pdf_storeitem(xref->store, fz_keeppixmap, fz_droppixmap, dict, *pixp); pdf_logimage("}\n"); return fz_okay; }
void pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *stm, int indexed, fz_image *image) { fz_compressed_buffer *bc = fz_malloc_struct(ctx, fz_compressed_buffer); fz_try(ctx) { int dummy_l2factor = 0; bc->buffer = fz_new_buffer(ctx, 1024); stm = pdf_open_inline_stream(ctx, doc, dict, length, stm, &bc->params); stm = fz_open_leecher(ctx, stm, bc->buffer); stm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor); image->tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, 0, 0); } fz_catch(ctx) { fz_drop_compressed_buffer(ctx, bc); fz_rethrow(ctx); } image->buffer = bc; }
fz_error fz_newfontfromfile(fz_font **fontp, char *path, int index) { fz_error error; fz_font *font; int fterr; error = fz_initfreetype(); if (error) return fz_rethrow(error, "cannot init freetype library"); font = fz_newfont(); fterr = FT_New_Face(fz_ftlib, path, index, (FT_Face*)&font->ftface); if (fterr) { fz_free(font); return fz_throw("freetype: cannot load font: %s", ft_errorstring(fterr)); } *fontp = font; return fz_okay; }
fz_error fz_newfontfrombuffer(fz_font **fontp, unsigned char *data, int len, int index) { fz_error error; fz_font *font; int fterr; error = fz_initfreetype(); if (error) return fz_rethrow(error, "cannot init freetype library"); font = fz_newfont(); fterr = FT_New_Memory_Face(fz_ftlib, data, len, index, (FT_Face*)&font->ftface); if (fterr) { fz_free(font); return fz_throw("freetype: cannot load font: %s", ft_errorstring(fterr)); } *fontp = font; return fz_okay; }
fz_stream * fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w) { fz_sgilog16 *state = fz_malloc_struct(ctx, fz_sgilog16); fz_try(ctx) { state->run = 0; state->n = 0; state->c = 0; state->w = w; state->temp = fz_malloc(ctx, w * sizeof(uint16_t)); state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { fz_free(ctx, state->temp); fz_free(ctx, state); fz_rethrow(ctx); } return fz_new_stream(ctx, state, next_sgilog16, close_sgilog16); }