fz_obj *xps_extract_doc_props(xps_context *ctx) { char path[1024]; xps_part *part; fz_obj *dict; if (xps_find_doc_props_path(ctx, path) != fz_okay) { fz_catch(-1, "couldn't find the exact part name for /docProps/core.xml"); fz_strlcpy(path, "/docProps/core.xml", sizeof(path)); } if (!*path) return NULL; part = xps_read_part(ctx, path); if (!part) { fz_catch(-1, "cannot read zip part '%s'", path); return NULL; } dict = fz_new_dict(8); xps_hacky_get_prop(part->data, dict, "Title", "dc:title"); xps_hacky_get_prop(part->data, dict, "Subject", "dc:subject"); xps_hacky_get_prop(part->data, dict, "Author", "dc:creator"); xps_hacky_get_prop(part->data, dict, "CreationDate", "dcterms:created"); xps_hacky_get_prop(part->data, dict, "ModDate", "dcterms:modified"); xps_free_part(ctx, part); return dict; }
static void cbz_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) { fz_cbz_writer *wri = (fz_cbz_writer*)wri_; fz_buffer *buffer; char name[40]; fz_try(ctx) fz_close_device(ctx, dev); fz_always(ctx) fz_drop_device(ctx, dev); fz_catch(ctx) fz_rethrow(ctx); wri->count += 1; fz_snprintf(name, sizeof name, "p%04d.png", wri->count); buffer = fz_new_buffer_from_pixmap_as_png(ctx, wri->pixmap, NULL); fz_try(ctx) fz_write_zip_entry(ctx, wri->zip, name, buffer, 0); fz_always(ctx) fz_drop_buffer(ctx, buffer); fz_catch(ctx) fz_rethrow(ctx); fz_drop_pixmap(ctx, wri->pixmap); wri->pixmap = NULL; }
static void fz_test_fill_image(fz_context *ctx, fz_device *dev_, fz_image *image, fz_matrix ctm, float alpha, const fz_color_params *color_params) { fz_test_device *dev = (fz_test_device*)dev_; while (dev->resolved == 0) /* So we can break out */ { fz_compressed_buffer *buffer; if (*dev->is_color || !image->colorspace || fz_colorspace_is_gray(ctx, image->colorspace)) break; if ((dev->options & FZ_TEST_OPT_IMAGES) == 0) { /* Don't test every pixel. Upgrade us from "black and white" to "probably color" */ if (*dev->is_color == 0) *dev->is_color = 1; dev->resolved = 1; if (dev->passthrough == NULL) fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); break; } buffer = fz_compressed_image_buffer(ctx, image); if (buffer && image->bpc == 8) { fz_stream *stream = fz_open_compressed_buffer(ctx, buffer); fz_try(ctx) fz_test_fill_compressed_8bpc_image(ctx, dev, image, stream, color_params); fz_always(ctx) fz_drop_stream(ctx, stream); fz_catch(ctx) fz_rethrow(ctx); } else { fz_pixmap *pix = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0); if (pix == NULL) /* Should never happen really, but... */ break; fz_try(ctx) fz_test_fill_other_image(ctx, dev, pix, color_params); fz_always(ctx) fz_drop_pixmap(ctx, pix); fz_catch(ctx) fz_rethrow(ctx); } break; } if (dev->passthrough) fz_fill_image(ctx, dev->passthrough, image, ctm, alpha, color_params); }
static pdf_obj *draw_radio_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h, int yes) { pdf_obj *ap; fz_buffer *buf; float b; buf = fz_new_buffer(ctx, 1024); fz_try(ctx) { fz_append_string(ctx, buf, "q\n"); if (pdf_write_MK_BG_appearance(ctx, annot, buf)) draw_circle_in_box(ctx, buf, "f\n", 0, 0, 0, w, h); b = pdf_write_border_appearance(ctx, annot, buf); if (b > 0 && pdf_write_MK_BC_appearance(ctx, annot, buf)) draw_circle_in_box(ctx, buf, "s\n", b, 0, 0, w, h); if (yes) { fz_append_string(ctx, buf, "0 g\n"); draw_circle(ctx, buf, "f\n", (w-b*2)/4, (h-b*2)/4, w/2, h/2); } fz_append_string(ctx, buf, "Q\n"); ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, NULL, buf); } fz_always(ctx) fz_drop_buffer(ctx, buf); fz_catch(ctx) fz_rethrow(ctx); return ap; }
static void pdf_begingroup(pdf_csi *csi, fz_rect bbox) { pdf_gstate *gstate = csi->gstate + csi->gtop; fz_error error; if (gstate->softmask) { pdf_xobject *softmask = gstate->softmask; fz_rect bbox = fz_transformrect(gstate->ctm, softmask->bbox); gstate->softmask = nil; csi->dev->beginmask(csi->dev->user, bbox, gstate->luminosity, softmask->colorspace, gstate->softmaskbc); error = pdf_runxobject(csi, nil, softmask, fz_identity); if (error) fz_catch(error, "cannot run softmask"); csi->dev->endmask(csi->dev->user); gstate->softmask = softmask; } if (gstate->blendmode != FZ_BNORMAL) csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1); }
void fz_dropstream(fz_stream *stm) { stm->refs --; if (stm->refs == 0) { if (stm->error) { fz_catch(stm->error, "dropped unhandled ioerror"); stm->error = fz_okay; } switch (stm->kind) { case FZ_SFILE: close(stm->file); break; case FZ_SFILTER: fz_dropfilter(stm->filter); fz_dropstream(stm->chain); break; case FZ_SBUFFER: break; } fz_dropbuffer(stm->buffer); fz_free(stm); } }
static pdf_obj *draw_check_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h, int yes) { float black[3] = { 0, 0, 0 }; pdf_obj *ap, *res = NULL; fz_buffer *buf; float b; fz_var(res); buf = fz_new_buffer(ctx, 1024); fz_try(ctx) { fz_append_string(ctx, buf, "q\n"); if (pdf_write_MK_BG_appearance(ctx, annot, buf)) fz_append_printf(ctx, buf, "0 0 %g %g re\nf\n", w, h); b = pdf_write_border_appearance(ctx, annot, buf); if (b > 0 && pdf_write_MK_BC_appearance(ctx, annot, buf)) fz_append_printf(ctx, buf, "%g %g %g %g re\nS\n", b/2, b/2, w-b, h-b); if (yes) write_variable_text(ctx, annot, buf, &res, "3", "ZaDb", h, black, 0, w, h, b+h/10, 0.8f, 1.2f, 0, 0, 0); fz_append_string(ctx, buf, "Q\n"); ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, res, buf); } fz_always(ctx) { pdf_drop_obj(ctx, res); fz_drop_buffer(ctx, buf); } fz_catch(ctx) fz_rethrow(ctx); return ap; }
static img_document * img_open_document_with_stream(fz_context *ctx, fz_stream *stm) { fz_buffer *buffer = NULL; fz_image *image = NULL; img_document *doc; fz_var(buffer); fz_var(image); fz_try(ctx) { buffer = fz_read_all(ctx, stm, 1024); image = fz_new_image_from_buffer(ctx, buffer); doc = img_new_document(ctx, image); } fz_always(ctx) { fz_drop_image(ctx, image); fz_drop_buffer(ctx, buffer); } fz_catch(ctx) fz_rethrow(ctx); return doc; }
static void pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, const char *usage, fz_cookie *cookie) { fz_matrix local_ctm, page_ctm; fz_rect mediabox; pdf_processor *proc; fz_default_colorspaces *default_cs; default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); fz_drop_default_colorspaces(ctx, default_cs); pdf_page_transform(ctx, page, &mediabox, &page_ctm); fz_concat(&local_ctm, &page_ctm, ctm); proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0); fz_try(ctx) { pdf_process_annot(ctx, proc, doc, page, annot, cookie); pdf_close_processor(ctx, proc); } fz_always(ctx) pdf_drop_processor(ctx, proc); fz_catch(ctx) fz_rethrow(ctx); }
void fz_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list old_args) { char buffer[256], *p = buffer; int len; va_list args; if (!out) return; /* First try using our fixed size buffer */ va_copy(args, old_args); len = fz_vsnprintf(buffer, sizeof buffer, fmt, args); va_copy_end(args); /* If that failed, allocate a big enough buffer */ if (len > sizeof buffer) { p = fz_malloc(ctx, len); va_copy(args, old_args); fz_vsnprintf(p, len, fmt, args); va_copy_end(args); } fz_try(ctx) out->write(ctx, out->opaque, p, len); fz_always(ctx) if (p != buffer) fz_free(ctx, p); fz_catch(ctx) fz_rethrow(ctx); }
xps_document * xps_open_document(fz_context *ctx, const char *filename) { char buf[2048]; fz_stream *file; char *p; xps_document *doc; if (strstr(filename, "/_rels/.rels") || strstr(filename, "\\_rels\\.rels")) { fz_strlcpy(buf, filename, sizeof buf); p = strstr(buf, "/_rels/.rels"); if (!p) p = strstr(buf, "\\_rels\\.rels"); *p = 0; return xps_open_document_with_directory(ctx, buf); } file = fz_open_file(ctx, filename); fz_try(ctx) doc = xps_open_document_with_stream(ctx, file); fz_always(ctx) fz_drop_stream(ctx, file); fz_catch(ctx) fz_rethrow_message(ctx, "cannot load document '%s'", filename); return doc; }
void die(fz_error error) { fz_catch(error, "aborting"); if (xref) pdf_freexref(xref); exit(1); }
fz_error pdf_loadfontdescriptor(pdf_fontdesc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection) { fz_error error; fz_obj *obj1, *obj2, *obj3, *obj; fz_rect bbox; char *fontname; pdf_logfont("load fontdescriptor {\n"); fontname = fz_toname(fz_dictgets(dict, "FontName")); pdf_logfont("fontname '%s'\n", fontname); fontdesc->flags = fz_toint(fz_dictgets(dict, "Flags")); fontdesc->italicangle = fz_toreal(fz_dictgets(dict, "ItalicAngle")); fontdesc->ascent = fz_toreal(fz_dictgets(dict, "Ascent")); fontdesc->descent = fz_toreal(fz_dictgets(dict, "Descent")); fontdesc->capheight = fz_toreal(fz_dictgets(dict, "CapHeight")); fontdesc->xheight = fz_toreal(fz_dictgets(dict, "XHeight")); fontdesc->missingwidth = fz_toreal(fz_dictgets(dict, "MissingWidth")); bbox = pdf_torect(fz_dictgets(dict, "FontBBox")); pdf_logfont("bbox [%g %g %g %g]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); pdf_logfont("flags %d\n", fontdesc->flags); obj1 = fz_dictgets(dict, "FontFile"); obj2 = fz_dictgets(dict, "FontFile2"); obj3 = fz_dictgets(dict, "FontFile3"); obj = obj1 ? obj1 : obj2 ? obj2 : obj3; if (getenv("NOFONT")) obj = nil; if (fz_isindirect(obj)) { error = pdf_loadembeddedfont(fontdesc, xref, obj); if (error) { fz_catch(error, "ignored error when loading embedded font, attempting to load system font"); error = pdf_loadsystemfont(fontdesc, fontname, collection); if (error) return fz_rethrow(error, "cannot load font descriptor"); } } else { error = pdf_loadsystemfont(fontdesc, fontname, collection); if (error) return fz_rethrow(error, "cannot load font descriptor"); } pdf_logfont("}\n"); return fz_okay; }
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(); }
static void pwg_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) { fz_pwg_writer *wri = (fz_pwg_writer*)wri_; fz_close_device(ctx, dev); fz_drop_device(ctx, dev); if (wri->mono) { fz_bitmap *bitmap = fz_new_bitmap_from_pixmap(ctx, wri->pixmap, NULL); fz_try(ctx) fz_write_bitmap_as_pwg_page(ctx, wri->out, bitmap, &wri->pwg); fz_always(ctx) fz_drop_bitmap(ctx, bitmap); fz_catch(ctx) fz_rethrow(ctx); } else { fz_write_pixmap_as_pwg_page(ctx, wri->out, wri->pixmap, &wri->pwg); } fz_drop_pixmap(ctx, wri->pixmap); wri->pixmap = NULL; }
static void saveimage(int num) { fz_image *image = NULL; fz_pixmap *pix = NULL; pdf_obj *ref; char buf[32]; ref = pdf_new_indirect(ctx, doc, num, 0); fz_var(image); fz_var(pix); fz_try(ctx) { /* TODO: detect DCTD and save as jpeg */ image = pdf_load_image(ctx, doc, ref); pix = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0); snprintf(buf, sizeof(buf), "img-%04d", num); writepixmap(ctx, pix, buf, dorgb); } fz_always(ctx) { fz_drop_image(ctx, image); fz_drop_pixmap(ctx, pix); pdf_drop_obj(ctx, ref); } fz_catch(ctx) fz_rethrow(ctx); }
static void fz_test_fill_compressed_8bpc_image(fz_context *ctx, fz_test_device *dev, fz_image *image, fz_stream *stream, const fz_color_params *color_params) { unsigned int count = (unsigned int)image->w * (unsigned int)image->h; unsigned int i; if (image->colorspace == fz_device_rgb(ctx)) { int threshold_u8 = dev->threshold * 255; for (i = 0; i < count; i++) { int r = fz_read_byte(ctx, stream); int g = fz_read_byte(ctx, stream); int b = fz_read_byte(ctx, stream); if (is_rgb_color_u8(threshold_u8, r, g, b)) { *dev->is_color = 1; dev->resolved = 1; if (dev->passthrough == NULL) fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); break; } } } else { fz_color_converter cc; unsigned int n = (unsigned int)image->n; fz_init_cached_color_converter(ctx, &cc, NULL, fz_device_rgb(ctx), image->colorspace, color_params); fz_try(ctx) { for (i = 0; i < count; i++) { float cs[FZ_MAX_COLORS]; float ds[FZ_MAX_COLORS]; unsigned int k; for (k = 0; k < n; k++) cs[k] = fz_read_byte(ctx, stream) / 255.0f; cc.convert(ctx, &cc, ds, cs); if (is_rgb_color(dev->threshold, ds[0], ds[1], ds[2])) { *dev->is_color = 1; dev->resolved = 1; if (dev->passthrough == NULL) fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); break; } } } fz_always(ctx) fz_fin_cached_color_converter(ctx, &cc); fz_catch(ctx) fz_rethrow(ctx); } }
void die(fz_error error) { fz_catch(error, "aborting"); if (cleanup) cleanup(); closexref(); exit(1); }
void fz_save_pixmap_as_ps(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append) { fz_output *out = fz_new_output_with_path(ctx, filename, append); fz_try(ctx) fz_write_pixmap_as_ps(ctx, out, pixmap); fz_always(ctx) fz_drop_output(ctx, out); fz_catch(ctx) fz_rethrow(ctx); }
void pdf_array_put_drop(fz_context *ctx, pdf_obj *obj, int i, pdf_obj *item) { fz_try(ctx) pdf_array_put(ctx, obj, i, item); fz_always(ctx) pdf_drop_obj(ctx, item); fz_catch(ctx) fz_rethrow(ctx); }
fz_pixmap * fz_rendert3glyph(fz_font *font, int gid, fz_matrix trm) { fz_error error; fz_matrix ctm; fz_buffer *contents; fz_bbox bbox; fz_device *dev; fz_glyphcache *cache; fz_pixmap *glyph; fz_pixmap *result; if (gid < 0 || gid > 255) return NULL; contents = font->t3procs[gid]; if (!contents) return NULL; ctm = fz_concat(font->t3matrix, trm); dev = fz_newbboxdevice(&bbox); error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); if (error) fz_catch(error, "cannot draw type3 glyph"); fz_freedevice(dev); glyph = fz_newpixmap(fz_devicegray, bbox.x0-1, bbox.y0-1, bbox.x1 - bbox.x0 + 1, bbox.y1 - bbox.y0 + 1); fz_clearpixmap(glyph, 0); cache = fz_newglyphcache(); dev = fz_newdrawdevice(cache, glyph); error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); if (error) fz_catch(error, "cannot draw type3 glyph"); fz_freedevice(dev); fz_freeglyphcache(cache); result = fz_alphafromgray(glyph, 0); fz_droppixmap(glyph); return result; }
void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename) { fz_output *out = fz_new_output_with_path(ctx, filename, 0); fz_try(ctx) fz_write(ctx, out, buf->data, buf->len); fz_always(ctx) fz_drop_output(ctx, out); fz_catch(ctx) fz_rethrow(ctx); }
static int do_name_tree_map(fz_context *ctx, pdf_obj *tree, pdf_name_tree_map_fn *fn, void *arg) { int i; int n = 0; int m = 0; fz_var(n); fz_var(m); if (pdf_mark_obj(ctx, tree)) fz_throw(ctx, FZ_ERROR_GENERIC, "Recursive name tree!"); fz_try(ctx) { pdf_obj *arr = pdf_dict_get(ctx, tree, PDF_NAME_Kids); n = pdf_array_len(ctx, arr); for (i = n; i > 0;) { i--; if (do_name_tree_map(ctx, pdf_array_get(ctx, arr, i), fn, arg)) { pdf_array_delete(ctx, arr, i); n--; } } arr = pdf_dict_get(ctx, tree, PDF_NAME_Names); m = pdf_array_len(ctx, arr); if (m & 1) fz_throw(ctx, FZ_ERROR_GENERIC, "Malformed Names array"); for (i = m; i > 0;) { i -= 2; if (fn(ctx, tree, pdf_array_get(ctx, arr, i), pdf_array_get(ctx, arr, i+1), arg)) { pdf_array_delete(ctx, arr, i+1); pdf_array_delete(ctx, arr, i); m -= 2; } } } fz_always(ctx) pdf_unmark_obj(ctx, tree); fz_catch(ctx) fz_rethrow(ctx); return n == 0 && m == 0; }
void fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename) { fz_output *out = fz_new_output_with_path(ctx, filename, 0); fz_try(ctx) { fz_write_pam_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); fz_write_pam_band(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->stride, 0, pixmap->h, pixmap->samples); } fz_always(ctx) fz_drop_output(ctx, out); fz_catch(ctx) fz_rethrow(ctx); }
void fz_write_pixmap_as_pam(fz_context *ctx, fz_output *out, fz_pixmap *pixmap) { fz_band_writer *writer = fz_new_pam_band_writer(ctx, out); fz_try(ctx) { 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_catch(ctx) fz_rethrow(ctx); }
void pdf_array_push_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *item) { RESOLVE(obj); if (obj >= PDF_OBJ__LIMIT) { fz_try(ctx) pdf_array_push(ctx, obj, item); fz_always(ctx) pdf_drop_obj(ctx, item); fz_catch(ctx) fz_rethrow(ctx); } }
static fz_error pdf_load_jpx_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict) { fz_error error; fz_buffer *buf; fz_colorspace *colorspace; fz_pixmap *img; fz_obj *obj; colorspace = NULL; error = pdf_load_stream(&buf, xref, fz_to_num(dict), fz_to_gen(dict)); if (error) return fz_rethrow(error, "cannot load jpx image data"); obj = fz_dict_gets(dict, "ColorSpace"); if (obj) { error = pdf_load_colorspace(&colorspace, xref, obj); if (error) fz_catch(error, "cannot load image colorspace"); } error = fz_load_jpx_image(&img, buf->data, buf->len, colorspace); if (error) { if (colorspace) fz_drop_colorspace(colorspace); fz_drop_buffer(buf); return fz_rethrow(error, "cannot load jpx image"); } if (colorspace) fz_drop_colorspace(colorspace); fz_drop_buffer(buf); obj = fz_dict_getsa(dict, "SMask", "Mask"); if (fz_is_dict(obj)) { error = pdf_load_image_imp(&img->mask, xref, NULL, obj, NULL, 1); if (error) { fz_drop_pixmap(img); return fz_rethrow(error, "cannot load image mask/softmask"); } } *imgp = img; return fz_okay; }
void pdf_array_insert_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *item, int i) { RESOLVE(obj); if (obj) { fz_try(ctx) pdf_array_insert(ctx, obj, item, i); fz_always(ctx) pdf_drop_obj(ctx, item); fz_catch(ctx) fz_rethrow(ctx); } }
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; }