X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=tiff%2Ftiff-document.c;h=f2ed498651d58e51232608a3b474025ead415e0e;hb=6283a64c4012cf257f62b4b12566191e35309d18;hp=5c8cc8d4bac0ea3c22e6d4de64206ba387b2467d;hpb=dbf6fafd2939f4ff959d2eff4181f880ebd7ceaf;p=evince.git diff --git a/tiff/tiff-document.c b/tiff/tiff-document.c index 5c8cc8d4..f2ed4986 100644 --- a/tiff/tiff-document.c +++ b/tiff/tiff-document.c @@ -36,6 +36,7 @@ struct _TiffDocument TIFF *tiff; gint n_pages; + EvOrientation orientation; }; typedef struct _TiffDocumentClass TiffDocumentClass; @@ -157,43 +158,124 @@ tiff_document_get_page_size (EvDocument *document, TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH, &h); - *width = w; - *height = h; + if (tiff_document->orientation == EV_ORIENTATION_PORTRAIT || + tiff_document->orientation == EV_ORIENTATION_UPSIDEDOWN) { + *width = w; + *height = h; + } else { + *width = h; + *height = w; + } pop_handlers (); } +static EvOrientation +tiff_document_get_orientation (EvDocument *document) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + + return tiff_document->orientation; +} + +static void +tiff_document_set_orientation (EvDocument *document, + EvOrientation orientation) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + + tiff_document->orientation = orientation; +} + +static GdkPixbuf * +rotate_pixbuf (EvDocument *document, GdkPixbuf *pixbuf) +{ + TiffDocument *tiff_document = TIFF_DOCUMENT (document); + + switch (tiff_document->orientation) + { + case EV_ORIENTATION_LANDSCAPE: + return gdk_pixbuf_rotate_simple (pixbuf, 90); + case EV_ORIENTATION_UPSIDEDOWN: + return gdk_pixbuf_rotate_simple (pixbuf, 180); + case EV_ORIENTATION_SEASCAPE: + return gdk_pixbuf_rotate_simple (pixbuf, 270); + default: + return g_object_ref (pixbuf); + } +} + static GdkPixbuf * -tiff_document_render_pixbuf (EvDocument *document, int page, double scale) +tiff_document_render_pixbuf (EvDocument *document, + EvRenderContext *rc) { TiffDocument *tiff_document = TIFF_DOCUMENT (document); int width, height; + gint rowstride, bytes; + guchar *pixels = NULL; GdkPixbuf *pixbuf; GdkPixbuf *scaled_pixbuf; + GdkPixbuf *rotated_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) + if (TIFFSetDirectory (tiff_document->tiff, rc->page) != 1) { pop_handlers (); return NULL; } - TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH, &height); + if (!TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGEWIDTH, &width)) + { + pop_handlers (); + return NULL; + } + + if (! TIFFGetField (tiff_document->tiff, TIFFTAG_IMAGELENGTH, &height)) + { + pop_handlers (); + return NULL; + } + + pop_handlers (); + + /* Sanity check the doc */ + if (width <= 0 || height <= 0) + return NULL; + + rowstride = width * 4; + if (rowstride / 4 != width) + /* overflow */ + return NULL; + + bytes = height * rowstride; + if (bytes / rowstride != height) + /* overflow */ + return NULL; + + pixels = g_try_malloc (bytes); + if (!pixels) + return NULL; + + pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE, 8, + width, height, rowstride, + (GdkPixbufDestroyNotify) g_free, NULL); 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, + width * rc->scale, + height * rc->scale, GDK_INTERP_BILINEAR); g_object_unref (pixbuf); - return scaled_pixbuf; + rotated_pixbuf = rotate_pixbuf (document, scaled_pixbuf); + g_object_unref (scaled_pixbuf); + + return rotated_pixbuf; } static void @@ -241,6 +323,8 @@ tiff_document_document_iface_init (EvDocumentIface *iface) iface->get_page_size = tiff_document_get_page_size; iface->render_pixbuf = tiff_document_render_pixbuf; iface->get_info = tiff_document_get_info; + iface->get_orientation = tiff_document_get_orientation; + iface->set_orientation = tiff_document_set_orientation; } static GdkPixbuf * @@ -249,6 +333,7 @@ tiff_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, gint size, gboolean border) { + EvRenderContext *rc; GdkPixbuf *pixbuf; gdouble w, h; @@ -256,9 +341,9 @@ tiff_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, page, &w, &h); - pixbuf = tiff_document_render_pixbuf (EV_DOCUMENT (document), - page, - size/w); + rc = ev_render_context_new (EV_ORIENTATION_PORTRAIT, page, size/w); + pixbuf = tiff_document_render_pixbuf (EV_DOCUMENT (document), rc); + g_object_unref (G_OBJECT (rc)); if (border) { @@ -301,4 +386,5 @@ static void tiff_document_init (TiffDocument *tiff_document) { tiff_document->n_pages = -1; + tiff_document->orientation = EV_ORIENTATION_PORTRAIT; }