28 #include <glib/gi18n-lib.h>
69 orig_error_handler = TIFFSetErrorHandler (NULL);
70 orig_warning_handler = TIFFSetWarningHandler (NULL);
76 TIFFSetErrorHandler (orig_error_handler);
77 TIFFSetWarningHandler (orig_warning_handler);
89 filename = g_filename_from_uri (uri, NULL, error);
97 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, error);
98 if (wfilename == NULL) {
102 tiff = TIFFOpenW (wfilename,
"r");
107 tiff = TIFFOpen (filename,
"r");
113 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
114 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
120 g_set_error_literal (error,
123 _(
"Invalid document"));
129 tiff_document->
tiff = tiff;
130 g_free (tiff_document->
uri);
132 tiff_document->
uri = g_strdup (uri);
154 g_return_val_if_fail (tiff_document->
tiff != NULL, 0);
156 if (tiff_document->
n_pages == -1) {
163 while (TIFFReadDirectory (tiff_document->
tiff));
179 if (TIFFGetField (tiff_document->
tiff, TIFFTAG_XRESOLUTION, &x) &&
180 TIFFGetField (tiff_document->
tiff, TIFFTAG_YRESOLUTION, &y)) {
181 if (TIFFGetFieldDefaulted (tiff_document->
tiff, TIFFTAG_RESOLUTIONUNIT, &unit)) {
182 if (unit == RESUNIT_CENTIMETER) {
190 *x_res = x > 0 ? x : 72.0;
191 *y_res = y > 0 ? y : 72.0;
205 g_return_if_fail (tiff_document->
tiff != NULL);
208 if (TIFFSetDirectory (tiff_document->
tiff, page->
index) != 1) {
213 TIFFGetField (tiff_document->
tiff, TIFFTAG_IMAGEWIDTH, &w);
214 TIFFGetField (tiff_document->
tiff, TIFFTAG_IMAGELENGTH, &h);
216 h = h * (x_res / y_res);
224 static cairo_surface_t *
230 int scaled_width, scaled_height;
232 gint rowstride, bytes;
233 guchar *pixels = NULL;
236 cairo_surface_t *surface;
237 cairo_surface_t *rotated_surface;
238 static const cairo_user_data_key_t key;
241 g_return_val_if_fail (tiff_document->
tiff != NULL, NULL);
244 if (TIFFSetDirectory (tiff_document->
tiff, rc->page->index) != 1) {
246 g_warning(
"Failed to select page %d", rc->page->index);
250 if (!TIFFGetField (tiff_document->
tiff, TIFFTAG_IMAGEWIDTH, &width)) {
252 g_warning(
"Failed to read image width");
256 if (! TIFFGetField (tiff_document->
tiff, TIFFTAG_IMAGELENGTH, &height)) {
258 g_warning(
"Failed to read image height");
262 if (! TIFFGetField (tiff_document->
tiff, TIFFTAG_ORIENTATION, &orientation)) {
263 orientation = ORIENTATION_TOPLEFT;
271 if (width <= 0 || height <= 0) {
272 g_warning(
"Invalid width or height.");
276 #ifdef HAVE_CAIRO_FORMAT_STRIDE_FOR_WIDTH
277 rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
279 rowstride = width * 4;
281 if (rowstride / 4 != width) {
282 g_warning(
"Overflow while rendering document.");
287 bytes = height * rowstride;
288 if (bytes / rowstride != height) {
289 g_warning(
"Overflow while rendering document.");
294 pixels = g_try_malloc (bytes);
296 g_warning(
"Failed to allocate memory for rendering.");
300 surface = cairo_image_surface_create_for_data (pixels,
304 cairo_surface_set_user_data (surface, &key,
305 pixels, (cairo_destroy_func_t)g_free);
307 TIFFReadRGBAImageOriented (tiff_document->
tiff,
317 while (p < pixels + bytes) {
318 guint32 *pixel = (guint32*)p;
319 guint8 r = TIFFGetR(*pixel);
320 guint8 g = TIFFGetG(*pixel);
321 guint8 b = TIFFGetB(*pixel);
322 guint8 a = TIFFGetA(*pixel);
324 *pixel = (a << 24) | (r << 16) | (g << 8) | b;
330 &scaled_width, &scaled_height);
332 scaled_width, scaled_height,
334 cairo_surface_destroy (surface);
336 return rotated_surface;
345 int scaled_width, scaled_height;
347 gint rowstride, bytes;
348 guchar *pixels = NULL;
350 GdkPixbuf *scaled_pixbuf;
351 GdkPixbuf *rotated_pixbuf;
354 if (TIFFSetDirectory (tiff_document->
tiff, rc->page->index) != 1) {
359 if (!TIFFGetField (tiff_document->
tiff, TIFFTAG_IMAGEWIDTH, &width)) {
364 if (! TIFFGetField (tiff_document->
tiff, TIFFTAG_IMAGELENGTH, &height)) {
374 if (width <= 0 || height <= 0)
377 rowstride = width * 4;
378 if (rowstride / 4 != width)
382 bytes = height * rowstride;
383 if (bytes / rowstride != height)
387 pixels = g_try_malloc (bytes);
391 pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB,
TRUE, 8,
392 width, height, rowstride,
393 (GdkPixbufDestroyNotify) g_free, NULL);
394 TIFFReadRGBAImageOriented (tiff_document->
tiff,
397 ORIENTATION_TOPLEFT, 0);
401 &scaled_width, &scaled_height);
402 scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
403 scaled_width, scaled_height,
404 GDK_INTERP_BILINEAR);
405 g_object_unref (pixbuf);
407 rotated_pixbuf = gdk_pixbuf_rotate_simple (scaled_pixbuf, 360 - rc->rotation);
408 g_object_unref (scaled_pixbuf);
410 return rotated_pixbuf;
420 if (TIFFGetField (tiff_document->
tiff, TIFFTAG_PAGENAME, &label) &&
421 g_utf8_validate (label, -1, NULL)) {
422 return g_strdup (label);
433 if (tiff_document->
tiff)
434 TIFFClose (tiff_document->
tiff);
435 if (tiff_document->
uri)
436 g_free (tiff_document->
uri);
438 G_OBJECT_CLASS (tiff_document_parent_class)->finalize (
object);
444 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
475 if (TIFFSetDirectory (document->
tiff, rc->page->index) != 1)