Merge lp:~djaler1/pantheon-photos/fix-1302900 into lp:~pantheon-photos/pantheon-photos/trunk

Proposed by Kirill Romanov
Status: Merged
Approved by: Danielle Foré
Approved revision: 3098
Merged at revision: 3097
Proposed branch: lp:~djaler1/pantheon-photos/fix-1302900
Merge into: lp:~pantheon-photos/pantheon-photos/trunk
Diff against target: 284 lines (+205/-2)
4 files modified
data/org.pantheon.photos-viewer.desktop.in.in (+1/-1)
src/CMakeLists.txt (+1/-0)
src/photos/GifSupport.vala (+185/-0)
src/photos/PhotoFileFormat.vala (+18/-1)
To merge this branch: bzr merge lp:~djaler1/pantheon-photos/fix-1302900
Reviewer Review Type Date Requested Status
Danielle Foré Needs Fixing
Review via email: mp+313936@code.launchpad.net

Commit message

Add Gif support

Description of the change

To post a comment you must log in.
Revision history for this message
Danielle Foré (danrabbit) wrote :

Don't forget to add gif as a supported mimetype in the .desktop file ;)

review: Needs Fixing
Revision history for this message
Danielle Foré (danrabbit) wrote :

I can confirm this add gif support to Photo Viewer, but I can't confirm that it makes them show in the photos library

3098. By Kirill Romanov

Added mimetype in .desktop file, fixed import gifs in library

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/org.pantheon.photos-viewer.desktop.in.in'
--- data/org.pantheon.photos-viewer.desktop.in.in 2016-08-28 20:08:59 +0000
+++ data/org.pantheon.photos-viewer.desktop.in.in 2017-01-01 21:59:12 +0000
@@ -8,7 +8,7 @@
8NoDisplay=true8NoDisplay=true
9Type=Application9Type=Application
10StartupNotify=true10StartupNotify=true
11MimeType=image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-3fr;image/x-adobe-dng;image/x-arw;image/x-bay;image/x-bmp;image/x-canon-cr2;image/x-canon-crw;image/x-cap;image/x-cr2;image/x-crw;image/x-dcr;image/x-dcraw;image/x-dcs;image/x-dng;image/x-drf;image/x-eip;image/x-erf;image/x-fff;image/x-fuji-raf;image/x-iiq;image/x-k25;image/x-kdc;image/x-mef;image/x-minolta-mrw;image/x-mos;image/x-mrw;image/x-nef;image/x-nikon-nef;image/x-nrw;image/x-olympus-orf;image/x-orf;image/x-panasonic-raw;image/x-pef;image/x-pentax-pef;image/x-png;image/x-ptx;image/x-pxn;image/x-r3d;image/x-raf;image/x-raw;image/x-rw2;image/x-rwl;image/x-rwz;image/x-sigma-x3f;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-sr2;image/x-srf;image/x-x3f;11MimeType=image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/gif;image/x-3fr;image/x-adobe-dng;image/x-arw;image/x-bay;image/x-bmp;image/x-canon-cr2;image/x-canon-crw;image/x-cap;image/x-cr2;image/x-crw;image/x-dcr;image/x-dcraw;image/x-dcs;image/x-dng;image/x-drf;image/x-eip;image/x-erf;image/x-fff;image/x-fuji-raf;image/x-iiq;image/x-k25;image/x-kdc;image/x-mef;image/x-minolta-mrw;image/x-mos;image/x-mrw;image/x-nef;image/x-nikon-nef;image/x-nrw;image/x-olympus-orf;image/x-orf;image/x-panasonic-raw;image/x-pef;image/x-pentax-pef;image/x-png;image/x-ptx;image/x-pxn;image/x-r3d;image/x-raf;image/x-raw;image/x-rw2;image/x-rwl;image/x-rwz;image/x-sigma-x3f;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-sr2;image/x-srf;image/x-x3f;
12Categories=Graphics;Viewer;Photography;GNOME;GTK;12Categories=Graphics;Viewer;Photography;GNOME;GTK;
13Actions=AboutDialog;13Actions=AboutDialog;
1414
1515
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2016-11-05 04:17:16 +0000
+++ src/CMakeLists.txt 2017-01-01 21:59:12 +0000
@@ -144,6 +144,7 @@
144144
145 photos/BmpSupport.vala145 photos/BmpSupport.vala
146 photos/GdkSupport.vala146 photos/GdkSupport.vala
147 photos/GifSupport.vala
147 photos/GRaw.vala148 photos/GRaw.vala
148 photos/JfifSupport.vala149 photos/JfifSupport.vala
149 photos/PhotoFileAdapter.vala150 photos/PhotoFileAdapter.vala
150151
=== added file 'src/photos/GifSupport.vala'
--- src/photos/GifSupport.vala 1970-01-01 00:00:00 +0000
+++ src/photos/GifSupport.vala 2017-01-01 21:59:12 +0000
@@ -0,0 +1,185 @@
1/* Copyright 2010-2013 Yorba Foundation
2 *
3 * This software is licensed under the GNU LGPL (version 2.1 or later).
4 * See the COPYING file in this distribution.
5 */
6
7class GifFileFormatProperties : PhotoFileFormatProperties {
8 private static string[] KNOWN_EXTENSIONS = { "gif" };
9 private static string[] KNOWN_MIME_TYPES = { "image/gif" };
10
11 private static GifFileFormatProperties instance = null;
12
13 public static void init () {
14 instance = new GifFileFormatProperties ();
15 }
16
17 public static GifFileFormatProperties get_instance () {
18 return instance;
19 }
20
21 public override PhotoFileFormat get_file_format () {
22 return PhotoFileFormat.GIF;
23 }
24
25 public override PhotoFileFormatFlags get_flags () {
26 return PhotoFileFormatFlags.NONE;
27 }
28
29 public override string get_user_visible_name () {
30 return _ ("GIF");
31 }
32
33 public override string get_default_extension () {
34 return KNOWN_EXTENSIONS[0];
35 }
36
37 public override string[] get_known_extensions () {
38 return KNOWN_EXTENSIONS;
39 }
40
41 public override string get_default_mime_type () {
42 return KNOWN_MIME_TYPES[0];
43 }
44
45 public override string[] get_mime_types () {
46 return KNOWN_MIME_TYPES;
47 }
48}
49
50public class GifSniffer : GdkSniffer {
51 private const uint8[] MAGIC_SEQUENCE_GIF87 = { 71, 73, 70, 56, 55, 97 };
52 private const uint8[] MAGIC_SEQUENCE_GIF89 = { 71, 73, 70, 56, 57, 97 };
53
54 public GifSniffer (File file, PhotoFileSniffer.Options options) {
55 base (file, options);
56 }
57
58 private static bool is_gif_file (File file) throws Error {
59 FileInputStream instream = file.read (null);
60
61 uint8[] file_lead_sequence = new uint8[MAGIC_SEQUENCE_GIF87.length];
62
63 instream.read (file_lead_sequence, null);
64
65 bool is_gif_87 = true;
66
67 for (int i = 0; i < MAGIC_SEQUENCE_GIF87.length; i++) {
68 if (file_lead_sequence[i] != MAGIC_SEQUENCE_GIF87[i]) {
69 is_gif_87 = false;
70 }
71 }
72
73 if (is_gif_87) {
74 return true;
75 } else {
76 instream.seek (0, SeekType.SET);
77
78 file_lead_sequence = new uint8[MAGIC_SEQUENCE_GIF89.length];
79
80 instream.read (file_lead_sequence, null);
81
82 bool is_gif_89 = true;
83
84 for (int i = 0; i < MAGIC_SEQUENCE_GIF89.length; i++) {
85 if (file_lead_sequence[i] != MAGIC_SEQUENCE_GIF89[i]) {
86 is_gif_89 = false;
87 }
88 }
89
90 return is_gif_89;
91 }
92 }
93
94 public override DetectedPhotoInformation? sniff () throws Error {
95 if (!is_gif_file (file))
96 return null;
97
98 DetectedPhotoInformation? detected = base.sniff ();
99
100 if (detected == null) {
101 return null;
102 }
103
104 return (detected.file_format == PhotoFileFormat.GIF) ? detected : null;
105 }
106}
107
108public class GifReader : GdkReader {
109 public GifReader (string filepath) {
110 base (filepath, PhotoFileFormat.GIF);
111 }
112
113 public override Gdk.Pixbuf scaled_read (Dimensions full, Dimensions scaled) throws Error {
114 Gdk.Pixbuf result = null;
115 /* if we encounter a situation where there are two orders of magnitude or more of
116 difference between the full image size and the scaled size, and if the full image
117 size has five or more decimal digits of precision, Gdk.Pixbuf.from_file_at_scale( ) can
118 fail due to what appear to be floating-point round-off issues. This isn't surprising,
119 since 32-bit floats only have 6-7 decimal digits of precision in their mantissa. In
120 this case, we prefetch the image at a larger scale and then downsample it to the
121 desired scale as a post-process step. This short-circuits Gdk.Pixbuf's buggy
122 scaling code. */
123 if (((full.width > 9999) || (full.height > 9999)) && ((scaled.width < 100) ||
124 (scaled.height < 100))) {
125 Dimensions prefetch_dimensions = full.get_scaled_by_constraint (1000,
126 ScaleConstraint.DIMENSIONS);
127
128 result = new Gdk.Pixbuf.from_file_at_scale (get_filepath (), prefetch_dimensions.width,
129 prefetch_dimensions.height, false);
130
131 result = result.scale_simple (scaled.width, scaled.height, Gdk.InterpType.HYPER);
132 } else {
133 result = new Gdk.Pixbuf.from_file_at_scale (get_filepath (), scaled.width,
134 scaled.height, false);
135 }
136
137 return result;
138 }
139}
140
141public class GifFileFormatDriver : PhotoFileFormatDriver {
142 private static GifFileFormatDriver instance = null;
143
144 public static void init () {
145 instance = new GifFileFormatDriver ();
146 GifFileFormatProperties.init ();
147 }
148
149 public static GifFileFormatDriver get_instance () {
150 return instance;
151 }
152
153 public override PhotoFileFormatProperties get_properties () {
154 return GifFileFormatProperties.get_instance ();
155 }
156
157 public override PhotoFileReader create_reader (string filepath) {
158 return new GifReader (filepath);
159 }
160
161 public override bool can_write_image () {
162 return false;
163 }
164
165 public override bool can_write_metadata () {
166 return false;
167 }
168
169 public override PhotoFileWriter? create_writer (string filepath) {
170 return null;
171 }
172
173 public override PhotoFileMetadataWriter? create_metadata_writer (string filepath) {
174 return null;
175 }
176
177 public override PhotoFileSniffer create_sniffer (File file, PhotoFileSniffer.Options options) {
178 return new GifSniffer (file, options);
179 }
180
181 public override PhotoMetadata create_metadata () {
182 return new PhotoMetadata ();
183 }
184}
185
0186
=== modified file 'src/photos/PhotoFileFormat.vala'
--- src/photos/PhotoFileFormat.vala 2014-08-08 21:13:09 +0000
+++ src/photos/PhotoFileFormat.vala 2017-01-01 21:59:12 +0000
@@ -63,12 +63,13 @@
63 PNG,63 PNG,
64 TIFF,64 TIFF,
65 BMP,65 BMP,
66 GIF,
66 UNKNOWN;67 UNKNOWN;
6768
68 // This is currently listed in the order of detection, that is, the file is examined from69 // This is currently listed in the order of detection, that is, the file is examined from
69 // left to right. (See PhotoFileInterrogator.)70 // left to right. (See PhotoFileInterrogator.)
70 public static PhotoFileFormat[] get_supported () {71 public static PhotoFileFormat[] get_supported () {
71 return { JFIF, RAW, PNG, TIFF, BMP };72 return { JFIF, RAW, PNG, TIFF, BMP, GIF};
72 }73 }
7374
74 public static PhotoFileFormat[] get_writeable () {75 public static PhotoFileFormat[] get_writeable () {
@@ -144,6 +145,9 @@
144 case BMP:145 case BMP:
145 return 4;146 return 4;
146147
148 case GIF:
149 return 5;
150
147 case UNKNOWN:151 case UNKNOWN:
148 default:152 default:
149 return -1;153 return -1;
@@ -168,6 +172,9 @@
168 case 4:172 case 4:
169 return BMP;173 return BMP;
170174
175 case 5:
176 return GIF;
177
171 default:178 default:
172 return UNKNOWN;179 return UNKNOWN;
173 }180 }
@@ -212,6 +219,9 @@
212 case "bmp":219 case "bmp":
213 return PhotoFileFormat.BMP;220 return PhotoFileFormat.BMP;
214221
222 case "gif":
223 return PhotoFileFormat.GIF;
224
215 default:225 default:
216 return PhotoFileFormat.UNKNOWN;226 return PhotoFileFormat.UNKNOWN;
217 }227 }
@@ -239,6 +249,10 @@
239 Photos.BmpFileFormatDriver.init ();249 Photos.BmpFileFormatDriver.init ();
240 break;250 break;
241251
252 case GIF:
253 GifFileFormatDriver.init ();
254 break;
255
242 default:256 default:
243 error ("Unsupported file format %s", this.to_string ());257 error ("Unsupported file format %s", this.to_string ());
244 }258 }
@@ -261,6 +275,9 @@
261 case BMP:275 case BMP:
262 return Photos.BmpFileFormatDriver.get_instance ();276 return Photos.BmpFileFormatDriver.get_instance ();
263277
278 case GIF:
279 return GifFileFormatDriver.get_instance ();
280
264 default:281 default:
265 error ("Unsupported file format %s", this.to_string ());282 error ("Unsupported file format %s", this.to_string ());
266 }283 }

Subscribers

People subscribed via source and target branches

to all changes: