fz_document * fz_open_document_with_stream(fz_context *ctx, char *magic, fz_stream *stream) { char *ext = strrchr(magic, '.'); if (ext) { if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels")) return (fz_document*) xps_open_document_with_stream(ctx, stream); if (!fz_strcasecmp(ext, ".cbz") || !fz_strcasecmp(ext, ".zip")) return (fz_document*) cbz_open_document_with_stream(ctx, stream); if (!fz_strcasecmp(ext, ".pdf")) return (fz_document*) pdf_open_document_with_stream(ctx, stream); } if (!strcmp(magic, "cbz") || !strcmp(magic, "application/x-cbz")) return (fz_document*) cbz_open_document_with_stream(ctx, stream); if (!strcmp(magic, "xps") || !strcmp(magic, "application/vnd.ms-xpsdocument")) return (fz_document*) xps_open_document_with_stream(ctx, stream); if (!strcmp(magic, "pdf") || !strcmp(magic, "application/pdf")) return (fz_document*) pdf_open_document_with_stream(ctx, stream); /* last guess: pdf */ return (fz_document*) pdf_open_document_with_stream(ctx, stream); }
static int tiff_recognize(fz_context *doc, const char *magic) { char *ext = strrchr(magic, '.'); if (ext) { if (!fz_strcasecmp(ext, ".tiff") || !fz_strcasecmp(ext, ".tif")) return 100; #ifdef _TINSPIRE if (!fz_strcasecmp(ext, ".tns")) { while (--ext >= magic) { if (*ext == '.') break; } if (ext >= magic && (!fz_strcasecmp(ext, ".tiff.tns") || !fz_strcasecmp(ext, ".tif.tns"))) return 100; } #endif } if (!strcmp(magic, "tif") || !strcmp(magic, "image/tiff") || !strcmp(magic, "tiff") || !strcmp(magic, "image/x-tiff")) return 100; return 0; }
static int cbz_recognize(fz_context *doc, const char *magic) { char *ext = strrchr(magic, '.'); if (ext) { if (!fz_strcasecmp(ext, ".cbz") || !fz_strcasecmp(ext, ".zip")) return 100; } if (!strcmp(magic, "cbz") || !strcmp(magic, "application/x-cbz")) return 100; return 0; }
static int htdoc_recognize(fz_context *doc, const char *magic) { char *ext = strrchr(magic, '.'); if (ext) { if (!fz_strcasecmp(ext, ".xml") || !fz_strcasecmp(ext, ".xhtml") || !fz_strcasecmp(ext, ".html")) return 100; } if (!strcmp(magic, "application/html+xml") || !strcmp(magic, "application/xml") || !strcmp(magic, "text/xml")) return 100; return 0; }
static void cbz_create_page_list(fz_context *ctx, cbz_document *doc) { fz_archive *arch = doc->arch; int i, k, count; count = fz_count_archive_entries(ctx, arch); doc->page_count = 0; doc->page = fz_malloc_array(ctx, count, sizeof *doc->page); for (i = 0; i < count; i++) { const char *name = fz_list_archive_entry(ctx, arch, i); const char *ext = name ? strrchr(name, '.') : NULL; for (k = 0; cbz_ext_list[k]; k++) { if (ext && !fz_strcasecmp(ext, cbz_ext_list[k])) { doc->page[doc->page_count++] = name; break; } } } qsort((char **)doc->page, doc->page_count, sizeof *doc->page, cbz_compare_page_names); }
static int tiff_recognize(fz_context *doc, const char *magic) { char *ext = strrchr(magic, '.'); if (ext) { if (!fz_strcasecmp(ext, ".tiff") || !fz_strcasecmp(ext, ".tif")) return 100; } if (!strcmp(magic, "tif") || !strcmp(magic, "image/tiff") || !strcmp(magic, "tiff") || !strcmp(magic, "image/x-tiff")) return 100; return 0; }
fz_document * fz_open_document(fz_context *ctx, char *filename) { char *ext = strrchr(filename, '.'); if (ext) { if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels")) return (fz_document*) xps_open_document(ctx, filename); if (!fz_strcasecmp(ext, ".cbz") || !fz_strcasecmp(ext, ".zip")) return (fz_document*) cbz_open_document(ctx, filename); if (!fz_strcasecmp(ext, ".pdf")) return (fz_document*) pdf_open_document(ctx, filename); } /* last guess: pdf */ return (fz_document*) pdf_open_document(ctx, filename); }
static int svg_recognize(fz_context *ctx, const char *magic) { char *ext = strrchr(magic, '.'); if (ext && !fz_strcasecmp(ext, ".svg")) return 100; if (!strcmp(magic, "svg") || !strcmp(magic, "image/svg+xml")) return 100; return 0; }
fz_document * fz_open_document(fz_context *ctx, char *filename) { char *ext = strrchr(filename, '.'); if (ext && (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels"))) return (fz_document*) xps_open_document(ctx, filename); if (ext && !fz_strcasecmp(ext, ".cbz")) return (fz_document*) cbz_open_document(ctx, filename); #if 0 /* We used to only open pdf files if they ended in .pdf. For now, * until we move to detecting filetypes by their content, we disable * this code, and assume that any file that hasn't matched an * extension already, is a PDF. */ if (ext && !fz_strcasecmp(ext, ".pdf")) return (fz_document*) pdf_open_document(ctx, filename); fz_throw(ctx, "unknown document type: '%s'", filename); return NULL; #else return (fz_document*) pdf_open_document(ctx, filename); #endif }
static int epub_recognize(fz_context *doc, const char *magic) { char *ext = strrchr(magic, '.'); if (ext) if (!fz_strcasecmp(ext, ".epub")) return 100; if (strstr(magic, "META-INF/container.xml") || strstr(magic, "META-INF\\container.xml")) return 200; if (!strcmp(magic, "application/epub+zip")) return 100; return 0; }
fz_document_writer * fz_new_document_writer(fz_context *ctx, const char *path, const char *format, const char *options) { if (!format) { format = strrchr(path, '.'); if (!format) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot detect document format"); format += 1; /* skip the '.' */ } if (!fz_strcasecmp(format, "cbz")) return fz_new_cbz_writer(ctx, path, options); if (!fz_strcasecmp(format, "png")) return fz_new_png_writer(ctx, path, options); #if FZ_ENABLE_PDF if (!fz_strcasecmp(format, "pdf")) return fz_new_pdf_writer(ctx, path, options); #endif fz_throw(ctx, FZ_ERROR_GENERIC, "unknown output document format: %s", format); }
static fz_css_rule * html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rule *css, fz_xml *root) { fz_xml *node; fz_buffer *buf; char path[2048]; for (node = root; node; node = fz_xml_next(node)) { const char *tag = fz_xml_tag(node); if (tag && !strcmp(tag, "link")) { char *rel = fz_xml_att(node, "rel"); if (rel && !fz_strcasecmp(rel, "stylesheet")) { char *type = fz_xml_att(node, "type"); if ((type && !strcmp(type, "text/css")) || !type) { char *href = fz_xml_att(node, "href"); if (href) { fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, href, sizeof path); fz_cleanname(path); buf = fz_read_archive_entry(ctx, zip, path); fz_write_buffer_byte(ctx, buf, 0); css = fz_parse_css(ctx, css, (char*)buf->data, path); fz_drop_buffer(ctx, buf); } } } } if (tag && !strcmp(tag, "style")) { char *s = concat_text(ctx, node); css = fz_parse_css(ctx, css, s, "<style>"); fz_free(ctx, s); } if (fz_xml_down(node)) css = html_load_css(ctx, zip, base_uri, css, fz_xml_down(node)); } return css; }
static fz_css_rule * html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rule *css, fz_xml *root) { fz_xml *html, *head, *node; fz_buffer *buf; char path[2048]; fz_var(buf); html = fz_xml_find(root, "html"); head = fz_xml_find_down(html, "head"); for (node = fz_xml_down(head); node; node = fz_xml_next(node)) { if (fz_xml_is_tag(node, "link")) { char *rel = fz_xml_att(node, "rel"); if (rel && !fz_strcasecmp(rel, "stylesheet")) { char *type = fz_xml_att(node, "type"); if ((type && !strcmp(type, "text/css")) || !type) { char *href = fz_xml_att(node, "href"); if (href) { fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, href, sizeof path); fz_urldecode(path); fz_cleanname(path); buf = NULL; fz_try(ctx) { buf = fz_read_archive_entry(ctx, zip, path); fz_write_buffer_byte(ctx, buf, 0); css = fz_parse_css(ctx, css, (char*)buf->data, path); } fz_always(ctx) fz_drop_buffer(ctx, buf); fz_catch(ctx) fz_warn(ctx, "ignoring stylesheet %s", path); } } }
/* Open an output stream that writes to a given path. filename: The filename to write to (specified in UTF-8). append: non-zero if we should append to the file, rather than overwriting it. */ fz_output * fz_new_output_with_path(fz_context *ctx, const char *filename, int append) { FILE *file; fz_output *out; if (!strcmp(filename, "/dev/null") || !fz_strcasecmp(filename, "nul:")) return fz_new_output(ctx, 0, NULL, null_write, NULL, NULL); #ifdef _WIN32 /* Ensure we create a brand new file. We don't want to clobber our old file. */ if (!append) { if (fz_remove_utf8(filename) < 0) if (errno != ENOENT) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot remove file '%s': %s", filename, strerror(errno)); } file = fz_fopen_utf8(filename, append ? "rb+" : "wb+"); #else /* Ensure we create a brand new file. We don't want to clobber our old file. */ if (!append) { if (remove(filename) < 0) if (errno != ENOENT) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot remove file '%s': %s", filename, strerror(errno)); } file = fopen(filename, append ? "rb+" : "wb+"); #endif if (!file) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); setvbuf(file, NULL, _IONBF, 0); /* we do our own buffering */ out = fz_new_output(ctx, 8192, file, file_write, NULL, file_drop); out->seek = file_seek; out->tell = file_tell; out->as_stream = file_as_stream; return out; }
fz_output * fz_new_output_with_path(fz_context *ctx, const char *filename, int append) { fz_output *out = NULL; FILE *file; if (!strcmp(filename, "/dev/null") || !fz_strcasecmp(filename, "nul:")) return NULL; file = fz_fopen(filename, append ? "ab" : "wb"); if (!file) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); fz_try(ctx) { out = fz_new_output_with_file_ptr(ctx, file, 1); } fz_catch(ctx) { fclose(file); fz_rethrow(ctx); } return out; }
static int img_recognize(fz_context *doc, const char *magic) { char *ext = strrchr(magic, '.'); if (ext) { if (!fz_strcasecmp(ext, ".png") || !fz_strcasecmp(ext, ".jpg") || !fz_strcasecmp(ext, ".jpeg") || !fz_strcasecmp(ext, ".jfif") || !fz_strcasecmp(ext, ".jfif-tbnl") || !fz_strcasecmp(ext, ".jpe") || !fz_strcasecmp(ext, ".gif") || !fz_strcasecmp(ext, ".bmp")) return 100; #ifdef _TINSPIRE if (!fz_strcasecmp(ext, ".tns")) { while (--ext >= magic) { if (*ext == '.') break; } if (ext >= magic && (!fz_strcasecmp(ext, ".png.tns") || !fz_strcasecmp(ext, ".jpg.tns") || !fz_strcasecmp(ext, ".jpeg.tns") || !fz_strcasecmp(ext, ".jfif.tns") || !fz_strcasecmp(ext, ".jfif-tbnl.tns") || !fz_strcasecmp(ext, ".jpe.tns") || !fz_strcasecmp(ext, ".gif.tns"))) return 100; } #endif } if (!strcmp(magic, "png") || !strcmp(magic, "image/png") || !strcmp(magic, "jpg") || !strcmp(magic, "image/jpeg") || !strcmp(magic, "jpeg") || !strcmp(magic, "image/pjpeg") || !strcmp(magic, "jpe") || !strcmp(magic, "jfif") || !strcmp(magic, "gif") || !strcmp(magic, "image/gif") || !strcmp(magic, "bmp") || !strcmp(magic, "image/bmp")) return 100; return 0; }