[f-spot/rubenv-gsoc-2009: 32/86] Fix Editors for RAW files, now saves a new .jpg version.



commit ab01b290fc9336997f9dd5819d3a2d347bf15fbb
Author: Ruben Vermeersch <ruben savanne be>
Date:   Wed Jul 29 14:58:33 2009 +0200

    Fix Editors for RAW files, now saves a new .jpg version.

 src/Core/Photo.cs                 |   25 +++++++++++++++++++++----
 src/Editors/Editor.cs             |   10 +++++++++-
 src/FSpot.Imaging.dll.config.in   |    1 +
 src/Filters/ResizeFilter.cs       |    5 +++--
 src/Filters/SharpFilter.cs        |    6 ++++--
 src/Imaging/IWritableImageFile.cs |   16 ++++++++++++++++
 src/Imaging/ImageFile.cs          |    5 -----
 src/Imaging/JpegFile.cs           |    5 +++--
 src/Imaging/PngFile.cs            |    5 +++--
 src/Imaging/PnmFile.cs            |    4 ++--
 src/Loaders/GdkImageLoader.cs     |   20 ++++++++++++++++----
 src/Makefile.am                   |    4 +++-
 src/PhotoImageView.cs             |    2 +-
 src/RotateCommand.cs              |    3 ++-
 14 files changed, 84 insertions(+), 27 deletions(-)
---
diff --git a/src/Core/Photo.cs b/src/Core/Photo.cs
index c29014c..6456431 100644
--- a/src/Core/Photo.cs
+++ b/src/Core/Photo.cs
@@ -18,6 +18,7 @@ using System.Collections.Generic;
 using Mono.Unix;
 
 using FSpot.Utils;
+using FSpot.Imaging;
 using FSpot.Platform;
 
 namespace FSpot
@@ -240,18 +241,29 @@ namespace FSpot
 			using (ImageFile img = ImageFile.Create (DefaultVersion.Uri)) {
 				// Always create a version if the source is not a jpeg for now.
 				create_version = create_version || !(img is FSpot.JpegFile);
+				bool original_format = img is IWritableImageFile;
 	
 				if (buffer == null)
 					throw new ApplicationException ("invalid (null) image");
 	
+				string extension = original_format ? null : ".jpg";
 				if (create_version)
-					version = CreateDefaultModifiedVersion (DefaultVersionId, false);
+					version = CreateDefaultModifiedVersion (DefaultVersionId, extension, false);
 	
 				try {
 					Uri versionUri = VersionUri (version);
 
-					using (Stream stream = System.IO.File.OpenWrite (versionUri.LocalPath)) {
-						img.Save (buffer, stream);
+					if (original_format) {
+						using (Stream stream = System.IO.File.OpenWrite (versionUri.LocalPath)) {
+							(img as IWritableImageFile).Save (buffer, stream);
+						}
+					} else {
+						// FIXME: There is no metadata copying yet!
+						byte [] image_data = PixbufUtils.Save (buffer, "jpeg", new string [] {"quality" }, new string [] { "95" });
+						using (Stream stream = System.IO.File.OpenWrite (versionUri.LocalPath)) {
+							stream.Write (image_data, 0, image_data.Length);
+						}
+
 					}
 					(GetVersion (version) as PhotoVersion).MD5Sum = GenerateMD5 (VersionUri (version));
 					FSpot.ThumbnailGenerator.Create (versionUri).Dispose ();
@@ -380,6 +392,11 @@ namespace FSpot
 	
 		public uint CreateDefaultModifiedVersion (uint base_version_id, bool create_file)
 		{
+			return CreateDefaultModifiedVersion (base_version_id, null, create_file);
+		}
+
+		public uint CreateDefaultModifiedVersion (uint base_version_id, string extension, bool create_file)
+		{
 			int num = 1;
 	
 			while (true) {
@@ -391,7 +408,7 @@ namespace FSpot
 				GLib.File file = GLib.FileFactory.NewForUri (uri);
 	
 				if (! VersionNameExists (name) && ! file.Exists)
-					return CreateVersion (name, base_version_id, create_file);
+					return CreateVersion (name, extension, base_version_id, create_file);
 	
 				num ++;
 			}
diff --git a/src/Editors/Editor.cs b/src/Editors/Editor.cs
index e751fae..2e79cd9 100644
--- a/src/Editors/Editor.cs
+++ b/src/Editors/Editor.cs
@@ -10,6 +10,7 @@
 using FSpot;
 using FSpot.Utils;
 using FSpot.Widgets;
+using FSpot.Loaders;
 
 using Gdk;
 using Gtk;
@@ -99,7 +100,14 @@ namespace FSpot.Editors {
 		protected void LoadPhoto (Photo photo, out Pixbuf photo_pixbuf, out Cms.Profile photo_profile) {
 			// FIXME: We might get this value from the PhotoImageView.
 			using (ImageFile img = ImageFile.Create (photo.DefaultVersion.Uri)) {
-				photo_pixbuf = img.Load ();
+				if (State.PhotoImageView != null) {
+					photo_pixbuf = State.PhotoImageView.CompletePixbuf ().ShallowCopy ();
+				} else {
+					using (IImageLoader loader = ImageLoader.Create (photo.DefaultVersionUri)) {
+						loader.Load (ImageLoaderItem.Full);
+						photo_pixbuf = loader.Full;
+					}
+				}
 				photo_profile = img.GetProfile ();
 			}
 		}
diff --git a/src/FSpot.Imaging.dll.config.in b/src/FSpot.Imaging.dll.config.in
index 7fbf2fd..c966f8d 100644
--- a/src/FSpot.Imaging.dll.config.in
+++ b/src/FSpot.Imaging.dll.config.in
@@ -2,4 +2,5 @@
   <dllmap dll="libgnomeui-2-0.dll" target="libgnomeui-2.so.0"/>
   <dllmap dll="libfspot" target="@expanded_libdir@/f-spot/libfspot.so.0"/>
   <dllmap dll="libfspotjpeg" target="@expanded_libdir@/f-spot/libfspotjpg.so.0"/>
+  <dllmap dll="libgdk_pixbuf-2.0-0.dll" target="libgdk_pixbuf-2.0.so.0"/>
 </configuration>
diff --git a/src/Filters/ResizeFilter.cs b/src/Filters/ResizeFilter.cs
index a9547e0..ccd3437 100644
--- a/src/Filters/ResizeFilter.cs
+++ b/src/Filters/ResizeFilter.cs
@@ -14,6 +14,7 @@ using System.IO;
 
 using FSpot;
 using FSpot.Loaders;
+using FSpot.Imaging;
 
 using Mono.Unix;
 
@@ -55,9 +56,9 @@ namespace FSpot.Filters {
 				using (scaled) {
 					string destination_extension = Path.GetExtension (dest);
 
-					if (Path.GetExtension (source).ToLower () == Path.GetExtension (dest).ToLower ()) {
+					if (Path.GetExtension (source).ToLower () == Path.GetExtension (dest).ToLower () && img is IWritableImageFile) {
 						using (Stream output = File.OpenWrite (dest)) {
-							img.Save (scaled, output);
+							(img as IWritableImageFile).Save (scaled, output);
 						}
 					} else if (destination_extension == ".jpg") {
 						// FIXME this is a bit of a nasty hack to work around
diff --git a/src/Filters/SharpFilter.cs b/src/Filters/SharpFilter.cs
index e6fb135..1fa3087 100644
--- a/src/Filters/SharpFilter.cs
+++ b/src/Filters/SharpFilter.cs
@@ -12,6 +12,8 @@ using System;
 using System.IO;
 using Gdk;
 
+using FSpot.Imaging;
+
 using Mono.Unix;
 
 namespace FSpot.Filters {
@@ -35,9 +37,9 @@ namespace FSpot.Filters {
 					using (Pixbuf out_pixbuf = PixbufUtils.UnsharpMask (in_pixbuf, radius, amount, threshold)) {
 						string destination_extension = Path.GetExtension (dest_uri.LocalPath);
 		
-						if (Path.GetExtension (req.Current.LocalPath).ToLower () == Path.GetExtension (dest_uri.LocalPath).ToLower ()) {
+						if (Path.GetExtension (req.Current.LocalPath).ToLower () == Path.GetExtension (dest_uri.LocalPath).ToLower () && img is IWritableImageFile) {
 							using (Stream output = File.OpenWrite (dest_uri.LocalPath)) {
-								img.Save (out_pixbuf, output);
+								(img as IWritableImageFile).Save (out_pixbuf, output);
 							}
 						} else if (destination_extension == ".jpg") {
 							// FIXME this is a bit of a nasty hack to work around
diff --git a/src/Imaging/IWritableImageFile.cs b/src/Imaging/IWritableImageFile.cs
new file mode 100644
index 0000000..1556140
--- /dev/null
+++ b/src/Imaging/IWritableImageFile.cs
@@ -0,0 +1,16 @@
+//
+// Fspot.Imaging.IWritableImageFile.cs
+//
+// Copyright (c) 2009 Novell, Inc.
+//
+// Author(s)
+//	Ruben Vermeersch  <ruben savanne be>
+//
+// This is free software. See COPYING for details
+//
+
+namespace FSpot.Imaging {
+	public interface IWritableImageFile {
+		void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream);
+	}
+}
diff --git a/src/Imaging/ImageFile.cs b/src/Imaging/ImageFile.cs
index 6ec1238..49358f1 100644
--- a/src/Imaging/ImageFile.cs
+++ b/src/Imaging/ImageFile.cs
@@ -122,11 +122,6 @@ namespace FSpot {
 		{
 			get { return null; }
 		}
-		
-		public virtual void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
-		{
-			throw new NotImplementedException (Catalog.GetString ("Writing to this file format is not supported"));
-		}
 
 		protected Gdk.Pixbuf TransformAndDispose (Gdk.Pixbuf orig)
 		{
diff --git a/src/Imaging/JpegFile.cs b/src/Imaging/JpegFile.cs
index c82e6dc..8c5ec5b 100644
--- a/src/Imaging/JpegFile.cs
+++ b/src/Imaging/JpegFile.cs
@@ -4,13 +4,14 @@ using System.IO;
 using FSpot.Xmp;
 using FSpot.Tiff;
 using FSpot.Utils;
+using FSpot.Imaging;
 
 namespace FSpot {
 	public interface IThumbnailContainer {
 		Gdk.Pixbuf GetEmbeddedThumbnail ();
 	}
 
-	public class JpegFile : ImageFile, IThumbnailContainer, SemWeb.StatementSource {
+	public class JpegFile : ImageFile, IWritableImageFile, IThumbnailContainer, SemWeb.StatementSource {
 		private Exif.ExifData exif_data;
 		private XmpFile xmp;
 		private JpegHeader header;
@@ -219,7 +220,7 @@ namespace FSpot {
 			image_content.GetEntry (Exif.Tag.PixelYDimension).SetData ((uint)height);
 		}
 
-		public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
+		public void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
 		{
 
 			// Console.WriteLine ("starting save");
diff --git a/src/Imaging/PngFile.cs b/src/Imaging/PngFile.cs
index 3b4d359..bc2a177 100644
--- a/src/Imaging/PngFile.cs
+++ b/src/Imaging/PngFile.cs
@@ -3,11 +3,12 @@ using SemWeb;
 using Cms;
 using System.IO;
 using FSpot.Xmp;
+using FSpot.Imaging;
 using System.Collections;
 using System.Reflection;
 
 namespace FSpot.Png {
-	public class PngFile : ImageFile, SemWeb.StatementSource {
+	public class PngFile : ImageFile, IWritableImageFile, SemWeb.StatementSource {
 		PngHeader header;
 
                 // false seems a safe default
@@ -1256,7 +1257,7 @@ namespace FSpot.Png {
 			}
 		}
 
-		public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
+		public void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
 		{
 			byte [] buffer = PixbufUtils.Save (pixbuf, "png", null, null);
 			using (MemoryStream mem = new MemoryStream (buffer)) {
diff --git a/src/Imaging/PnmFile.cs b/src/Imaging/PnmFile.cs
index fd73f34..da6f0b5 100644
--- a/src/Imaging/PnmFile.cs
+++ b/src/Imaging/PnmFile.cs
@@ -8,7 +8,7 @@ using NUnit.Framework;
 #endif
 
 namespace FSpot.Pnm {
-	public class PnmFile : ImageFile, StatementSource {
+	public class PnmFile : ImageFile, IWritableImageFile, StatementSource {
 
                 // false seems a safe default
                 public bool Distinct {
@@ -225,7 +225,7 @@ namespace FSpot.Pnm {
 			return PixbufUtils.ScaleToMaxSize (this.Load (), width, height);
 		}
 
-		public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
+		public void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
 		{
 			if (pixbuf.HasAlpha)
 				throw new NotImplementedException ();
diff --git a/src/Loaders/GdkImageLoader.cs b/src/Loaders/GdkImageLoader.cs
index 4ace520..e206972 100644
--- a/src/Loaders/GdkImageLoader.cs
+++ b/src/Loaders/GdkImageLoader.cs
@@ -33,8 +33,9 @@ namespace FSpot.Loaders {
 		}
 		public PixbufOrientation ThumbnailOrientation { get; private set; }
 
+		Pixbuf error = null;
 		public Pixbuf Large {
-			get { return Pixbuf.ShallowCopy (); }
+			get { return error == null ? Pixbuf.ShallowCopy () : error.ShallowCopy (); }
 		}
 		public PixbufOrientation LargeOrientation { get; private set; }
 
@@ -87,6 +88,10 @@ namespace FSpot.Loaders {
 				thumbnail.Dispose ();
 				thumbnail = null;
 			}
+			if (error != null) {
+				error.Dispose ();
+				error = null;
+			}
 			base.Dispose ();
 		}
 
@@ -204,9 +209,16 @@ namespace FSpot.Loaders {
 			if (is_disposed)
 				return;
 
-			image_stream = new GLib.GioStream (GLib.FileFactory.NewForUri (uri).Read (null));
-			using (ImageFile image_file = ImageFile.Create (uri)) {
-				LargeOrientation = image_file.Orientation;
+			try {
+				image_stream = new GLib.GioStream (GLib.FileFactory.NewForUri (uri).Read (null));
+				using (ImageFile image_file = ImageFile.Create (uri)) {
+					LargeOrientation = image_file.Orientation;
+				}
+			} catch (GLib.GException) {
+				error = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "f-spot-question-mark", 256, (Gtk.IconLookupFlags)0);
+				LargeOrientation = PixbufOrientation.TopLeft;
+				SignalItemCompleted (ImageLoaderItem.Large | ImageLoaderItem.Full);
+				return;
 			}
 
 			while (Loading && !is_disposed) {
diff --git a/src/Makefile.am b/src/Makefile.am
index 7ecdd75..10947d6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,6 +52,7 @@ IMAGING_CSDISTFILES =						\
 	$(srcdir)/Imaging/InternalProcess.cs	\
 	$(srcdir)/Imaging/IOChannel.cs			\
 	$(srcdir)/Imaging/IRawFile.cs			\
+	$(srcdir)/Imaging/IWritableImageFile.cs	\
 	$(srcdir)/Imaging/JpegFile.cs			\
 	$(srcdir)/Imaging/JpegHeader.cs			\
 	$(srcdir)/Imaging/JpegUtils.cs			\
@@ -367,6 +368,7 @@ LOADERS_ASSEMBLIES =			\
 	$(LINK_FSPOTRAWSHARP)		\
 	-pkg:gtk-sharp-2.0			\
 	-r:Mono.Posix				\
+	-r:FSpot.Core.dll			\
 	-r:FSpot.Imaging.dll		\
 	-r:FSpot.Platform.dll		\
 	-r:FSpot.Utils.dll
@@ -548,7 +550,7 @@ FSpot.Imaging.dll: $(IMAGING_CSFILES) FSpot.Utils.dll FSpot.Core.dll
 
 FSpot.Loaders.dll.mdb: FSpot.Loaders.dll
 
-FSpot.Loaders.dll: $(LOADERS_CSFILES) FSpot.Platform.dll FSpot.Utils.dll FSpot.Imaging.dll
+FSpot.Loaders.dll: $(LOADERS_CSFILES) FSpot.Platform.dll FSpot.Utils.dll FSpot.Imaging.dll FSpot.Core.dll
 	$(CSC_LIB) -out:$@ $(EXTRAFLAGS) $(LOADERS_CSFILES) $(LOADERS_ASSEMBLIES)
 
 FSpot.Query.dll.mdb: FSpot.Query.dll
diff --git a/src/PhotoImageView.cs b/src/PhotoImageView.cs
index 5d75ec8..729e7d4 100644
--- a/src/PhotoImageView.cs
+++ b/src/PhotoImageView.cs
@@ -57,7 +57,7 @@ namespace FSpot.Widgets {
 			//FIXME: this should be an async call
 			if (loader != null)
 				while (loader.Loading)
-					Gtk.Application.RunIteration ();
+					Gtk.Application.RunIteration (true);
 			return this.Pixbuf;
 		}
 
diff --git a/src/RotateCommand.cs b/src/RotateCommand.cs
index a1faf4b..bc2484f 100644
--- a/src/RotateCommand.cs
+++ b/src/RotateCommand.cs
@@ -16,6 +16,7 @@ using Gdk;
 
 using FSpot;
 using FSpot.Png;
+using FSpot.Imaging;
 using FSpot.UI.Dialog;
 
 using FSpot.Utils;
@@ -101,7 +102,7 @@ namespace FSpot {
 						using (Pixbuf pixbuf = img.Load ()) {
 							PixbufOrientation fake = (direction == RotateDirection.Clockwise) ? PixbufOrientation.RightTop : PixbufOrientation.LeftBottom;
 							using (Pixbuf rotated = FSpot.Utils.PixbufUtils.TransformOrientation (pixbuf, fake)) {
-								img.Save (rotated, stream);
+								(img as IWritableImageFile).Save (rotated, stream);
 							}
 						}
 					}



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