[f-spot/taglib-metadata: 2/5] Initial replacement of libexif usage by Taglib#.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/taglib-metadata: 2/5] Initial replacement of libexif usage by Taglib#.
- Date: Fri, 11 Jun 2010 21:08:41 +0000 (UTC)
commit f02ed0ce864ef9481169bac17ce8b60aaed5a5e0
Author: Ruben Vermeersch <ruben savanne be>
Date: Sun May 16 11:33:13 2010 +0200
Initial replacement of libexif usage by Taglib#.
lib/libfspot/f-jpeg-utils.c | 10 --
lib/libfspot/f-jpeg-utils.h | 6 -
src/Imaging/JpegFile.cs | 267 ++++++---------------------------
src/Imaging/JpegUtils.cs | 33 ----
src/Imaging/RafFile.cs | 13 +--
src/Jobs/SyncMetadataJob.cs | 14 ++-
src/Utils/GIOTagLibFileAbstraction.cs | 33 ++++
src/Utils/Unix.cs | 19 ---
8 files changed, 97 insertions(+), 298 deletions(-)
---
diff --git a/lib/libfspot/f-jpeg-utils.c b/lib/libfspot/f-jpeg-utils.c
index a237bd8..0c1fdf8 100644
--- a/lib/libfspot/f-jpeg-utils.c
+++ b/lib/libfspot/f-jpeg-utils.c
@@ -304,16 +304,6 @@ do_load_internal (const char *path,
/* Public API. */
-//GdkPixbuf *
-//f_load_scaled_jpeg (const char *path,
-// int target_width,
-// int target_height,
-// int *original_width_return,
-// int *original_height_return)
-//{
-// return do_load_internal (path, target_width, target_height, original_width_return, original_height_return);
-//}
-
/* FIXME: Error reporting in this function sucks... */
void
diff --git a/lib/libfspot/f-jpeg-utils.h b/lib/libfspot/f-jpeg-utils.h
index 35dd596..74fef89 100644
--- a/lib/libfspot/f-jpeg-utils.h
+++ b/lib/libfspot/f-jpeg-utils.h
@@ -31,12 +31,6 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
-//GdkPixbuf *f_load_scaled_jpeg (const char *path,
-// int target_width,
-// int target_heigh,
-// int *original_width_return,
-// int *original_height_return);
-//
void f_get_jpeg_size (const char *path,
int *width_return,
int *height_return);
diff --git a/src/Imaging/JpegFile.cs b/src/Imaging/JpegFile.cs
index f341ee0..2a65937 100644
--- a/src/Imaging/JpegFile.cs
+++ b/src/Imaging/JpegFile.cs
@@ -5,133 +5,49 @@ using FSpot.Xmp;
using FSpot.Tiff;
using FSpot.Utils;
using Hyena;
+using TagLib;
namespace FSpot {
public interface IThumbnailContainer {
Gdk.Pixbuf GetEmbeddedThumbnail ();
}
- public class JpegFile : ImageFile, IThumbnailContainer, SemWeb.StatementSource {
- private Exif.ExifData exif_data;
- private XmpFile xmp;
- private JpegHeader header;
- private FSpot.Tiff.Header exif_header;
+ public class JpegFile : ImageFile, IThumbnailContainer {
+ public Image.File Metadata {
+ get { return metadata_file; }
+ }
- // False seems a safe default
- public bool Distinct {
- get { return false; }
- }
+ private Image.File metadata_file;
public JpegFile (SafeUri uri) : base (uri)
{
- try {
- // Console.WriteLine ("approximate quality = {0}", Header.GuessQuality ());
- } catch (Exception e) {
- Log.Exception (e);
- }
+ metadata_file = TagLib.File.Create (new GIOTagLibFileAbstraction () { Uri = uri }) as Image.File;
}
- public JpegHeader Header {
- get {
- if (header == null) {
- using (Stream stream = this.Open ()) {
- header = new JpegHeader (stream, true);
- }
- }
- return header;
- }
- }
-
- public FSpot.Tiff.Header ExifHeader {
- get {
- if (exif_header == null) {
- exif_header = Header.GetExifHeader ();
- }
- return exif_header;
- }
- }
-
- public override Stream PixbufStream ()
- {
- if (header != null)
- return Open ();
-
- Stream s = Open ();
- if (s.CanSeek) {
- header = new JpegHeader (s, true);
- s.Position = 0;
- } else
- Log.DebugFormat ("{0} can not seek :(", s);
- return s;
- }
-
- public void Select (SemWeb.StatementSink sink)
- {
- Header.Select (sink);
- }
-
public override Cms.Profile GetProfile ()
{
- return Header.GetProfile ();
+ return null;
}
public override string Description {
get {
-#if USE_TIFF
- try {
- SubdirectoryEntry sub = (SubdirectoryEntry) ExifHeader.Directory.Lookup (TagId.ExifIfdPointer);
- if (sub != null) {
- DirectoryEntry entry = sub.Directory [0].Lookup (TagId.UserComment);
- if (entry != null)
- return entry.ValueAsString [0];
- }
- } catch (System.Exception e) {
- Log.Exception (e);
- }
- return null;
-#else
- try {
- Exif.ExifContent exif_content = this.ExifData.GetContents (Exif.Ifd.Exif);
- Exif.ExifEntry entry = exif_content.Lookup (Exif.Tag.UserComment);
-
- if (entry == null)
- return null;
-
- UserComment comment = new UserComment (entry.Data, entry.ByteOrder == Exif.ByteOrder.Intel);
- return comment.Value;
- } catch (Exception e) {
- // errors here shouldn't be fatal
- return null;
- }
-#endif
+ return metadata_file.ImageTag.Comment;
}
}
public void SetDescription (string value)
{
- Exif.ExifContent exif_content = this.ExifData.GetContents (Exif.Ifd.Exif);
- Exif.ExifEntry entry = exif_content.GetEntry (Exif.Tag.UserComment);
-
- UserComment comment = new UserComment (value);
- byte [] data = comment.GetBytes (entry.ByteOrder == Exif.ByteOrder.Intel);
- entry.SetData (data);
- }
-
- public void SetXmp (XmpFile xmp)
- {
- this.xmp = xmp;
+ metadata_file.GetTag (TagTypes.XMP, true); // Ensure XMP tag
+ metadata_file.ImageTag.Comment = value;
}
private void UpdateMeta ()
{
- Exif.ExifContent image_content = this.ExifData.GetContents (Exif.Ifd.Zero);
- image_content.GetEntry (Exif.Tag.Software).SetData (FSpot.Defines.PACKAGE + " version " + FSpot.Defines.VERSION);
-
- // set the write time in the datetime tag
- image_content.GetEntry (Exif.Tag.DateTime).Reset ();
+ metadata_file.GetTag (TagTypes.XMP, true); // Ensure XMP tag
+ metadata_file.ImageTag.Software = FSpot.Defines.PACKAGE + " version " + FSpot.Defines.VERSION;
}
- private void SaveMetaData (System.IO.Stream input, System.IO.Stream output)
+ /*private void SaveMetaData (System.IO.Stream input, System.IO.Stream output)
{
JpegHeader header = new JpegHeader (input);
UpdateMeta ();
@@ -144,44 +60,34 @@ namespace FSpot {
// Console.WriteLine ("set xmp");
header.Save (output);
// Console.WriteLine ("saved");
- }
+ }*/
public void SaveMetaData (string path)
{
- UpdateMeta ();
-
- //Get file permissions... (mkstemp does not keep permissions or ownership)
- Mono.Unix.Native.Stat stat;
- int stat_err = Mono.Unix.Native.Syscall.stat (path, out stat);
+ // FIXME: This currently copies the file out to a tmp file, overwrites it
+ // and restores the tmp file in case of failure. Should obviously be the
+ // other way around, but Taglib# doesn't have an interface to do this.
+ // https://bugzilla.gnome.org/show_bug.cgi?id=618768
- string temp_path = path;
- using (System.IO.FileStream stream = System.IO.File.OpenRead (path)) {
- using (System.IO.Stream output = FSpot.Utils.Unix.MakeSafeTemp (ref temp_path)) {
- SaveMetaData (stream, output);
- }
- }
+ var uri = UriUtils.PathToFileUri (path);
+ var tmp = System.IO.Path.GetTempFileName ();
+ var tmp_uri = UriUtils.PathToFileUri (tmp);
- File.SetAttributes (temp_path, File.GetAttributes (path));
+ var orig_file = GLib.FileFactory.NewForUri (uri);
+ var tmp_file = GLib.FileFactory.NewForUri (tmp_uri);
- if (FSpot.Utils.Unix.Rename (temp_path, path) < 0) {
- System.IO.File.Delete (temp_path);
- throw new System.Exception (System.String.Format ("Unable to rename {0} to {1}",
- temp_path, path));
- }
+ orig_file.Copy (tmp_file, GLib.FileCopyFlags.AllMetadata, null, null);
- //Set file permissions and gid...
- if (stat_err == 0)
- try {
- Mono.Unix.Native.Syscall.chmod (path, stat.st_mode |
- Mono.Unix.Native.FilePermissions.S_IRUSR |
- Mono.Unix.Native.FilePermissions.S_IWUSR);
- Mono.Unix.Native.Syscall.chown(path, Mono.Unix.Native.Syscall.getuid (), stat.st_gid);
- } catch (Exception) {}
+ try {
+ metadata_file.Save ();
+ } catch (Exception) {
+ tmp_file.Copy (orig_file, GLib.FileCopyFlags.AllMetadata, null, null);
+ }
}
public void SetThumbnail (Gdk.Pixbuf source)
{
- // Then create the thumbnail
+ /*// Then create the thumbnail
// The DCF spec says thumbnails should be 160x120 always
Gdk.Pixbuf thumbnail = PixbufUtils.ScaleToAspect (source, 160, 120);
byte [] thumb_data = PixbufUtils.Save (thumbnail, "jpeg", null, null);
@@ -189,12 +95,15 @@ namespace FSpot {
// System.Console.WriteLine ("saving thumbnail");
// now update the exif data
- ExifData.Data = thumb_data;
+ ExifData.Data = thumb_data;*/
+ // FIXME: needs to be readded https://bugzilla.gnome.org/show_bug.cgi?id=618769
}
public void SetDimensions (int width, int height)
{
- Exif.ExifEntry e;
+ /* FIXME: disabled, related to metadata copying
+ * https://bugzilla.gnome.org/show_bug.cgi?id=618770
+ * Exif.ExifEntry e;
Exif.ExifContent thumb_content;
// update the thumbnail related image fields if they exist.
@@ -213,7 +122,7 @@ namespace FSpot {
//image_content.GetEntry (Exif.Tag.ImageWidth).SetData ((uint)pixbuf.Width);
//image_content.GetEntry (Exif.Tag.ImageHeight).SetData ((uint)pixbuf.Height);
image_content.GetEntry (Exif.Tag.PixelXDimension).SetData ((uint)width);
- image_content.GetEntry (Exif.Tag.PixelYDimension).SetData ((uint)height);
+ image_content.GetEntry (Exif.Tag.PixelYDimension).SetData ((uint)height);*/
}
public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
@@ -221,11 +130,12 @@ namespace FSpot {
// Console.WriteLine ("starting save");
// First save the imagedata
- int quality = Header.GuessQuality ();
+ int quality = metadata_file.Properties.PhotoQuality;
quality = quality == 0 ? 75 : quality;
byte [] image_data = PixbufUtils.Save (pixbuf, "jpeg", new string [] {"quality" }, new string [] { quality.ToString () });
System.IO.MemoryStream buffer = new System.IO.MemoryStream ();
buffer.Write (image_data, 0, image_data.Length);
+/* FIXME: Metadata copying doesn't work yet https://bugzilla.gnome.org/show_bug.cgi?id=618770
buffer.Position = 0;
// Console.WriteLine ("setting thumbnail");
@@ -235,13 +145,13 @@ namespace FSpot {
// Console.WriteLine ("saving metatdata");
SaveMetaData (buffer, stream);
- // Console.WriteLine ("done");
+ // Console.WriteLine ("done");*/
buffer.Close ();
}
public Gdk.Pixbuf GetEmbeddedThumbnail ()
{
- if (this.ExifData.Data.Length > 0) {
+ /*if (this.ExifData.Data.Length > 0) {
MemoryStream mem = new MemoryStream (this.ExifData.Data);
Gdk.Pixbuf thumb = new Gdk.Pixbuf (mem);
Gdk.Pixbuf rotated = FSpot.Utils.PixbufUtils.TransformOrientation (thumb, this.Orientation);
@@ -249,110 +159,31 @@ namespace FSpot {
mem.Close ();
return rotated;
- }
+ }*/
+ // FIXME: No thumbnail support in TagLib# https://bugzilla.gnome.org/show_bug.cgi?id=618769
return null;
}
- public Exif.ExifData ExifData {
- get {
- if (exif_data == null) {
- exif_data = Header.Exif;
-
- if (exif_data == null || exif_data.Handle.Handle == System.IntPtr.Zero)
- exif_data = new Exif.ExifData ();
- }
- // System.Console.WriteLine ("loading exif data");
- return exif_data;
- }
- set {
- this.exif_data = value;
- }
- }
-
public override PixbufOrientation GetOrientation ()
{
- PixbufOrientation orientation = PixbufOrientation.TopLeft;
-#if USE_TIFF
- try {
- DirectoryEntry e = ExifHeader.Directory.Lookup (TagId.Orientation);
- orientation = (PixbufOrientation)e.ValueAsLong [0];
- } catch {
- Log.Warning ("Error checking orientation", uri);
- }
-#else
-Log.Debug (">>>");
- Exif.ExifEntry e = this.ExifData.GetContents (Exif.Ifd.Zero).Lookup (Exif.Tag.Orientation);
-Log.Debug ("<<<");
-
- if (e != null) {
- ushort [] value = e.GetDataUShort ();
- orientation = (PixbufOrientation) value [0];
- }
-#endif
- if (orientation < PixbufOrientation.TopLeft || orientation > PixbufOrientation.LeftBottom)
- orientation = PixbufOrientation.TopLeft;
-
- return orientation;
+ var orientation = metadata_file.ImageTag.Orientation;
+ return (PixbufOrientation) orientation;
}
public void SetOrientation (PixbufOrientation orientation)
{
- Exif.ExifEntry e = this.ExifData.GetContents (Exif.Ifd.Zero).GetEntry (Exif.Tag.Orientation);
- // System.Console.WriteLine ("Saving orientation as {0}", orientation);
- e.SetData ((ushort)orientation);
-
- e = this.ExifData.GetContents (Exif.Ifd.One).Lookup (Exif.Tag.Orientation);
- if (e != null)
- e.SetData ((ushort)orientation);
+ metadata_file.ImageTag.Orientation = (Image.ImageOrientation) orientation;
}
public void SetDateTimeOriginal (DateTime time)
{
- Exif.ExifEntry e = ExifData.LookupFirst (Exif.Tag.DateTimeOriginal);
- if (e != null)
- e.SetData (time);
- else {
- Exif.ExifContent exif_content = this.ExifData.GetContents (Exif.Ifd.Exif);
- Exif.ExifEntry entry = exif_content.GetEntry (Exif.Tag.DateTimeOriginal);
- entry.SetData (time);
- }
+ metadata_file.ImageTag.DateTime = time;
}
public override System.DateTime Date {
get {
- System.DateTime time;
- try {
-#if USE_TIFF
- SubdirectoryEntry sub = (SubdirectoryEntry) ExifHeader.Directory.Lookup (TagId.ExifIfdPointer);
- DirectoryEntry e;
-
- if (sub != null) {
- e = sub.Directory [0].Lookup (TagId.DateTimeOriginal);
-
- if (e != null)
- return DirectoryEntry.DateTimeFromString (e.StringValue);
- }
-
- e = ExifHeader.Directory.Lookup (TagId.DateTime);
-
- if (e != null)
- return DirectoryEntry.DateTimeFromString (e.StringValue);
-
- return base.Date;
-#else
- string time_str = "";
- time_str = ExifData.LookupFirstValue (Exif.Tag.DateTimeOriginal);
-
- if (time_str == null || time_str == "")
- time_str = ExifData.LookupFirstValue (Exif.Tag.DateTime);
-
- time = Exif.ExifUtil.DateTimeFromString (time_str);
-#endif
- } catch (System.Exception e) {
- Log.Exception (e);
- time = base.Date;
- }
- return time;
+ var date = metadata_file.ImageTag.DateTime;
+ return date.HasValue ? date.Value : base.Date;
}
}
diff --git a/src/Imaging/JpegUtils.cs b/src/Imaging/JpegUtils.cs
index e6a1f72..981b1e9 100644
--- a/src/Imaging/JpegUtils.cs
+++ b/src/Imaging/JpegUtils.cs
@@ -3,39 +3,6 @@ using System;
using Gdk;
public class JpegUtils {
-// [DllImport ("libfspot")]
-// static extern IntPtr f_load_scaled_jpeg (string path,
-// int target_width,
-// int target_height,
-// out int original_width_return,
-// out int original_height_return);
-//
-// /* FIXME */
-// [DllImport("libgobject-2.0-0.dll")]
-// static extern void g_object_unref (IntPtr raw);
-//
-// public static Pixbuf LoadScaled (string path, int target_width, int target_height,
-// out int original_width, out int original_height)
-// {
-// Pixbuf pixbuf = new Pixbuf (f_load_scaled_jpeg (path, target_width, target_height,
-// out original_width, out original_height));
-// g_object_unref (pixbuf.Handle);
-// return pixbuf;
-// }
-
-// public static Pixbuf LoadScaled (string path, int target_width, int target_height)
-// {
-// int unused;
-// return LoadScaled (path, target_width, target_height, out unused, out unused);
-// }
-
- [DllImport ("libfspot")]
- static extern void f_save_jpeg_exif (string path, HandleRef data);
-
- public static void SaveExif (string path, Exif.ExifData data)
- {
- f_save_jpeg_exif (path, data.Handle);
- }
[DllImport ("libfspot")]
static extern void f_get_jpeg_size (string path, out int width_return, out int height_return);
diff --git a/src/Imaging/RafFile.cs b/src/Imaging/RafFile.cs
index 13a191b..cff1128 100644
--- a/src/Imaging/RafFile.cs
+++ b/src/Imaging/RafFile.cs
@@ -12,15 +12,6 @@ namespace FSpot.Raf {
// completely figured out yet. More to follow.
// ALL the sample files I have begin with "FUJIFILMCCD-RAW "
-
-
- public class WhiteBalance {
- // see dcraw parse_fuli
- public WhiteBalance (System.IO.Stream stream)
- {
-
- }
- }
public class RafFile : ImageFile, SemWeb.StatementSource {
@@ -84,12 +75,12 @@ namespace FSpot.Raf {
public void Select (SemWeb.StatementSink sink)
{
- byte [] data = GetEmbeddedJpeg ();
+ /*byte [] data = GetEmbeddedJpeg ();
if (data != null) {
System.IO.Stream stream = new System.IO.MemoryStream (data);
JpegHeader header = new JpegHeader (stream);
header.Select (sink);
- }
+ }*/
}
private byte [] GetEmbeddedJpeg ()
diff --git a/src/Jobs/SyncMetadataJob.cs b/src/Jobs/SyncMetadataJob.cs
index 0ecda15..ab0b379 100644
--- a/src/Jobs/SyncMetadataJob.cs
+++ b/src/Jobs/SyncMetadataJob.cs
@@ -48,6 +48,12 @@ namespace FSpot.Jobs {
void WriteMetadataToImage (Photo photo)
{
string path = photo.DefaultVersion.Uri.LocalPath;
+
+ Tag [] tags = photo.Tags;
+ string [] names = new string [tags.Length];
+
+ for (int i = 0; i < tags.Length; i++)
+ names [i] = tags [i].Name;
using (FSpot.ImageFile img = FSpot.ImageFile.Create (photo.DefaultVersion.Uri)) {
if (img is FSpot.JpegFile) {
@@ -55,7 +61,13 @@ namespace FSpot.Jobs {
jimg.SetDescription (photo.Description);
jimg.SetDateTimeOriginal (photo.Time);
- jimg.SetXmp (UpdateXmp (photo, jimg.Header.GetXmp ()));
+
+ var meta = jimg.Metadata;
+ meta.GetTag (TagLib.TagTypes.XMP, true);
+
+ var tag = meta.ImageTag;
+ tag.Keywords = names;
+ tag.Rating = photo.Rating;
jimg.SaveMetaData (path);
} else if (img is FSpot.Png.PngFile) {
diff --git a/src/Utils/GIOTagLibFileAbstraction.cs b/src/Utils/GIOTagLibFileAbstraction.cs
new file mode 100644
index 0000000..46a5626
--- /dev/null
+++ b/src/Utils/GIOTagLibFileAbstraction.cs
@@ -0,0 +1,33 @@
+using System;
+using System.IO;
+using GLib;
+
+namespace FSpot.Utils
+{
+ public sealed class GIOTagLibFileAbstraction : TagLib.File.IFileAbstraction
+ {
+ public string Name {
+ get {
+ return Uri.ToString ();
+ }
+ set {
+ Uri = new Uri (value);
+ }
+ }
+
+ public Uri Uri { get; set; }
+
+ public Stream ReadStream {
+ get { return new GioStream (FileFactory.NewForUri(Uri).Read (null)); }
+ }
+
+ public Stream WriteStream {
+ get { throw new NotImplementedException (); }
+ }
+
+ public void CloseStream (Stream stream)
+ {
+ stream.Close ();
+ }
+ }
+}
diff --git a/src/Utils/Unix.cs b/src/Utils/Unix.cs
index 099e510..ac5db78 100644
--- a/src/Utils/Unix.cs
+++ b/src/Utils/Unix.cs
@@ -9,9 +9,6 @@ namespace FSpot.Utils {
[DllImport ("libc", EntryPoint="rename", CharSet = CharSet.Auto)]
public static extern int Rename (string oldpath, string newpath);
- [DllImport ("libc", EntryPoint="mkstemp")]
- public static extern int MkSTemp (byte []template);
-
[DllImport("libc", EntryPoint="prctl")]
public static extern int PrCtl(int option, string name, ulong arg3, ulong arg4, ulong arg5);
@@ -24,22 +21,6 @@ namespace FSpot.Utils {
return NativeMethods.Rename (oldpath, newpath);
}
-
- public static Mono.Unix.UnixStream MakeSafeTemp (ref string template)
- {
- byte [] template_bytes = System.Text.Encoding.UTF8.GetBytes (template + ".XXXXXX\0");
-
- int fd = NativeMethods.MkSTemp (template_bytes);
-
- if (fd < 0) {
- //Mono.Unix.Error error = Mono.Unix.Stdlib.GetLastError ();
- throw new System.ApplicationException (Mono.Unix.Catalog.GetString ("Unable to create temporary file"));
- }
-
- template = System.Text.Encoding.UTF8.GetString (template_bytes, 0, template_bytes.Length - 1);
- return new Mono.Unix.UnixStream (fd);
- }
-
public static void SetProcessName (string name)
{
try {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]