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 | } |