| File: | backend/tiff/tiff-document.c |
| Warning: | line 481, column 32 The left operand of '*' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ | |||
| 2 | /* | |||
| 3 | * Copyright (C) 2005, Jonathan Blandford <jrb@gnome.org> | |||
| 4 | * | |||
| 5 | * This program is free software; you can redistribute it and/or modify | |||
| 6 | * it under the terms of the GNU General Public License as published by | |||
| 7 | * the Free Software Foundation; either version 2, or (at your option) | |||
| 8 | * any later version. | |||
| 9 | * | |||
| 10 | * This program is distributed in the hope that it will be useful, | |||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 13 | * GNU General Public License for more details. | |||
| 14 | * | |||
| 15 | * You should have received a copy of the GNU General Public License | |||
| 16 | * along with this program; if not, write to the Free Software | |||
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
| 18 | */ | |||
| 19 | ||||
| 20 | /* FIXME: Should probably buffer calls to libtiff with TIFFSetWarningHandler | |||
| 21 | */ | |||
| 22 | ||||
| 23 | #include "config.h" | |||
| 24 | ||||
| 25 | #include <config.h> | |||
| 26 | #include <stdio.h> | |||
| 27 | #include <glib.h> | |||
| 28 | #include <glib/gi18n-lib.h> | |||
| 29 | ||||
| 30 | #include "tiffio.h" | |||
| 31 | #include "tiff2ps.h" | |||
| 32 | #include "tiff-document.h" | |||
| 33 | #include "ev-document-misc.h" | |||
| 34 | #include "ev-document-thumbnails.h" | |||
| 35 | #include "ev-file-exporter.h" | |||
| 36 | #include "ev-file-helpers.h" | |||
| 37 | ||||
| 38 | struct _TiffDocumentClass | |||
| 39 | { | |||
| 40 | EvDocumentClass parent_class; | |||
| 41 | }; | |||
| 42 | ||||
| 43 | struct _TiffDocument | |||
| 44 | { | |||
| 45 | EvDocument parent_instance; | |||
| 46 | ||||
| 47 | TIFF *tiff; | |||
| 48 | gint n_pages; | |||
| 49 | TIFF2PSContext *ps_export_ctx; | |||
| 50 | ||||
| 51 | gchar *uri; | |||
| 52 | }; | |||
| 53 | ||||
| 54 | typedef struct _TiffDocumentClass TiffDocumentClass; | |||
| 55 | ||||
| 56 | static void tiff_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); | |||
| 57 | static void tiff_document_document_file_exporter_iface_init (EvFileExporterInterface *iface); | |||
| 58 | ||||
| 59 | EV_BACKEND_REGISTER_WITH_CODE (TiffDocument, tiff_document,static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 60 | {static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 61 | EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 62 | tiff_document_document_thumbnails_iface_init);static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 63 | EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 64 | tiff_document_document_file_exporter_iface_init);static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 65 | })static GType g_define_type_id = 0; GType tiff_document_get_type (void) { return g_define_type_id; } static void tiff_document_init (TiffDocument *self); static void tiff_document_class_init ( TiffDocumentClass *klass); static gpointer tiff_document_parent_class = ((void*)0); static void tiff_document_class_intern_init (gpointer klass) { tiff_document_parent_class = g_type_class_peek_parent (klass); tiff_document_class_init ((TiffDocumentClass *) klass ); } __attribute__((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof ( TiffDocumentClass), ((void*)0), ((void*)0), (GClassInitFunc) tiff_document_class_intern_init , ((void*)0), ((void*)0), sizeof (TiffDocument), 0, (GInstanceInitFunc ) tiff_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "TiffDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) tiff_document_document_thumbnails_iface_init, ((void*)0), ( (void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) tiff_document_document_file_exporter_iface_init , ((void*)0), ((void*)0) }; g_type_module_add_interface (module , g_define_type_id, (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; }; | |||
| 66 | ||||
| 67 | static TIFFErrorHandler orig_error_handler = NULL((void*)0); | |||
| 68 | static TIFFErrorHandler orig_warning_handler = NULL((void*)0); | |||
| 69 | ||||
| 70 | static void | |||
| 71 | push_handlers (void) | |||
| 72 | { | |||
| 73 | orig_error_handler = TIFFSetErrorHandler (NULL((void*)0)); | |||
| 74 | orig_warning_handler = TIFFSetWarningHandler (NULL((void*)0)); | |||
| 75 | } | |||
| 76 | ||||
| 77 | static void | |||
| 78 | pop_handlers (void) | |||
| 79 | { | |||
| 80 | TIFFSetErrorHandler (orig_error_handler); | |||
| 81 | TIFFSetWarningHandler (orig_warning_handler); | |||
| 82 | } | |||
| 83 | ||||
| 84 | static gboolean | |||
| 85 | tiff_document_load (EvDocument *document, | |||
| 86 | const char *uri, | |||
| 87 | GError **error) | |||
| 88 | { | |||
| 89 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 90 | gchar *filename; | |||
| 91 | TIFF *tiff; | |||
| 92 | ||||
| 93 | filename = g_filename_from_uri (uri, NULL((void*)0), error); | |||
| 94 | if (!filename) | |||
| 95 | return FALSE(0); | |||
| 96 | ||||
| 97 | push_handlers (); | |||
| 98 | ||||
| 99 | tiff = TIFFOpen (filename, "r"); | |||
| 100 | if (tiff) { | |||
| 101 | guint32 w, h; | |||
| 102 | ||||
| 103 | /* FIXME: unused data? why bother here */ | |||
| 104 | TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH256, &w); | |||
| 105 | TIFFGetField(tiff, TIFFTAG_IMAGELENGTH257, &h); | |||
| 106 | } | |||
| 107 | ||||
| 108 | if (!tiff) { | |||
| 109 | pop_handlers (); | |||
| 110 | ||||
| 111 | g_set_error_literal (error, | |||
| 112 | EV_DOCUMENT_ERRORev_document_error_quark (), | |||
| 113 | EV_DOCUMENT_ERROR_INVALID, | |||
| 114 | _("Invalid document")((char *) g_dgettext ("lector", "Invalid document"))); | |||
| 115 | ||||
| 116 | g_free (filename); | |||
| 117 | return FALSE(0); | |||
| 118 | } | |||
| 119 | ||||
| 120 | tiff_document->tiff = tiff; | |||
| 121 | g_free (tiff_document->uri); | |||
| 122 | g_free (filename); | |||
| 123 | tiff_document->uri = g_strdup (uri)g_strdup_inline (uri); | |||
| 124 | ||||
| 125 | pop_handlers (); | |||
| 126 | return TRUE(!(0)); | |||
| 127 | } | |||
| 128 | ||||
| 129 | static gboolean | |||
| 130 | tiff_document_save (EvDocument *document, | |||
| 131 | const char *uri, | |||
| 132 | GError **error) | |||
| 133 | { | |||
| 134 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 135 | ||||
| 136 | return ev_xfer_uri_simple (tiff_document->uri, uri, error); | |||
| 137 | } | |||
| 138 | ||||
| 139 | static int | |||
| 140 | tiff_document_get_n_pages (EvDocument *document) | |||
| 141 | { | |||
| 142 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 143 | ||||
| 144 | g_return_val_if_fail (TIFF_IS_DOCUMENT (document), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((document)); GType __t = ((tiff_document_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "TIFF_IS_DOCUMENT (document)"); return (0); } } while (0); | |||
| 145 | g_return_val_if_fail (tiff_document->tiff != NULL, 0)do { if ((tiff_document->tiff != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "tiff_document->tiff != NULL" ); return (0); } } while (0); | |||
| 146 | ||||
| 147 | if (tiff_document->n_pages == -1) { | |||
| 148 | push_handlers (); | |||
| 149 | tiff_document->n_pages = 0; | |||
| 150 | ||||
| 151 | do { | |||
| 152 | tiff_document->n_pages ++; | |||
| 153 | } | |||
| 154 | while (TIFFReadDirectory (tiff_document->tiff)); | |||
| 155 | pop_handlers (); | |||
| 156 | } | |||
| 157 | ||||
| 158 | return tiff_document->n_pages; | |||
| 159 | } | |||
| 160 | ||||
| 161 | static void | |||
| 162 | tiff_document_get_resolution (TiffDocument *tiff_document, | |||
| 163 | gfloat *x_res, | |||
| 164 | gfloat *y_res) | |||
| 165 | { | |||
| 166 | gfloat x = 72.0, y = 72.0; | |||
| 167 | gushort unit; | |||
| 168 | ||||
| 169 | if (TIFFGetField (tiff_document->tiff, TIFFTAG_XRESOLUTION282, &x) && | |||
| 170 | TIFFGetField (tiff_document->tiff, TIFFTAG_YRESOLUTION283, &y)) { | |||
| 171 | if (TIFFGetFieldDefaulted (tiff_document->tiff, TIFFTAG_RESOLUTIONUNIT296, &unit)) { | |||
| 172 | if (unit == RESUNIT_CENTIMETER3) { | |||
| 173 | x *= 2.54; | |||
| 174 | y *= 2.54; | |||
| 175 | } | |||
| 176 | } | |||
| 177 | } | |||
| 178 | ||||
| 179 | *x_res = x; | |||
| 180 | *y_res = y; | |||
| 181 | } | |||
| 182 | ||||
| 183 | static void | |||
| 184 | tiff_document_get_page_size (EvDocument *document, | |||
| 185 | EvPage *page, | |||
| 186 | double *width, | |||
| 187 | double *height) | |||
| 188 | { | |||
| 189 | guint32 w, h; | |||
| 190 | gfloat x_res, y_res; | |||
| 191 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 192 | ||||
| 193 | g_return_if_fail (TIFF_IS_DOCUMENT (document))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((document)); GType __t = ((tiff_document_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "TIFF_IS_DOCUMENT (document)"); return; } } while (0); | |||
| 194 | g_return_if_fail (tiff_document->tiff != NULL)do { if ((tiff_document->tiff != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "tiff_document->tiff != NULL" ); return; } } while (0); | |||
| 195 | ||||
| 196 | push_handlers (); | |||
| 197 | if (TIFFSetDirectory (tiff_document->tiff, page->index) != 1) { | |||
| 198 | pop_handlers (); | |||
| 199 | return; | |||
| 200 | } | |||
| 201 | ||||
| 202 | TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH256, &w); | |||
| 203 | TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH257, &h); | |||
| 204 | tiff_document_get_resolution (tiff_document, &x_res, &y_res); | |||
| 205 | h = h * (x_res / y_res); | |||
| 206 | ||||
| 207 | *width = w; | |||
| 208 | *height = h; | |||
| 209 | ||||
| 210 | pop_handlers (); | |||
| 211 | } | |||
| 212 | ||||
| 213 | static cairo_surface_t * | |||
| 214 | tiff_document_render (EvDocument *document, | |||
| 215 | EvRenderContext *rc) | |||
| 216 | { | |||
| 217 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 218 | int width, height; | |||
| 219 | float x_res, y_res; | |||
| 220 | gint rowstride, bytes; | |||
| 221 | guchar *pixels = NULL((void*)0); | |||
| 222 | guchar *p; | |||
| 223 | int orientation; | |||
| 224 | cairo_surface_t *surface; | |||
| 225 | cairo_surface_t *rotated_surface; | |||
| 226 | static const cairo_user_data_key_t key; | |||
| 227 | ||||
| 228 | g_return_val_if_fail (TIFF_IS_DOCUMENT (document), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((document)); GType __t = ((tiff_document_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "TIFF_IS_DOCUMENT (document)"); return (((void *)0)); } } while (0); | |||
| 229 | g_return_val_if_fail (tiff_document->tiff != NULL, NULL)do { if ((tiff_document->tiff != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "tiff_document->tiff != NULL" ); return (((void*)0)); } } while (0); | |||
| 230 | ||||
| 231 | push_handlers (); | |||
| 232 | if (TIFFSetDirectory (tiff_document->tiff, rc->page->index) != 1) { | |||
| 233 | pop_handlers (); | |||
| 234 | g_warning("Failed to select page %d", rc->page->index); | |||
| 235 | return NULL((void*)0); | |||
| 236 | } | |||
| 237 | ||||
| 238 | if (!TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH256, &width)) { | |||
| 239 | pop_handlers (); | |||
| 240 | g_warning("Failed to read image width"); | |||
| 241 | return NULL((void*)0); | |||
| 242 | } | |||
| 243 | ||||
| 244 | if (! TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH257, &height)) { | |||
| 245 | pop_handlers (); | |||
| 246 | g_warning("Failed to read image height"); | |||
| 247 | return NULL((void*)0); | |||
| 248 | } | |||
| 249 | ||||
| 250 | if (! TIFFGetField (tiff_document->tiff, TIFFTAG_ORIENTATION274, &orientation)) { | |||
| 251 | orientation = ORIENTATION_TOPLEFT1; | |||
| 252 | } | |||
| 253 | ||||
| 254 | tiff_document_get_resolution (tiff_document, &x_res, &y_res); | |||
| 255 | ||||
| 256 | pop_handlers (); | |||
| 257 | ||||
| 258 | /* Sanity check the doc */ | |||
| 259 | if (width <= 0 || height <= 0) { | |||
| 260 | g_warning("Invalid width or height."); | |||
| 261 | return NULL((void*)0); | |||
| 262 | } | |||
| 263 | ||||
| 264 | rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width); | |||
| 265 | if (rowstride / 4 != width) { | |||
| 266 | g_warning("Overflow while rendering document."); | |||
| 267 | /* overflow, or cairo was changed in an unsupported way */ | |||
| 268 | return NULL((void*)0); | |||
| 269 | } | |||
| 270 | ||||
| 271 | if (height >= INT_MAX2147483647 / rowstride) { | |||
| 272 | g_warning("Overflow while rendering document."); | |||
| 273 | /* overflow */ | |||
| 274 | return NULL((void*)0); | |||
| 275 | } | |||
| 276 | ||||
| 277 | bytes = height * rowstride; | |||
| 278 | ||||
| 279 | pixels = g_try_malloc (bytes); | |||
| 280 | if (!pixels) { | |||
| 281 | g_warning("Failed to allocate memory for rendering."); | |||
| 282 | return NULL((void*)0); | |||
| 283 | } | |||
| 284 | ||||
| 285 | if (!TIFFReadRGBAImageOriented (tiff_document->tiff, | |||
| 286 | width, height, | |||
| 287 | (uint32_t *)pixels, | |||
| 288 | orientation, 0)) { | |||
| 289 | g_warning ("Failed to read TIFF image."); | |||
| 290 | g_free (pixels); | |||
| 291 | return NULL((void*)0); | |||
| 292 | } | |||
| 293 | ||||
| 294 | surface = cairo_image_surface_create_for_data (pixels, | |||
| 295 | CAIRO_FORMAT_RGB24, | |||
| 296 | width, height, | |||
| 297 | rowstride); | |||
| 298 | cairo_surface_set_user_data (surface, &key, | |||
| 299 | pixels, (cairo_destroy_func_t)g_free); | |||
| 300 | pop_handlers (); | |||
| 301 | ||||
| 302 | /* Convert the format returned by libtiff to | |||
| 303 | * what cairo expects | |||
| 304 | */ | |||
| 305 | p = pixels; | |||
| 306 | while (p < pixels + bytes) { | |||
| 307 | guint32 *pixel = (guint32*)p; | |||
| 308 | guint8 r = TIFFGetR(*pixel)((*pixel)&0xff); | |||
| 309 | guint8 g = TIFFGetG(*pixel)(((*pixel) >> 8) & 0xff); | |||
| 310 | guint8 b = TIFFGetB(*pixel)(((*pixel) >> 16) & 0xff); | |||
| 311 | guint8 a = TIFFGetA(*pixel)(((*pixel) >> 24) & 0xff); | |||
| 312 | ||||
| 313 | *pixel = (a << 24) | (r << 16) | (g << 8) | b; | |||
| 314 | ||||
| 315 | p += 4; | |||
| 316 | } | |||
| 317 | ||||
| 318 | rotated_surface = ev_document_misc_surface_rotate_and_scale (surface, | |||
| 319 | (width * rc->scale) + 0.5, | |||
| 320 | (height * rc->scale * (x_res / y_res)) + 0.5, | |||
| 321 | rc->rotation); | |||
| 322 | cairo_surface_destroy (surface); | |||
| 323 | ||||
| 324 | return rotated_surface; | |||
| 325 | } | |||
| 326 | ||||
| 327 | static GdkPixbuf * | |||
| 328 | tiff_document_render_pixbuf (EvDocument *document, | |||
| 329 | EvRenderContext *rc) | |||
| 330 | { | |||
| 331 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 332 | int width, height; | |||
| 333 | float x_res, y_res; | |||
| 334 | gint rowstride, bytes; | |||
| 335 | guchar *pixels = NULL((void*)0); | |||
| 336 | GdkPixbuf *pixbuf; | |||
| 337 | GdkPixbuf *scaled_pixbuf; | |||
| 338 | GdkPixbuf *rotated_pixbuf; | |||
| 339 | ||||
| 340 | push_handlers (); | |||
| 341 | if (TIFFSetDirectory (tiff_document->tiff, rc->page->index) != 1) { | |||
| 342 | pop_handlers (); | |||
| 343 | return NULL((void*)0); | |||
| 344 | } | |||
| 345 | ||||
| 346 | if (!TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH256, &width)) { | |||
| 347 | pop_handlers (); | |||
| 348 | return NULL((void*)0); | |||
| 349 | } | |||
| 350 | ||||
| 351 | if (! TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH257, &height)) { | |||
| 352 | pop_handlers (); | |||
| 353 | return NULL((void*)0); | |||
| 354 | } | |||
| 355 | ||||
| 356 | tiff_document_get_resolution (tiff_document, &x_res, &y_res); | |||
| 357 | ||||
| 358 | pop_handlers (); | |||
| 359 | ||||
| 360 | /* Sanity check the doc */ | |||
| 361 | if (width <= 0 || height <= 0) | |||
| 362 | return NULL((void*)0); | |||
| 363 | ||||
| 364 | ||||
| 365 | if (width >= INT_MAX2147483647 / 4) | |||
| 366 | /* overflow */ | |||
| 367 | return NULL((void*)0); | |||
| 368 | ||||
| 369 | rowstride = width * 4; | |||
| 370 | ||||
| 371 | if (height >= INT_MAX2147483647 / rowstride) | |||
| 372 | /* overflow */ | |||
| 373 | return NULL((void*)0); | |||
| 374 | bytes = height * rowstride; | |||
| 375 | ||||
| 376 | pixels = g_try_malloc (bytes); | |||
| 377 | if (!pixels) | |||
| 378 | return NULL((void*)0); | |||
| 379 | ||||
| 380 | if (!TIFFReadRGBAImageOriented (tiff_document->tiff, | |||
| 381 | width, height, | |||
| 382 | (uint32_t *)pixels, | |||
| 383 | ORIENTATION_TOPLEFT1, 0)) { | |||
| 384 | g_free (pixels); | |||
| 385 | return NULL((void*)0); | |||
| 386 | } | |||
| 387 | ||||
| 388 | pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE(!(0)), 8, | |||
| 389 | width, height, rowstride, | |||
| 390 | (GdkPixbufDestroyNotify) g_free, NULL((void*)0)); | |||
| 391 | pop_handlers (); | |||
| 392 | ||||
| 393 | scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, | |||
| 394 | width * rc->scale, | |||
| 395 | height * rc->scale * (x_res / y_res), | |||
| 396 | GDK_INTERP_BILINEAR); | |||
| 397 | g_object_unref (pixbuf); | |||
| 398 | ||||
| 399 | rotated_pixbuf = gdk_pixbuf_rotate_simple (scaled_pixbuf, 360 - rc->rotation); | |||
| 400 | g_object_unref (scaled_pixbuf); | |||
| 401 | ||||
| 402 | return rotated_pixbuf; | |||
| 403 | } | |||
| 404 | ||||
| 405 | static gchar * | |||
| 406 | tiff_document_get_page_label (EvDocument *document, | |||
| 407 | EvPage *page) | |||
| 408 | { | |||
| 409 | TiffDocument *tiff_document = TIFF_DOCUMENT (document)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((tiff_document_get_type ())))))); | |||
| 410 | static gchar *label; | |||
| 411 | ||||
| 412 | if (TIFFGetField (tiff_document->tiff, TIFFTAG_PAGENAME285, &label) && | |||
| 413 | g_utf8_validate (label, -1, NULL((void*)0))) { | |||
| 414 | return g_strdup (label)g_strdup_inline (label); | |||
| 415 | } | |||
| 416 | ||||
| 417 | return NULL((void*)0); | |||
| 418 | } | |||
| 419 | ||||
| 420 | static void | |||
| 421 | tiff_document_finalize (GObject *object) | |||
| 422 | { | |||
| 423 | TiffDocument *tiff_document = TIFF_DOCUMENT (object)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((tiff_document_get_type ())))))); | |||
| 424 | ||||
| 425 | if (tiff_document->tiff) | |||
| 426 | TIFFClose (tiff_document->tiff); | |||
| 427 | if (tiff_document->uri) | |||
| 428 | g_free (tiff_document->uri); | |||
| 429 | ||||
| 430 | G_OBJECT_CLASS (tiff_document_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((tiff_document_parent_class)), (((GType) ((20) << ( 2))))))))->finalize (object); | |||
| 431 | } | |||
| 432 | ||||
| 433 | static void | |||
| 434 | tiff_document_class_init (TiffDocumentClass *klass) | |||
| 435 | { | |||
| 436 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | |||
| 437 | EvDocumentClass *ev_document_class = EV_DOCUMENT_CLASS (klass)((((EvDocumentClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), ((ev_document_get_type ())))))); | |||
| 438 | ||||
| 439 | gobject_class->finalize = tiff_document_finalize; | |||
| 440 | ||||
| 441 | ev_document_class->load = tiff_document_load; | |||
| 442 | ev_document_class->save = tiff_document_save; | |||
| 443 | ev_document_class->get_n_pages = tiff_document_get_n_pages; | |||
| 444 | ev_document_class->get_page_size = tiff_document_get_page_size; | |||
| 445 | ev_document_class->render = tiff_document_render; | |||
| 446 | ev_document_class->get_page_label = tiff_document_get_page_label; | |||
| 447 | } | |||
| 448 | ||||
| 449 | static GdkPixbuf * | |||
| 450 | tiff_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, | |||
| 451 | EvRenderContext *rc, | |||
| 452 | gboolean border) | |||
| 453 | { | |||
| 454 | GdkPixbuf *pixbuf; | |||
| 455 | ||||
| 456 | pixbuf = tiff_document_render_pixbuf (EV_DOCUMENT (document)((((EvDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((ev_document_get_type ())))))), rc); | |||
| 457 | ||||
| 458 | if (border) { | |||
| 459 | GdkPixbuf *tmp_pixbuf = pixbuf; | |||
| 460 | ||||
| 461 | pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, tmp_pixbuf); | |||
| 462 | g_object_unref (tmp_pixbuf); | |||
| 463 | } | |||
| 464 | ||||
| 465 | return pixbuf; | |||
| 466 | } | |||
| 467 | ||||
| 468 | static void | |||
| 469 | tiff_document_thumbnails_get_dimensions (EvDocumentThumbnails *document, | |||
| 470 | EvRenderContext *rc, | |||
| 471 | gint *width, | |||
| 472 | gint *height) | |||
| 473 | { | |||
| 474 | gdouble page_width, page_height; | |||
| ||||
| 475 | ||||
| 476 | tiff_document_get_page_size (EV_DOCUMENT (document)((((EvDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((ev_document_get_type ())))))), | |||
| 477 | rc->page, | |||
| 478 | &page_width, &page_height); | |||
| 479 | ||||
| 480 | if (rc->rotation == 90 || rc->rotation == 270) { | |||
| 481 | *width = (gint) (page_height * rc->scale); | |||
| ||||
| 482 | *height = (gint) (page_width * rc->scale); | |||
| 483 | } else { | |||
| 484 | *width = (gint) (page_width * rc->scale); | |||
| 485 | *height = (gint) (page_height * rc->scale); | |||
| 486 | } | |||
| 487 | } | |||
| 488 | ||||
| 489 | static void | |||
| 490 | tiff_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface) | |||
| 491 | { | |||
| 492 | iface->get_thumbnail = tiff_document_thumbnails_get_thumbnail; | |||
| 493 | iface->get_dimensions = tiff_document_thumbnails_get_dimensions; | |||
| 494 | } | |||
| 495 | ||||
| 496 | /* postscript exporter implementation */ | |||
| 497 | static void | |||
| 498 | tiff_document_file_exporter_begin (EvFileExporter *exporter, | |||
| 499 | EvFileExporterContext *fc) | |||
| 500 | { | |||
| 501 | TiffDocument *document = TIFF_DOCUMENT (exporter)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((exporter)), ((tiff_document_get_type ())))))); | |||
| 502 | ||||
| 503 | document->ps_export_ctx = tiff2ps_context_new(fc->filename); | |||
| 504 | } | |||
| 505 | ||||
| 506 | static void | |||
| 507 | tiff_document_file_exporter_do_page (EvFileExporter *exporter, EvRenderContext *rc) | |||
| 508 | { | |||
| 509 | TiffDocument *document = TIFF_DOCUMENT (exporter)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((exporter)), ((tiff_document_get_type ())))))); | |||
| 510 | ||||
| 511 | if (document->ps_export_ctx == NULL((void*)0)) | |||
| 512 | return; | |||
| 513 | if (TIFFSetDirectory (document->tiff, rc->page->index) != 1) | |||
| 514 | return; | |||
| 515 | tiff2ps_process_page (document->ps_export_ctx, document->tiff, | |||
| 516 | 0, 0, 0, 0, 0); | |||
| 517 | } | |||
| 518 | ||||
| 519 | static void | |||
| 520 | tiff_document_file_exporter_end (EvFileExporter *exporter) | |||
| 521 | { | |||
| 522 | TiffDocument *document = TIFF_DOCUMENT (exporter)((((TiffDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((exporter)), ((tiff_document_get_type ())))))); | |||
| 523 | ||||
| 524 | if (document->ps_export_ctx == NULL((void*)0)) | |||
| 525 | return; | |||
| 526 | tiff2ps_context_finalize(document->ps_export_ctx); | |||
| 527 | } | |||
| 528 | ||||
| 529 | static EvFileExporterCapabilities | |||
| 530 | tiff_document_file_exporter_get_capabilities (EvFileExporter *exporter) | |||
| 531 | { | |||
| 532 | return EV_FILE_EXPORTER_CAN_PAGE_SET | | |||
| 533 | EV_FILE_EXPORTER_CAN_COPIES | | |||
| 534 | EV_FILE_EXPORTER_CAN_COLLATE | | |||
| 535 | EV_FILE_EXPORTER_CAN_REVERSE | | |||
| 536 | EV_FILE_EXPORTER_CAN_GENERATE_PS; | |||
| 537 | } | |||
| 538 | ||||
| 539 | static void | |||
| 540 | tiff_document_document_file_exporter_iface_init (EvFileExporterInterface *iface) | |||
| 541 | { | |||
| 542 | iface->begin = tiff_document_file_exporter_begin; | |||
| 543 | iface->do_page = tiff_document_file_exporter_do_page; | |||
| 544 | iface->end = tiff_document_file_exporter_end; | |||
| 545 | iface->get_capabilities = tiff_document_file_exporter_get_capabilities; | |||
| 546 | } | |||
| 547 | ||||
| 548 | static void | |||
| 549 | tiff_document_init (TiffDocument *tiff_document) | |||
| 550 | { | |||
| 551 | tiff_document->n_pages = -1; | |||
| 552 | } |