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
1=== modified file 'data/org.pantheon.photos-viewer.desktop.in.in'
2--- data/org.pantheon.photos-viewer.desktop.in.in 2016-08-28 20:08:59 +0000
3+++ data/org.pantheon.photos-viewer.desktop.in.in 2017-01-01 21:59:12 +0000
4@@ -8,7 +8,7 @@
5 NoDisplay=true
6 Type=Application
7 StartupNotify=true
8-MimeType=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;
9+MimeType=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;
10 Categories=Graphics;Viewer;Photography;GNOME;GTK;
11 Actions=AboutDialog;
12
13
14=== modified file 'src/CMakeLists.txt'
15--- src/CMakeLists.txt 2016-11-05 04:17:16 +0000
16+++ src/CMakeLists.txt 2017-01-01 21:59:12 +0000
17@@ -144,6 +144,7 @@
18
19 photos/BmpSupport.vala
20 photos/GdkSupport.vala
21+ photos/GifSupport.vala
22 photos/GRaw.vala
23 photos/JfifSupport.vala
24 photos/PhotoFileAdapter.vala
25
26=== added file 'src/photos/GifSupport.vala'
27--- src/photos/GifSupport.vala 1970-01-01 00:00:00 +0000
28+++ src/photos/GifSupport.vala 2017-01-01 21:59:12 +0000
29@@ -0,0 +1,185 @@
30+/* Copyright 2010-2013 Yorba Foundation
31+ *
32+ * This software is licensed under the GNU LGPL (version 2.1 or later).
33+ * See the COPYING file in this distribution.
34+ */
35+
36+class GifFileFormatProperties : PhotoFileFormatProperties {
37+ private static string[] KNOWN_EXTENSIONS = { "gif" };
38+ private static string[] KNOWN_MIME_TYPES = { "image/gif" };
39+
40+ private static GifFileFormatProperties instance = null;
41+
42+ public static void init () {
43+ instance = new GifFileFormatProperties ();
44+ }
45+
46+ public static GifFileFormatProperties get_instance () {
47+ return instance;
48+ }
49+
50+ public override PhotoFileFormat get_file_format () {
51+ return PhotoFileFormat.GIF;
52+ }
53+
54+ public override PhotoFileFormatFlags get_flags () {
55+ return PhotoFileFormatFlags.NONE;
56+ }
57+
58+ public override string get_user_visible_name () {
59+ return _ ("GIF");
60+ }
61+
62+ public override string get_default_extension () {
63+ return KNOWN_EXTENSIONS[0];
64+ }
65+
66+ public override string[] get_known_extensions () {
67+ return KNOWN_EXTENSIONS;
68+ }
69+
70+ public override string get_default_mime_type () {
71+ return KNOWN_MIME_TYPES[0];
72+ }
73+
74+ public override string[] get_mime_types () {
75+ return KNOWN_MIME_TYPES;
76+ }
77+}
78+
79+public class GifSniffer : GdkSniffer {
80+ private const uint8[] MAGIC_SEQUENCE_GIF87 = { 71, 73, 70, 56, 55, 97 };
81+ private const uint8[] MAGIC_SEQUENCE_GIF89 = { 71, 73, 70, 56, 57, 97 };
82+
83+ public GifSniffer (File file, PhotoFileSniffer.Options options) {
84+ base (file, options);
85+ }
86+
87+ private static bool is_gif_file (File file) throws Error {
88+ FileInputStream instream = file.read (null);
89+
90+ uint8[] file_lead_sequence = new uint8[MAGIC_SEQUENCE_GIF87.length];
91+
92+ instream.read (file_lead_sequence, null);
93+
94+ bool is_gif_87 = true;
95+
96+ for (int i = 0; i < MAGIC_SEQUENCE_GIF87.length; i++) {
97+ if (file_lead_sequence[i] != MAGIC_SEQUENCE_GIF87[i]) {
98+ is_gif_87 = false;
99+ }
100+ }
101+
102+ if (is_gif_87) {
103+ return true;
104+ } else {
105+ instream.seek (0, SeekType.SET);
106+
107+ file_lead_sequence = new uint8[MAGIC_SEQUENCE_GIF89.length];
108+
109+ instream.read (file_lead_sequence, null);
110+
111+ bool is_gif_89 = true;
112+
113+ for (int i = 0; i < MAGIC_SEQUENCE_GIF89.length; i++) {
114+ if (file_lead_sequence[i] != MAGIC_SEQUENCE_GIF89[i]) {
115+ is_gif_89 = false;
116+ }
117+ }
118+
119+ return is_gif_89;
120+ }
121+ }
122+
123+ public override DetectedPhotoInformation? sniff () throws Error {
124+ if (!is_gif_file (file))
125+ return null;
126+
127+ DetectedPhotoInformation? detected = base.sniff ();
128+
129+ if (detected == null) {
130+ return null;
131+ }
132+
133+ return (detected.file_format == PhotoFileFormat.GIF) ? detected : null;
134+ }
135+}
136+
137+public class GifReader : GdkReader {
138+ public GifReader (string filepath) {
139+ base (filepath, PhotoFileFormat.GIF);
140+ }
141+
142+ public override Gdk.Pixbuf scaled_read (Dimensions full, Dimensions scaled) throws Error {
143+ Gdk.Pixbuf result = null;
144+ /* if we encounter a situation where there are two orders of magnitude or more of
145+ difference between the full image size and the scaled size, and if the full image
146+ size has five or more decimal digits of precision, Gdk.Pixbuf.from_file_at_scale( ) can
147+ fail due to what appear to be floating-point round-off issues. This isn't surprising,
148+ since 32-bit floats only have 6-7 decimal digits of precision in their mantissa. In
149+ this case, we prefetch the image at a larger scale and then downsample it to the
150+ desired scale as a post-process step. This short-circuits Gdk.Pixbuf's buggy
151+ scaling code. */
152+ if (((full.width > 9999) || (full.height > 9999)) && ((scaled.width < 100) ||
153+ (scaled.height < 100))) {
154+ Dimensions prefetch_dimensions = full.get_scaled_by_constraint (1000,
155+ ScaleConstraint.DIMENSIONS);
156+
157+ result = new Gdk.Pixbuf.from_file_at_scale (get_filepath (), prefetch_dimensions.width,
158+ prefetch_dimensions.height, false);
159+
160+ result = result.scale_simple (scaled.width, scaled.height, Gdk.InterpType.HYPER);
161+ } else {
162+ result = new Gdk.Pixbuf.from_file_at_scale (get_filepath (), scaled.width,
163+ scaled.height, false);
164+ }
165+
166+ return result;
167+ }
168+}
169+
170+public class GifFileFormatDriver : PhotoFileFormatDriver {
171+ private static GifFileFormatDriver instance = null;
172+
173+ public static void init () {
174+ instance = new GifFileFormatDriver ();
175+ GifFileFormatProperties.init ();
176+ }
177+
178+ public static GifFileFormatDriver get_instance () {
179+ return instance;
180+ }
181+
182+ public override PhotoFileFormatProperties get_properties () {
183+ return GifFileFormatProperties.get_instance ();
184+ }
185+
186+ public override PhotoFileReader create_reader (string filepath) {
187+ return new GifReader (filepath);
188+ }
189+
190+ public override bool can_write_image () {
191+ return false;
192+ }
193+
194+ public override bool can_write_metadata () {
195+ return false;
196+ }
197+
198+ public override PhotoFileWriter? create_writer (string filepath) {
199+ return null;
200+ }
201+
202+ public override PhotoFileMetadataWriter? create_metadata_writer (string filepath) {
203+ return null;
204+ }
205+
206+ public override PhotoFileSniffer create_sniffer (File file, PhotoFileSniffer.Options options) {
207+ return new GifSniffer (file, options);
208+ }
209+
210+ public override PhotoMetadata create_metadata () {
211+ return new PhotoMetadata ();
212+ }
213+}
214+
215
216=== modified file 'src/photos/PhotoFileFormat.vala'
217--- src/photos/PhotoFileFormat.vala 2014-08-08 21:13:09 +0000
218+++ src/photos/PhotoFileFormat.vala 2017-01-01 21:59:12 +0000
219@@ -63,12 +63,13 @@
220 PNG,
221 TIFF,
222 BMP,
223+ GIF,
224 UNKNOWN;
225
226 // This is currently listed in the order of detection, that is, the file is examined from
227 // left to right. (See PhotoFileInterrogator.)
228 public static PhotoFileFormat[] get_supported () {
229- return { JFIF, RAW, PNG, TIFF, BMP };
230+ return { JFIF, RAW, PNG, TIFF, BMP, GIF};
231 }
232
233 public static PhotoFileFormat[] get_writeable () {
234@@ -144,6 +145,9 @@
235 case BMP:
236 return 4;
237
238+ case GIF:
239+ return 5;
240+
241 case UNKNOWN:
242 default:
243 return -1;
244@@ -168,6 +172,9 @@
245 case 4:
246 return BMP;
247
248+ case 5:
249+ return GIF;
250+
251 default:
252 return UNKNOWN;
253 }
254@@ -212,6 +219,9 @@
255 case "bmp":
256 return PhotoFileFormat.BMP;
257
258+ case "gif":
259+ return PhotoFileFormat.GIF;
260+
261 default:
262 return PhotoFileFormat.UNKNOWN;
263 }
264@@ -239,6 +249,10 @@
265 Photos.BmpFileFormatDriver.init ();
266 break;
267
268+ case GIF:
269+ GifFileFormatDriver.init ();
270+ break;
271+
272 default:
273 error ("Unsupported file format %s", this.to_string ());
274 }
275@@ -261,6 +275,9 @@
276 case BMP:
277 return Photos.BmpFileFormatDriver.get_instance ();
278
279+ case GIF:
280+ return GifFileFormatDriver.get_instance ();
281+
282 default:
283 error ("Unsupported file format %s", this.to_string ());
284 }

Subscribers

People subscribed via source and target branches

to all changes: