From dbf6fafd2939f4ff959d2eff4181f880ebd7ceaf Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Sun, 22 May 2005 03:21:31 +0000 Subject: Rough TIFF backend. Sat May 21 23:18:30 2005 Jonathan Blandford * tiff/tiff-document.c: Rough TIFF backend. --- diff --git a/ChangeLog b/ChangeLog index 3b7f0d6..186c5ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sat May 21 23:18:30 2005 Jonathan Blandford + + * tiff/tiff-document.c: Rough TIFF backend. + 2005-05-21 Marco Pesenti Gritti * NEWS: diff --git a/Makefile.am b/Makefile.am index 79f128e..0ccf05b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = lib cut-n-paste backend po help data # Backends -SUBDIRS += pdf ps pixbuf +SUBDIRS += pdf ps pixbuf tiff if ENABLE_DJVU SUBDIRS += djvu diff --git a/configure.ac b/configure.ac index 71c6338..b43a5c0 100644 --- a/configure.ac +++ b/configure.ac @@ -104,6 +104,36 @@ AC_DEFINE_UNQUOTED(ALPHA_PARAMS, "$AA_PARMS", [Anti-aliasing parameters for Ghos AC_MSG_RESULT(Antialiasing parameters for Ghostscript: $AA_PARMS) dnl ======================== End of ggv checks ================================= +dnl ================== tiff checks =================================================== +AC_ARG_WITH(libtiff, + [AC_HELP_STRING([--without-libtiff], + [disable TIFF loader for gdk-pixbuf])]) + +dnl Test for libtiff + if test x$with_libtiff != xno && test -z "$LIBTIFF"; then + AC_CHECK_LIB(tiff, TIFFReadScanline, + [AC_CHECK_HEADER(tiffio.h, + TIFF='tiff'; LIBTIFF='-ltiff', + AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))], + [AC_CHECK_LIB(tiff, TIFFWriteScanline, + [AC_CHECK_HEADER(tiffio.h, + TIFF='tiff'; LIBTIFF='-ltiff -ljpeg -lz', + AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))], + [AC_CHECK_LIB(tiff34, TIFFFlushData, + [AC_CHECK_HEADER(tiffio.h, + TIFF='tiff'; LIBTIFF='-ltiff34 -ljpeg -lz', + AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))], + AC_MSG_WARN(*** TIFF loader will not be built (TIFF library not found) ***), -ljpeg -lz -lm)], -ljpeg -lz -lm)], -lm) + fi + + if test x$with_libtiff != xno && test -z "$LIBTIFF"; then + AC_MSG_ERROR([ +*** Checks for TIFF loader failed. You can build without it by passing +*** --without-libtiff to configure ]) + fi +AC_SUBST(LIBTIFF) +dnl ================== end of tiff checks ============================================ + dnl ================== djvu checks =================================================== AC_ARG_ENABLE(djvu, @@ -239,6 +269,7 @@ data/evince.desktop.in lib/Makefile pdf/Makefile pixbuf/Makefile +tiff/Makefile ps/Makefile djvu/Makefile dvi/Makefile diff --git a/shell/Makefile.am b/shell/Makefile.am index 032735d..43279e5 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -10,6 +10,7 @@ INCLUDES= \ -I$(top_srcdir)/backend \ -I$(top_srcdir)/pdf \ -I$(top_srcdir)/pixbuf \ + -I$(top_srcdir)/tiff \ -I$(top_srcdir)/ps \ -I$(top_srcdir)/djvu \ -I$(top_srcdir)/dvi \ @@ -29,6 +30,7 @@ libevbackendfactory_la_SOURCES= \ libevbackendfactory_la_LIBADD = \ $(top_builddir)/pdf/libpdfdocument.la \ $(top_builddir)/pixbuf/libpixbufdocument.la \ + $(top_builddir)/tiff/libtiffdocument.la \ $(top_builddir)/ps/libgtkgs.la \ $(top_builddir)/backend/libevbackend.la \ $(NULL) @@ -84,6 +86,7 @@ evince_SOURCES= \ evince_LDADD= \ $(SHELL_LIBS) \ + $(LIBTIFF) \ $(top_builddir)/cut-n-paste/recent-files/librecent.la \ $(top_builddir)/cut-n-paste/zoom-control/libephymisc.la \ $(top_builddir)/cut-n-paste/zoom-control/libephywidgets.la \ diff --git a/shell/ev-document-types.c b/shell/ev-document-types.c index a373d18..b39cfd7 100644 --- a/shell/ev-document-types.c +++ b/shell/ev-document-types.c @@ -27,6 +27,7 @@ /* The various document type backends: */ #include "ev-poppler.h" #include "pixbuf-document.h" +#include "tiff-document.h" #include "ps-document.h" #ifdef ENABLE_DVI #include "dvi-document.h" @@ -56,6 +57,9 @@ const EvDocumentType document_types[] = { {"application/x-gzpostscript", ps_document_get_type}, {"image/x-eps", ps_document_get_type}, + /* Tiff: */ + {"image/tiff", tiff_document_get_type}, + #ifdef ENABLE_DJVU /* djvu: */ {"image/vnd.djvu", djvu_document_get_type}, diff --git a/thumbnailer/Makefile.am b/thumbnailer/Makefile.am index f3a2175..ea9dc34 100644 --- a/thumbnailer/Makefile.am +++ b/thumbnailer/Makefile.am @@ -22,6 +22,7 @@ evince_thumbnailer_SOURCES= \ evince_thumbnailer_LDADD= \ $(THUMBNAILER_LIBS) \ + $(LIBTIFF) \ $(top_builddir)/lib/libev.la \ $(top_builddir)/shell/libevbackendfactory.la \ $(NULL) diff --git a/tiff/.cvsignore b/tiff/.cvsignore new file mode 100644 index 0000000..3dda729 --- /dev/null +++ b/tiff/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/tiff/Makefile.am b/tiff/Makefile.am new file mode 100644 index 0000000..ce4b8bd --- /dev/null +++ b/tiff/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/backend \ + $(GTK_CFLAGS) \ + -ltiff \ + -DDATADIR=\""$(datadir)"\" + +noinst_LTLIBRARIES = libtiffdocument.la + +libtiffdocument_la_SOURCES = \ + tiff-document.c \ + tiff-document.h diff --git a/tiff/tiff-document.c b/tiff/tiff-document.c new file mode 100644 index 0000000..5c8cc8d --- /dev/null +++ b/tiff/tiff-document.c @@ -0,0 +1,304 @@ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2005, Jonathan Blandford + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* FIXME: Shoudl probably buffer calls to libtiff with TIFFSetWarningHandler + */ +#include "tiffio.h" +#include "tiff-document.h" +#include "ev-document-thumbnails.h" +#include "ev-document-misc.h" + +struct _TiffDocumentClass +{ + GObjectClass parent_class; +}; + +struct _TiffDocument +{ + GObject parent_instance; + + TIFF *tiff; + gint n_pages; +}; + +typedef struct _TiffDocumentClass TiffDocumentClass; + +static void tiff_document_document_iface_init (EvDocumentIface *iface); +static void tiff_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); + +G_DEFINE_TYPE_WITH_CODE (TiffDocument, tiff_document, G_TYPE_OBJECT, + { G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT, + tiff_document_document_iface_init); + G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, + tiff_document_document_thumbnails_iface_init); + }); + +static TIFFErrorHandler orig_error_handler = NULL; +static TIFFErrorHandler orig_warning_handler = NULL; + +static void +push_handlers (void) +{ + orig_error_handler = TIFFSetErrorHandler (NULL); + orig_warning_handler = TIFFSetWarningHandler (NULL); +} + +static void +pop_handlers (void) +{ + TIFFSetErrorHandler (orig_error_handler); + TIFFSetWarningHandler (orig_warning_handler); +} + +static gboolean +tiff_document_load (EvDocument *document, + const char *uri, + GError **error) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + gchar *filename; + TIFF *tiff; + + push_handlers (); + /* FIXME: We could actually load uris */ + filename = g_filename_from_uri (uri, NULL, error); + if (!filename) + { + pop_handlers (); + return FALSE; + } + + tiff = TIFFOpen (filename, "r"); + if (tiff) + { + guint32 w, h; + + TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); + } + if (!tiff) + { + pop_handlers (); + return FALSE; + } + tiff_document->tiff = tiff; + + pop_handlers (); + return TRUE; +} + +static gboolean +tiff_document_save (EvDocument *document, + const char *uri, + GError **error) +{ + return FALSE; +} + +static int +tiff_document_get_n_pages (EvDocument *document) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + + g_return_val_if_fail (TIFF_IS_DOCUMENT (document), 0); + g_return_val_if_fail (tiff_document->tiff != NULL, 0); + + if (tiff_document->n_pages == -1) + { + push_handlers (); + tiff_document->n_pages = 0; + do + { + tiff_document->n_pages ++; + } + while (TIFFReadDirectory (tiff_document->tiff)); + pop_handlers (); + } + + return tiff_document->n_pages; +} + +static void +tiff_document_get_page_size (EvDocument *document, + int page, + double *width, + double *height) +{ + guint32 w, h; + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + + g_return_if_fail (TIFF_IS_DOCUMENT (document)); + g_return_if_fail (tiff_document->tiff != NULL); + + push_handlers (); + if (TIFFSetDirectory (tiff_document->tiff, page) != 1) + { + pop_handlers (); + return; + } + + TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH, &h); + + *width = w; + *height = h; + pop_handlers (); +} + +static GdkPixbuf * +tiff_document_render_pixbuf (EvDocument *document, int page, double scale) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + int width, height; + GdkPixbuf *pixbuf; + GdkPixbuf *scaled_pixbuf; + + g_return_val_if_fail (TIFF_IS_DOCUMENT (document), 0); + g_return_val_if_fail (tiff_document->tiff != NULL, 0); + + push_handlers (); + if (TIFFSetDirectory (tiff_document->tiff, page) != 1) + { + pop_handlers (); + return NULL; + } + + TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH, &height); + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); + TIFFReadRGBAImageOriented (tiff_document->tiff, width, height, (uint32 *)gdk_pixbuf_get_pixels (pixbuf), ORIENTATION_TOPLEFT, 1); + pop_handlers (); + + scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, + width * scale, + height * scale, + GDK_INTERP_BILINEAR); + g_object_unref (pixbuf); + + return scaled_pixbuf; +} + +static void +tiff_document_finalize (GObject *object) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (object); + + TIFFClose (tiff_document->tiff); + + G_OBJECT_CLASS (tiff_document_parent_class)->finalize (object); +} + +static void +tiff_document_class_init (TiffDocumentClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = tiff_document_finalize; +} + +static gboolean +tiff_document_can_get_text (EvDocument *document) +{ + return FALSE; +} + +static EvDocumentInfo * +tiff_document_get_info (EvDocument *document) +{ + EvDocumentInfo *info; + + info = g_new0 (EvDocumentInfo, 1); + info->fields_mask = 0; + + return info; +} + +static void +tiff_document_document_iface_init (EvDocumentIface *iface) +{ + iface->load = tiff_document_load; + iface->save = tiff_document_save; + iface->can_get_text = tiff_document_can_get_text; + iface->get_n_pages = tiff_document_get_n_pages; + iface->get_page_size = tiff_document_get_page_size; + iface->render_pixbuf = tiff_document_render_pixbuf; + iface->get_info = tiff_document_get_info; +} + +static GdkPixbuf * +tiff_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, + gint page, + gint size, + gboolean border) +{ + GdkPixbuf *pixbuf; + gdouble w, h; + + tiff_document_get_page_size (EV_DOCUMENT (document), + page, + &w, &h); + + pixbuf = tiff_document_render_pixbuf (EV_DOCUMENT (document), + page, + size/w); + + if (border) + { + GdkPixbuf *tmp_pixbuf = pixbuf; + pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, tmp_pixbuf); + g_object_unref (tmp_pixbuf); + } + + return pixbuf; +} + +static void +tiff_document_thumbnails_get_dimensions (EvDocumentThumbnails *document, + gint page, + gint suggested_width, + gint *width, + gint *height) +{ + gdouble page_ratio; + gdouble w, h; + + tiff_document_get_page_size (EV_DOCUMENT (document), + page, + &w, &h); + g_return_if_fail (w > 0); + page_ratio = h/w; + *width = suggested_width; + *height = (gint) (suggested_width * page_ratio); +} + +static void +tiff_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface) +{ + iface->get_thumbnail = tiff_document_thumbnails_get_thumbnail; + iface->get_dimensions = tiff_document_thumbnails_get_dimensions; +} + + +static void +tiff_document_init (TiffDocument *tiff_document) +{ + tiff_document->n_pages = -1; +} diff --git a/tiff/tiff-document.h b/tiff/tiff-document.h new file mode 100644 index 0000000..bdf0e29 --- /dev/null +++ b/tiff/tiff-document.h @@ -0,0 +1,38 @@ + +/* pdfdocument.h: Implementation of EvDocument for tiffs + * Copyright (C) 2005, Jonathan Blandford + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __TIFF_DOCUMENT_H__ +#define __TIFF_DOCUMENT_H__ + +#include "ev-document.h" + +G_BEGIN_DECLS + +#define TIFF_TYPE_DOCUMENT (tiff_document_get_type ()) +#define TIFF_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIFF_TYPE_DOCUMENT, TiffDocument)) +#define TIFF_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIFF_TYPE_DOCUMENT)) + +typedef struct _TiffDocument TiffDocument; + +TiffDocument *tiff_document_new (void); +GType tiff_document_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __TIFF_DOCUMENT_H__ */ -- cgit v0.9.1