diff options
Diffstat (limited to 'backend')
44 files changed, 919 insertions, 929 deletions
diff --git a/backend/comics/Makefile.am b/backend/comics/Makefile.am index 49821093..77f3dedb 100644 --- a/backend/comics/Makefile.am +++ b/backend/comics/Makefile.am @@ -12,18 +12,25 @@ backend_LTLIBRARIES = libcomicsdocument.la libcomicsdocument_la_SOURCES = \ comics-document.c \ - comics-document.h + comics-document.h \ + ev-archive.c \ + ev-archive.h libcomicsdocument_la_LDFLAGS = $(BACKEND_LIBTOOL_FLAGS) libcomicsdocument_la_LIBADD = \ $(top_builddir)/libdocument/libatrildocument.la \ $(BACKEND_LIBS) \ + $(COMICS_LIBS) \ $(LIB_LIBS) backend_in_files = comicsdocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/comics/comics-document.c b/backend/comics/comics-document.c index d799b208..1da1eee2 100644 --- a/backend/comics/comics-document.c +++ b/backend/comics/comics-document.c @@ -30,24 +30,17 @@ #include <glib/gstdio.h> #include <gio/gio.h> -#include <sys/wait.h> - #include "comics-document.h" #include "ev-document-misc.h" #include "ev-document-thumbnails.h" #include "ev-file-helpers.h" +#include "ev-archive.h" +#include <archive.h> +#include <archive_entry.h> #define EV_EOL "\n" -typedef enum -{ - RARLABS, - GNAUNRAR, - UNZIP, - P7ZIP, - TAR, - UNARCHIVER -} ComicBookDecompressType; +#define BLOCK_SIZE 10240 typedef struct _ComicsDocumentClass ComicsDocumentClass; @@ -58,400 +51,269 @@ struct _ComicsDocumentClass struct _ComicsDocument { - EvDocument parent_instance; - - gchar *archive, *dir; - GPtrArray *page_names; - gchar *selected_command, *alternative_command; - gchar *extract_command, *list_command, *decompress_tmp; - gboolean regex_arg; - gint offset; - ComicBookDecompressType command_usage; + EvDocument parent_instance; + EvArchive *archive; + gchar *archive_path; + gchar *archive_uri; + GPtrArray *page_names; /* elem: char * */ + GHashTable *page_positions; /* key: char *, value: uint + 1 */ + }; -#define OFFSET_7Z 53 -#define OFFSET_ZIP 2 -#define NO_OFFSET 0 - -/* For perfomance reasons of 7z* we've choosen to decompress on the temporary - * directory instead of decompressing on the stdout */ - -/** - * @extract: command line arguments to pass to extract a file from the archive - * to stdout. - * @list: command line arguments to list the archive contents - * @decompress_tmp: command line arguments to pass to extract the archive - * into a directory. - * @regex_arg: whether the command can accept regex expressions - * @offset: the position offset of the filename on each line in the output of - * running the @list command - */ -typedef struct { - char *extract; - char *list; - char *decompress_tmp; - gboolean regex_arg; - gint offset; -} ComicBookDecompressCommand; +static void +comics_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); +EV_BACKEND_REGISTER_WITH_CODE (ComicsDocument, comics_document, + { + EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, + comics_document_document_thumbnails_iface_init); + } ); + +#define FORMAT_UNKNOWN 0 +#define FORMAT_SUPPORTED 1 +#define FORMAT_UNSUPPORTED 2 + +/* Returns a GHashTable of: + * <key>: file extensions + * <value>: degree of support in gdk-pixbuf */ +static GHashTable * +get_image_extensions(void) +{ + GHashTable *extensions; + GSList *formats = gdk_pixbuf_get_formats (); + GSList *l; + guint i; + const char *known_image_formats[] = { + "png", + "jpg", + "jpeg", + "webp" + }; + + extensions = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + for (l = formats; l != NULL; l = l->next) { + int i; + gchar **ext = gdk_pixbuf_format_get_extensions (l->data); + + for (i = 0; ext[i] != NULL; i++) { + g_hash_table_insert (extensions, + g_strdup (ext[i]), + GINT_TO_POINTER (FORMAT_SUPPORTED)); + } -static const ComicBookDecompressCommand command_usage_def[] = { - /* RARLABS unrar */ - {"%s p -c- -ierr --", "%s vb -c- -- %s", NULL , FALSE, NO_OFFSET}, + g_strfreev (ext); + } + g_slist_free (formats); - /* GNA! unrar */ - {NULL , "%s t %s" , "%s -xf %s %s" , FALSE, NO_OFFSET}, + /* Add known image formats that aren't supported by gdk-pixbuf */ + for (i = 0; i < G_N_ELEMENTS (known_image_formats); i++) { + if (!g_hash_table_lookup (extensions, known_image_formats[i])) { + g_hash_table_insert (extensions, + g_strdup (known_image_formats[i]), + GINT_TO_POINTER (FORMAT_UNSUPPORTED)); + } + } - /* unzip */ - {"%s -p -C --" , "%s %s" , NULL , TRUE , OFFSET_ZIP}, + return extensions; +} - /* 7zip */ - {NULL , "%s l -- %s" , "%s x -y %s -o%s", FALSE, OFFSET_7Z}, +static int +has_supported_extension (const char *name, + GHashTable *supported_extensions) +{ + gboolean ret = FALSE; + gchar *suffix; + suffix = g_strrstr (name, "."); + if (!suffix) + return ret; - /* tar */ - {"%s -xOf" , "%s -tf %s" , NULL , FALSE, NO_OFFSET}, + suffix = g_ascii_strdown (suffix + 1, -1); + ret = GPOINTER_TO_INT (g_hash_table_lookup (supported_extensions, suffix)); + g_free (suffix); - /* UNARCHIVER */ - {"unar -o -" , "%s %s" , NULL , FALSE, NO_OFFSET} -}; + return ret; +} -static void comics_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); +#define APPLE_DOUBLE_PREFIX "._" +static gboolean +is_apple_double (const char *name) +{ +char *basename; + gboolean ret = FALSE; -static GSList* get_supported_image_extensions (void); -static void get_page_size_area_prepared_cb (GdkPixbufLoader *loader, - gpointer data); -static void render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader, - gint width, - gint height, - gpointer data); -static char** extract_argv (EvDocument *document, - gint page); + basename = g_path_get_basename (name); + if (basename == NULL) { + g_debug ("Filename '%s' doesn't have a basename?", name); + return ret; + } + ret = g_str_has_prefix (basename, APPLE_DOUBLE_PREFIX); + g_free (basename); + return ret; +} -EV_BACKEND_REGISTER_WITH_CODE (ComicsDocument, comics_document, - { - EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, - comics_document_document_thumbnails_iface_init); - } ); - -/** - * comics_regex_quote: - * @unquoted_string: a literal string - * - * Quotes a string so unzip will not interpret the regex expressions of - * @unquoted_string. Basically, this functions uses [] to disable regex - * expressions. The return value must be freed with * g_free() - * - * Return value: quoted and disabled-regex string - **/ -static gchar * -comics_regex_quote (const gchar *unquoted_string) +static gboolean +archive_reopen_if_needed (ComicsDocument *comics_document, + const char *page_wanted, + GError **error) { - const gchar *p; - GString *dest; - - dest = g_string_new ("'"); - - p = unquoted_string; - - while (*p) { - switch (*p) { - /* * matches a sequence of 0 or more characters */ - case ('*'): - /* ? matches exactly 1 charactere */ - case ('?'): - /* [...] matches any single character found inside - * the brackets. Disabling the first bracket is enough. - */ - case ('['): - g_string_append (dest, "["); - g_string_append_c (dest, *p); - g_string_append (dest, "]"); - break; - /* Because \ escapes regex expressions that we are - * disabling for unzip, we need to disable \ too */ - case ('\\'): - g_string_append (dest, "[\\\\]"); - break; - /* Escape single quote inside the string */ - case ('\''): - g_string_append (dest, "'\\''"); - break; - default: - g_string_append_c (dest, *p); - break; + const char *current_page; + guint current_page_idx, page_wanted_idx; + + if (ev_archive_at_entry (comics_document->archive)) { + current_page = ev_archive_get_entry_pathname (comics_document->archive); + if (current_page) { + current_page_idx = GPOINTER_TO_UINT (g_hash_table_lookup (comics_document->page_positions, current_page)); + page_wanted_idx = GPOINTER_TO_UINT (g_hash_table_lookup (comics_document->page_positions, page_wanted)); + + if (current_page_idx != 0 && + page_wanted_idx != 0 && + page_wanted_idx > current_page_idx) + return TRUE; } - ++p; + + ev_archive_reset (comics_document->archive); } - g_string_append_c (dest, '\''); - return g_string_free (dest, FALSE); +return ev_archive_open_filename (comics_document->archive, comics_document->archive_path, error); } - -/* This function manages the command for decompressing a comic book */ -static gboolean -comics_decompress_temp_dir (const gchar *command_decompress_tmp, - const gchar *command, - GError **error) +static GPtrArray * +comics_document_list (ComicsDocument *comics_document, + GError **error) { - gboolean success; - gchar *std_out, *basename; - GError *err = NULL; - gint retval; - - success = g_spawn_command_line_sync (command_decompress_tmp, &std_out, - NULL, &retval, &err); - basename = g_path_get_basename (command); - if (!success) { - g_set_error (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("Error launching the command “%s” in order to " - "decompress the comic book: %s"), - basename, - err->message); - g_error_free (err); - } else if (WIFEXITED (retval)) { - if (WEXITSTATUS (retval) == EXIT_SUCCESS) { - g_free (std_out); - g_free (basename); - return TRUE; - } else { - g_set_error (error, +GPtrArray *array = NULL; + gboolean has_encrypted_files, has_unsupported_images, has_archive_errors; + GHashTable *supported_extensions = NULL; + + if (!ev_archive_open_filename (comics_document->archive, comics_document->archive_path, error)) { + if (*error != NULL) { + g_warning ("Fatal error handling archive (%s): %s", G_STRFUNC, (*error)->message); + g_clear_error (error); + } + + g_set_error_literal (error, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_INVALID, - _("The command “%s” failed at " - "decompressing the comic book."), - basename); - g_free (std_out); + _("File is corrupted")); + goto out; + } + + supported_extensions = get_image_extensions (); + + has_encrypted_files = FALSE; + has_unsupported_images = FALSE; + has_archive_errors = FALSE; + array = g_ptr_array_sized_new (64); + + while (1) { + const char *name; + int supported; + + if (!ev_archive_read_next_header (comics_document->archive, error)) { + if (*error != NULL) { + g_debug ("Fatal error handling archive (%s): %s", G_STRFUNC, (*error)->message); + g_clear_error (error); + has_archive_errors = TRUE; + goto out; + } + break; } - } else { - g_set_error (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("The command “%s” did not end normally."), - basename); - g_free (std_out); + + name = ev_archive_get_entry_pathname (comics_document->archive); + /* Ignore https://en.wikipedia.org/wiki/AppleSingle_and_AppleDouble_formats */ + if (is_apple_double (name)) { + g_debug ("Not adding AppleDouble file '%s' to the list of files in the comics", name); + continue; + } + + supported = has_supported_extension (name, supported_extensions); + if (supported == FORMAT_UNKNOWN) { + g_debug ("Not adding unsupported file '%s' to the list of files in the comics", name); + continue; + } else if (supported == FORMAT_UNSUPPORTED) { + g_debug ("Not adding unsupported image '%s' to the list of files in the comics", name); + has_unsupported_images = TRUE; + continue; + } + + if (ev_archive_get_entry_is_encrypted (comics_document->archive)) { + g_debug ("Not adding encrypted file '%s' to the list of files in the comics", name); + has_encrypted_files = TRUE; + continue; + } + + g_debug ("Adding '%s' to the list of files in the comics", name); + g_ptr_array_add (array, g_strdup (name)); } - g_free (basename); - return FALSE; +out: + if (array->len == 0) { + g_ptr_array_free (array, TRUE); + array = NULL; + + if (has_encrypted_files) { + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_ENCRYPTED, + _("Archive is encrypted")); + } else if (has_unsupported_images) { + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_UNSUPPORTED_CONTENT, + _("No supported images in archive")); + } else if (has_archive_errors) { + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("File is corrupted")); + } else { + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("No files in archive")); + } + } + + if (supported_extensions) + g_hash_table_destroy (supported_extensions); + ev_archive_reset (comics_document->archive); + return array; } -/* This function shows how to use the choosen command for decompressing a - * comic book file. It modifies fields of the ComicsDocument struct with - * this information */ -static gboolean -comics_generate_command_lines (ComicsDocument *comics_document, - GError **error) +static GHashTable * +save_positions (GPtrArray *page_names) { - gchar *quoted_file, *quoted_file_aux; - gchar *quoted_command; - ComicBookDecompressType type; - - type = comics_document->command_usage; - comics_document->regex_arg = command_usage_def[type].regex_arg; - quoted_command = g_shell_quote (comics_document->selected_command); - if (comics_document->regex_arg) { - quoted_file = comics_regex_quote (comics_document->archive); - quoted_file_aux = g_shell_quote (comics_document->archive); - comics_document->list_command = - g_strdup_printf (command_usage_def[type].list, - comics_document->alternative_command, - quoted_file_aux); - g_free (quoted_file_aux); - } else { - quoted_file = g_shell_quote (comics_document->archive); - comics_document->list_command = - g_strdup_printf (command_usage_def[type].list, - quoted_command, quoted_file); - } - comics_document->extract_command = - g_strdup_printf (command_usage_def[type].extract, - quoted_command); - comics_document->offset = command_usage_def[type].offset; - if (command_usage_def[type].decompress_tmp) { - comics_document->dir = ev_mkdtemp ("atril-comics-XXXXXX", error); - if (comics_document->dir == NULL) - return FALSE; - - /* unrar-free can't create directories, but ev_mkdtemp already created the dir */ - - comics_document->decompress_tmp = - g_strdup_printf (command_usage_def[type].decompress_tmp, - quoted_command, quoted_file, - comics_document->dir); - g_free (quoted_file); - g_free (quoted_command); - - if (!comics_decompress_temp_dir (comics_document->decompress_tmp, - comics_document->selected_command, error)) - return FALSE; - else - return TRUE; - } else { - g_free (quoted_file); - g_free (quoted_command); - return TRUE; - } + guint i; + GHashTable *ht; + ht = g_hash_table_new (g_str_hash, g_str_equal); + for (i = 0; i < page_names->len; i++) + g_hash_table_insert (ht, page_names->pdata[i], GUINT_TO_POINTER(i + 1)); + return ht; } -/* This function chooses an external command for decompressing a comic - * book based on its mime tipe. */ +/*This function chooses the archive decompression support + * book based on its mime type. */ static gboolean -comics_check_decompress_command (gchar *mime_type, +comics_check_decompress_support (gchar *mime_type, ComicsDocument *comics_document, GError **error) { - gboolean success; - gchar *std_out, *std_err; - gint retval; - GError *err = NULL; - - /* FIXME, use proper cbr/cbz mime types once they're - * included in shared-mime-info */ - if (g_content_type_is_a (mime_type, "application/x-cbr") || g_content_type_is_a (mime_type, "application/x-rar")) { - /* The RARLAB provides a no-charge proprietary (freeware) - * decompress-only client for Linux called unrar. Another - * option is a GPLv2-licensed command-line tool developed by - * the Gna! project. Confusingly enough, the free software RAR - * decoder is also named unrar. For this reason we need to add - * some lines for disambiguation. Sorry for the added the - * complexity but it's life :) - * Finally, some distributions, like Debian, rename this free - * option as unrar-free. - * */ - comics_document->selected_command = - g_find_program_in_path ("unrar"); - if (comics_document->selected_command) { - /* We only use std_err to avoid printing useless error - * messages on the terminal */ - success = - g_spawn_command_line_sync ( - comics_document->selected_command, - &std_out, &std_err, - &retval, &err); - if (!success) { - g_propagate_error (error, err); - g_error_free (err); - return FALSE; - /* I don't check retval status because RARLAB unrar - * doesn't have a way to return 0 without involving an - * operation with a file*/ - } else if (WIFEXITED (retval)) { - if (g_strrstr (std_out,"freeware") != NULL) - /* The RARLAB freeware client */ - comics_document->command_usage = RARLABS; - else - /* The Gna! free software client */ - comics_document->command_usage = GNAUNRAR; - - g_free (std_out); - g_free (std_err); - return TRUE; - } - } - /* The Gna! free software client with Debian naming convention */ - comics_document->selected_command = - g_find_program_in_path ("unrar-free"); - if (comics_document->selected_command) { - comics_document->command_usage = GNAUNRAR; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("lsar"); - if (comics_document->selected_command) { - comics_document->command_usage = UNARCHIVER; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("bsdtar"); - if (comics_document->selected_command) { - comics_document->command_usage = TAR; + if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_RAR)) return TRUE; - } - } else if (g_content_type_is_a (mime_type, "application/x-cbz") || g_content_type_is_a (mime_type, "application/zip")) { - /* InfoZIP's unzip program */ - comics_document->selected_command = - g_find_program_in_path ("unzip"); - comics_document->alternative_command = - g_find_program_in_path ("zipnote"); - if (comics_document->selected_command && - comics_document->alternative_command) { - comics_document->command_usage = UNZIP; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("bsdtar"); - if (comics_document->selected_command) { - comics_document->command_usage = TAR; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("lsar"); - if (comics_document->selected_command) { - comics_document->command_usage = UNARCHIVER; + if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_ZIP)) return TRUE; - } - } else if (g_content_type_is_a (mime_type, "application/x-cb7") || g_content_type_is_a (mime_type, "application/x-7z-compressed")) { - /* 7zr, 7za and 7z are the commands from the p7zip project able - * to decompress .7z files */ - comics_document->selected_command = - g_find_program_in_path ("7zr"); - if (comics_document->selected_command) { - comics_document->command_usage = P7ZIP; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("7za"); - if (comics_document->selected_command) { - comics_document->command_usage = P7ZIP; + if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_7Z)) return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("7z"); - if (comics_document->selected_command) { - comics_document->command_usage = P7ZIP; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("bsdtar"); - if (comics_document->selected_command) { - comics_document->command_usage = TAR; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("lsar"); - if (comics_document->selected_command) { - comics_document->command_usage = UNARCHIVER; - return TRUE; - } } else if (g_content_type_is_a (mime_type, "application/x-cbt") || g_content_type_is_a (mime_type, "application/x-tar")) { - /* tar utility (Tape ARchive) */ - comics_document->selected_command = - g_find_program_in_path ("tar"); - if (comics_document->selected_command) { - comics_document->command_usage = TAR; + if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_TAR)) return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("bsdtar"); - if (comics_document->selected_command) { - comics_document->command_usage = TAR; - return TRUE; - } - comics_document->selected_command = - g_find_program_in_path ("lsar"); - if (comics_document->selected_command) { - comics_document->command_usage = UNARCHIVER; - return TRUE; - } } else { g_set_error (error, EV_DOCUMENT_ERROR, @@ -463,8 +325,9 @@ comics_check_decompress_command (gchar *mime_type, g_set_error_literal (error, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_INVALID, - _("Can't find an appropriate command to " - "decompress this type of comic book")); + _("libarchive lacks support for this comic book’s " + "compression, please contact your distributor")); + return FALSE; } @@ -472,43 +335,15 @@ static int sort_page_names (gconstpointer a, gconstpointer b) { - const char *name_1, *name_2; - gchar *key_1, *key_2; - gboolean sort_last_1, sort_last_2; - int compare; - - name_1 = * (const char **) a; - name_2 = * (const char **) b; - - #define SORT_LAST_CHAR1 '.' - #define SORT_LAST_CHAR2 '#' - - sort_last_1 = name_1[0] == SORT_LAST_CHAR1 || name_1[0] == SORT_LAST_CHAR2; - sort_last_2 = name_2[0] == SORT_LAST_CHAR1 || name_2[0] == SORT_LAST_CHAR2; - - #undef SORT_LAST_CHAR1 - #undef SORT_LAST_CHAR2 - - if (sort_last_1 && !sort_last_2) - { - compare = +1; - } - else if (!sort_last_1 && sort_last_2) - { - compare = -1; - } - else - { - key_1 = g_utf8_collate_key_for_filename (name_1, -1); - key_2 = g_utf8_collate_key_for_filename (name_2, -1); - - compare = strcmp (key_1, key_2); - - g_free (key_1); - g_free (key_2); - } - - return compare; + gchar *temp1, *temp2; + gint ret; + temp1 = g_utf8_collate_key_for_filename (* (const char **) a, -1); + temp2 = g_utf8_collate_key_for_filename (* (const char **) b, -1); + ret = strcmp (temp1, temp2); + + g_free (temp1); + g_free (temp2); + return ret; } static gboolean @@ -517,50 +352,13 @@ comics_document_load (EvDocument *document, GError **error) { ComicsDocument *comics_document = COMICS_DOCUMENT (document); - GSList *supported_extensions; - gchar *std_out; gchar *mime_type; - gchar **cb_files, *cb_file; - gboolean success; - int i, retval; - GError *err = NULL; + GFile *file; + file = g_file_new_for_uri (uri); + comics_document->archive_path = g_file_get_path (file); + g_object_unref (file); - comics_document->archive = g_filename_from_uri (uri, NULL, error); - if (!comics_document->archive) - return FALSE; - - mime_type = ev_file_get_mime_type (uri, FALSE, &err); - if (!mime_type) { - if (err) { - g_propagate_error (error, err); - } else { - g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("Unknown MIME Type")); - } - - return FALSE; - } - - if (!comics_check_decompress_command (mime_type, comics_document, - error)) { - g_free (mime_type); - return FALSE; - } else if (!comics_generate_command_lines (comics_document, error)) { - g_free (mime_type); - return FALSE; - } - - g_free (mime_type); - - /* Get list of files in archive */ - success = g_spawn_command_line_sync (comics_document->list_command, - &std_out, NULL, &retval, error); - - if (!success) { - return FALSE; - } else if (!WIFEXITED(retval) || WEXITSTATUS(retval) != EXIT_SUCCESS) { + if (!comics_document->archive_path) { g_set_error_literal (error, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_INVALID, @@ -568,58 +366,26 @@ comics_document_load (EvDocument *document, return FALSE; } - /* FIXME: is this safe against filenames containing \n in the archive ? */ - cb_files = g_strsplit (std_out, EV_EOL, 0); + comics_document->archive_uri = g_strdup (uri); + mime_type = ev_file_get_mime_type (uri, FALSE, error); - g_free (std_out); + if (mime_type == NULL) + return FALSE; - if (!cb_files) { - g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("No files in archive")); + if (!comics_check_decompress_support (mime_type, comics_document, error)) { + g_free (mime_type); return FALSE; } - comics_document->page_names = g_ptr_array_sized_new (64); - - supported_extensions = get_supported_image_extensions (); - for (i = 0; cb_files[i] != NULL; i++) { - if (comics_document->offset != NO_OFFSET) { - if (g_utf8_strlen (cb_files[i],-1) > - comics_document->offset) { - cb_file = - g_utf8_offset_to_pointer (cb_files[i], - comics_document->offset); - } else { - continue; - } - } else { - cb_file = cb_files[i]; - } - gchar *suffix = g_strrstr (cb_file, "."); - if (!suffix) - continue; - suffix = g_ascii_strdown (suffix + 1, -1); - if (g_slist_find_custom (supported_extensions, suffix, - (GCompareFunc) strcmp) != NULL) { - g_ptr_array_add (comics_document->page_names, - g_strstrip (g_strdup (cb_file))); - } - g_free (suffix); - } - g_strfreev (cb_files); - g_slist_foreach (supported_extensions, (GFunc) g_free, NULL); - g_slist_free (supported_extensions); + g_free (mime_type); - if (comics_document->page_names->len == 0) { - g_set_error (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("No images found in archive %s"), - uri); + /* Get list of files in archive */ + comics_document->page_names = comics_document_list (comics_document, error); + if (!comics_document->page_names) return FALSE; - } + + /* Keep an index */ + comics_document->page_positions = save_positions (comics_document->page_names); /* Now sort the pages */ g_ptr_array_sort (comics_document->page_names, sort_page_names); @@ -627,7 +393,6 @@ comics_document_load (EvDocument *document, return TRUE; } - static gboolean comics_document_save (EvDocument *document, const char *uri, @@ -635,7 +400,7 @@ comics_document_save (EvDocument *document, { ComicsDocument *comics_document = COMICS_DOCUMENT (document); - return ev_xfer_uri_simple (comics_document->archive, uri, error); + return ev_xfer_uri_simple (comics_document->archive_uri, uri, error); } static int @@ -649,6 +414,23 @@ comics_document_get_n_pages (EvDocument *document) return comics_document->page_names->len; } +typedef struct { + gboolean got_info; + int height; + int width; +} PixbufInfo; + +static void +get_page_size_prepared_cb (GdkPixbufLoader *loader, + int width, + int height, + PixbufInfo *info) +{ + info->got_info = TRUE; + info->height = height; + info->width = width; +} + static void comics_document_get_page_size (EvDocument *document, EvPage *page, @@ -656,74 +438,89 @@ comics_document_get_page_size (EvDocument *document, double *height) { GdkPixbufLoader *loader; - char **argv; - guchar buf[1024]; - gboolean success, got_size = FALSE; - gint outpipe = -1; - GPid child_pid; - gssize bytes; - GdkPixbuf *pixbuf; - gchar *filename; + ComicsDocument *comics_document = COMICS_DOCUMENT (document); - if (!comics_document->decompress_tmp) { - argv = extract_argv (document, page->index); - success = g_spawn_async_with_pipes (NULL, argv, NULL, - G_SPAWN_SEARCH_PATH | - G_SPAWN_STDERR_TO_DEV_NULL, - NULL, NULL, - &child_pid, - NULL, &outpipe, NULL, NULL); - g_strfreev (argv); - g_return_if_fail (success == TRUE); - - loader = gdk_pixbuf_loader_new (); - g_signal_connect (loader, "area-prepared", - G_CALLBACK (get_page_size_area_prepared_cb), - &got_size); - - while (outpipe >= 0) { - bytes = read (outpipe, buf, 1024); - - if (bytes > 0) - gdk_pixbuf_loader_write (loader, buf, bytes, NULL); - if (bytes <= 0 || got_size) { - close (outpipe); - outpipe = -1; - gdk_pixbuf_loader_close (loader, NULL); + const char *page_path; + PixbufInfo info; + GError *error = NULL; + + page_path = g_ptr_array_index (comics_document->page_names, page->index); + + if (!archive_reopen_if_needed (comics_document, page_path, &error)) { + g_warning ("Fatal error opening archive: %s", error->message); + g_error_free (error); + return; + } + + loader = gdk_pixbuf_loader_new (); + info.got_info = FALSE; + g_signal_connect (loader, "size-prepared", + G_CALLBACK (get_page_size_prepared_cb), + &info); + + while (1) { + const char *name; + GError *error = NULL; + + if (!ev_archive_read_next_header (comics_document->archive, &error)) { + if (error != NULL) { + g_warning ("Fatal error handling archive (%s): %s", G_STRFUNC, error->message); + g_error_free (error); } + break; } - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf) { - if (width) - *width = gdk_pixbuf_get_width (pixbuf); - if (height) - *height = gdk_pixbuf_get_height (pixbuf); - } - g_spawn_close_pid (child_pid); - g_object_unref (loader); - } else { - filename = g_build_filename (comics_document->dir, - (char *) comics_document->page_names->pdata[page->index], - NULL); - pixbuf = gdk_pixbuf_new_from_file (filename, NULL); - if (pixbuf) { - if (width) - *width = gdk_pixbuf_get_width (pixbuf); - if (height) - *height = gdk_pixbuf_get_height (pixbuf); - g_object_unref (pixbuf); + + name = ev_archive_get_entry_pathname (comics_document->archive); + if (g_strcmp0 (name, page_path) == 0) { + char buf[BLOCK_SIZE]; + gssize read; + gint64 left; + + left = ev_archive_get_entry_size (comics_document->archive); + read = ev_archive_read_data (comics_document->archive, buf, + MIN(BLOCK_SIZE, left), &error); + while (read > 0 && !info.got_info) { + if (!gdk_pixbuf_loader_write (loader, (guchar *) buf, read, &error)) { + read = -1; + break; + } + left -= read; + read = ev_archive_read_data (comics_document->archive, buf, + MIN(BLOCK_SIZE, left), &error); + } + if (read < 0) { + g_warning ("Fatal error reading '%s' in archive: %s", name, error->message); + g_error_free (error); + } + break; } - g_free (filename); + } + + gdk_pixbuf_loader_close (loader, NULL); + g_object_unref (loader); + + if (info.got_info) { + if (width) + *width = info.width; + if (height) + *height = info.height; } } static void -get_page_size_area_prepared_cb (GdkPixbufLoader *loader, - gpointer data) +render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader, + gint width, + gint height, + EvRenderContext *rc) { - gboolean *got_size = data; - *got_size = TRUE; + // int scaled_width, scaled_height; + double scale = rc->scale; + int w = (width * scale + 0.5); + int h = (height * scale + 0.5); + + // ev_render_context_compute_scaled_size (rc, width, height, &scaled_width, &scaled_height); + gdk_pixbuf_loader_set_size (loader, w, h); } static GdkPixbuf * @@ -731,69 +528,68 @@ comics_document_render_pixbuf (EvDocument *document, EvRenderContext *rc) { GdkPixbufLoader *loader; - GdkPixbuf *rotated_pixbuf, *tmp_pixbuf; - char **argv; - guchar buf[4096]; - gboolean success; - gint outpipe = -1; - GPid child_pid; - gssize bytes; - gint width, height; - gchar *filename; + GdkPixbuf *tmp_pixbuf; + GdkPixbuf *rotated_pixbuf = NULL; ComicsDocument *comics_document = COMICS_DOCUMENT (document); + const char *page_path; + GError *error = NULL; + + page_path = g_ptr_array_index (comics_document->page_names, rc->page->index); + + if (!archive_reopen_if_needed (comics_document, page_path, &error)) { + g_warning ("Fatal error opening archive: %s", error->message); + g_error_free (error); + return NULL; + } - if (!comics_document->decompress_tmp) { - argv = extract_argv (document, rc->page->index); - success = g_spawn_async_with_pipes (NULL, argv, NULL, - G_SPAWN_SEARCH_PATH | - G_SPAWN_STDERR_TO_DEV_NULL, - NULL, NULL, - &child_pid, - NULL, &outpipe, NULL, NULL); - g_strfreev (argv); - g_return_val_if_fail (success == TRUE, NULL); - - loader = gdk_pixbuf_loader_new (); - g_signal_connect (loader, "size-prepared", - G_CALLBACK (render_pixbuf_size_prepared_cb), - &rc->scale); - - while (outpipe >= 0) { - bytes = read (outpipe, buf, 4096); - - if (bytes > 0) { - gdk_pixbuf_loader_write (loader, buf, bytes, - NULL); + loader = gdk_pixbuf_loader_new (); + g_signal_connect (loader, "size-prepared", + G_CALLBACK (render_pixbuf_size_prepared_cb), + rc); + + while (1) { + const char *name; + + if (!ev_archive_read_next_header (comics_document->archive, &error)) { + if (error != NULL) { + g_warning ("Fatal error handling archive (%s): %s", G_STRFUNC, error->message); + g_error_free (error); + } + break; + } + + name = ev_archive_get_entry_pathname (comics_document->archive); + if (g_strcmp0 (name, page_path) == 0) { + size_t size = ev_archive_get_entry_size (comics_document->archive); + char *buf; + ssize_t read; + + buf = g_malloc (size); + read = ev_archive_read_data (comics_document->archive, buf, size, &error); + if (read <= 0) { + if (read < 0) { + g_warning ("Fatal error reading '%s' in archive: %s", name, error->message); + g_error_free (error); + } else { + g_warning ("Read an empty file from the archive"); + } } else { - close (outpipe); - gdk_pixbuf_loader_close (loader, NULL); - outpipe = -1; + gdk_pixbuf_loader_write (loader, (guchar *) buf, size, NULL); } + g_free (buf); + gdk_pixbuf_loader_close (loader, NULL); + break; } - tmp_pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - rotated_pixbuf = - gdk_pixbuf_rotate_simple (tmp_pixbuf, - 360 - rc->rotation); - g_spawn_close_pid (child_pid); - g_object_unref (loader); - } else { - filename = - g_build_filename (comics_document->dir, - (char *) comics_document->page_names->pdata[rc->page->index], - NULL); - - gdk_pixbuf_get_file_info (filename, &width, &height); - - tmp_pixbuf = - gdk_pixbuf_new_from_file_at_size ( - filename, width * (rc->scale) + 0.5, - height * (rc->scale) + 0.5, NULL); - rotated_pixbuf = - gdk_pixbuf_rotate_simple (tmp_pixbuf, - 360 - rc->rotation); - g_free (filename); - g_object_unref (tmp_pixbuf); } + tmp_pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (tmp_pixbuf) { + if ((rc->rotation % 360) == 0) + rotated_pixbuf = g_object_ref (tmp_pixbuf); + else + rotated_pixbuf = gdk_pixbuf_rotate_simple (tmp_pixbuf, + 360 - rc->rotation); + } + g_object_unref (loader); return rotated_pixbuf; } @@ -805,79 +601,26 @@ comics_document_render (EvDocument *document, cairo_surface_t *surface; pixbuf = comics_document_render_pixbuf (document, rc); + if (!pixbuf) + return NULL; surface = ev_document_misc_surface_from_pixbuf (pixbuf); - g_object_unref (pixbuf); - + g_clear_object (&pixbuf); return surface; } static void -render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader, - gint width, - gint height, - gpointer data) -{ - double *scale = data; - int w = (width * (*scale) + 0.5); - int h = (height * (*scale) + 0.5); - - gdk_pixbuf_loader_set_size (loader, w, h); -} - -/** - * comics_remove_dir: Removes a directory recursively. - * Returns: - * 0 if it was successfully deleted, - * -1 if an error occurred - */ -static int -comics_remove_dir (gchar *path_name) -{ - GDir *content_dir; - const gchar *filename; - gchar *filename_with_path; - - if (g_file_test (path_name, G_FILE_TEST_IS_DIR)) { - content_dir = g_dir_open (path_name, 0, NULL); - filename = g_dir_read_name (content_dir); - while (filename) { - filename_with_path = - g_build_filename (path_name, - filename, NULL); - comics_remove_dir (filename_with_path); - g_free (filename_with_path); - filename = g_dir_read_name (content_dir); - } - g_dir_close (content_dir); - } - /* Note from g_remove() documentation: on Windows, it is in general not - * possible to remove a file that is open to some process, or mapped - * into memory.*/ - return (g_remove (path_name)); -} - -static void comics_document_finalize (GObject *object) { ComicsDocument *comics_document = COMICS_DOCUMENT (object); - if (comics_document->decompress_tmp) { - if (comics_remove_dir (comics_document->dir) == -1) - g_warning (_("There was an error deleting “%s”."), - comics_document->dir); - g_free (comics_document->dir); - } - if (comics_document->page_names) { g_ptr_array_foreach (comics_document->page_names, (GFunc) g_free, NULL); g_ptr_array_free (comics_document->page_names, TRUE); } - - g_free (comics_document->archive); - g_free (comics_document->selected_command); - g_free (comics_document->alternative_command); - g_free (comics_document->extract_command); - g_free (comics_document->list_command); + g_clear_pointer (&comics_document->page_positions, g_hash_table_destroy); + g_clear_object (&comics_document->archive); + g_free (comics_document->archive_path); + g_free (comics_document->archive_uri); G_OBJECT_CLASS (comics_document_parent_class)->finalize (object); } @@ -900,33 +643,7 @@ comics_document_class_init (ComicsDocumentClass *klass) static void comics_document_init (ComicsDocument *comics_document) { - comics_document->archive = NULL; - comics_document->page_names = NULL; - comics_document->extract_command = NULL; -} - -/* Returns a list of file extensions supported by gdk-pixbuf */ -static GSList* -get_supported_image_extensions(void) -{ - GSList *extensions = NULL; - GSList *formats = gdk_pixbuf_get_formats (); - GSList *l; - - for (l = formats; l != NULL; l = l->next) { - int i; - gchar **ext = gdk_pixbuf_format_get_extensions (l->data); - - for (i = 0; ext[i] != NULL; i++) { - extensions = g_slist_append (extensions, - g_strdup (ext[i])); - } - - g_strfreev (ext); - } - - g_slist_free (formats); - return extensions; + comics_document->archive = ev_archive_new (); } static GdkPixbuf * @@ -974,48 +691,3 @@ comics_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *i iface->get_thumbnail = comics_document_thumbnails_get_thumbnail; iface->get_dimensions = comics_document_thumbnails_get_dimensions; } - -static char** -extract_argv (EvDocument *document, gint page) -{ - ComicsDocument *comics_document = COMICS_DOCUMENT (document); - char **argv; - char *command_line, *quoted_archive, *quoted_filename; - GError *err = NULL; - - if (g_strrstr (comics_document->page_names->pdata[page], "--checkpoint-action=")) - { - g_warning ("File unsupported\n"); - gtk_main_quit (); - } - - if (page >= comics_document->page_names->len) - return NULL; - - if (comics_document->regex_arg) { - quoted_archive = g_shell_quote (comics_document->archive); - quoted_filename = - comics_regex_quote (comics_document->page_names->pdata[page]); - } else { - quoted_archive = g_shell_quote (comics_document->archive); - quoted_filename = g_shell_quote (comics_document->page_names->pdata[page]); - } - - command_line = g_strdup_printf ("%s %s %s", - comics_document->extract_command, - quoted_archive, - quoted_filename); - g_free (quoted_archive); - g_free (quoted_filename); - - g_shell_parse_argv (command_line, NULL, &argv, &err); - g_free (command_line); - - if (err) { - g_warning (_("Error %s"), err->message); - g_error_free (err); - return NULL; - } - - return argv; -} diff --git a/backend/comics/comics-document.h b/backend/comics/comics-document.h index f6a4b440..4417a69f 100644 --- a/backend/comics/comics-document.h +++ b/backend/comics/comics-document.h @@ -16,9 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __COMICS_DOCUMENT_H__ -#define __COMICS_DOCUMENT_H__ +#pragma once +#include "ev-macros.h" #include "ev-document.h" G_BEGIN_DECLS @@ -30,9 +30,8 @@ G_BEGIN_DECLS typedef struct _ComicsDocument ComicsDocument; GType comics_document_get_type (void) G_GNUC_CONST; +GType register_atril_backend (GTypeModule *module); -G_MODULE_EXPORT GType register_atril_backend (GTypeModule *module); G_END_DECLS -#endif /* __COMICS_DOCUMENT_H__ */ diff --git a/backend/comics/ev-archive.c b/backend/comics/ev-archive.c new file mode 100644 index 00000000..568e1621 --- /dev/null +++ b/backend/comics/ev-archive.c @@ -0,0 +1,323 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2017, Bastien Nocera <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "ev-archive.h" + +#include <archive.h> +#include <archive_entry.h> +#include <gio/gio.h> + +#define BUFFER_SIZE (64 * 1024) + +struct _EvArchive { + GObject parent_instance; + EvArchiveType type; + + /* libarchive */ + struct archive *libar; + struct archive_entry *libar_entry; +}; + +G_DEFINE_TYPE(EvArchive, ev_archive, G_TYPE_OBJECT); + +static void +ev_archive_finalize (GObject *object) +{ + EvArchive *archive = EV_ARCHIVE (object); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + g_clear_pointer (&archive->libar, archive_free); + break; + default: + break; + } + + G_OBJECT_CLASS (ev_archive_parent_class)->finalize (object); +} + +static void +ev_archive_class_init (EvArchiveClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + object_class->finalize = ev_archive_finalize; +} + +EvArchive * +ev_archive_new (void) +{ + return g_object_new (EV_TYPE_ARCHIVE, NULL); +} + +static void +libarchive_set_archive_type (EvArchive *archive, + EvArchiveType archive_type) +{ + archive->type = archive_type; + archive->libar = archive_read_new (); + + if (archive_type == EV_ARCHIVE_TYPE_ZIP) + archive_read_support_format_zip (archive->libar); + else if (archive_type == EV_ARCHIVE_TYPE_7Z) + archive_read_support_format_7zip (archive->libar); + else if (archive_type == EV_ARCHIVE_TYPE_TAR) + archive_read_support_format_tar (archive->libar); + else if (archive_type == EV_ARCHIVE_TYPE_RAR) { + archive_read_support_format_rar (archive->libar); + archive_read_support_format_rar5 (archive->libar); + } else + g_assert_not_reached (); +} + +EvArchiveType +ev_archive_get_archive_type (EvArchive *archive) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), EV_ARCHIVE_TYPE_NONE); + + return archive->type; +} + +gboolean +ev_archive_set_archive_type (EvArchive *archive, + EvArchiveType archive_type) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); + g_return_val_if_fail (archive->type == EV_ARCHIVE_TYPE_NONE, FALSE); + + switch (archive_type) { + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + libarchive_set_archive_type (archive, archive_type); + break; + default: + g_assert_not_reached (); + } + + return TRUE; +} + +gboolean +ev_archive_open_filename (EvArchive *archive, + const char *path, + GError **error) +{ + int r; + + g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); + g_return_val_if_fail (path != NULL, FALSE); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_NONE: + g_assert_not_reached (); + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + r = archive_read_open_filename (archive->libar, path, BUFFER_SIZE); + if (r != ARCHIVE_OK) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Error opening archive: %s", archive_error_string (archive->libar)); + return FALSE; + } + return TRUE; + } + + return FALSE; +} + +static gboolean +libarchive_read_next_header (EvArchive *archive, + GError **error) +{ + while (1) { + int r; + + r = archive_read_next_header (archive->libar, &archive->libar_entry); + if (r != ARCHIVE_OK) { + if (r != ARCHIVE_EOF) + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Error reading archive: %s", archive_error_string (archive->libar)); + return FALSE; + } + + if (archive_entry_filetype (archive->libar_entry) != AE_IFREG) { + g_debug ("Skipping '%s' as it's not a regular file", + archive_entry_pathname (archive->libar_entry)); + continue; + } + + g_debug ("At header for file '%s'", archive_entry_pathname (archive->libar_entry)); + + break; + } + + return TRUE; +} + +gboolean +ev_archive_read_next_header (EvArchive *archive, + GError **error) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_NONE: + g_assert_not_reached (); + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + return libarchive_read_next_header (archive, error); + } + + return FALSE; +} + +gboolean +ev_archive_at_entry (EvArchive *archive) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); + + return (archive->libar_entry != NULL); +} + +const char * +ev_archive_get_entry_pathname (EvArchive *archive) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), NULL); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, NULL); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_NONE: + g_assert_not_reached (); + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + g_return_val_if_fail (archive->libar_entry != NULL, NULL); + return archive_entry_pathname (archive->libar_entry); + } + + return NULL; +} + +gint64 +ev_archive_get_entry_size (EvArchive *archive) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), -1); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, -1); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_NONE: + g_assert_not_reached (); + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + g_return_val_if_fail (archive->libar_entry != NULL, -1); + return archive_entry_size (archive->libar_entry); + } + + return -1; +} + +gboolean +ev_archive_get_entry_is_encrypted (EvArchive *archive) +{ + g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_NONE: + g_assert_not_reached (); + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + g_return_val_if_fail (archive->libar_entry != NULL, -1); + return archive_entry_is_encrypted (archive->libar_entry); + } + + return FALSE; +} + +gssize +ev_archive_read_data (EvArchive *archive, + void *buf, + gsize count, + GError **error) +{ + gssize r = -1; + + g_return_val_if_fail (EV_IS_ARCHIVE (archive), -1); + g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, -1); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_NONE: + g_assert_not_reached (); + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + g_return_val_if_fail (archive->libar_entry != NULL, -1); + r = archive_read_data (archive->libar, buf, count); + if (r < 0) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to decompress data: %s", archive_error_string (archive->libar)); + } + break; + } + + return r; +} + +void +ev_archive_reset (EvArchive *archive) +{ + g_return_if_fail (EV_IS_ARCHIVE (archive)); + g_return_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE); + + switch (archive->type) { + case EV_ARCHIVE_TYPE_RAR: + case EV_ARCHIVE_TYPE_ZIP: + case EV_ARCHIVE_TYPE_7Z: + case EV_ARCHIVE_TYPE_TAR: + g_clear_pointer (&archive->libar, archive_free); + libarchive_set_archive_type (archive, archive->type); + archive->libar_entry = NULL; + break; + default: + g_assert_not_reached (); + } +} + +static void +ev_archive_init (EvArchive *archive) +{ +} diff --git a/backend/comics/ev-archive.h b/backend/comics/ev-archive.h new file mode 100644 index 00000000..b4e1399c --- /dev/null +++ b/backend/comics/ev-archive.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2017, Bastien Nocera <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define EV_TYPE_ARCHIVE ev_archive_get_type () +G_DECLARE_FINAL_TYPE (EvArchive, ev_archive, EV, ARCHIVE, GObject) + +typedef enum { + EV_ARCHIVE_TYPE_NONE = 0, + EV_ARCHIVE_TYPE_RAR, + EV_ARCHIVE_TYPE_ZIP, + EV_ARCHIVE_TYPE_7Z, + EV_ARCHIVE_TYPE_TAR +} EvArchiveType; + +EvArchive *ev_archive_new (void); +gboolean ev_archive_set_archive_type (EvArchive *archive, + EvArchiveType archive_type); +EvArchiveType ev_archive_get_archive_type (EvArchive *archive); +gboolean ev_archive_open_filename (EvArchive *archive, + const char *path, + GError **error); +gboolean ev_archive_read_next_header (EvArchive *archive, + GError **error); +gboolean ev_archive_at_entry (EvArchive *archive); +const char *ev_archive_get_entry_pathname (EvArchive *archive); +gint64 ev_archive_get_entry_size (EvArchive *archive); +gboolean ev_archive_get_entry_is_encrypted (EvArchive *archive); +gssize ev_archive_read_data (EvArchive *archive, + void *buf, + gsize count, + GError **error); +void ev_archive_reset (EvArchive *archive); + +G_END_DECLS diff --git a/backend/djvu/Makefile.am b/backend/djvu/Makefile.am index 1f28ae76..a25134e8 100644 --- a/backend/djvu/Makefile.am +++ b/backend/djvu/Makefile.am @@ -28,7 +28,11 @@ libdjvudocument_la_LIBADD = \ backend_in_files = djvudocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/djvu/djvu-document.c b/backend/djvu/djvu-document.c index b3e41a8d..9ed327ad 100644 --- a/backend/djvu/djvu-document.c +++ b/backend/djvu/djvu-document.c @@ -66,7 +66,6 @@ EV_BACKEND_REGISTER_WITH_CODE (DjvuDocument, djvu_document, EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_SELECTION, djvu_selection_iface_init); }); - #define EV_DJVU_ERROR ev_djvu_error_quark () static GQuark @@ -256,7 +255,6 @@ djvu_document_load (EvDocument *document, return TRUE; } - static gboolean djvu_document_save (EvDocument *document, const char *uri, @@ -676,7 +674,6 @@ djvu_document_find_find_text (EvDocumentFind *document, r->y2 = height - tmp * SCALE_FACTOR; } - return matches; } diff --git a/backend/djvu/djvu-links.c b/backend/djvu/djvu-links.c index da871dac..03da5983 100644 --- a/backend/djvu/djvu-links.c +++ b/backend/djvu/djvu-links.c @@ -181,7 +181,6 @@ build_tree (const DjvuDocument *djvu_document, if (!string_from_miniexp (miniexp_car (iter), &title)) goto unknown_entry; if (!string_from_miniexp (miniexp_cadr (iter), &link_dest)) goto unknown_entry; - if (!g_utf8_validate (title, -1, NULL)) { utf8_title = str_to_utf8 (title); title_markup = g_markup_escape_text (utf8_title, -1); @@ -342,7 +341,6 @@ get_djvu_hyperlink_mapping (DjvuDocument *djvu_document, return NULL; } - gboolean djvu_links_has_document_links (EvDocumentLinks *document_links) { diff --git a/backend/djvu/djvu-text-page.c b/backend/djvu/djvu-text-page.c index 6cbf54e6..72813bd4 100644 --- a/backend/djvu/djvu-text-page.c +++ b/backend/djvu/djvu-text-page.c @@ -23,7 +23,6 @@ #include <libdjvu/miniexp.h> #include "djvu-text-page.h" - /** * djvu_text_page_selection_process: * @page: #DjvuTextPage instance @@ -117,7 +116,6 @@ djvu_text_page_limits_process (DjvuTextPage *page, } } - static void djvu_text_page_limits (DjvuTextPage *page, miniexp_t p, @@ -404,7 +402,6 @@ djvu_text_page_search (DjvuTextPage *page, g_free (search_text); } - /** * djvu_text_page_prepare_search: * @page: #DjvuTextPage instance diff --git a/backend/djvu/djvu-text-page.h b/backend/djvu/djvu-text-page.h index a25284f5..ed8f3c7a 100644 --- a/backend/djvu/djvu-text-page.h +++ b/backend/djvu/djvu-text-page.h @@ -25,7 +25,6 @@ #include <glib.h> #include <libdjvu/miniexp.h> - typedef struct _DjvuTextPage DjvuTextPage; typedef struct _DjvuTextLink DjvuTextLink; diff --git a/backend/dvi/Makefile.am b/backend/dvi/Makefile.am index c94c10ad..26571c6f 100644 --- a/backend/dvi/Makefile.am +++ b/backend/dvi/Makefile.am @@ -36,7 +36,11 @@ endif backend_in_files = dvidocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/dvi/dvi-document.c b/backend/dvi/dvi-document.c index 1a84fe72..7971b662 100644 --- a/backend/dvi/dvi-document.c +++ b/backend/dvi/dvi-document.c @@ -110,7 +110,6 @@ dvi_document_load (EvDocument *document, mdvi_cairo_device_init (&dvi_document->context->device); - dvi_document->base_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv + 2 * unit2pix(dvi_document->params->dpi, MDVI_HMARGIN) / dvi_document->params->hshrink; @@ -123,7 +122,6 @@ dvi_document_load (EvDocument *document, return TRUE; } - static gboolean dvi_document_save (EvDocument *document, const char *uri, diff --git a/backend/dvi/fonts.c b/backend/dvi/fonts.c index 7c15f8d7..903eefa9 100644 --- a/backend/dvi/fonts.c +++ b/backend/dvi/fonts.c @@ -54,4 +54,3 @@ void mdvi_register_fonts (void) return; } - diff --git a/backend/dvi/mdvi-lib/Makefile.am b/backend/dvi/mdvi-lib/Makefile.am index 5edcdd03..e41b10bc 100644 --- a/backend/dvi/mdvi-lib/Makefile.am +++ b/backend/dvi/mdvi-lib/Makefile.am @@ -37,7 +37,9 @@ libmdvi_la_SOURCES = \ tfmfile.c \ tt.c \ util.c \ - vf.c + vf.c +libmdvi_la_LIBADD = $(GLIB_LIBS) +libmdvi_la_CFLAGS = $(GLIB_CFLAGS) -include $(top_srcdir)/git.mk diff --git a/backend/dvi/mdvi-lib/afmparse.c b/backend/dvi/mdvi-lib/afmparse.c index f8d840b7..f01042d2 100644 --- a/backend/dvi/mdvi-lib/afmparse.c +++ b/backend/dvi/mdvi-lib/afmparse.c @@ -81,13 +81,10 @@ #define MATCH(A,B) (strncmp((A),(B), MAX_NAME) == 0) - - /*************************** GLOBALS ***********************/ static char *ident = NULL; /* storage buffer for keywords */ - /* "shorts" for fast case statement * The values of each of these enumerated items correspond to an entry in the * table of strings defined below. Therefore, if you add a new string as @@ -175,7 +172,6 @@ static char *token(FILE *stream) } /* token */ - /*************************** linetoken *************************/ /* "linetoken" will get read all tokens until the EOL character from @@ -203,7 +199,6 @@ static char *linetoken(FILE *stream) } /* linetoken */ - /*************************** recognize *************************/ /* This function tries to match a string to a known list of @@ -234,7 +229,6 @@ static enum parseKey recognize(char *ident) } /* recognize */ - /************************* parseGlobals *****************************/ /* This function is called by "parseFile". It will parse the AFM File @@ -401,8 +395,6 @@ static BOOL parseGlobals(FILE *fp, GlobalFontInfo *gfi) } /* parseGlobals */ - - #if 0 /* this function does not seem to be used anywhere */ /************************* initializeArray ************************/ @@ -584,7 +576,6 @@ static int parseCharWidths(FILE *fp, int *cwi) } /* parseCharWidths */ - /************************* parseCharMetrics ************************/ /* This function is called by parseFile if the caller of parseFile @@ -694,8 +685,6 @@ static int parseCharMetrics(FILE *fp, FontInfo *fi) } /* parseCharMetrics */ - - /************************* parseTrackKernData ***********************/ /* This function is called by "parseFile". It will parse the AFM File @@ -797,7 +786,6 @@ static int parseTrackKernData(FILE *fp, FontInfo *fi) } /* parseTrackKernData */ - /************************* parsePairKernData ************************/ /* This function is called by "parseFile". It will parse the AFM File @@ -918,7 +906,6 @@ static int parsePairKernData(FILE *fp, FontInfo *fi) } /* parsePairKernData */ - /************************* parseCompCharData **************************/ /* This function is called by "parseFile". It will parse the AFM File @@ -1043,12 +1030,8 @@ static int parseCompCharData(FILE *fp, FontInfo *fi) } /* parseCompCharData */ - - - /*************************** 'PUBLIC' FUNCTION ********************/ - /*************************** parseFile *****************************/ /* parseFile is the only 'public' procedure available. It is called @@ -1078,7 +1061,6 @@ extern int afm_parse_file(FILE *fp, FontInfo **fi, FLAGS flags) register char *keyword; /* used to store a token */ - /* storage data for the global variable ident */ ident = (char *) calloc(MAX_NAME, sizeof(char)); if (ident == NULL) {error = storageProblem; return(error);} diff --git a/backend/dvi/mdvi-lib/bitmap.c b/backend/dvi/mdvi-lib/bitmap.c index de1de6a7..877aef5d 100644 --- a/backend/dvi/mdvi-lib/bitmap.c +++ b/backend/dvi/mdvi-lib/bitmap.c @@ -117,7 +117,6 @@ static Uchar bit_swap[] = { 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; - /* * next we have three bitmap functions to convert bitmaps in LSB bit order * with 8, 16 and 32 bits per unit, to our internal format. The differences @@ -192,7 +191,6 @@ BITMAP *bitmap_convert_msb8(Uchar *data, int w, int h, int stride) return bm; } - BITMAP *bitmap_copy(BITMAP *bm) { BITMAP *nb = bitmap_alloc(bm->width, bm->height); diff --git a/backend/dvi/mdvi-lib/color.c b/backend/dvi/mdvi-lib/color.c index ef6036a9..ced9ac0c 100644 --- a/backend/dvi/mdvi-lib/color.c +++ b/backend/dvi/mdvi-lib/color.c @@ -79,7 +79,6 @@ static int cc_entries; #define GAMMA_DIFF 0.005 - /* create a color table */ Ulong *get_color_table(DviDevice *dev, int nlevels, Ulong fg, Ulong bg, double gamma, int density) diff --git a/backend/dvi/mdvi-lib/color.h b/backend/dvi/mdvi-lib/color.h index cbc3c0ef..c87c4dcf 100644 --- a/backend/dvi/mdvi-lib/color.h +++ b/backend/dvi/mdvi-lib/color.h @@ -16,7 +16,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #ifndef _COLOR_H_ #define _COLOR_H_ diff --git a/backend/dvi/mdvi-lib/dviread.c b/backend/dvi/mdvi-lib/dviread.c index 44005117..dbb4abbb 100644 --- a/backend/dvi/mdvi-lib/dviread.c +++ b/backend/dvi/mdvi-lib/dviread.c @@ -614,8 +614,6 @@ int mdvi_configure(DviContext *dvi, DviParamCode option, ...) return -1; if(np.mag <= 0.0) return -1; - if(np.density < 0) - return -1; if(np.hshrink < 1 || np.vshrink < 1) return -1; if(np.hdrift < 0 || np.vdrift < 0) diff --git a/backend/dvi/mdvi-lib/fontmap.c b/backend/dvi/mdvi-lib/fontmap.c index 36111bd5..24b497bb 100644 --- a/backend/dvi/mdvi-lib/fontmap.c +++ b/backend/dvi/mdvi-lib/fontmap.c @@ -834,7 +834,6 @@ int mdvi_add_fontmap_file(const char *name, const char *fullpath) return 0; } - void mdvi_flush_encodings(void) { DviEncoding *enc; diff --git a/backend/dvi/mdvi-lib/hash.c b/backend/dvi/mdvi-lib/hash.c index 3327fa58..693f67f6 100644 --- a/backend/dvi/mdvi-lib/hash.c +++ b/backend/dvi/mdvi-lib/hash.c @@ -21,7 +21,6 @@ /* simple hash tables for MDVI */ - struct _DviHashBucket { DviHashBucket *next; DviHashKey key; diff --git a/backend/dvi/mdvi-lib/hash.h b/backend/dvi/mdvi-lib/hash.h index b10afd60..ed1cdfb0 100644 --- a/backend/dvi/mdvi-lib/hash.h +++ b/backend/dvi/mdvi-lib/hash.h @@ -3,7 +3,6 @@ /* Hash tables */ - typedef struct _DviHashBucket DviHashBucket; typedef struct _DviHashTable DviHashTable; @@ -18,7 +17,6 @@ typedef Ulong (*DviHashFunc) __PROTO((DviHashKey key)); typedef int (*DviHashComp) __PROTO((DviHashKey key1, DviHashKey key2)); typedef void (*DviHashFree) __PROTO((DviHashKey key, void *data)); - struct _DviHashTable { DviHashBucket **buckets; int nbucks; diff --git a/backend/dvi/mdvi-lib/mdvi.h b/backend/dvi/mdvi-lib/mdvi.h index a05f9278..a0857f3f 100644 --- a/backend/dvi/mdvi-lib/mdvi.h +++ b/backend/dvi/mdvi-lib/mdvi.h @@ -414,7 +414,6 @@ struct _DviRange { int step; /* step */ }; - typedef void (*DviSpecialHandler) __PROTO((DviContext *dvi, const char *prefix, const char *arg)); @@ -600,7 +599,6 @@ extern int font_free_unused __PROTO((DviDevice *)); extern int mdvi_encode_font __PROTO((DviParams *, DviFont *)); - /* font lookup functions */ extern int mdvi_register_font_type __PROTO((DviFontInfo *, int)); extern char **mdvi_list_font_class __PROTO((int)); diff --git a/backend/dvi/mdvi-lib/paper.h b/backend/dvi/mdvi-lib/paper.h index d42ee079..0eb2c938 100644 --- a/backend/dvi/mdvi-lib/paper.h +++ b/backend/dvi/mdvi-lib/paper.h @@ -24,7 +24,6 @@ struct _DviPaperSpec { const char *height; }; - extern int mdvi_get_paper_size __PROTO((const char *, DviPaper *)); extern DviPaperSpec* mdvi_get_paper_specs __PROTO((DviPaperClass)); extern void mdvi_free_paper_specs __PROTO((DviPaperSpec *)); diff --git a/backend/dvi/mdvi-lib/private.h b/backend/dvi/mdvi-lib/private.h index 9f89dc70..9bb89e13 100644 --- a/backend/dvi/mdvi-lib/private.h +++ b/backend/dvi/mdvi-lib/private.h @@ -16,8 +16,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MDVI_PRIVATE_H -#define _MDVI_PRIVATE_H 1 +#include <config.h> +#include <glib/gi18n-lib.h> + +#define _MDVI_PRIVATE_H 1 #define HAVE_PROTOTYPES 1 #if STDC_HEADERS @@ -45,15 +48,6 @@ #define SKIPSP(p) while(ISSP(p)) p++ #define SKIPNSP(p) while(*(p) && !ISSP(p)) p++ -#ifdef ENABLE_NLS -#include <libintl.h> -#define _(x) gettext(x) -#define _G(x) x -#else -#define _(x) x -#define _G(x) x -#endif /* ENABLE_NLS */ - #if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2 #define _BREAKPOINT() do { __asm__ __volatile__ ("int $03"); } while(0) #elif defined (__alpha__) && defined (__GNUC__) && __GNUC__ >= 2 diff --git a/backend/dvi/mdvi-lib/special.c b/backend/dvi/mdvi-lib/special.c index 64a1647b..93dd390e 100644 --- a/backend/dvi/mdvi-lib/special.c +++ b/backend/dvi/mdvi-lib/special.c @@ -212,7 +212,6 @@ void mdvi_flush_specials(void) { DviSpecial *sp, *list; - for(list = (DviSpecial *)specials.head; (sp = list); ) { list = sp->next; if(sp->prefix) mdvi_free(sp->prefix); diff --git a/backend/dvi/mdvi-lib/tfmfile.c b/backend/dvi/mdvi-lib/tfmfile.c index f7ba251f..52259dfb 100644 --- a/backend/dvi/mdvi-lib/tfmfile.c +++ b/backend/dvi/mdvi-lib/tfmfile.c @@ -258,7 +258,6 @@ int tfm_load_file(const char *filename, TFMInfo *info) /* allocate characters */ info->chars = xnalloc(TFMChar, size); - #ifdef WORD_LITTLE_ENDIAN /* byte-swap the three arrays at once (they are consecutive in memory) */ swap_array((Uint32 *)widths, nw + nh + nd); diff --git a/backend/dvi/mdvi-lib/util.c b/backend/dvi/mdvi-lib/util.c index 15b53f13..feb55ee8 100644 --- a/backend/dvi/mdvi-lib/util.c +++ b/backend/dvi/mdvi-lib/util.c @@ -17,6 +17,8 @@ */ #include <config.h> +#include <glib/gi18n-lib.h> + #include <stdio.h> #include <stdlib.h> #include <stdarg.h> @@ -30,14 +32,14 @@ #include "private.h" static char *const messages[] = { - _G("Ooops!"), - _G("Aieeeee!!"), - _G("Ouch!"), - _G("Houston, we have a problem"), - _G("3.. 2.. 1.. BOOM!"), - _G("I'm history"), - _G("I'm going down"), - _G("I smell a rat") + N_("Ooops!"), + N_("Aieeeee!!"), + N_("Ouch!"), + N_("Houston, we have a problem"), + N_("3.. 2.. 1.. BOOM!"), + N_("I'm history"), + N_("I'm going down"), + N_("I smell a rat") }; #define NMSGS (sizeof(messages) / sizeof(char *)) @@ -139,7 +141,7 @@ void mdvi_crash(const char *format, ...) va_start(ap, format); fprintf(stderr, "%s: %s: ", program_name, - gettext(messages[(int)time(NULL) % NMSGS])); + _(messages[(int)time(NULL) % NMSGS])); vfprintf(stderr, format, ap); #ifndef __GNUC__ /* let's be portable */ diff --git a/backend/epub/Makefile.am b/backend/epub/Makefile.am index 9eca6519..e1dee6ca 100644 --- a/backend/epub/Makefile.am +++ b/backend/epub/Makefile.am @@ -15,7 +15,7 @@ backend_LTLIBRARIES = libepubdocument.la libepubdocument_la_SOURCES = \ epub-document.c \ - epub-document.h + epub-document.h libepubdocument_la_LDFLAGS = $(BACKEND_LIBTOOL_FLAGS) libepubdocument_la_LIBADD = \ @@ -29,7 +29,11 @@ backend_in_files = epubdocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/epub/epub-document.c b/backend/epub/epub-document.c index 52530f47..b63f91cb 100644 --- a/backend/epub/epub-document.c +++ b/backend/epub/epub-document.c @@ -31,9 +31,9 @@ #include <libxml/parser.h> #include <libxml/xmlmemory.h> #include <libxml/HTMLparser.h> -#include <config.h> -#include <glib/gi18n.h> +#include <config.h> +#include <glib/gi18n-lib.h> #include <glib/gstdio.h> #include <gtk/gtk.h> @@ -224,7 +224,6 @@ epub_document_links_has_document_links(EvDocumentLinks *document_links) return TRUE; } - typedef struct _LinksCBStruct { GtkTreeModel *model; GtkTreeIter *parent; @@ -413,7 +412,6 @@ epub_remove_temporary_dir (gchar *path_name) return (g_remove (path_name)); } - static gboolean check_mime_type (const gchar* uri, GError** error); @@ -625,45 +623,55 @@ xml_get_data_from_node(xmlNodePtr node, static gboolean check_mime_type(const gchar* uri,GError** error) { - GError * err = NULL ; - const gchar* mimeFromFile = ev_file_get_mime_type(uri,FALSE,&err); + GError * err = NULL; + const gchar* mimeFromFile; - gchar* mimetypes[] = {"application/epub+zip","application/x-booki+zip"}; - int typecount = 2; - if ( !mimeFromFile ) + mimeFromFile = ev_file_get_mime_type(uri, FALSE, &err); + if (mimeFromFile) { - if (err) { - g_propagate_error (error, err); + const gchar* mimetypes[] = {"application/epub+zip", "application/x-booki+zip", NULL}; + guint i; + + for (i = 0; mimetypes[i]; i++) { + if (strcmp(mimeFromFile, mimetypes[i]) == 0) + return TRUE; } - else { - g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("Unknown MIME Type")); + + /* fallback for malformed epub files */ + if (strcmp (mimeFromFile, "application/zip") == 0) + { + mimeFromFile = ev_file_get_mime_type (uri, TRUE, &err); + if (mimeFromFile) + { + for (i = 0; i < G_N_ELEMENTS (mimetypes); i++) { + if (g_strcmp0(mimeFromFile, mimetypes[i]) == 0) + return TRUE; + } + + /*We didn't find a match*/ + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("Not an ePub document")); + + return FALSE; + } } - return FALSE; } - else - { - int i=0; - for (i=0; i < typecount ;i++) { - if ( g_strcmp0(mimeFromFile, mimetypes[i]) == 0 ) { - return TRUE; - } - } - /*We didn't find a match*/ + if (err) + g_propagate_error (error, err); + else g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("Not an ePub document")); + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("Unknown MIME Type")); - return FALSE; - } + return FALSE; } static gboolean -extract_one_file(EpubDocument* epub_document,GError ** error) +extract_one_file(EpubDocument* epub_document, GFile *tmp_gfile, GError ** error) { GFile * outfile ; gsize writesize = 0; @@ -690,6 +698,20 @@ extract_one_file(EpubDocument* epub_document,GError ** error) gfilepath = g_string_new(epub_document->tmp_archive_dir) ; g_string_append_printf(gfilepath,"/%s",(gchar*)currentfilename); + outfile = g_file_new_for_path (gfilepath->str); + g_autofree gchar *rpath = g_file_get_relative_path (tmp_gfile, outfile); + + if (rpath == NULL) + { + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("epub file is invalid or corrupt")); + g_critical ("Invalid filename in Epub container - '%s'", (gchar *) currentfilename); + result = FALSE; + goto out; + } + /*if we encounter a directory, make a directory inside our temporary folder.*/ if (directory != NULL && *directory == '\0') { @@ -717,7 +739,6 @@ extract_one_file(EpubDocument* epub_document,GError ** error) g_string_free(dir_create,TRUE); } - outfile = g_file_new_for_path(gfilepath->str); outstream = g_file_create(outfile,G_FILE_CREATE_PRIVATE,NULL,error); gpointer buffer = g_malloc0(512); while ( (writesize = unzReadCurrentFile(epub_document->epubDocument,buffer,512) ) != 0 ) @@ -730,10 +751,10 @@ extract_one_file(EpubDocument* epub_document,GError ** error) } g_free(buffer); g_output_stream_close((GOutputStream*)outstream,NULL,error); - g_object_unref(outfile) ; - g_object_unref(outstream) ; + g_object_unref(outstream); out: + g_object_unref(outfile); unzCloseCurrentFile (epub_document->epubDocument) ; g_string_free(gfilepath,TRUE); g_free(currentfilename); @@ -745,6 +766,7 @@ extract_epub_from_container (const gchar* uri, EpubDocument *epub_document, GError ** error) { + GFile *tmp_gfile = NULL; GError *err = NULL; epub_document->archivename = g_filename_from_uri(uri,NULL,error); @@ -806,9 +828,10 @@ extract_epub_from_container (const gchar* uri, goto out; } + tmp_gfile = g_file_new_for_path (epub_document->tmp_archive_dir); while ( TRUE ) { - if ( extract_one_file(epub_document,&err) == FALSE ) + if ( extract_one_file(epub_document, tmp_gfile, &err) == FALSE ) { if (err) { g_propagate_error (error, err); @@ -829,6 +852,7 @@ extract_epub_from_container (const gchar* uri, } out: + g_clear_object (&tmp_gfile); unzClose(epub_document->epubDocument); return result; } @@ -1020,7 +1044,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *docu } if ( xmlStrcmp(itemrefptr->name,(xmlChar*)"itemref") == 0) { - contentListNode *newnode = g_malloc0(sizeof(newnode)); + contentListNode *newnode = g_malloc0(sizeof(*newnode)); newnode->key = (gchar*)xml_get_data_from_node(itemrefptr,XML_ATTRIBUTE,(xmlChar*)"idref"); if ( newnode->key == NULL ) { @@ -1201,7 +1225,13 @@ setup_index_from_navfile(gchar *tocpath) GList *index = NULL; open_xml_document(tocpath); set_xml_root_node(NULL); - xmlNodePtr nav = xml_get_pointer_to_node((xmlChar*)"nav",(xmlChar*)"id",(xmlChar*)"toc"); + xmlNodePtr nav = xml_get_pointer_to_node((xmlChar*)"nav",(xmlChar*)"type",(xmlChar*)"toc"); + + if (nav == NULL) { + xml_free_doc(); + return NULL; + } + xmlretval=NULL; xml_parse_children_of_node(nav,(xmlChar*)"ol", NULL,NULL); gchar *navdirend = g_strrstr(tocpath,"/"); @@ -1546,7 +1576,6 @@ epub_document_check_add_night_sheet(EvDocument *document) gchar *csspath = g_strdup_printf("%s/atrilnightstyle.css",epub_document->documentdir); - GFile *styles = g_file_new_for_path (csspath); GOutputStream *outstream = (GOutputStream*)g_file_create(styles,G_FILE_CREATE_PRIVATE,NULL,NULL); if ( g_output_stream_write((GOutputStream*)outstream,style,strlen(style),NULL,NULL) == -1 ) @@ -1597,7 +1626,7 @@ page_set_function(linknode *Link, GList *contentList) contentListNode *pagedata; guint flag=0; - while (!flag) { + while (!flag && listiter) { pagedata = listiter->data; if (link_present_on_page(Link->pagelink, pagedata->value)) { flag=1; @@ -1620,7 +1649,6 @@ epub_document_set_index_pages(GList *index,GList *contentList) g_list_foreach(index,(GFunc)page_set_function,contentList); } - static void add_mathjax_script_node_to_file(gchar *filename, gchar *data) { @@ -1768,7 +1796,6 @@ epub_document_init (EpubDocument *epub_document) epub_document->docTitle = NULL; } - static void epub_document_finalize (GObject *object) { @@ -1810,7 +1837,6 @@ epub_document_finalize (GObject *object) G_OBJECT_CLASS (epub_document_parent_class)->finalize (object); } - static void epub_document_class_init (EpubDocumentClass *klass) { diff --git a/backend/epub/minizip/ioapi.c b/backend/epub/minizip/ioapi.c index 7f5c191b..c20d20e3 100644 --- a/backend/epub/minizip/ioapi.c +++ b/backend/epub/minizip/ioapi.c @@ -25,7 +25,6 @@ #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) #endif - #include "ioapi.h" voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) @@ -82,8 +81,6 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; } - - static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); @@ -128,7 +125,6 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, return file; } - static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) { uLong ret; @@ -150,7 +146,6 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) return ret; } - static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) { ZPOS64_T ret; @@ -206,7 +201,6 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T return ret; } - static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) { int ret; diff --git a/backend/epub/minizip/ioapi.h b/backend/epub/minizip/ioapi.h index 7a0f44ad..eaf6b303 100644 --- a/backend/epub/minizip/ioapi.h +++ b/backend/epub/minizip/ioapi.h @@ -110,7 +110,6 @@ typedef unsigned long long int ZPOS64_T; extern "C" { #endif - #define ZLIB_FILEFUNC_SEEK_CUR (1) #define ZLIB_FILEFUNC_SEEK_END (2) #define ZLIB_FILEFUNC_SEEK_SET (0) @@ -122,7 +121,6 @@ extern "C" { #define ZLIB_FILEFUNC_MODE_EXISTING (4) #define ZLIB_FILEFUNC_MODE_CREATE (8) - #ifndef ZCALLBACK #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) #define ZCALLBACK CALLBACK @@ -131,9 +129,6 @@ extern "C" { #endif #endif - - - typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); @@ -143,7 +138,6 @@ typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stre typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); - /* here is the "old" 32 bits structure structure */ typedef struct zlib_filefunc_def_s { @@ -185,7 +179,6 @@ typedef struct zlib_filefunc64_32_def_s seek_file_func zseek32_file; } zlib_filefunc64_32_def; - #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) diff --git a/backend/epub/minizip/unzip.c b/backend/epub/minizip/unzip.c index 2ed54a11..3c4a6415 100644 --- a/backend/epub/minizip/unzip.c +++ b/backend/epub/minizip/unzip.c @@ -12,7 +12,6 @@ For more info read MiniZip_info.txt - ------------------------------------------------------------------------------------ Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of compatibility with older software. The following is from the original crypt.c. @@ -48,7 +47,6 @@ Copyright (C) 2007-2008 Even Rouault - Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G should only read the compressed/uncompressed size from the Zip64 format if @@ -63,7 +61,6 @@ */ - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -86,20 +83,17 @@ # include <errno.h> #endif - #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ - #ifndef CASESENSITIVITYDEFAULT_NO # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) # define CASESENSITIVITYDEFAULT_NO # endif #endif - #ifndef UNZ_BUFSIZE #define UNZ_BUFSIZE (16384) #endif @@ -118,14 +112,12 @@ #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) - /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ } unz_file_info64_internal; - /* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */ typedef struct @@ -156,7 +148,6 @@ typedef struct int raw; } file_in_zip64_read_info_s; - /* unz64_s contain internal information about the zipfile */ typedef struct @@ -189,7 +180,6 @@ typedef struct # endif } unz64_s; - #ifndef NOUNCRYPT #include "crypt.h" #endif @@ -197,10 +187,9 @@ typedef struct /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. - IN assertion: the stream s has been sucessfully opened for reading. + IN assertion: the stream s has been successfully opened for reading. */ - local int unz64local_getByte OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, @@ -224,7 +213,6 @@ local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, v } } - /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ @@ -295,7 +283,6 @@ local int unz64local_getLong64 OF(( voidpf filestream, ZPOS64_T *pX)); - local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) @@ -364,7 +351,6 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil } } - #ifdef CASESENSITIVITYDEFAULT_NO #define CASESENSITIVITYDEFAULTVALUE 2 #else @@ -418,7 +404,6 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) @@ -463,7 +448,6 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f return uPosFound; } - /* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) @@ -486,7 +470,6 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) @@ -605,8 +588,6 @@ local unzFile unzOpenInternal (const void *path, us.z_filefunc = *pzlib_filefunc64_32_def; us.is64bitOpenFunction = is64bitOpenFunction; - - us.filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | @@ -745,7 +726,6 @@ local unzFile unzOpenInternal (const void *path, us.pfile_in_zip_read = NULL; us.encrypted = 0; - s=(unz64_s*)ALLOC(sizeof(unz64_s)); if( s != NULL) { @@ -755,7 +735,6 @@ local unzFile unzOpenInternal (const void *path, return (unzFile)s; } - extern unzFile ZEXPORT unzOpen2 (const char *path, zlib_filefunc_def* pzlib_filefunc32_def) { @@ -814,7 +793,6 @@ extern int ZEXPORT unzClose (unzFile file) return UNZ_OK; } - /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed @@ -897,7 +875,6 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; - /* we check the magic */ if (err==UNZ_OK) { @@ -1002,7 +979,6 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, else lSeek += file_info.size_file_extra; - if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) { uLong acc = 0; @@ -1032,8 +1008,6 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, /* ZIP64 extra fields */ if (headerId == 0x0001) { - uLong uL; - if(file_info.uncompressed_size == MAXU32) { if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) @@ -1098,7 +1072,6 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, else lSeek+=file_info.size_file_comment; - if ((err==UNZ_OK) && (pfile_info!=NULL)) *pfile_info=file_info; @@ -1108,8 +1081,6 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, return err; } - - /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed @@ -1158,7 +1129,6 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, pfile_info->tmu_date = file_info64.tmu_date, - pfile_info->compressed_size = (uLong)file_info64.compressed_size; pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; @@ -1214,7 +1184,6 @@ extern int ZEXPORT unzGoToNextFile (unzFile file) return err; } - /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzStringFileNameCompare @@ -1236,7 +1205,6 @@ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas ZPOS64_T num_fileSaved; ZPOS64_T pos_in_central_dirSaved; - if (file==NULL) return UNZ_PARAMERROR; @@ -1280,7 +1248,6 @@ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas return err; } - /* /////////////////////////////////////////// // Contributed by Ryan Haksi (mailto://[email protected]) @@ -1393,7 +1360,6 @@ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; - if (err==UNZ_OK) { if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) @@ -1596,7 +1562,6 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size ; - pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; @@ -1628,7 +1593,6 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, } # endif - return UNZ_OK; } @@ -1689,7 +1653,6 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) @@ -1733,7 +1696,6 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) uReadThis)!=uReadThis) return UNZ_ERRNO; - # ifndef NOUNCRYPT if(s->encrypted) { @@ -1745,7 +1707,6 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) } # endif - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; pfile_in_zip_read_info->rest_read_compressed-=uReadThis; @@ -1876,7 +1837,6 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) return err; } - /* Give the current position in uncompressed data */ @@ -1911,7 +1871,6 @@ extern ZPOS64_T ZEXPORT unztell64 (unzFile file) return pfile_in_zip_read_info->total_out_64; } - /* return 1 if the end of file was reached, 0 elsewhere */ @@ -1933,8 +1892,6 @@ extern int ZEXPORT unzeof (unzFile file) return 0; } - - /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is @@ -2009,7 +1966,6 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) { @@ -2017,7 +1973,6 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) err=UNZ_CRCERROR; } - TRYFREE(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) @@ -2027,7 +1982,6 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); #endif - pfile_in_zip_read_info->stream_initialised = 0; TRYFREE(pfile_in_zip_read_info); @@ -2036,7 +1990,6 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) return err; } - /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. diff --git a/backend/epub/minizip/unzip.h b/backend/epub/minizip/unzip.h index 2104e391..5c5a3f99 100644 --- a/backend/epub/minizip/unzip.h +++ b/backend/epub/minizip/unzip.h @@ -70,7 +70,6 @@ typedef unzFile__ *unzFile; typedef voidp unzFile; #endif - #define UNZ_OK (0) #define UNZ_END_OF_LIST_OF_FILE (-100) #define UNZ_ERRNO (Z_ERRNO) @@ -162,7 +161,6 @@ extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, (like 1 on Unix, 2 on Windows) */ - extern unzFile ZEXPORT unzOpen OF((const char *path)); extern unzFile ZEXPORT unzOpen64 OF((const void *path)); /* @@ -180,7 +178,6 @@ extern unzFile ZEXPORT unzOpen64 OF((const void *path)); does not describe the reality */ - extern unzFile ZEXPORT unzOpen2 OF((const char *path, zlib_filefunc_def* pzlib_filefunc_def)); /* @@ -212,7 +209,6 @@ extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, No preparation of the structure is needed return UNZ_OK if there is no problem. */ - extern int ZEXPORT unzGetGlobalComment OF((unzFile file, char *szComment, uLong uSizeBuf)); @@ -222,7 +218,6 @@ extern int ZEXPORT unzGetGlobalComment OF((unzFile file, return the number of byte copied or an error code <0 */ - /***************************************************************************/ /* Unzip package allow you browse the directory of the zipfile */ @@ -251,7 +246,6 @@ extern int ZEXPORT unzLocateFile OF((unzFile file, UNZ_END_OF_LIST_OF_FILE if the file is not found */ - /* ****************************************** */ /* Ryan supplied functions */ /* unz_file_info contain information about a file in the zipfile */ @@ -315,14 +309,12 @@ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, (commentBufferSize is the size of the buffer) */ - /** Addition for GDAL : START */ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); /** Addition for GDAL : END */ - /***************************************************************************/ /* for reading the content of the current zipfile, you can open it, read data from it, and close it (you can close it before reading all the file) @@ -369,7 +361,6 @@ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, but you CANNOT set method parameter as NULL */ - extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); /* Close the file in zip opened with unzOpenCurrentFile @@ -428,8 +419,6 @@ extern uLong ZEXPORT unzGetOffset (unzFile file); extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - #ifdef __cplusplus } #endif diff --git a/backend/pdf/Makefile.am b/backend/pdf/Makefile.am index e51dfdca..4934a31d 100644 --- a/backend/pdf/Makefile.am +++ b/backend/pdf/Makefile.am @@ -30,6 +30,10 @@ EXTRA_DIST = $(backend_in_files) CLEANFILES = $(backend_DATA) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif -include $(top_srcdir)/git.mk diff --git a/backend/pdf/ev-poppler.h b/backend/pdf/ev-poppler.h index c70fc7d0..8f98fa02 100644 --- a/backend/pdf/ev-poppler.h +++ b/backend/pdf/ev-poppler.h @@ -34,7 +34,6 @@ GType pdf_document_get_type (void) G_GNUC_CONST; G_MODULE_EXPORT GType register_atril_backend (GTypeModule *module); - G_END_DECLS #endif /* __PDF_DOCUMENT_H__ */ diff --git a/backend/pixbuf/Makefile.am b/backend/pixbuf/Makefile.am index 194c6be5..2c9a742b 100644 --- a/backend/pixbuf/Makefile.am +++ b/backend/pixbuf/Makefile.am @@ -21,7 +21,11 @@ libpixbufdocument_la_LIBADD = \ backend_in_files = pixbufdocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/pixbuf/pixbuf-document.c b/backend/pixbuf/pixbuf-document.c index a4fe88ed..92bc7097 100644 --- a/backend/pixbuf/pixbuf-document.c +++ b/backend/pixbuf/pixbuf-document.c @@ -201,7 +201,6 @@ pixbuf_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *i iface->get_dimensions = pixbuf_document_thumbnails_get_dimensions; } - static void pixbuf_document_init (PixbufDocument *pixbuf_document) { diff --git a/backend/ps/Makefile.am b/backend/ps/Makefile.am index 0cac11ff..7e431376 100644 --- a/backend/ps/Makefile.am +++ b/backend/ps/Makefile.am @@ -24,7 +24,11 @@ backend_in_files = psdocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/tiff/Makefile.am b/backend/tiff/Makefile.am index 1be66eca..5ceaa69c 100644 --- a/backend/tiff/Makefile.am +++ b/backend/tiff/Makefile.am @@ -24,7 +24,11 @@ libtiffdocument_la_LIBADD = \ backend_in_files = tiffdocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/tiff/tiff-document.c b/backend/tiff/tiff-document.c index 2129de20..c47be57f 100644 --- a/backend/tiff/tiff-document.c +++ b/backend/tiff/tiff-document.c @@ -361,7 +361,6 @@ tiff_document_render_pixbuf (EvDocument *document, if (width <= 0 || height <= 0) return NULL; - if (width >= INT_MAX / 4) /* overflow */ return NULL; diff --git a/backend/tiff/tiff2ps.c b/backend/tiff/tiff2ps.c index bcbbf885..41f2fb9a 100644 --- a/backend/tiff/tiff2ps.c +++ b/backend/tiff/tiff2ps.c @@ -449,7 +449,6 @@ PlaceImage(TIFF2PSContext *ctx, double pagewidth, double pageheight, return splitpage; } - void tiff2ps_process_page(TIFF2PSContext* ctx, TIFF* tif, double pw, double ph, double lm, double bm, gboolean cnt) @@ -592,7 +591,6 @@ tiff2ps_process_page(TIFF2PSContext* ctx, TIFF* tif, double pw, double ph, } } - static char DuplexPreamble[] = "\ %%BeginFeature: *Duplex True\n\ systemdict begin\n\ diff --git a/backend/xps/Makefile.am b/backend/xps/Makefile.am index b0be0664..b2b2e5c7 100644 --- a/backend/xps/Makefile.am +++ b/backend/xps/Makefile.am @@ -22,7 +22,11 @@ libxpsdocument_la_LIBADD = \ backend_in_files = xpsdocument.atril-backend.desktop.in backend_DATA = $(backend_in_files:.atril-backend.desktop.in=.atril-backend) $(backend_DATA): $(backend_in_files) +if USE_NLS $(AM_V_GEN) $(MSGFMT) --desktop --keyword=TypeDescription --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) cp -f $< $@ +endif EXTRA_DIST = $(backend_in_files) diff --git a/backend/xps/xps-document.c b/backend/xps/xps-document.c index 8db7d56c..e7e9ef2b 100644 --- a/backend/xps/xps-document.c +++ b/backend/xps/xps-document.c @@ -176,7 +176,6 @@ xps_document_get_info (EvDocument *document) EV_DOCUMENT_INFO_N_PAGES | EV_DOCUMENT_INFO_PAPER_SIZE; - if (gxps_document_get_n_pages (xps->doc) > 0) { ev_document_get_page_size (document, 0, &(info->paper_width), @@ -483,7 +482,6 @@ xps_document_document_links_iface_init (EvDocumentLinksInterface *iface) iface->find_link_page = xps_document_links_find_link_page; } - /* EvDocumentPrint */ static void xps_document_print_print_page (EvDocumentPrint *document, |