beagle r4709 - trunk/beagle/Filters



Author: dbera
Date: Sun Apr 13 23:38:00 2008
New Revision: 4709
URL: http://svn.gnome.org/viewvc/beagle?rev=4709&view=rev

Log:
Add a new Jpeg Filter based on the managed Tiff parser in F-Spot (yes yes, we bypassed libexif). The filter passes the test for the images in the testsuite/files directory but more testing would be nice (hint hint ;-).


Modified:
   trunk/beagle/Filters/FilterJpeg.cs

Modified: trunk/beagle/Filters/FilterJpeg.cs
==============================================================================
--- trunk/beagle/Filters/FilterJpeg.cs	(original)
+++ trunk/beagle/Filters/FilterJpeg.cs	Sun Apr 13 23:38:00 2008
@@ -2,6 +2,7 @@
 // FilterJpeg.cs
 //
 // Copyright (C) 2004 Novell, Inc.
+// Copyright (C) 2008 D Bera <dbera web gmail com>
 //
 
 //
@@ -59,69 +60,150 @@
 			AddProperty (Beagle.Property.New ("jfif:Comment", comment));
 		}
 
+		private static string GetExifString (Tiff.ImageDirectory directory, Tiff.TagId id)
+		{
+			if (directory == null)
+				return null;
+
+			Tiff.DirectoryEntry entry = directory.Lookup (id);
+			if (entry == null)
+				return null;
+
+			return entry.ValueAsString [0];
+		}
+
+		private static double GetExifRational (Tiff.ImageDirectory directory, Tiff.TagId id)
+		{
+			if (directory == null)
+				return 0;
+
+			Tiff.DirectoryEntry entry = directory.Lookup (id);
+			if (entry == null)
+				return -1;
+
+			return entry.RationalValue [0].Value;
+		}
+
+		static string GetFlashString (ushort flash_value)
+		{
+			switch (flash_value) {
+			case 0x0000 : return "Flash did not fire";
+			case 0x0001 : return "Flash fired";
+			case 0x0005 : return "Strobe return light not detected";
+			case 0x0007 : return "Strobe return light detected";
+			case 0x0009 : return "Flash fired, compulsory flash mode";
+			case 0x000D : return "Flash fired, compulsory flash mode, return light not detected";
+			case 0x000F : return "Flash fired, compulsory flash mode, return light detected";
+			case 0x0010 : return "Flash did not fire, compulsory flash mode";
+			case 0x0018 : return "Flash did not fire, auto mode";
+			case 0x0019 : return "Flash fired, auto mode";
+			case 0x001D : return "Flash fired, auto mode, return light not detected";
+			case 0x001F : return "Flash fired, auto mode, return light detected";
+			case 0x0020 : return "No flash function";
+			case 0x0041 : return "Flash fired, red-eye reduction mode";
+			case 0x0045 : return "Flash fired, red-eye reduction mode, return light not detected";
+			case 0x0047 : return "Flash fired, red-eye reduction mode, return light detected";
+			case 0x0049 : return "Flash fired, compulsory flash mode, red-eye reduction mode";
+			case 0x004D : return "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected";
+			case 0x004F : return "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected";
+			case 0x0059 : return "Flash fired, auto mode, red-eye reduction mode";
+			case 0x005D : return "Flash fired, auto mode, return light not detected, red-eye reduction mode";
+			case 0x005F : return "Flash fired, auto mode, return light detected, red-eye reduction mode";
+			default     : return null;
+			}
+		}
+
 		private void AddExifProperties (JpegHeader header)
 		{
-			ExifData exif = header.Exif;
-			if (exif == null)
+			Tiff.Header ifd = header.GetExifHeader ();
+			if (ifd == null)
 				return;
+			//ifd.Dump ("foo"); // Uncomment to debug
 
 			string str;
-			
-			str = exif.LookupFirstValue (Exif.Tag.UserComment);
-			AddProperty (Beagle.Property.New ("exif:UserComment", str));
+			Tiff.DirectoryEntry entry;
 
-			str = exif.LookupFirstValue (Exif.Tag.ImageDescription);
-			AddProperty (Beagle.Property.New ("exif:ImageDescription", str));
+			// Add IFD 0 properies
 
-			str = exif.LookupFirstValue (Exif.Tag.PixelXDimension);
-			if (str != null && str != String.Empty) {
-				Width = Int32.Parse (str);
-				AddProperty (Beagle.Property.NewUnsearched ("exif:PixelXDimension", str));
-			}
+			str = GetExifString (ifd.Directory, Tiff.TagId.Model);
+			AddProperty (Beagle.Property.New ("exif:Model", str));
 
-			str = exif.LookupFirstValue (Exif.Tag.PixelYDimension);
-			if (str != null && str != String.Empty) {
-				Height = Int32.Parse (str);
-				AddProperty (Beagle.Property.NewUnsearched ("exif:PixelYDimension", str));
-			}
+			str = GetExifString (ifd.Directory, Tiff.TagId.ImageDescription);
+			AddProperty (Beagle.Property.New ("exif:ImageDescription", str));
 
-			str = exif.LookupFirstValue (Exif.Tag.ISOSpeedRatings);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:ISOSpeedRatings", str));
+			try {
+				entry = ifd.Directory.Lookup (Tiff.TagId.DateTime);
+				if (entry != null)
+					// Assume datetime stored in the images are local times
+					AddProperty (Beagle.Property.NewDate ("exif:DateTime", entry.ValueAsDate.ToUniversalTime ()));
+			} catch (ArgumentOutOfRangeException) {
+				Logger.Log.Debug("EXIF DateTime '{0}' is invalid.", GetExifString (ifd.Directory, Tiff.TagId.DateTime));
+			}
 
-			str = exif.LookupFirstValue (Exif.Tag.ShutterSpeedValue);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:ShutterSpeedValue", str));
+			str = GetExifString (ifd.Directory, Tiff.TagId.Copyright);
+			AddProperty (Beagle.Property.New ("dc:rights", str));
 
-			str = exif.LookupFirstValue (Exif.Tag.ExposureTime);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:ExposureTime", str));
+			// Add IFD 1 properties
 
-			str = exif.LookupFirstValue (Exif.Tag.FNumber);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:FNumber", str));
+			Tiff.SubdirectoryEntry subdir = (Tiff.SubdirectoryEntry) ifd.Directory.Lookup (Tiff.TagId.ExifIfdPointer);
+			if (subdir == null)
+				return;
 
-			str = exif.LookupFirstValue (Exif.Tag.ApertureValue);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:ApertureValue", str));
+			Tiff.ImageDirectory exif = subdir.Directory [0];
+			if (exif == null)
+				return;
 
-			str = exif.LookupFirstValue (Exif.Tag.FocalLength);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:FocalLength", str));
+			entry = exif.Lookup (Tiff.TagId.UserComment);
+			if (entry != null)
+				AddProperty (Beagle.Property.New ("exif:UserComment", entry.UserCommentValue));
+
+			uint val = 0;
+			entry = exif.Lookup (Tiff.TagId.PixelXDimension);
+			if (entry != null)
+				val = entry.ValueAsLong [0];
+			if (val > 0) {
+				Width = (int) val;
+				AddProperty (Beagle.Property.NewUnsearched ("exif:PixelXDimension", val));
+			}
 
-			str = exif.LookupFirstValue (Exif.Tag.Flash);
-			AddProperty (Beagle.Property.NewUnsearched ("exif:Flash", str));
+			val = 0;
+			entry = exif.Lookup (Tiff.TagId.PixelYDimension);
+			if (entry != null)
+				val = entry.ValueAsLong [0];
+			if (val > 0) {
+				Height = (int) val;
+				AddProperty (Beagle.Property.NewUnsearched ("exif:PixelYDimension", val));
+			}
 
-			str = exif.LookupFirstValue (Exif.Tag.Model);
-			AddProperty (Beagle.Property.New ("exif:Model", str));
+			str = GetExifString (exif, Tiff.TagId.ISOSpeedRatings);
+			AddProperty (Beagle.Property.NewUnsearched ("exif:ISOSpeedRatings", str));
 
-			str = exif.LookupFirstValue (Exif.Tag.Copyright);
-			AddProperty (Beagle.Property.New ("dc:rights", str));
+			str = GetExifString (exif, Tiff.TagId.ShutterSpeedValue);
+			AddProperty (Beagle.Property.NewUnsearched ("exif:ShutterSpeedValue", str));
 
-			str = exif.LookupFirstValue (Exif.Tag.DateTime);
-			if (str != null && str != String.Empty) {
-				try {
-					DateTime dt = ExifUtil.DateTimeFromString (str);
-					AddProperty (Beagle.Property.NewDate ("exif:DateTime", dt));
-				} catch (ArgumentOutOfRangeException) {
-					Logger.Log.Debug("EXIF DateTime '{0}' is invalid.", str);
-				}
+			str = GetExifString (exif, Tiff.TagId.ExposureTime);
+			if (! String.IsNullOrEmpty (str))
+				AddProperty (Beagle.Property.NewUnsearched ("exif:ExposureTime", str + " sec."));
+
+			double rational_val;
+
+			rational_val = GetExifRational (exif, Tiff.TagId.FNumber);
+			if (rational_val > 0)
+				AddProperty (Beagle.Property.NewUnsearched ("exif:FNumber", String.Format ("f/{0}", rational_val)));
+
+			rational_val = GetExifRational (exif, Tiff.TagId.ApertureValue);
+			if (rational_val > 0)
+				AddProperty (Beagle.Property.NewUnsearched ("exif:ApertureValue", rational_val));
+
+			rational_val = GetExifRational (exif, Tiff.TagId.FocalLength);
+			if (rational_val > 0)
+				AddProperty (Beagle.Property.NewUnsearched ("exif:FocalLength", String.Format ("{0} mm", rational_val)));
+
+			entry = exif.Lookup (Tiff.TagId.Flash);
+			if (entry != null) {
+				ushort flash = entry.ShortValue [0];
+				AddProperty (Beagle.Property.NewUnsearched ("exif:Flash", GetFlashString (flash)));
 			}
-
 		}
 
 		private void AddXmpProperties (JpegHeader header)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]