[f-spot] Switch to mime-type based image loading.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot] Switch to mime-type based image loading.
- Date: Thu, 8 Jul 2010 18:03:54 +0000 (UTC)
commit f680fd0dfd56522e399bc52452c69808856ed9d9
Author: Ruben Vermeersch <ruben savanne be>
Date: Thu Jul 8 20:02:49 2010 +0200
Switch to mime-type based image loading.
The mime type is now used for detecting how to load an image.
A test to ensure that we load everything Taglib# supports is added.
https://bugzilla.gnome.org/show_bug.cgi?id=622147
src/Imaging/ImageFile.cs | 187 ++++++++++++++++++++++--------------------
src/Makefile.am | 1 +
src/Tests/ImageFileTests.cs | 45 ++++++++++
src/Utils/Metadata.cs | 26 ++++--
4 files changed, 161 insertions(+), 98 deletions(-)
---
diff --git a/src/Imaging/ImageFile.cs b/src/Imaging/ImageFile.cs
index 5f8f910..7a1d659 100644
--- a/src/Imaging/ImageFile.cs
+++ b/src/Imaging/ImageFile.cs
@@ -2,13 +2,14 @@ using Hyena;
using System;
using System.IO;
-using System.Collections;
+using System.Collections.Generic;
using FSpot.Utils;
using Mono.Unix;
using Mono.Unix.Native;
using Gdk;
+using GLib;
using TagLib.Image;
using GFileInfo = GLib.FileInfo;
@@ -24,91 +25,99 @@ namespace FSpot.Imaging {
#region Factory functionality
- static Hashtable name_table;
- internal static Hashtable NameTable { get { return name_table; } }
+ static Dictionary<string, Type> name_table;
+ internal static Dictionary<string, Type> NameTable { get { return name_table; } }
- static ImageFile ()
- {
- name_table = new Hashtable ();
- name_table [".svg"] = typeof (BaseImageFile);
- name_table [".gif"] = typeof (BaseImageFile);
- name_table [".bmp"] = typeof (BaseImageFile);
- name_table [".pcx"] = typeof (BaseImageFile);
- name_table [".jpeg"] = typeof (BaseImageFile);
- name_table [".jpg"] = typeof (BaseImageFile);
- name_table [".png"] = typeof (BaseImageFile);
- name_table [".cr2"] = typeof (FSpot.Imaging.Tiff.Cr2File);
- name_table [".nef"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".pef"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".raw"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".kdc"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".arw"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".rw2"] = typeof (FSpot.Imaging.DCRawFile);
- name_table [".tiff"] = typeof (BaseImageFile);
- name_table [".tif"] = typeof (BaseImageFile);
- name_table [".orf"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".srf"] = typeof (FSpot.Imaging.Tiff.NefFile);
- name_table [".dng"] = typeof (FSpot.Imaging.Tiff.DngFile);
- name_table [".crw"] = typeof (FSpot.Imaging.Ciff.CiffFile);
- name_table [".ppm"] = typeof (BaseImageFile);
- name_table [".mrw"] = typeof (FSpot.Imaging.DCRawFile);
- name_table [".raf"] = typeof (FSpot.Imaging.Raf.RafFile);
- name_table [".x3f"] = typeof (FSpot.Imaging.DCRawFile);
-
- // add mimetypes for fallback
- name_table ["image/bmp"] = name_table ["image/x-bmp"] = name_table [".bmp"];
- name_table ["image/gif"] = name_table [".gif"];
- name_table ["image/pjpeg"] = name_table ["image/jpeg"] = name_table ["image/jpg"] = name_table [".jpg"];
- name_table ["image/x-png"] = name_table ["image/png"] = name_table [".png"];
- name_table ["image/svg+xml"] = name_table [".svg"];
- name_table ["image/tiff"] = name_table [".tiff"];
- name_table ["image/x-dcraw"] = name_table [".raw"];
- name_table ["image/x-ciff"] = name_table [".crw"];
- name_table ["image/x-mrw"] = name_table [".mrw"];
- name_table ["image/x-x3f"] = name_table [".x3f"];
- name_table ["image/x-orf"] = name_table [".orf"];
- name_table ["image/x-nef"] = name_table [".nef"];
- name_table ["image/x-cr2"] = name_table [".cr2"];
- name_table ["image/x-raf"] = name_table [".raf"];
-
- //as xcf pixbufloader is not part of gdk-pixbuf, check if it's there,
- //and enable it if needed.
- foreach (Gdk.PixbufFormat format in Gdk.Pixbuf.Formats)
- if (format.Name == "xcf") {
- if (format.IsDisabled)
- format.SetDisabled (false);
- name_table [".xcf"] = typeof (ImageFile);
- }
- }
+ static ImageFile ()
+ {
+ var base_type = typeof (BaseImageFile);
+ var raw_type = typeof (DCRawFile);
+ var nef_type = typeof (FSpot.Imaging.Tiff.NefFile);
+
+ name_table = new Dictionary<string, Type> ();
+
+ // Plain image files
+ name_table ["image/gif"] = name_table [".gif"] = base_type;
+ name_table ["image/x-pcx"] = name_table [".pcx"] = base_type;
+ name_table ["image/x-portable-anymap"] = name_table [".pnm"] = base_type;
+ name_table ["image/x-portable-bitmap"] = name_table [".pbm"] = base_type;
+ name_table ["image/x-portable-graymap"] = name_table [".pgm"] = base_type;
+ name_table ["image/x-portable-pixmap"] = name_table [".ppm"] = base_type;
+ name_table ["image/x-bmp"] = name_table ["image/x-MS-bmp"] = name_table [".bmp"] = base_type;
+ name_table ["image/jpeg"] = name_table [".jfi"] = name_table [".jfif"] = name_table [".jif"] = name_table [".jpe"] = name_table [".jpeg"] = name_table [".jpg"] = base_type;
+ name_table ["image/png"] = name_table [".png"] = base_type;
+ name_table ["image/tiff"] = name_table [".tif"] = name_table [".tiff"] = base_type;
+
+ // RAW files
+ name_table ["image/arw"] = name_table ["image/x-sony-arw"] = name_table [".arw"] = nef_type;
+ name_table ["image/cr2"] = name_table ["image/x-canon-cr"] = name_table [".cr2"] = typeof (FSpot.Imaging.Tiff.Cr2File);
+ name_table ["image/dng"] = name_table ["image/x-adobe-dng"] = name_table [".dng"] = typeof (FSpot.Imaging.Tiff.DngFile);
+ name_table ["image/nef"] = name_table ["image/x-nikon-nef"] = name_table [".nef"] = nef_type;
+ name_table ["image/rw2"] = name_table ["image/x-raw"] = name_table [".rw2"] = raw_type;
+
+ // Other types (FIXME: Currently unsupported by Taglib#, this list should shrink).
+ name_table ["image/svg+xml"] = name_table [".svg"] = base_type;
+ name_table [".pef"] = nef_type;
+ name_table [".raw"] = typeof (FSpot.Imaging.Tiff.NefFile);
+ name_table [".kdc"] = typeof (FSpot.Imaging.Tiff.NefFile);
+ name_table [".rw2"] = typeof (FSpot.Imaging.DCRawFile);
+ name_table [".orf"] = typeof (FSpot.Imaging.Tiff.NefFile);
+ name_table [".srf"] = typeof (FSpot.Imaging.Tiff.NefFile);
+ name_table [".crw"] = typeof (FSpot.Imaging.Ciff.CiffFile);
+ name_table [".mrw"] = typeof (FSpot.Imaging.DCRawFile);
+ name_table [".raf"] = typeof (FSpot.Imaging.Raf.RafFile);
+ name_table [".x3f"] = typeof (FSpot.Imaging.DCRawFile);
+ name_table ["image/x-dcraw"] = name_table [".raw"];
+ name_table ["image/x-ciff"] = name_table [".crw"];
+ name_table ["image/x-mrw"] = name_table [".mrw"];
+ name_table ["image/x-x3f"] = name_table [".x3f"];
+ name_table ["image/x-orf"] = name_table [".orf"];
+ name_table ["image/x-raf"] = name_table [".raf"];
+
+ // as xcf pixbufloader is not part of gdk-pixbuf, check if it's there,
+ // and enable it if needed.
+ foreach (Gdk.PixbufFormat format in Gdk.Pixbuf.Formats)
+ if (format.Name == "xcf") {
+ if (format.IsDisabled)
+ format.SetDisabled (false);
+ name_table [".xcf"] = base_type;
+ }
+ }
- public static bool HasLoader (SafeUri uri)
- {
- return GetLoaderType (uri) != null;
- }
+ public static bool HasLoader (SafeUri uri)
+ {
+ return GetLoaderType (uri) != null;
+ }
- static Type GetLoaderType (SafeUri uri)
- {
- string extension = uri.GetExtension ().ToLower ();
- if (extension == ".thm") {
- // Ignore video thumbnails.
- return null;
- }
+ static Type GetLoaderType (SafeUri uri)
+ {
+ // check if GIO can find the file, which is not the case
+ // with filenames with invalid encoding
+ var file = GLib.FileFactory.NewForUri (uri);
+ if (!file.Exists) {
+ return null;
+ }
- Type t = (Type) name_table [extension];
+ var extension = uri.GetExtension ().ToLower ();
+ if (extension == ".thm") {
+ // Ignore video thumbnails.
+ return null;
+ }
- if (t == null) {
- // check if GIO can find the file, which is not the case
- // with filenames with invalid encoding
- GLib.File f = GLib.FileFactory.NewForUri (uri);
- if (f.QueryExists (null)) {
- GLib.FileInfo info = f.QueryInfo ("standard::type,standard::content-type", GLib.FileQueryInfoFlags.None, null);
- t = (Type) name_table [info.ContentType];
- }
- }
+ // Detect mime-type
+ var info = file.QueryInfo ("standard::content-type", FileQueryInfoFlags.None, null);
+ var mime = info.ContentType;
+
+ Type t = null;
+
+ if (name_table.TryGetValue (mime, out t)) {
+ return t;
+ } else if (name_table.TryGetValue (extension, out t)) {
+ return t;
+ }
+ return null;
+ }
- return t;
- }
-
public static IImageFile Create (SafeUri uri)
{
var t = GetLoaderType (uri);
@@ -160,11 +169,11 @@ namespace FSpot.Imaging {
public interface IImageFile : IDisposable {
SafeUri Uri { get; }
- Gdk.Pixbuf Load ();
- Cms.Profile GetProfile ();
- Gdk.Pixbuf Load (int max_width, int max_height);
- Stream PixbufStream ();
- ImageOrientation Orientation { get; }
+ Gdk.Pixbuf Load ();
+ Cms.Profile GetProfile ();
+ Gdk.Pixbuf Load (int max_width, int max_height);
+ Stream PixbufStream ();
+ ImageOrientation Orientation { get; }
}
public class BaseImageFile : IImageFile {
@@ -192,7 +201,7 @@ namespace FSpot.Imaging {
public virtual Stream PixbufStream ()
{
- Log.DebugFormat ("open uri = {0}", Uri.ToString ());
+ Hyena.Log.DebugFormat ("open uri = {0}", Uri.ToString ());
return new GLib.GioStream (GLib.FileFactory.NewForUri (Uri).Read (null));
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 0bab324..92568a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -188,6 +188,7 @@ SOURCES = \
Widgets/ViewContext.cs \
Widgets/Wipe.cs \
main.cs \
+ Tests/ImageFileTests.cs \
Tests/UpdaterTests.cs
diff --git a/src/Tests/ImageFileTests.cs b/src/Tests/ImageFileTests.cs
new file mode 100644
index 0000000..cbc6fd8
--- /dev/null
+++ b/src/Tests/ImageFileTests.cs
@@ -0,0 +1,45 @@
+#if ENABLE_TESTS
+using NUnit.Framework;
+using System;
+using Hyena;
+using Banshee.Database;
+using FSpot.Imaging;
+
+namespace FSpot.Tests
+{
+ [TestFixture]
+ public class ImageFileTests
+ {
+ [SetUp]
+ public void Initialize () {
+ GLib.GType.Init ();
+ }
+
+ [Test]
+ public void CheckLoadableTypes ()
+ {
+ bool missing = false;
+
+ // Test that we have loaders defined for all Taglib# parseable types.
+ foreach (var key in TagLib.FileTypes.AvailableTypes.Keys) {
+ Type type = TagLib.FileTypes.AvailableTypes [key];
+ if (!type.IsSubclassOf (typeof (TagLib.Image.File))) {
+ continue;
+ }
+
+ var test_key = key;
+ if (key.StartsWith ("taglib/")) {
+ test_key = "." + key.Substring (7);
+ }
+
+ if (!ImageFile.NameTable.ContainsKey (test_key)) {
+ Log.InformationFormat ("Missing key for {0}", test_key);
+ missing = true;
+ }
+ }
+
+ Assert.IsFalse (missing, "No missing loaders for Taglib# parseable files.");
+ }
+ }
+}
+#endif
diff --git a/src/Utils/Metadata.cs b/src/Utils/Metadata.cs
index 2ab9471..882b818 100644
--- a/src/Utils/Metadata.cs
+++ b/src/Utils/Metadata.cs
@@ -1,24 +1,32 @@
using Hyena;
using TagLib;
using System;
+using GLib;
namespace FSpot.Utils
{
public static class Metadata
{
public static TagLib.Image.File Parse (SafeUri uri)
- {
- var res = new GIOTagLibFileAbstraction () { Uri = uri };
+ {
+ // Detect mime-type
+ var gfile = FileFactory.NewForUri (uri);
+ var info = gfile.QueryInfo ("standard::content-type", FileQueryInfoFlags.None, null);
+ var mime = info.ContentType;
+
+ // Parse file
+ var res = new GIOTagLibFileAbstraction () { Uri = uri };
var sidecar_uri = uri.ReplaceExtension (".xmp");
var sidecar_res = new GIOTagLibFileAbstraction () { Uri = sidecar_uri };
- var file = File.Create (res) as TagLib.Image.File;
+ var file = TagLib.File.Create (res, mime, ReadStyle.Average) as TagLib.Image.File;
+ // Load XMP sidecar
var sidecar_file = GLib.FileFactory.NewForUri (sidecar_uri);
- if (sidecar_file.Exists) {
- file.ParseXmpSidecar (sidecar_res);
- }
+ if (sidecar_file.Exists) {
+ file.ParseXmpSidecar (sidecar_res);
+ }
- return file;
- }
- }
+ return file;
+ }
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]