Merge lp:~jpakkane/thumbnailer/manual-orient into lp:thumbnailer

Proposed by Jussi Pakkanen
Status: Merged
Merged at revision: 73
Proposed branch: lp:~jpakkane/thumbnailer/manual-orient
Merge into: lp:thumbnailer
Diff against target: 139 lines (+58/-2)
4 files modified
CMakeLists.txt (+1/-1)
debian/control (+1/-0)
src/imagescaler.cpp (+37/-1)
tests/basic.cpp (+19/-0)
To merge this branch: bzr merge lp:~jpakkane/thumbnailer/manual-orient
Reviewer Review Type Date Requested Status
James Henstridge Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+209407@code.launchpad.net

Commit message

Reorient images manually to work around a bug in GdkPixbuf.

Description of the change

Reorient images manually to work around a bug in GdkPixbuf.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

Looks good. Hopefully the workaround can be removed at some point.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-12-10 09:08:21 +0000
3+++ CMakeLists.txt 2014-03-05 09:32:01 +0000
4@@ -30,7 +30,7 @@
5
6 include(FindPkgConfig)
7 pkg_check_modules(GST_DEPS REQUIRED gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-pbutils-1.0 gstreamer-app-1.0)
8-pkg_check_modules(IMG_DEPS REQUIRED gdk-pixbuf-2.0)
9+pkg_check_modules(IMG_DEPS REQUIRED gdk-pixbuf-2.0 libexif)
10
11 include_directories(${GST_DEPS_INCLUDE_DIRS})
12 include_directories(${IMG_DEPS_INCLUDE_DIRS})
13
14=== modified file 'debian/control'
15--- debian/control 2013-09-30 15:55:07 +0000
16+++ debian/control 2014-03-05 09:32:01 +0000
17@@ -10,6 +10,7 @@
18 libgstreamer-plugins-base1.0-dev,
19 libgstreamer1.0-dev,
20 shared-mime-info,
21+ libexif-dev,
22 Homepage: https://launchpad.net/thumbnailer
23 # if you don't have have commit access to this branch but would like to upload
24 # directly to Ubuntu, don't worry: your changes will be merged back into the
25
26=== modified file 'src/imagescaler.cpp'
27--- src/imagescaler.cpp 2014-02-25 09:26:09 +0000
28+++ src/imagescaler.cpp 2014-03-05 09:32:01 +0000
29@@ -19,6 +19,7 @@
30 #include<internal/imagescaler.h>
31 #include<internal/gobj_memory.h>
32 #include<gdk-pixbuf/gdk-pixbuf.h>
33+#include<libexif/exif-loader.h>
34 #include<memory>
35 #include<stdexcept>
36 #include<sys/stat.h>
37@@ -49,6 +50,37 @@
38 }
39 }
40
41+static GdkPixbuf* fix_orientation(const char *infile, GdkPixbuf *src) {
42+ ExifLoader *l;
43+ l = exif_loader_new();
44+ ExifData *ed;
45+ exif_loader_write_file(l, infile);
46+ ed = exif_loader_get_data(l);
47+ exif_loader_unref(l);
48+ GdkPixbuf *rot = nullptr;
49+ // Have to do this manually because of
50+ // https://bugzilla.gnome.org/show_bug.cgi?id=725582
51+ if(ed) {
52+ ExifEntry *e = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
53+ int orientation = exif_get_short(e->data, exif_data_get_byte_order(ed));
54+ if(orientation == 6) {
55+ rot = gdk_pixbuf_rotate_simple(src, GDK_PIXBUF_ROTATE_CLOCKWISE);
56+ } else if (orientation == 8) {
57+ rot = gdk_pixbuf_rotate_simple(src, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
58+ } else if (orientation == 3) {
59+ rot = gdk_pixbuf_rotate_simple(src, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
60+ } else {
61+ // We don't do mirrored images, at least not yet.
62+ }
63+ }
64+ if(!rot) {
65+ // This entire function should only contain this call, really.
66+ rot = gdk_pixbuf_apply_embedded_orientation(src);
67+ }
68+ exif_data_unref(ed);
69+ return rot;
70+}
71+
72 class ImageScalerPrivate {
73 };
74
75@@ -68,12 +100,16 @@
76 GError *err = nullptr;
77 string ofilename_tmp = ofilename;
78 ofilename_tmp += ".tmp." + to_string(rnd());
79- unique_gobj<GdkPixbuf> src(gdk_pixbuf_new_from_file(ifilename.c_str(), &err));
80+ unique_gobj<GdkPixbuf> orig(gdk_pixbuf_new_from_file(ifilename.c_str(), &err));
81 if(err) {
82 string msg = err->message;
83 g_error_free(err);
84 throw runtime_error(msg);
85 }
86+ unique_gobj<GdkPixbuf> src(fix_orientation(ifilename.c_str(), orig.get()));
87+ if(!src) {
88+ throw runtime_error("Unknown error reorienting image.");
89+ }
90 const int w = gdk_pixbuf_get_width(src.get());
91 const int h = gdk_pixbuf_get_height(src.get());
92 if(w == 0 || h == 0) {
93
94=== modified file 'tests/basic.cpp'
95--- tests/basic.cpp 2014-02-20 17:01:39 +0000
96+++ tests/basic.cpp 2014-03-05 09:32:01 +0000
97@@ -23,6 +23,7 @@
98 #include<gdk-pixbuf/gdk-pixbuf.h>
99
100 #define TESTIMAGE TESTDATADIR "/testimage.jpg"
101+#define ROTTESTIMAGE TESTDATADIR "/testrotate.jpg"
102 #define TESTVIDEO TESTDATADIR "/testvideo.ogg"
103
104 using namespace std;
105@@ -79,6 +80,23 @@
106 file_test(tn, imfile);
107 }
108
109+void rotate_test() {
110+ Thumbnailer tn;
111+ string imfile(ROTTESTIMAGE);
112+ int w, h;
113+ assert(file_exists(imfile));
114+ string thumbfile = tn.get_thumbnail(imfile, TN_SIZE_LARGE);
115+ unlink(thumbfile.c_str());
116+ assert(!file_exists(thumbfile));
117+ string thumbfile2 = tn.get_thumbnail(imfile, TN_SIZE_LARGE);
118+ assert(thumbfile == thumbfile2);
119+ assert(file_exists(thumbfile));
120+ assert(gdk_pixbuf_get_file_info(imfile.c_str(), &w, &h));
121+ assert(w > h); // gdk_pixbuf does not reorient images automatically.
122+ assert(gdk_pixbuf_get_file_info(thumbfile.c_str(), &w, &h));
123+ assert(h > w); // Has the orientation been straightened during scaling?
124+}
125+
126 void video_test() {
127 Thumbnailer tn;
128 string videofile(TESTVIDEO);
129@@ -155,6 +173,7 @@
130 #else
131 trivial_test();
132 image_test();
133+ rotate_test();
134 video_test();
135 video_original_test();
136 size_test();
137
138=== added file 'tests/testrotate.jpg'
139Binary files tests/testrotate.jpg 1970-01-01 00:00:00 +0000 and tests/testrotate.jpg 2014-03-05 09:32:01 +0000 differ

Subscribers

People subscribed via source and target branches

to all changes: