commit 1936240171c2608af9eb417bf715aa767826d3e0
parent 37f727d780b69645f7811e255bca2cdbba40138a
Author: Colin Leroy <colin@colino.net>
Date: Mon, 29 Aug 2011 08:12:13 +0000
2011-08-29 [colin] 3.7.10cvs3
* src/image_viewer.c
* src/textview.c
* src/gtk/gtkutils.c
* src/gtk/gtkutils.h
Handle EXIF orientation in images (both in textview's
preview and image viewer)
Diffstat:
7 files changed, 141 insertions(+), 35 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,12 @@
+2011-08-29 [colin] 3.7.10cvs3
+
+ * src/image_viewer.c
+ * src/textview.c
+ * src/gtk/gtkutils.c
+ * src/gtk/gtkutils.h
+ Handle EXIF orientation in images (both in textview's
+ preview and image viewer)
+
2011-08-28 [paul] 3.7.10cvs2
* src/prefs_common.c
diff --git a/PATCHSETS b/PATCHSETS
@@ -4206,3 +4206,4 @@
( cvs diff -u -r 1.9.2.22 -r 1.9.2.23 po/cs.po; cvs diff -u -r 1.42.2.54 -r 1.42.2.55 po/fr.po; cvs diff -u -r 1.5.2.19 -r 1.5.2.20 po/hu.po; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 po/lt.po; cvs diff -u -r 1.50.2.41 -r 1.50.2.42 po/pt_BR.po; cvs diff -u -r 1.2.2.33 -r 1.2.2.34 po/sk.po; ) > 3.7.9cvs52.patchset
( cvs diff -u -r 1.53.2.37 -r 1.53.2.38 po/POTFILES.in; cvs diff -u -r 1.4.2.38 -r 1.4.2.39 src/common/ssl_certificate.c; cvs diff -u -r 1.1.4.114 -r 1.1.4.115 src/etpan/imap-thread.c; cvs diff -u -r 1.1.2.16 -r 1.1.2.17 src/etpan/nntp-thread.c; ) > 3.7.10cvs1.patchset
( cvs diff -u -r 1.204.2.201 -r 1.204.2.202 src/prefs_common.c; cvs diff -u -r 1.103.2.132 -r 1.103.2.133 src/prefs_common.h; cvs diff -u -r 1.395.2.429 -r 1.395.2.430 src/summaryview.c; ) > 3.7.10cvs2.patchset
+( cvs diff -u -r 1.1.2.29 -r 1.1.2.30 src/image_viewer.c; cvs diff -u -r 1.96.2.231 -r 1.96.2.232 src/textview.c; cvs diff -u -r 1.5.2.94 -r 1.5.2.95 src/gtk/gtkutils.c; cvs diff -u -r 1.4.2.56 -r 1.4.2.57 src/gtk/gtkutils.h; ) > 3.7.10cvs3.patchset
diff --git a/configure.ac b/configure.ac
@@ -12,7 +12,7 @@ MINOR_VERSION=7
MICRO_VERSION=10
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=2
+EXTRA_VERSION=3
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
diff --git a/src/gtk/gtkutils.c b/src/gtk/gtkutils.c
@@ -1864,3 +1864,108 @@ void gtkut_widget_set_has_window(GtkWidget *widget, gboolean has_window)
GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW);
#endif
}
+
+/**
+ * Load a pixbuf fitting inside the specified size. EXIF orientation is
+ * respected if available.
+ *
+ * @param[in] filename the file to load
+ * @param[in] box_width the max width (-1 for no resize)
+ * @param[in] box_height the max height (-1 for no resize)
+ * @param[out] error the possible load error
+ *
+ * @return a GdkPixbuf
+ */
+GdkPixbuf *claws_load_pixbuf_fitting(GdkPixbuf *src_pixbuf, int box_width,
+ int box_height)
+{
+ gint w, h, orientation, angle;
+ gint avail_width, avail_height;
+ gboolean flip_horiz, flip_vert;
+ const gchar *orient_str;
+ GdkPixbuf *pixbuf, *t_pixbuf;
+
+ pixbuf = src_pixbuf;
+
+ if (pixbuf == NULL)
+ return NULL;
+
+ angle = 0;
+ flip_horiz = flip_vert = FALSE;
+
+ /* EXIF orientation */
+ orient_str = gdk_pixbuf_get_option(pixbuf, "orientation");
+ if (orient_str != NULL && *orient_str != '\0') {
+ orientation = atoi(orient_str);
+ switch(orientation) {
+ /* See EXIF standard for different values */
+ case 1: break;
+ case 2: flip_horiz = 1;
+ break;
+ case 3: angle = 180;
+ break;
+ case 4: flip_vert = 1;
+ break;
+ case 5: angle = 90;
+ flip_horiz = 1;
+ break;
+ case 6: angle = 270;
+ break;
+ case 7: angle = 90;
+ flip_vert = 1;
+ break;
+ case 8: angle = 90;
+ break;
+ }
+ }
+
+ w = gdk_pixbuf_get_width(pixbuf);
+ h = gdk_pixbuf_get_height(pixbuf);
+
+ if (angle == 90 || angle == 270) {
+ avail_height = box_width;
+ avail_width = box_height;
+ } else {
+ avail_width = box_width;
+ avail_height = box_height;
+ }
+
+ /* Scale first */
+ if (box_width != -1 && box_height != -1 && avail_width - 100 > 0) {
+ if (w > avail_width) {
+ h = (avail_width * h) / w;
+ w = avail_width;
+ }
+ if (h > avail_height) {
+ w = (avail_height * w) / h;
+ h = avail_height;
+ }
+ t_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
+ w, h, GDK_INTERP_BILINEAR);
+ g_object_unref(pixbuf);
+ pixbuf = t_pixbuf;
+ }
+
+ /* Rotate if needed */
+ if (angle != 0) {
+ t_pixbuf = gdk_pixbuf_rotate_simple(pixbuf, angle);
+ g_object_unref(pixbuf);
+ pixbuf = t_pixbuf;
+ }
+
+ /* Flip horizontally if needed */
+ if (flip_horiz) {
+ t_pixbuf = gdk_pixbuf_flip(pixbuf, TRUE);
+ g_object_unref(pixbuf);
+ pixbuf = t_pixbuf;
+ }
+
+ /* Flip vertically if needed */
+ if (flip_vert) {
+ t_pixbuf = gdk_pixbuf_flip(pixbuf, FALSE);
+ g_object_unref(pixbuf);
+ pixbuf = t_pixbuf;
+ }
+
+ return pixbuf;
+}
diff --git a/src/gtk/gtkutils.h b/src/gtk/gtkutils.h
@@ -210,6 +210,8 @@ gboolean gtkut_list_view_select_row(GtkWidget *list, gint row);
GtkUIManager *gtkut_create_ui_manager(void);
GtkUIManager *gtkut_ui_manager(void);
+GdkPixbuf *claws_load_pixbuf_fitting(GdkPixbuf *pixbuf, int box_width,
+ int box_height);
gint
claws_input_add (gint source,
GdkInputCondition condition,
diff --git a/src/image_viewer.c b/src/image_viewer.c
@@ -71,28 +71,24 @@ static void image_viewer_load_file(ImageViewer *imageviewer, const gchar *imgfil
{
GdkPixbufAnimation *animation = NULL;
GdkPixbuf *pixbuf = NULL;
- gint avail_width;
- gint avail_height;
GError *error = NULL;
debug_print("image_viewer_show_mimepart\n");
- if (!imageviewer->resize_img) {
- animation = gdk_pixbuf_animation_new_from_file(imgfile, &error);
- } else {
- gint w, h;
- gdk_pixbuf_get_file_info(imgfile, &w, &h);
- avail_width = imageviewer->notebook->parent->allocation.width;
- avail_height = imageviewer->notebook->parent->allocation.height;
- if (avail_width > 8) avail_width -= 8;
- if (avail_height > 8) avail_height -= 8;
- if (avail_width - 100 > 0 &&
- (w > avail_width || h > avail_height)) {
- pixbuf = gdk_pixbuf_new_from_file_at_scale(imgfile, avail_width,
- avail_height, TRUE, &error);
- } else {
- animation = gdk_pixbuf_animation_new_from_file(imgfile, &error);
- }
+ animation = gdk_pixbuf_animation_new_from_file(imgfile, &error);
+ if (gdk_pixbuf_animation_is_static_image(animation)
+ || imageviewer->resize_img) {
+ pixbuf = gdk_pixbuf_animation_get_static_image(animation);
+ g_object_ref(pixbuf);
+ g_object_unref(animation);
+ animation = NULL;
+
+ if (imageviewer->resize_img)
+ pixbuf = claws_load_pixbuf_fitting(pixbuf,
+ imageviewer->notebook->parent->allocation.width,
+ imageviewer->notebook->parent->allocation.height);
+ else
+ pixbuf = claws_load_pixbuf_fitting(pixbuf, -1, -1);
}
if (error && !pixbuf && !animation) {
diff --git a/src/textview.c b/src/textview.c
@@ -679,8 +679,6 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
if (mimeinfo->type == MIMETYPE_IMAGE &&
prefs_common.inline_img ) {
GdkPixbuf *pixbuf;
- gint avail_width;
- gint avail_height;
GError *error = NULL;
gchar *filename;
ClickableText *uri;
@@ -697,20 +695,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
return;
}
- if (!prefs_common.resize_img) {
- pixbuf = gdk_pixbuf_new_from_file(filename, &error);
- } else {
- gint w, h;
- gdk_pixbuf_get_file_info(filename, &w, &h);
- avail_width = textview->scrolledwin->allocation.width;
- avail_height = textview->scrolledwin->allocation.height;
- if (avail_width - 100 > 0 &&
- (w > avail_width || h > avail_height))
- pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
- avail_width, avail_height, TRUE, &error);
- else
- pixbuf = gdk_pixbuf_new_from_file(filename, &error);
- }
+ pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if (textview->stop_loading) {
return;
}
@@ -725,6 +710,14 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
return;
}
+ pixbuf = claws_load_pixbuf_fitting(pixbuf,
+ textview->scrolledwin->allocation.width,
+ textview->scrolledwin->allocation.height);
+
+ if (textview->stop_loading) {
+ return;
+ }
+
uri_str = g_filename_to_uri(filename, NULL, NULL);
if (uri_str) {
uri = g_new0(ClickableText, 1);