[f-spot/rubenv-gsoc-2009: 27/86] Split loaders and imaging out into separate assemblies.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/rubenv-gsoc-2009: 27/86] Split loaders and imaging out into separate assemblies.
- Date: Sun, 23 May 2010 12:34:13 +0000 (UTC)
commit 36a7f37447a52b503ae6539cb54596042eb30bf2
Author: Ruben Vermeersch <ruben savanne be>
Date: Tue Jul 28 19:21:37 2009 +0200
Split loaders and imaging out into separate assemblies.
configure.ac | 1 +
extensions/Exporters/FacebookExport/Makefile.am | 5 +-
extensions/Exporters/FolderExport/Makefile.am | 1 +
extensions/Exporters/PicasaWebExport/Makefile.am | 2 +-
src/.gitignore | 5 +
src/FSpot.Loaders.dll.config.in | 16 +
src/Filters/JpegFilter.cs | 2 +-
src/Filters/ResizeFilter.cs | 2 +-
src/Filters/SharpFilter.cs | 2 +-
src/{ => Imaging}/BitConverter.cs | 22 +-
src/Imaging/Exif.cs | 2 +-
src/{ => Imaging}/IOChannel.cs | 48 +-
src/Imaging/ImageFile.cs | 5 +
src/{ => Imaging}/InternalProcess.cs | 6 +-
src/{ => Imaging}/MetadataStore.cs | 66 ++--
src/Imaging/PixbufUtils.cs | 622 +++++++++++++++++++++
src/{ => Imaging}/PixelBuffer.cs | 32 +-
src/Loaders/GdkImageLoader.cs | 6 +-
src/Loaders/LibrawImageLoader.cs | 6 +-
src/MainWindow.cs | 2 +-
src/Makefile.am | 131 ++++--
src/PhotoImageView.cs | 7 +-
src/PixbufUtils.cs | 631 +---------------------
src/PrintOperation.cs | 6 +-
src/SlideView.cs | 558 +++++++++++++++++++
src/ThumbnailGenerator.cs | 4 +-
src/UI.Dialog/EditTagIconDialog.cs | 6 +-
src/Utils/PixbufExtensions.cs | 49 ++
src/Widgets/Filmstrip.cs | 2 +-
src/Widgets/IconView.cs | 3 +-
src/Widgets/PreviewPopup.cs | 2 +-
src/Widgets/SlideShow.cs | 2 +-
tests/src/Makefile.am | 1 +
33 files changed, 1474 insertions(+), 781 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 265388a..0a23e16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -374,6 +374,7 @@ src/Core/Defines.cs
src/AssemblyInfo.cs
src/f-spot.exe.config
src/Cms.dll.config
+src/FSpot.Loaders.dll.config
src/FSpot.Widgets.dll.config
src/Makefile
extensions/Makefile
diff --git a/extensions/Exporters/FacebookExport/Makefile.am b/extensions/Exporters/FacebookExport/Makefile.am
index 10f4c05..0bfeea3 100644
--- a/extensions/Exporters/FacebookExport/Makefile.am
+++ b/extensions/Exporters/FacebookExport/Makefile.am
@@ -34,8 +34,9 @@ PLUGIN_SOURCES = \
REFS = \
-r:$(top_builddir)/src/f-spot.exe \
- -r:$(top_builddir)/src/FSpot.Core.dll \
- -r:$(top_builddir)/src/FSpot.Utils.dll \
+ -r:$(top_builddir)/src/FSpot.Core.dll \
+ -r:$(top_builddir)/src/FSpot.Utils.dll \
+ -r:$(top_builddir)/src/FSpot.Imaging.dll \
-r:$(top_builddir)/src/FSpot.Platform.dll \
-r:$(top_builddir)/src/FSpot.Widgets.dll \
$(LINK_GTKSHARPBEANS) \
diff --git a/extensions/Exporters/FolderExport/Makefile.am b/extensions/Exporters/FolderExport/Makefile.am
index c4762ca..54143e9 100644
--- a/extensions/Exporters/FolderExport/Makefile.am
+++ b/extensions/Exporters/FolderExport/Makefile.am
@@ -12,6 +12,7 @@ PLUGIN_SOURCES = \
REFS = \
-r:$(top_builddir)/src/f-spot.exe \
-r:$(top_builddir)/src/FSpot.Core.dll \
+ -r:$(top_builddir)/src/FSpot.Imaging.dll \
-r:$(top_builddir)/src/FSpot.Utils.dll \
$(LINK_SEMWEB) \
$(LINK_GPHOTO2) \
diff --git a/extensions/Exporters/PicasaWebExport/Makefile.am b/extensions/Exporters/PicasaWebExport/Makefile.am
index 2d99f7c..a1fe340 100644
--- a/extensions/Exporters/PicasaWebExport/Makefile.am
+++ b/extensions/Exporters/PicasaWebExport/Makefile.am
@@ -13,9 +13,9 @@ REFS = \
-r:$(top_builddir)/src/f-spot.exe \
-r:$(top_builddir)/src/FSpot.Core.dll \
-r:$(top_builddir)/src/FSpot.Utils.dll \
+ -r:$(top_builddir)/src/FSpot.Imaging.dll \
$(LINK_SEMWEB) \
-r:google-sharp/Mono.Google.dll \
- $(LINK_KEYRING) \
$(LINK_GIOSHARP) \
$(LINK_GPHOTO2) \
$(LINK_UNIQUESHARP) \
diff --git a/src/.gitignore b/src/.gitignore
index f4fcdfe..dcca615 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -7,6 +7,11 @@
/FSpot.Core.dll.mdb
/FSpot.JobScheduler.dll
/FSpot.JobScheduler.dll.mdb
+/FSpot.Imaging.dll
+/FSpot.Imaging.dll.mdb
+/FSpot.Loaders.dll
+/FSpot.Loaders.dll.mdb
+/FSpot.Loaders.dll.config
/FSpot.Query.dll
/FSpot.Query.dll.mdb
/FSpot.Utils.dll
diff --git a/src/FSpot.Loaders.dll.config.in b/src/FSpot.Loaders.dll.config.in
new file mode 100644
index 0000000..b392442
--- /dev/null
+++ b/src/FSpot.Loaders.dll.config.in
@@ -0,0 +1,16 @@
+<configuration>
+ <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.so.0"/>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0"/>
+ <dllmap dll="libgdk-2.0-0.dll" target="libgdk-x11-2.0.so.0"/>
+ <dllmap dll="libgdk_pixbuf-2.0-0.dll" target="libgdk_pixbuf-2.0.so.0"/>
+ <dllmap dll="libgnomevfs-2-0.dll" target="libgnomevfs-2.so.0"/>
+ <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="X11" target="libX11.so.6"/>
+ <dllmap dll="GL" target="libGL.so.1"/>
+ <dllmap dll="libXcomposite.dll" target="libXcomposite.so.1"/>
+ <dllmap dll="liblcms-1.0.0.dll" target="liblcms.so.1"/>
+ <dllmap dll="libexif.dll" target="libexif so EXIF_SOVERSION@"/>
+</configuration>
diff --git a/src/Filters/JpegFilter.cs b/src/Filters/JpegFilter.cs
index 791ed16..8daa0f9 100644
--- a/src/Filters/JpegFilter.cs
+++ b/src/Filters/JpegFilter.cs
@@ -51,7 +51,7 @@ namespace FSpot.Filters {
using (IImageLoader loader = ImageLoader.Create (req.Current)) {
loader.Load (ImageLoaderItem.Full);
using (Pixbuf full = loader.Full)
- PixbufUtils.SaveJpeg (full, dest, (int) quality, exif_data);
+ FSpotPixbufUtils.SaveJpeg (full, dest, (int) quality, exif_data);
}
}
diff --git a/src/Filters/ResizeFilter.cs b/src/Filters/ResizeFilter.cs
index aa9574e..a9547e0 100644
--- a/src/Filters/ResizeFilter.cs
+++ b/src/Filters/ResizeFilter.cs
@@ -67,7 +67,7 @@ namespace FSpot.Filters {
exif_data = new Exif.ExifData (source);
- PixbufUtils.SaveJpeg (scaled, dest, 95, exif_data);
+ FSpotPixbufUtils.SaveJpeg (scaled, dest, 95, exif_data);
} else
throw new NotImplementedException (String.Format (Catalog.GetString ("No way to save files of type \"{0}\""), destination_extension));
}
diff --git a/src/Filters/SharpFilter.cs b/src/Filters/SharpFilter.cs
index 64ac496..e6fb135 100644
--- a/src/Filters/SharpFilter.cs
+++ b/src/Filters/SharpFilter.cs
@@ -47,7 +47,7 @@ namespace FSpot.Filters {
exif_data = new Exif.ExifData (req.Current.LocalPath);
- PixbufUtils.SaveJpeg (out_pixbuf, dest_uri.LocalPath, 90, exif_data);
+ FSpotPixbufUtils.SaveJpeg (out_pixbuf, dest_uri.LocalPath, 90, exif_data);
} else
throw new NotImplementedException (String.Format (Catalog.GetString ("No way to save files of type \"{0}\""), destination_extension));
diff --git a/src/BitConverter.cs b/src/Imaging/BitConverter.cs
similarity index 88%
rename from src/BitConverter.cs
rename to src/Imaging/BitConverter.cs
index 00f34c5..4e55070 100644
--- a/src/BitConverter.cs
+++ b/src/Imaging/BitConverter.cs
@@ -4,16 +4,16 @@ using System.Runtime.InteropServices;
namespace FSpot {
//[Obsolete ("use Mono.DataConvert instead")]
public class BitConverter {
- public static uint Swap (uint val, bool little)
+ public static uint Swap (uint val, bool little)
{
return (little != System.BitConverter.IsLittleEndian) ?
((uint) ((((uint) (val) & (uint) 0x000000ffU) << 24) |
- (((uint) (val) & (uint) 0x0000ff00U) << 8) |
+ (((uint) (val) & (uint) 0x0000ff00U) << 8) |
(((uint) (val) & (uint) 0x00ff0000U) >> 8) |
(((uint) (val) & (uint) 0xff000000U) >> 24)))
: val;
}
-
+
public static ushort Swap (ushort val, bool little)
{
return (little != System.BitConverter.IsLittleEndian) ?
@@ -25,27 +25,27 @@ namespace FSpot {
{
return ((ushort) ((ushort)(val >> 8) | (ushort)(val << 8)));
}
-
+
public static ulong Swap (ulong val, bool little)
{
return (little != System.BitConverter.IsLittleEndian) ?
- ((ulong) ((((ulong) (val) & (ulong) 0x00000000000000ffU) << 56) |
- (((ulong) (val) & (ulong) 0x000000000000ff00U) << 40) |
+ ((ulong) ((((ulong) (val) & (ulong) 0x00000000000000ffU) << 56) |
+ (((ulong) (val) & (ulong) 0x000000000000ff00U) << 40) |
(((ulong) (val) & (ulong) 0x0000000000ff0000U) << 24) |
(((ulong) (val) & (ulong) 0x00000000ff000000U) << 8) |
- (((ulong) (val) & (ulong) 0x000000ff00000000U) >> 8) |
+ (((ulong) (val) & (ulong) 0x000000ff00000000U) >> 8) |
(((ulong) (val) & (ulong) 0x0000ff0000000000U) >> 24) |
(((ulong) (val) & (ulong) 0x00ff000000000000U) >> 40) |
(((ulong) (val) & (ulong) 0xff00000000000000U) >> 56)))
: val;
}
-
- public static byte [] GetBytes (uint val, bool little)
+
+ public static byte [] GetBytes (uint val, bool little)
{
val = Swap (val, little);
return System.BitConverter.GetBytes (val);
}
-
+
public static byte [] GetBytes (ushort val, bool little)
{
val = Swap (val, little);
@@ -57,7 +57,7 @@ namespace FSpot {
val = Swap (val, little);
return System.BitConverter.GetBytes (val);
}
-
+
public static ushort ToUInt16 (byte [] data, int position, bool little)
{
ushort val = System.BitConverter.ToUInt16 (data, position);
diff --git a/src/Imaging/Exif.cs b/src/Imaging/Exif.cs
index 2a31444..54684cb 100644
--- a/src/Imaging/Exif.cs
+++ b/src/Imaging/Exif.cs
@@ -156,7 +156,7 @@ namespace Exif {
Count
}
- internal class ExifUtil {
+ public class ExifUtil {
[DllImport ("libexif.dll")]
static extern IntPtr exif_tag_get_name (Tag tag);
diff --git a/src/IOChannel.cs b/src/Imaging/IOChannel.cs
similarity index 95%
rename from src/IOChannel.cs
rename to src/Imaging/IOChannel.cs
index d7e357a..cf5a0f3 100644
--- a/src/IOChannel.cs
+++ b/src/Imaging/IOChannel.cs
@@ -37,7 +37,7 @@ namespace FSpot {
public class DataReadEventArgs : EventArgs {
public bool Continue;
IOCondition condition;
-
+
public IOCondition Condition {
get { return condition; }
}
@@ -48,29 +48,29 @@ namespace FSpot {
Continue = true;
}
}
-
+
public class IOChannel : System.IO.Stream {
private HandleRef handle;
-
+
private delegate bool IOFunc (IntPtr source_channel, IOCondition cond, IntPtr data);
[DllImport("libglib-2.0-0.dll")]
static extern IOFlags g_io_channel_get_flags (HandleRef channel);
public override bool CanRead {
- get {
+ get {
IOFlags flags = g_io_channel_get_flags (handle);
- return (flags & IOFlags.Readable) == IOFlags.Readable;
+ return (flags & IOFlags.Readable) == IOFlags.Readable;
}
}
public override bool CanSeek {
get {
-#if NOTDONE
+#if NOTDONE
IOFlags flags = g_io_channel_get_flags (handle);
- return (flags & IOFlags.Seekable) == IOFlags.Seekable;
+ return (flags & IOFlags.Seekable) == IOFlags.Seekable;
#else
return false;
#endif
@@ -81,16 +81,16 @@ namespace FSpot {
get {
IOFlags flags = g_io_channel_get_flags (handle);
- return (flags & IOFlags.Writable) == IOFlags.Writable;
+ return (flags & IOFlags.Writable) == IOFlags.Writable;
}
}
public override long Length {
- get {
+ get {
throw new NotSupportedException ("IOChannel doesn't support seeking");
}
}
-
+
public override long Position {
get {
throw new NotSupportedException ("IOChannel doesn't support seeking");
@@ -125,7 +125,7 @@ namespace FSpot {
{
IOStatus status;
IntPtr error;
-
+
status = g_io_channel_flush (handle, out error);
if (status != IOStatus.Normal && status != IOStatus.Eof)
@@ -137,7 +137,7 @@ namespace FSpot {
[DllImport("libglib-2.0-0.dll")]
static extern unsafe IOStatus g_io_channel_write_chars (HandleRef channel, byte *data, int count, out int bytes_written, out IntPtr error);
-
+
public override void Write (byte [] buffer, int offset, int count)
{
IOStatus status = IOStatus.Again;
@@ -146,7 +146,7 @@ namespace FSpot {
if (buffer == null)
throw new ArgumentNullException ();
-
+
unsafe {
while (status == IOStatus.Again && count > 0) {
fixed (byte *data = &buffer [offset]) {
@@ -155,13 +155,13 @@ namespace FSpot {
if (error != IntPtr.Zero)
throw new GException (error);
-
+
offset += written;
count -= written;
}
}
}
-
+
[DllImport("libglib-2.0-0.dll")]
static unsafe extern IOStatus g_io_channel_read_chars (HandleRef channel, byte *data, int count, out int bytes_read, out IntPtr error);
@@ -193,7 +193,7 @@ namespace FSpot {
{
return g_io_add_watch (handle, condition, func, IntPtr.Zero);
}
-
+
// FIXME this should hold more than one source in a table
// but I am lazy
uint data_ready_source;
@@ -215,9 +215,9 @@ namespace FSpot {
private bool DataReadyHandler (IntPtr channel, IOCondition condition, IntPtr data)
{
DataReadEventArgs args = new DataReadEventArgs (condition);
- if (data_ready != null)
+ if (data_ready != null)
data_ready (this, args);
-
+
return args.Continue;
}
@@ -225,7 +225,7 @@ namespace FSpot {
{
throw new NotSupportedException ();
}
-
+
private enum SeekType {
Current,
Set,
@@ -237,7 +237,7 @@ namespace FSpot {
public override long Seek (long position, SeekOrigin origin)
{
-#if false
+#if false
// GIOChannels have the interesting property of having a seek interface
// but no method to retrieve the current position or length.
// we could support these actions for unix iochannels with extra work
@@ -246,13 +246,13 @@ namespace FSpot {
SeekType type;
IntPtr error;
long final;
-
+
switch (origin) {
case SeekOrigin.Begin:
type = SeekType.Set;
break;
case SeekOrigin.Current:
-
+
break;
}
@@ -260,7 +260,7 @@ namespace FSpot {
if (error != IntPtr.Zero)
throw new GException (error);
-
+
if (SeekOrigin == SeekOrigin.Begin)
return position;
else
@@ -284,7 +284,7 @@ namespace FSpot {
data_ready_source = 0;
g_io_channel_shutdown (handle, false, out error);
-
+
base.Close ();
if (error != IntPtr.Zero)
diff --git a/src/Imaging/ImageFile.cs b/src/Imaging/ImageFile.cs
index cd34063..6ec1238 100644
--- a/src/Imaging/ImageFile.cs
+++ b/src/Imaging/ImageFile.cs
@@ -51,6 +51,11 @@ namespace FSpot {
return Open ();
}
+ public static void AddExtension (string extension, Type type)
+ {
+ name_table [extension] = type;
+ }
+
static ImageFile ()
{
name_table = new Hashtable ();
diff --git a/src/InternalProcess.cs b/src/Imaging/InternalProcess.cs
similarity index 98%
rename from src/InternalProcess.cs
rename to src/Imaging/InternalProcess.cs
index 15d6e43..5ff29b9 100644
--- a/src/InternalProcess.cs
+++ b/src/Imaging/InternalProcess.cs
@@ -54,7 +54,7 @@ namespace FSpot {
IntPtr err,
//ref int stderr,
out IntPtr error);
-
+
public InternalProcess (string path, string [] args)
{
IntPtr error;
@@ -64,8 +64,8 @@ namespace FSpot {
Array.Copy (args, nargs, args.Length);
args = nargs;
}
-
- g_spawn_async_with_pipes (path, args, null, InternalProcessFlags.SearchPath,
+
+ g_spawn_async_with_pipes (path, args, null, InternalProcessFlags.SearchPath,
IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
ref stdin, ref stdout, IntPtr.Zero, out error);
diff --git a/src/MetadataStore.cs b/src/Imaging/MetadataStore.cs
similarity index 95%
rename from src/MetadataStore.cs
rename to src/Imaging/MetadataStore.cs
index 991b175..f9dac0f 100644
--- a/src/MetadataStore.cs
+++ b/src/Imaging/MetadataStore.cs
@@ -5,12 +5,12 @@ using FSpot.Xmp;
using FSpot.Utils;
namespace FSpot {
- internal class Description {
+ public class Description {
string predicate;
string description;
string title;
ValueFormat formater;
-
+
static System.Collections.Hashtable table;
static Description ()
@@ -20,7 +20,7 @@ namespace FSpot {
new Description ("dc:title", Catalog.GetString ("Title")),
new Description ("dc:rights", Catalog.GetString ("Copyright")),
new Description ("dc:subject", Catalog.GetString ("Subject and Keywords")),
- new Description ("tiff:Compression", Catalog.GetString ("Compression"),
+ new Description ("tiff:Compression", Catalog.GetString ("Compression"),
typeof (FSpot.Tiff.Compression)),
/* Translators: Planar Configuration is the label for the tiff:PlanarConfiguration tag
"when Planar Configuration=1, this implies that all components must have
@@ -28,19 +28,19 @@ namespace FSpot {
components could have different bit depths." */
new Description ("tiff:PlanarConfiguration", Catalog.GetString ("Planar Configuration"),
typeof (FSpot.Tiff.PlanarConfiguration)),
- new Description ("tiff:Orientation", Catalog.GetString ("Orientation"),
+ new Description ("tiff:Orientation", Catalog.GetString ("Orientation"),
typeof (PixbufOrientation)),
- new Description ("tiff:PhotometricInterpretation", Catalog.GetString ("Photometric Interpretation"),
+ new Description ("tiff:PhotometricInterpretation", Catalog.GetString ("Photometric Interpretation"),
typeof (FSpot.Tiff.PhotometricInterpretation)),
new Description ("tiff:ResolutionUnit", Catalog.GetString ("Resolution Unit"),
typeof (FSpot.Tiff.ResolutionUnit)),
- new Description ("exif:ExposureProgram", Catalog.GetString ("Exposure Program"),
+ new Description ("exif:ExposureProgram", Catalog.GetString ("Exposure Program"),
typeof (FSpot.Tiff.ExposureProgram)),
- new Description ("exif:MeteringMode", Catalog.GetString ("Metering Mode"),
+ new Description ("exif:MeteringMode", Catalog.GetString ("Metering Mode"),
typeof (FSpot.Tiff.MeteringMode)),
- new Description ("exif:ExposureMode", Catalog.GetString ("Exposure Mode"),
+ new Description ("exif:ExposureMode", Catalog.GetString ("Exposure Mode"),
typeof (FSpot.Tiff.ExposureMode)),
- new Description ("exif:CustomRendered", Catalog.GetString ("Custom Rendered"),
+ new Description ("exif:CustomRendered", Catalog.GetString ("Custom Rendered"),
typeof (FSpot.Tiff.CustomRendered)),
new Description ("exif:ComponentsConfiguration", Catalog.GetString ("Components Configuration"),
typeof (FSpot.Tiff.ComponentsConfiguration)),
@@ -74,18 +74,18 @@ namespace FSpot {
};
-
+
table = new System.Collections.Hashtable ();
foreach (Description d in preset) {
table [MetadataStore.Namespaces.Resolve (d.predicate)] = d;
}
}
-
+
public Description (string predicate, string title) : this (predicate, title, null, null) {}
public Description (string predicate, string title, string description) : this (predicate, title, description, null) {}
-
+
public Description (string predicate, string title, System.Type type) : this (predicate, title)
{
formater = new ValueFormat (type);
@@ -97,7 +97,7 @@ namespace FSpot {
this.title = title;
this.formater = formater;
}
-
+
public static void GetDescription (MemoryStore store, Statement stmt, out string label, out string value)
{
string predicate = stmt.Predicate.Uri;
@@ -119,7 +119,7 @@ namespace FSpot {
Statement sstmt = new Statement (stmt.Predicate,
(Entity)MetadataStore.Namespaces.Resolve ("rdfs:label"),
null);
-
+
foreach (Statement tstmt in MetadataStore.Descriptions.Select (sstmt))
if (tstmt.Object is SemWeb.Literal)
label = ((SemWeb.Literal)(tstmt.Object)).Value;
@@ -127,11 +127,11 @@ namespace FSpot {
return;
}
}
-
- internal class ValueFormat
+
+ public class ValueFormat
{
System.Type type;
-
+
public ValueFormat (System.Type type)
{
this.type = type;
@@ -152,17 +152,17 @@ namespace FSpot {
/*
else if (type == typeof (Rational)) {
object o = FSpot.Tiff.Rational.Parse (obj.Value);
- }
+ }
*/
return result;
}
}
-
+
public class MetadataStore : MemoryStore
{
public static NamespaceManager Namespaces;
private static MetadataStore descriptions;
-
+
public const string PhotoshopNS = "http://ns.adobe.com/photoshop/1.0/";
public const string Iptc4xmpCoreNS = "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/";
public const string DcNS = "http://purl.org/dc/elements/1.1/";
@@ -184,7 +184,7 @@ namespace FSpot {
static MetadataStore ()
{
Namespaces = new NamespaceManager ();
-
+
Namespaces.AddNamespace (PhotoshopNS, "photoshop");
Namespaces.AddNamespace (Iptc4xmpCoreNS, "Iptc4xmpCore");
Namespaces.AddNamespace (DcNS, "dc");
@@ -211,7 +211,7 @@ namespace FSpot {
System.Console.WriteLine ("Can't find resource");
}
}
-
+
return descriptions;
}
}
@@ -229,8 +229,8 @@ namespace FSpot {
{
Entity empty = new BNode ();
Statement top = new Statement (FSpotXMPBase, (Entity)MetadataStore.Namespaces.Resolve (predicate), empty);
- Statement desc = new Statement (empty,
- (Entity)MetadataStore.Namespaces.Resolve ("rdf:type"),
+ Statement desc = new Statement (empty,
+ (Entity)MetadataStore.Namespaces.Resolve ("rdf:type"),
(Entity)MetadataStore.Namespaces.Resolve (type));
sink.Add (desc);
Statement literal = new Statement (empty,
@@ -243,7 +243,7 @@ namespace FSpot {
public static void AddLiteral (StatementSink sink, string predicate, string value)
{
Statement stmt = new Statement (FSpotXMPBase,
- (Entity)MetadataStore.Namespaces.Resolve (predicate),
+ (Entity)MetadataStore.Namespaces.Resolve (predicate),
new SemWeb.Literal (value));
sink.Add (stmt);
}
@@ -304,7 +304,7 @@ namespace FSpot {
Add (this, predicate, type, values);
}
}
-
+
public static void Add (StatementSink sink, Entity subject, string predicate, string type, string [] values)
{
if (values == null) {
@@ -314,8 +314,8 @@ namespace FSpot {
Entity empty = new SemWeb.BNode();
Statement top = new Statement (subject, (Entity)MetadataStore.Namespaces.Resolve (predicate), empty);
- Statement desc = new Statement (empty,
- (Entity)MetadataStore.Namespaces.Resolve ("rdf:type"),
+ Statement desc = new Statement (empty,
+ (Entity)MetadataStore.Namespaces.Resolve ("rdf:type"),
(Entity)MetadataStore.Namespaces.Resolve (type));
sink.Add (desc);
foreach (string value in values) {
@@ -327,7 +327,7 @@ namespace FSpot {
sink.Add (top);
}
- private class StatementWriter : StatementSink
+ private class StatementWriter : StatementSink
{
string name;
public StatementWriter (string name)
@@ -355,14 +355,14 @@ namespace FSpot {
this.Statement = stmt;
return false;
}
- }
+ }
public void DumpNode (XPathSemWebNavigator navi, int depth)
{
- do {
+ do {
System.Console.WriteLine ("node [{0}] {1} {2}", depth, navi.Name, navi.Value);
} while (navi.MoveToNext ());
}
-
- }
+
+ }
}
diff --git a/src/Imaging/PixbufUtils.cs b/src/Imaging/PixbufUtils.cs
new file mode 100644
index 0000000..d073432
--- /dev/null
+++ b/src/Imaging/PixbufUtils.cs
@@ -0,0 +1,622 @@
+//
+// FSpot.PixbufUtils.cs
+//
+// Author(s):
+// Ettore Perazzoli
+// Larry Ewing <lewing novell com>
+// Stephane Delcroix <stephane declroix org>
+//
+// This is free softwae. See cOPYING for details
+//
+
+using Gdk;
+using System.Collections;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using FSpot;
+using FSpot.Utils;
+
+public class PixbufUtils {
+ public static int GetSize (Pixbuf pixbuf)
+ {
+ return Math.Max (pixbuf.Width, pixbuf.Height);
+ }
+
+ public static double Fit (Pixbuf pixbuf,
+ int dest_width, int dest_height,
+ bool upscale_smaller,
+ out int fit_width, out int fit_height)
+ {
+ return Fit (pixbuf.Width, pixbuf.Height,
+ dest_width, dest_height,
+ upscale_smaller,
+ out fit_width, out fit_height);
+ }
+
+ public static double Fit (int orig_width, int orig_height,
+ int dest_width, int dest_height,
+ bool upscale_smaller,
+ out int fit_width, out int fit_height)
+ {
+ if (orig_width == 0 || orig_height == 0) {
+ fit_width = 0;
+ fit_height = 0;
+ return 0.0;
+ }
+
+ double scale = Math.Min (dest_width / (double)orig_width,
+ dest_height / (double)orig_height);
+
+ if (scale > 1.0 && !upscale_smaller)
+ scale = 1.0;
+
+ fit_width = (int) Math.Round (scale * orig_width);
+ fit_height = (int) Math.Round (scale * orig_height);
+
+ return scale;
+ }
+
+
+ // FIXME: These should be in GTK#. When my patch is committed, these LoadFrom* methods will
+ // go away.
+
+ public class AspectLoader {
+ Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
+ int max_width;
+ int max_height;
+ PixbufOrientation orientation;
+
+ public AspectLoader (int max_width, int max_height)
+ {
+ this.max_height = max_height;
+ this.max_width = max_width;
+ loader.SizePrepared += HandleSizePrepared;
+ }
+
+ private void HandleSizePrepared (object obj, SizePreparedArgs args)
+ {
+ switch (orientation) {
+ case PixbufOrientation.LeftTop:
+ case PixbufOrientation.LeftBottom:
+ case PixbufOrientation.RightTop:
+ case PixbufOrientation.RightBottom:
+ int tmp = max_width;
+ max_width = max_height;
+ max_height = tmp;
+ break;
+ default:
+ break;
+ }
+
+ int scale_width = 0;
+ int scale_height = 0;
+
+ double scale = Fit (args.Width, args.Height, max_width, max_height, true, out scale_width, out scale_height);
+
+ if (scale < 1.0)
+ loader.SetSize (scale_width, scale_height);
+ }
+
+ public Pixbuf Load (System.IO.Stream stream, PixbufOrientation orientation)
+ {
+ int count;
+ byte [] data = new byte [8192];
+ while (((count = stream.Read (data, 0, data.Length)) > 0) && loader.Write (data, (ulong)count))
+ ;
+
+ loader.Close ();
+ Pixbuf orig = loader.Pixbuf;
+ Gdk.Pixbuf rotated = FSpot.Utils.PixbufUtils.TransformOrientation (orig, orientation);
+
+ if (orig != rotated) {
+ rotated.CopyThumbnailOptionsFrom (orig);
+ orig.Dispose ();
+ }
+ loader.Dispose ();
+ return rotated;
+ }
+
+ public Pixbuf LoadFromFile (string path)
+ {
+ try {
+ orientation = GetOrientation (path);
+ using (FileStream fs = File.OpenRead (path)) {
+ return Load (fs, orientation);
+ }
+ } catch (Exception) {
+ System.Console.WriteLine ("Error loading photo {0}", path);
+ return null;
+ }
+ }
+ }
+
+ [Obsolete ("Use the extension method instead!")]
+ public static Pixbuf ShallowCopy (Pixbuf pixbuf)
+ {
+ if (pixbuf == null)
+ return null;
+ return pixbuf.ShallowCopy ();
+ }
+
+ public static Pixbuf ScaleToMaxSize (Pixbuf pixbuf, int width, int height)
+ {
+ return ScaleToMaxSize (pixbuf, width, height, true);
+ }
+
+ public static Pixbuf ScaleToMaxSize (Pixbuf pixbuf, int width, int height, bool upscale)
+ {
+ int scale_width = 0;
+ int scale_height = 0;
+ double scale = Fit (pixbuf, width, height, upscale, out scale_width, out scale_height);
+
+ Gdk.Pixbuf result;
+ if (upscale || (scale < 1.0))
+ result = pixbuf.ScaleSimple (scale_width, scale_height, (scale_width > 20) ? Gdk.InterpType.Bilinear : Gdk.InterpType.Nearest);
+ else
+ result = pixbuf.Copy ();
+
+ result.CopyThumbnailOptionsFrom (pixbuf);
+
+ return result;
+ }
+
+ static public void GetSize (string path, out int width, out int height)
+ {
+#if true
+ using (Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (path)) {
+ width = pixbuf.Width;
+ height = pixbuf.Height;
+ }
+#else //yes, the pixbuf loader hack is smarter, but it leaks like an old women
+ Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
+ int orig_width = 0;
+ int orig_height = 0;
+ bool done = false;
+
+ loader.SizePrepared += delegate (object obj, SizePreparedArgs args) {
+ orig_width = args.Width;
+ orig_height = args.Height;
+ done = true;
+ };
+
+ using (Stream stream = File.OpenRead (path)) {
+ byte [] data = new byte [4096];
+ int count;
+
+ while (((count = stream.Read (data, 0, data.Length)) > 0) && loader.Write (data, (ulong)count)) {
+ if (done)
+ break;
+ }
+ }
+
+ width = orig_width;
+ height = orig_height;
+#endif
+ }
+
+ static public Pixbuf LoadAtMaxSize (string path, int max_width, int max_height)
+ {
+#if true
+ AspectLoader loader = new AspectLoader (max_width, max_height);
+ return loader.LoadFromFile (path);
+#else
+ int width, height;
+ JpegUtils.GetSize (path, out width, out height);
+ PixbufUtils.Fit (width, height, max_width, max_height, false, out width, out height);
+ Gdk.Pixbuf image = JpegUtils.LoadScaled (path, width, height);
+
+ return image;
+#endif
+ }
+
+ static public Pixbuf LoadFromStream (System.IO.Stream input)
+ {
+ Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
+ byte [] buffer = new byte [8192];
+ int n;
+
+ while ((n = input.Read (buffer, 0, 8192)) != 0)
+ loader.Write (buffer, (ulong) n);
+
+ loader.Close ();
+
+ return loader.Pixbuf;
+
+ }
+
+ public static void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream, string type, string [] options, string [] values)
+ {
+ byte [] data;
+
+ data = Save (pixbuf, type, options, values);
+ stream.Write (data, 0, data.Length);
+ }
+
+ static string [] NullTerminateArray (string [] options)
+ {
+ string [] terminated_options = options;
+
+ if (options != null && options [ options.Length - 1 ] != null) {
+ terminated_options = new string [options.Length + 1];
+ Array.Copy (options, terminated_options, options.Length);
+ }
+
+ return terminated_options;
+ }
+
+ [DllImport("libgdk_pixbuf-2.0-0.dll")]
+ static extern bool gdk_pixbuf_save_to_bufferv (IntPtr raw, out IntPtr data, out IntPtr length,
+ string type,
+ string [] keys, string [] values, out IntPtr error);
+
+
+ public static byte [] Save (Gdk.Pixbuf pixbuf, string type, string [] options, string [] values)
+ {
+ IntPtr error = IntPtr.Zero;
+ IntPtr data;
+ IntPtr length;
+
+ bool success = gdk_pixbuf_save_to_bufferv (pixbuf.Handle,
+ out data,
+ out length,
+ type,
+ NullTerminateArray (options),
+ NullTerminateArray (values),
+ out error);
+
+ if (error != IntPtr.Zero)
+ throw new GLib.GException (error);
+
+ if (!success)
+ throw new ApplicationException ("Unknown error while saving file");
+
+ byte [] content = new byte [(int)length];
+ Marshal.Copy (data, content, 0, (int)length);
+
+ GLib.Marshaller.Free (data);
+
+ return content;
+ }
+
+ static public Pixbuf LoadFromScreen (Gdk.Window win) {
+ Gdk.Screen screen = win.Screen;
+ Drawable d = screen.RootWindow;
+ int monitor = screen.GetMonitorAtWindow (win);
+ Gdk.Rectangle geom = screen.GetMonitorGeometry (monitor);
+
+ //
+ // We use the screen width and height because that reflects
+ // the current resolution, the RootWindow can actually be different.
+ //
+
+ Pixbuf buf = new Pixbuf (Colorspace.Rgb, false, 8, geom.Width, geom.Height);
+
+ return buf.GetFromDrawable (d,
+ d.Colormap, geom.X, geom.Y, 0, 0,
+ geom.Width, geom.Height);
+ }
+
+ static public Pixbuf LoadFromScreen () {
+ Screen screen = Display.Default.GetScreen (0);
+ Drawable d = screen.RootWindow;
+ int width = screen.Width;
+ int height = screen.Height;
+
+ //
+ // We use the screen width and height because that reflects
+ // the current resolution, the RootWindow can actually be different.
+ //
+
+ Pixbuf buf = new Pixbuf (Colorspace.Rgb, false, 8, width, height);
+
+ return buf.GetFromDrawable (d,
+ d.Colormap, 0, 0, 0, 0,
+ width, height);
+ }
+
+ static public Pixbuf LoadFromAssembly (string resource)
+ {
+ try {
+ return new Pixbuf (System.Reflection.Assembly.GetEntryAssembly (), resource);
+ } catch {
+ return null;
+ }
+ }
+
+ [DllImport ("libc")]
+ static extern int rename (string oldpath, string newpath);
+
+ public static void SaveAtomic (Gdk.Pixbuf src, string filename, string type, string [] keys, string [] values)
+ {
+ string tmpname = filename + ".tmp";
+ src.Savev (tmpname, type, NullTerminateArray (keys), NullTerminateArray (values));
+ if (rename (tmpname, filename) < 0)
+ throw new Exception ("Error renaming file");
+ }
+
+ public static Gdk.Pixbuf ScaleToAspect (Gdk.Pixbuf orig, int width, int height)
+ {
+ Gdk.Rectangle pos;
+ double scale = Fit (orig, width, height, false, out pos.Width, out pos.Height);
+ pos.X = (width - pos.Width) / 2;
+ pos.Y = (height - pos.Height) / 2;
+
+ Pixbuf scaled = new Pixbuf (Colorspace.Rgb, false, 8, width, height);
+ scaled.Fill (0x000000);
+
+ orig.Composite (scaled, pos.X, pos.Y,
+ pos.Width, pos.Height,
+ pos.X, pos.Y, scale, scale,
+ Gdk.InterpType.Bilinear,
+ 255);
+
+ return scaled;
+ }
+
+ public static Pixbuf Flatten (Pixbuf pixbuf)
+ {
+ if (!pixbuf.HasAlpha)
+ return null;
+
+ Pixbuf flattened = new Pixbuf (Colorspace.Rgb, false, 8, pixbuf.Width, pixbuf.Height);
+ pixbuf.CompositeColor (flattened, 0, 0,
+ pixbuf.Width, pixbuf.Height,
+ 0, 0, 1, 1,
+ InterpType.Bilinear,
+ 255, 0, 0, 2000, 0xffffff, 0xffffff);
+
+ return flattened;
+ }
+
+
+
+ [DllImport ("libfspot")]
+ static extern IntPtr f_pixbuf_unsharp_mask (IntPtr src, double radius, double amount, double threshold);
+
+ public static Pixbuf UnsharpMask (Pixbuf src, double radius, double amount, double threshold)
+ {
+ IntPtr raw_ret = f_pixbuf_unsharp_mask (src.Handle, radius, amount, threshold);
+ Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
+ return ret;
+ }
+
+ [DllImport ("libfspot")]
+ static extern IntPtr f_pixbuf_blur (IntPtr src, double radius);
+
+ public static Pixbuf Blur (Pixbuf src, double radius)
+ {
+ IntPtr raw_ret = f_pixbuf_blur (src.Handle, radius);
+ Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
+ return ret;
+ }
+
+ public unsafe static Gdk.Pixbuf RemoveRedeye (Gdk.Pixbuf src, Gdk.Rectangle area)
+ {
+ return RemoveRedeye (src, area, -15);
+ }
+
+ public unsafe static Gdk.Pixbuf RemoveRedeye (Gdk.Pixbuf src, Gdk.Rectangle area, int threshold)
+ //threshold, factors and comparisons borrowed from the gimp plugin 'redeye.c' by Robert Merkel
+ {
+ Gdk.Pixbuf copy = src.Copy ();
+ Gdk.Pixbuf selection = new Gdk.Pixbuf (copy, area.X, area.Y, area.Width, area.Height);
+ byte *spix = (byte *)selection.Pixels;
+ int h = selection.Height;
+ int w = selection.Width;
+ int channels = src.NChannels;
+
+ double RED_FACTOR = 0.5133333;
+ double GREEN_FACTOR = 1;
+ double BLUE_FACTOR = 0.1933333;
+
+ for (int j = 0; j < h; j++) {
+ byte *s = spix;
+ for (int i = 0; i < w; i++) {
+ int adjusted_red = (int)(s[0] * RED_FACTOR);
+ int adjusted_green = (int)(s[1] * GREEN_FACTOR);
+ int adjusted_blue = (int)(s[2] * BLUE_FACTOR);
+
+ if (adjusted_red >= adjusted_green - threshold
+ && adjusted_red >= adjusted_blue - threshold)
+ s[0] = (byte)(((double)(adjusted_green + adjusted_blue)) / (2.0 * RED_FACTOR));
+ s += channels;
+ }
+ spix += selection.Rowstride;
+ }
+
+ return copy;
+ }
+
+ public static unsafe Pixbuf ColorAdjust (Pixbuf src, double brightness, double contrast,
+ double hue, double saturation, int src_color, int dest_color)
+ {
+ Pixbuf adjusted = new Pixbuf (Colorspace.Rgb, src.HasAlpha, 8, src.Width, src.Height);
+ ColorAdjust (src, adjusted, brightness, contrast, hue, saturation, src_color, dest_color);
+ return adjusted;
+ }
+
+ public static Cms.Format PixbufCmsFormat (Pixbuf buf)
+ {
+ return buf.HasAlpha ? Cms.Format.Rgba8Planar : Cms.Format.Rgb8;
+ }
+
+ public static unsafe void ColorAdjust (Pixbuf src, Pixbuf dest,
+ double brightness, double contrast,
+ double hue, double saturation,
+ int src_color, int dest_color)
+ {
+ if (src.Width != dest.Width || src.Height != dest.Height)
+ throw new Exception ("Invalid Dimensions");
+
+ //Cms.Profile eos10d = new Cms.Profile ("/home/lewing/ICCProfiles/EOS-10D-True-Color-Non-Linear.icm");
+ Cms.Profile srgb = Cms.Profile.CreateStandardRgb ();
+
+ Cms.Profile bchsw = Cms.Profile.CreateAbstract (256,
+ 0.0,
+ brightness, contrast,
+ hue, saturation, src_color,
+ dest_color);
+
+ Cms.Profile [] list = new Cms.Profile [] { srgb, bchsw, srgb };
+ Cms.Transform trans = new Cms.Transform (list,
+ PixbufCmsFormat (src),
+ PixbufCmsFormat (dest),
+ Cms.Intent.Perceptual, 0x0100);
+
+ ColorAdjust (src, dest, trans);
+
+ trans.Dispose ();
+ srgb.Dispose ();
+ bchsw.Dispose ();
+ }
+
+
+ public static unsafe void ColorAdjust (Gdk.Pixbuf src, Gdk.Pixbuf dest, Cms.Transform trans)
+ {
+ int width = src.Width;
+ byte * srcpix = (byte *) src.Pixels;
+ byte * destpix = (byte *) dest.Pixels;
+
+ for (int row = 0; row < src.Height; row++) {
+ trans.Apply ((IntPtr) (srcpix + row * src.Rowstride),
+ (IntPtr) (destpix + row * dest.Rowstride),
+ (uint)width);
+ }
+
+ }
+
+ public static unsafe bool IsGray (Gdk.Pixbuf pixbuf, int max_difference)
+ {
+ int chan = pixbuf.NChannels;
+
+ byte *pix = (byte *)pixbuf.Pixels;
+ int h = pixbuf.Height;
+ int w = pixbuf.Width;
+ int stride = pixbuf.Rowstride;
+
+ for (int j = 0; j < h; j++) {
+ byte *p = pix;
+ for (int i = 0; i < w; i++) {
+ if (Math.Abs (p[0] - p[1]) > max_difference || Math.Abs (p[0] - p [2]) > max_difference) {
+ goto Found;
+ }
+ p += chan;
+ }
+ pix += stride;
+ }
+
+ return true;
+
+ Found:
+ return false;
+ }
+
+ public static unsafe void ReplaceColor (Gdk.Pixbuf src, Gdk.Pixbuf dest)
+ {
+ if (src.HasAlpha || !dest.HasAlpha || (src.Width != dest.Width) || (src.Height != dest.Height))
+ throw new ApplicationException ("invalid pixbufs");
+
+ byte *dpix = (byte *)dest.Pixels;
+ byte *spix = (byte *)src.Pixels;
+ int h = src.Height;
+ int w = src.Width;
+ for (int j = 0; j < h; j++) {
+ byte *d = dpix;
+ byte *s = spix;
+ for (int i = 0; i < w; i++) {
+ d[0] = s[0];
+ d[1] = s[1];
+ d[2] = s[2];
+ d += 4;
+ s += 3;
+ }
+ dpix += dest.Rowstride;
+ spix += src.Rowstride;
+ }
+ }
+
+ public static Gdk.Pixbuf GetThumbnail (Exif.ExifData data)
+ {
+ byte [] thumb_data = data.Data;
+ if (thumb_data.Length > 0) {
+ PixbufOrientation orientation = GetOrientation (data);
+
+ using (MemoryStream mem = new MemoryStream (thumb_data)) {
+ Gdk.Pixbuf thumb = new Gdk.Pixbuf (mem);
+
+ Gdk.Pixbuf rotated = FSpot.Utils.PixbufUtils.TransformOrientation (thumb, orientation);
+
+ if (rotated != thumb)
+ thumb.Dispose ();
+ return rotated;
+ }
+ }
+ return null;
+ }
+
+ public static PixbufOrientation GetOrientation (Exif.ExifData data)
+ {
+ PixbufOrientation orientation = PixbufOrientation.TopLeft;
+
+ Exif.ExifEntry e = data.GetContents (Exif.Ifd.Zero).Lookup (Exif.Tag.Orientation);
+
+ if (e != null) {
+ ushort [] value = e.GetDataUShort ();
+ orientation = (PixbufOrientation) value [0];
+ }
+
+ return orientation;
+ }
+
+ public static PixbufOrientation GetOrientation (System.Uri uri)
+ {
+ using (FSpot.ImageFile img = FSpot.ImageFile.Create (uri)) {
+ return img.Orientation;
+ }
+ }
+
+ [Obsolete ("Use GetOrientation (System.Uri) instead")]
+ public static PixbufOrientation GetOrientation (string path)
+ {
+ using (FSpot.ImageFile img = FSpot.ImageFile.Create (path)) {
+ return img.Orientation;
+ }
+ }
+
+ [DllImport("libgnomeui-2-0.dll")]
+ static extern IntPtr gnome_thumbnail_scale_down_pixbuf(IntPtr pixbuf, int dest_width, int dest_height);
+
+ public static Gdk.Pixbuf ScaleDown (Gdk.Pixbuf src, int width, int height)
+ {
+ IntPtr raw_ret = gnome_thumbnail_scale_down_pixbuf(src.Handle, width, height);
+ Gdk.Pixbuf ret;
+ if (raw_ret == IntPtr.Zero)
+ ret = null;
+ else
+ ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
+ return ret;
+ }
+
+ // Bindings from libf.
+
+ [DllImport ("libfspot")]
+ static extern IntPtr f_pixbuf_copy_apply_brightness_and_contrast (IntPtr src, float brightness, float contrast);
+
+ public static Pixbuf ApplyBrightnessAndContrast (Pixbuf src, float brightness, float contrast)
+ {
+ return new Pixbuf (f_pixbuf_copy_apply_brightness_and_contrast (src.Handle, brightness, contrast));
+ }
+
+ [DllImport ("libfspot")]
+ static extern bool f_pixbuf_save_jpeg_atomic (IntPtr pixbuf, string filename, int quality, out IntPtr error);
+
+ public static void SaveAsJpegAtomically (Pixbuf pixbuf, string filename, int quality)
+ {
+ IntPtr error = IntPtr.Zero;
+
+ if (! f_pixbuf_save_jpeg_atomic (pixbuf.Handle, filename, quality, out error)) {
+ throw new GLib.GException (error);
+ }
+ }
+}
diff --git a/src/PixelBuffer.cs b/src/Imaging/PixelBuffer.cs
similarity index 98%
rename from src/PixelBuffer.cs
rename to src/Imaging/PixelBuffer.cs
index 544aa94..c1b1d09 100644
--- a/src/PixelBuffer.cs
+++ b/src/Imaging/PixelBuffer.cs
@@ -28,11 +28,11 @@ namespace FSpot.Imaging {
width = pixbuf.Width;
height = pixbuf.Height;
this.nchannels = pixbuf.HasAlpha ? 4 : 3;
-
+
depth = PixelBufferDepth.UInt16;
data = new ushort [width * height * nchannels];
-
+
unsafe {
byte * src_pixels = (byte *) pixbuf.Pixels;
int src_stride = pixbuf.Rowstride;
@@ -53,10 +53,10 @@ namespace FSpot.Imaging {
public unsafe void Fill8 (int i, int j, byte * src_data, int offset, int count)
{
ushort * rowpix;
-
+
fixed (ushort * pixels = &data [0]) {
rowpix = pixels + i * rowstride + j;
-
+
for (int col = 0; col < count; col++) {
int val = src_data [col];
rowpix [col] = (ushort) (val << 8 & val);
@@ -80,9 +80,9 @@ namespace FSpot.Imaging {
else
Fill16Swap (i, j, src_data, offset, count);
}
-
+
public void Fill16 (int i, int j, byte [] src_data, int offset, int count)
- {
+ {
unsafe {
ushort * rowpix;
@@ -115,24 +115,24 @@ namespace FSpot.Imaging {
}
}
}
-
+
public override Gdk.Pixbuf ToPixbuf (Cms.Profile destination_profile)
{
#if true //USE_LCMS
profile = Cms.Profile.CreateStandardRgb ();
Cms.Profile [] list = new Cms.Profile [] { profile, destination_profile };
- Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, 8,
+ Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, 8,
width, height);
-
+
Cms.Transform t = new Cms.Transform (list,
Cms.Format.Rgb16,
PixbufUtils.PixbufCmsFormat (pixbuf),
Cms.Intent.Perceptual, 0x0);
-
+
unsafe {
fixed (ushort * srcpix = &data[0]) {
byte * destpix = (byte *) pixbuf.Pixels;
-
+
for (int row = 0; row < height; row++)
t.Apply ((IntPtr) (srcpix + row * rowstride),
(IntPtr) (destpix + row * pixbuf.Rowstride),
@@ -142,18 +142,18 @@ namespace FSpot.Imaging {
return pixbuf;
#else
- Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, 8,
+ Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, 8,
width, height);
unsafe {
fixed (ushort * src = &data[0]) {
ushort * srcpix = src;
byte * destpix = (byte *) pixbuf.Pixels;
-
+
for (int row = 0; row < height; row++) {
for (int col = 0; col < width * nchannels; col++)
destpix [col] = (byte) (srcpix [col] >> 8);
-
+
srcpix += rowstride;
destpix += pixbuf.Rowstride;
}
@@ -168,8 +168,8 @@ namespace FSpot.Imaging {
#if false
public class UInt8Buffer : PixelBuffer {
protected ushort [] data;
-
-
+
+
}
public class PixbufBuffer : PixelBuffer {
diff --git a/src/Loaders/GdkImageLoader.cs b/src/Loaders/GdkImageLoader.cs
index 58fcd30..4ace520 100644
--- a/src/Loaders/GdkImageLoader.cs
+++ b/src/Loaders/GdkImageLoader.cs
@@ -28,13 +28,13 @@ namespace FSpot.Loaders {
Pixbuf thumbnail;
public Pixbuf Thumbnail {
- get { return PixbufUtils.ShallowCopy (thumbnail); }
+ get { return thumbnail.ShallowCopy (); }
private set { thumbnail = value; }
}
public PixbufOrientation ThumbnailOrientation { get; private set; }
public Pixbuf Large {
- get { return PixbufUtils.ShallowCopy (Pixbuf); }
+ get { return Pixbuf.ShallowCopy (); }
}
public PixbufOrientation LargeOrientation { get; private set; }
@@ -204,8 +204,8 @@ 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)) {
- image_stream = image_file.PixbufStream ();
LargeOrientation = image_file.Orientation;
}
diff --git a/src/Loaders/LibrawImageLoader.cs b/src/Loaders/LibrawImageLoader.cs
index 64517ba..2f8bbdb 100644
--- a/src/Loaders/LibrawImageLoader.cs
+++ b/src/Loaders/LibrawImageLoader.cs
@@ -30,20 +30,20 @@ namespace FSpot.Loaders {
Pixbuf thumbnail;
public Pixbuf Thumbnail {
- get { return PixbufUtils.ShallowCopy (thumbnail); }
+ get { return thumbnail.ShallowCopy (); }
private set { thumbnail = value; }
}
public PixbufOrientation ThumbnailOrientation { get; private set; }
Pixbuf large;
public Pixbuf Large {
- get { return PixbufUtils.ShallowCopy (large); }
+ get { return large.ShallowCopy (); }
}
public PixbufOrientation LargeOrientation { get; private set; }
Pixbuf full;
public Pixbuf Full {
- get { return PixbufUtils.ShallowCopy (full); }
+ get { return full.ShallowCopy (); }
}
public PixbufOrientation FullOrientation { get; private set; }
diff --git a/src/MainWindow.cs b/src/MainWindow.cs
index 44574c3..af253a1 100644
--- a/src/MainWindow.cs
+++ b/src/MainWindow.cs
@@ -943,7 +943,7 @@ namespace FSpot
Pixbuf icon = null;
try {
Pixbuf tmp = FSpot.PhotoLoader.LoadAtMaxSize (query [nums[0]], 128, 128);
- icon = PixbufUtils.TagIconFromPixbuf (tmp);
+ icon = FSpotPixbufUtils.TagIconFromPixbuf (tmp);
tmp.Dispose ();
} catch {
icon = null;
diff --git a/src/Makefile.am b/src/Makefile.am
index 875edcd..7f98254 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -40,6 +40,46 @@ CORE_CSDISTFILES = \
$(srcdir)/Core/PhotosChanges.cs \
$(srcdir)/Core/Roll.cs
+IMAGING_CSDISTFILES = \
+ $(srcdir)/Imaging/PixbufUtils.cs \
+ $(srcdir)/Imaging/DCRawFile.cs \
+ $(srcdir)/Imaging/BitConverter.cs \
+ $(srcdir)/Imaging/Bim.cs \
+ $(srcdir)/Imaging/Ciff.cs \
+ $(srcdir)/Imaging/Exif.cs \
+ $(srcdir)/Imaging/ImageFile.cs \
+ $(srcdir)/Imaging/IptcFile.cs \
+ $(srcdir)/Imaging/InternalProcess.cs \
+ $(srcdir)/Imaging/IOChannel.cs \
+ $(srcdir)/Imaging/IRawFile.cs \
+ $(srcdir)/Imaging/JpegFile.cs \
+ $(srcdir)/Imaging/JpegHeader.cs \
+ $(srcdir)/Imaging/JpegUtils.cs \
+ $(srcdir)/Imaging/MetadataStore.cs \
+ $(srcdir)/Imaging/MrwFile.cs \
+ $(srcdir)/Imaging/OrderedWriter.cs \
+ $(srcdir)/Imaging/PixelBuffer.cs \
+ $(srcdir)/Imaging/PngFile.cs \
+ $(srcdir)/Imaging/PnmFile.cs \
+ $(srcdir)/Imaging/RafFile.cs \
+ $(srcdir)/Imaging/SvgFile.cs \
+ $(srcdir)/Imaging/X3fFile.cs \
+ $(srcdir)/Imaging/XmpFile.cs \
+ $(srcdir)/Imaging/Tiff.cs
+
+LOADERS_CSDISTFILES = \
+ $(srcdir)/Loaders/AreaPreparedEventArgs.cs \
+ $(srcdir)/Loaders/AreaUpdatedEventArgs.cs \
+ $(srcdir)/Loaders/GdkImageLoader.cs \
+ $(srcdir)/Loaders/IImageLoader.cs \
+ $(srcdir)/Loaders/IImageLoaderExtensions.cs \
+ $(srcdir)/Loaders/ImageLoader.cs \
+ $(srcdir)/Loaders/ImageLoaderItem.cs \
+ $(srcdir)/Loaders/ImageLoaderItemExtensions.cs \
+ $(srcdir)/Loaders/ItemCompletedEventArgs.cs \
+ $(srcdir)/Loaders/LibrawImageLoader.cs \
+ $(srcdir)/Loaders/ProgressHintEventArgs.cs
+
QUERY_CSDISTFILES = \
$(srcdir)/Query/DateRange.cs \
$(srcdir)/Query/FolderSet.cs \
@@ -61,6 +101,7 @@ UTILS_CSDISTFILES = \
$(srcdir)/Utils/GdkUtils.cs \
$(srcdir)/Utils/GtkUtil.cs \
$(srcdir)/Utils/Log.cs \
+ $(srcdir)/Utils/PixbufExtensions.cs \
$(srcdir)/Utils/PixbufOrientation.cs \
$(srcdir)/Utils/PixbufUtils.cs \
$(srcdir)/Utils/RecursiveFileEnumerator.cs \
@@ -127,7 +168,6 @@ NULL_PLATFORM_CSDISTFILES = \
F_SPOT_CSDISTFILES = \
$(srcdir)/BlockProcessor.cs \
- $(srcdir)/BitConverter.cs \
$(srcdir)/PhotoList.cs \
$(srcdir)/ColorAdjustment/Adjustment.cs \
$(srcdir)/ColorAdjustment/AutoStretch.cs \
@@ -186,43 +226,11 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/GroupSelector.cs \
$(srcdir)/Accelerometer.cs \
$(srcdir)/Histogram.cs \
- $(srcdir)/Loaders/AreaPreparedEventArgs.cs \
- $(srcdir)/Loaders/AreaUpdatedEventArgs.cs \
- $(srcdir)/Loaders/GdkImageLoader.cs \
- $(srcdir)/Loaders/IImageLoader.cs \
- $(srcdir)/Loaders/IImageLoaderExtensions.cs \
- $(srcdir)/Loaders/ImageLoader.cs \
- $(srcdir)/Loaders/ImageLoaderItem.cs \
- $(srcdir)/Loaders/ImageLoaderItemExtensions.cs \
- $(srcdir)/Loaders/ItemCompletedEventArgs.cs \
- $(srcdir)/Loaders/LibrawImageLoader.cs \
- $(srcdir)/Loaders/ProgressHintEventArgs.cs \
$(srcdir)/ImageLoaderThread.cs \
$(srcdir)/ImportBackend.cs \
$(srcdir)/ImportCommand.cs \
$(srcdir)/InfoOverlay.cs \
- $(srcdir)/InternalProcess.cs \
- $(srcdir)/IOChannel.cs \
$(srcdir)/ItemAction.cs \
- $(srcdir)/Imaging/DCRawFile.cs \
- $(srcdir)/Imaging/Bim.cs \
- $(srcdir)/Imaging/Ciff.cs \
- $(srcdir)/Imaging/Exif.cs \
- $(srcdir)/Imaging/ImageFile.cs \
- $(srcdir)/Imaging/IptcFile.cs \
- $(srcdir)/Imaging/IRawFile.cs \
- $(srcdir)/Imaging/JpegFile.cs \
- $(srcdir)/Imaging/JpegHeader.cs \
- $(srcdir)/Imaging/JpegUtils.cs \
- $(srcdir)/Imaging/MrwFile.cs \
- $(srcdir)/Imaging/OrderedWriter.cs \
- $(srcdir)/Imaging/PngFile.cs \
- $(srcdir)/Imaging/PnmFile.cs \
- $(srcdir)/Imaging/RafFile.cs \
- $(srcdir)/Imaging/SvgFile.cs \
- $(srcdir)/Imaging/X3fFile.cs \
- $(srcdir)/Imaging/XmpFile.cs \
- $(srcdir)/Imaging/Tiff.cs \
$(srcdir)/JobStore.cs \
$(srcdir)/Jobs/SyncMetadataJob.cs \
$(srcdir)/Jobs/CalculateHashJob.cs \
@@ -230,7 +238,6 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/MainWindow.cs \
$(srcdir)/MemorySurface.cs \
$(srcdir)/MetaStore.cs \
- $(srcdir)/MetadataStore.cs \
$(srcdir)/PhotoEventArgs.cs \
$(srcdir)/PhotoImageView.cs \
$(srcdir)/PhotoLoader.cs \
@@ -241,9 +248,8 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/PhotoVersionCommands.cs \
$(srcdir)/PhotoVersionMenu.cs \
$(srcdir)/PhotoView.cs \
- $(srcdir)/PixbufUtils.cs \
$(srcdir)/PixbufCache.cs \
- $(srcdir)/PixelBuffer.cs \
+ $(srcdir)/PixbufUtils.cs \
$(srcdir)/Preferences.cs \
$(srcdir)/PrintOperation.cs \
$(srcdir)/ProgressItem.cs \
@@ -343,6 +349,28 @@ CORE_ASSEMBLIES = \
-r:Mono.Posix \
-r:FSpot.Utils.dll
+IMAGING_ASSEMBLIES = \
+ $(LINK_SEMWEB) \
+ $(LINK_GIOSHARP) \
+ $(LINK_GTKSHARPBEANS) \
+ -pkg:gnome-sharp-2.0 \
+ -pkg:gtk-sharp-2.0 \
+ -r:ICSharpCode.SharpZipLib \
+ -r:Cms.dll \
+ -r:Mono.Posix \
+ -r:FSpot.Core.dll \
+ -r:FSpot.Utils.dll
+
+LOADERS_ASSEMBLIES = \
+ $(LINK_GIOSHARP) \
+ $(LINK_GTKSHARPBEANS) \
+ $(LINK_FSPOTRAWSHARP) \
+ -pkg:gtk-sharp-2.0 \
+ -r:Mono.Posix \
+ -r:FSpot.Imaging.dll \
+ -r:FSpot.Platform.dll \
+ -r:FSpot.Utils.dll
+
QUERY_ASSEMBLIES = \
$(LINK_GIOSHARP) \
-r:FSpot.Core.dll \
@@ -396,18 +424,19 @@ F_SPOT_ASSEMBLIES = \
$(LINK_KEYRING) \
$(LINK_SMUGMUG) \
$(LINK_SEMWEB) \
+ $(LINK_FSPOTRAWSHARP) \
$(LINK_GTKSHARPBEANS) \
$(LINK_GIOSHARP) \
$(LINK_UNIQUESHARP) \
- $(LINK_FSPOTRAWSHARP) \
-r:System.Data \
-r:System.Web \
-r:Mono.Data.SqliteClient \
-r:Mono.Posix \
-r:Mono.Security \
-r:Mono.Cairo \
- -r:ICSharpCode.SharpZipLib \
-r:FSpot.Core.dll \
+ -r:FSpot.Imaging.dll \
+ -r:FSpot.Loaders.dll \
-r:FSpot.Query.dll \
-r:FSpot.Utils.dll \
-r:FSpot.JobScheduler.dll \
@@ -456,6 +485,10 @@ fspotlib_DATA = f-spot.exe.config \
FSpot.Utils.dll \
FSpot.Utils.dll.mdb \
FSpot.Utils.dll.config \
+ FSpot.Imaging.dll \
+ FSpot.Imaging.dll.mdb \
+ FSpot.Loaders.dll \
+ FSpot.Loaders.dll.mdb \
FSpot.Query.dll \
FSpot.Query.dll.mdb \
FSpot.Core.dll \
@@ -477,6 +510,10 @@ CMS_CSFILES = $(CMS_CSDISTFILES)
CORE_CSFILES = $(CORE_CSDISTFILES) \
Core/Defines.cs
+IMAGING_CSFILES = $(IMAGING_CSDISTFILES)
+
+LOADERS_CSFILES = $(LOADERS_CSDISTFILES)
+
QUERY_CSFILES = $(QUERY_CSDISTFILES)
UTILS_CSFILES = $(UTILS_CSDISTFILES)
@@ -504,6 +541,16 @@ FSpot.Core.dll.mdb: FSpot.Core.dll
FSpot.Core.dll: $(CORE_CSFILES) FSpot.Utils.dll Cms.dll
$(CSC_LIB) -warnaserror -out:$@ $(EXTRAFLAGS) $(CORE_CSFILES) $(CORE_ASSEMBLIES)
+FSpot.Imaging.dll.mdb: FSpot.Imaging.dll
+
+FSpot.Imaging.dll: $(IMAGING_CSFILES) FSpot.Utils.dll FSpot.Core.dll
+ $(CSC_LIB) -out:$@ $(EXTRAFLAGS) $(UNSAFE) $(IMAGING_CSFILES) $(IMAGING_ASSEMBLIES)
+
+FSpot.Loaders.dll.mdb: FSpot.Loaders.dll
+
+FSpot.Loaders.dll: $(LOADERS_CSFILES) FSpot.Platform.dll FSpot.Utils.dll FSpot.Imaging.dll
+ $(CSC_LIB) -out:$@ $(EXTRAFLAGS) $(LOADERS_CSFILES) $(LOADERS_ASSEMBLIES)
+
FSpot.Query.dll.mdb: FSpot.Query.dll
FSpot.Query.dll: $(QUERY_CSFILES) FSpot.Utils.dll FSpot.Core.dll
@@ -539,7 +586,7 @@ FSpot.Platform.dll: $(PLATFORM_CSFILES) FSpot.Utils.dll
f-spot.exe.mdb: f-spot.exe
-f-spot.exe: $(F_SPOT_CSFILES) FSpot.Utils.dll FSpot.Core.dll FSpot.Query.dll FSpot.JobScheduler.dll FSpot.Bling.dll FSpot.Widgets.dll Cms.dll FSpot.Platform.dll $(F_SPOT_RESOURCES)
+f-spot.exe: $(F_SPOT_CSFILES) FSpot.Utils.dll FSpot.Core.dll FSpot.Imaging.dll FSpot.Loaders.dll FSpot.Query.dll FSpot.JobScheduler.dll FSpot.Bling.dll FSpot.Widgets.dll Cms.dll FSpot.Platform.dll $(F_SPOT_RESOURCES)
$(CSC) -target:winexe -out:$@ $(EXTRAFLAGS) $(UNSAFE) $(NOWARN) $(NUNIT_DEFINES) $(F_SPOT_CSFILES) $(F_SPOT_ASSEMBLIES) $(RESOURCES)
all: f-spot.exe
@@ -548,6 +595,8 @@ EXTRA_DIST = \
$(UTILS_CSDISTFILES) \
$(CMS_CSDISTFILES) \
$(CORE_CSDISTFILES) \
+ $(IMAGING_CSDISTFILES) \
+ $(LOADERS_CSDISTFILES) \
$(QUERY_CSDISTFILES) \
$(JOBSCHEDULER_CSDISTFILES) \
$(BLING_CSDISTFILES) \
@@ -571,6 +620,10 @@ CLEANFILES = \
Cms.dll \
FSpot.Utils.dll.mdb \
FSpot.Utils.dll \
+ FSpot.Imaging.dll \
+ FSpot.Imaging.dll.mdb \
+ FSpot.Loaders.dll \
+ FSpot.Loaders.dll.mdb \
FSpot.Query.dll \
FSpot.Query.dll.mdb \
FSpot.Core.dll.mdb \
diff --git a/src/PhotoImageView.cs b/src/PhotoImageView.cs
index eaa9e3e..5d75ec8 100644
--- a/src/PhotoImageView.cs
+++ b/src/PhotoImageView.cs
@@ -346,9 +346,10 @@ namespace FSpot.Widgets {
// like offer the user a chance to locate the moved file and
// update the db entry, but for now just set the error pixbuf
Pixbuf old = Pixbuf;
- Pixbuf = new Pixbuf (PixbufUtils.ErrorPixbuf, 0, 0,
- PixbufUtils.ErrorPixbuf.Width,
- PixbufUtils.ErrorPixbuf.Height);
+ Pixbuf err = new Pixbuf (FSpotPixbufUtils.ErrorPixbuf, 0, 0,
+ FSpotPixbufUtils.ErrorPixbuf.Width,
+ FSpotPixbufUtils.ErrorPixbuf.Height);
+ ChangeImage (err, PixbufOrientation.TopLeft, true, false);
if (old != null)
old.Dispose ();
diff --git a/src/PixbufUtils.cs b/src/PixbufUtils.cs
index 87baa26..7a05028 100644
--- a/src/PixbufUtils.cs
+++ b/src/PixbufUtils.cs
@@ -11,13 +11,13 @@
using Gdk;
using System.Collections;
-using System.Runtime.InteropServices;
using System;
using System.IO;
+using System.Runtime.InteropServices;
using FSpot;
using FSpot.Utils;
-public class PixbufUtils {
+public class FSpotPixbufUtils {
static Pixbuf error_pixbuf = null;
public static Pixbuf ErrorPixbuf {
get {
@@ -27,270 +27,6 @@ public class PixbufUtils {
}
}
public static Pixbuf LoadingPixbuf = PixbufUtils.LoadFromAssembly ("f-spot-loading.png");
-
- public static int GetSize (Pixbuf pixbuf)
- {
- return Math.Max (pixbuf.Width, pixbuf.Height);
- }
-
- public static double Fit (Pixbuf pixbuf,
- int dest_width, int dest_height,
- bool upscale_smaller,
- out int fit_width, out int fit_height)
- {
- return Fit (pixbuf.Width, pixbuf.Height,
- dest_width, dest_height,
- upscale_smaller,
- out fit_width, out fit_height);
- }
-
- public static double Fit (int orig_width, int orig_height,
- int dest_width, int dest_height,
- bool upscale_smaller,
- out int fit_width, out int fit_height)
- {
- if (orig_width == 0 || orig_height == 0) {
- fit_width = 0;
- fit_height = 0;
- return 0.0;
- }
-
- double scale = Math.Min (dest_width / (double)orig_width,
- dest_height / (double)orig_height);
-
- if (scale > 1.0 && !upscale_smaller)
- scale = 1.0;
-
- fit_width = (int) Math.Round (scale * orig_width);
- fit_height = (int) Math.Round (scale * orig_height);
-
- return scale;
- }
-
-
- // FIXME: These should be in GTK#. When my patch is committed, these LoadFrom* methods will
- // go away.
-
- public class AspectLoader {
- Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
- int max_width;
- int max_height;
- PixbufOrientation orientation;
- int orig_width;
-
- public AspectLoader (int max_width, int max_height)
- {
- this.max_height = max_height;
- this.max_width = max_width;
- loader.SizePrepared += HandleSizePrepared;
- }
-
- private void HandleSizePrepared (object obj, SizePreparedArgs args)
- {
- switch (orientation) {
- case PixbufOrientation.LeftTop:
- case PixbufOrientation.LeftBottom:
- case PixbufOrientation.RightTop:
- case PixbufOrientation.RightBottom:
- int tmp = max_width;
- max_width = max_height;
- max_height = tmp;
- break;
- default:
- break;
- }
-
- int scale_width = 0;
- int scale_height = 0;
-
- double scale = Fit (args.Width, args.Height, max_width, max_height, true, out scale_width, out scale_height);
-
- if (scale < 1.0)
- loader.SetSize (scale_width, scale_height);
- }
-
- public Pixbuf Load (System.IO.Stream stream, PixbufOrientation orientation)
- {
- int count;
- byte [] data = new byte [8192];
- while (((count = stream.Read (data, 0, data.Length)) > 0) && loader.Write (data, (ulong)count))
- ;
-
- loader.Close ();
- Pixbuf orig = loader.Pixbuf;
- Gdk.Pixbuf rotated = FSpot.Utils.PixbufUtils.TransformOrientation (orig, orientation);
-
- if (orig != rotated) {
- FSpot.Utils.PixbufUtils.CopyThumbnailOptions (orig, rotated);
- orig.Dispose ();
- }
- loader.Dispose ();
- return rotated;
- }
-
- public Pixbuf LoadFromFile (string path)
- {
- try {
- orientation = GetOrientation (path);
- using (FileStream fs = File.OpenRead (path)) {
- return Load (fs, orientation);
- }
- } catch (Exception) {
- System.Console.WriteLine ("Error loading photo {0}", path);
- return null;
- }
- }
- }
-
- public static Pixbuf ShallowCopy (Pixbuf pixbuf)
- {
- if (pixbuf == null)
- return null;
- Pixbuf result = new Pixbuf (pixbuf, 0, 0, pixbuf.Width, pixbuf.Height);
- FSpot.Utils.PixbufUtils.CopyThumbnailOptions (pixbuf, result);
- return result;
- }
-
- public static Pixbuf ScaleToMaxSize (Pixbuf pixbuf, int width, int height)
- {
- return ScaleToMaxSize (pixbuf, width, height, true);
- }
-
- public static Pixbuf ScaleToMaxSize (Pixbuf pixbuf, int width, int height, bool upscale)
- {
- int scale_width = 0;
- int scale_height = 0;
- double scale = Fit (pixbuf, width, height, upscale, out scale_width, out scale_height);
-
- Gdk.Pixbuf result;
- if (upscale || (scale < 1.0))
- result = pixbuf.ScaleSimple (scale_width, scale_height, (scale_width > 20) ? Gdk.InterpType.Bilinear : Gdk.InterpType.Nearest);
- else
- result = pixbuf.Copy ();
-
- FSpot.Utils.PixbufUtils.CopyThumbnailOptions (pixbuf, result);
-
- return result;
- }
-
- static public void GetSize (string path, out int width, out int height)
- {
-#if true
- using (Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (path)) {
- width = pixbuf.Width;
- height = pixbuf.Height;
- }
-#else //yes, the pixbuf loader hack is smarter, but it leaks like an old women
- Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
- int orig_width = 0;
- int orig_height = 0;
- bool done = false;
-
- loader.SizePrepared += delegate (object obj, SizePreparedArgs args) {
- orig_width = args.Width;
- orig_height = args.Height;
- done = true;
- };
-
- using (Stream stream = File.OpenRead (path)) {
- byte [] data = new byte [4096];
- int count;
-
- while (((count = stream.Read (data, 0, data.Length)) > 0) && loader.Write (data, (ulong)count)) {
- if (done)
- break;
- }
- }
-
- width = orig_width;
- height = orig_height;
-#endif
- }
-
- static public Pixbuf LoadAtMaxSize (string path, int max_width, int max_height)
- {
-#if true
- PixbufUtils.AspectLoader loader = new AspectLoader (max_width, max_height);
- return loader.LoadFromFile (path);
-#else
- int width, height;
- JpegUtils.GetSize (path, out width, out height);
- PixbufUtils.Fit (width, height, max_width, max_height, false, out width, out height);
- Gdk.Pixbuf image = JpegUtils.LoadScaled (path, width, height);
-
- return image;
-#endif
- }
-
- static public Pixbuf LoadFromStream (System.IO.Stream input)
- {
- Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
- byte [] buffer = new byte [8192];
- int n;
-
- while ((n = input.Read (buffer, 0, 8192)) != 0)
- loader.Write (buffer, (ulong) n);
-
- loader.Close ();
-
- return loader.Pixbuf;
-
- }
-
-
- public static void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream, string type, string [] options, string [] values)
- {
- byte [] data;
-
- data = PixbufUtils.Save (pixbuf, type, options, values);
- stream.Write (data, 0, data.Length);
- }
-
- static string [] NullTerminateArray (string [] options)
- {
- string [] terminated_options = options;
-
- if (options != null && options [ options.Length - 1 ] != null) {
- terminated_options = new string [options.Length + 1];
- Array.Copy (options, terminated_options, options.Length);
- }
-
- return terminated_options;
- }
-
- [DllImport("libgdk_pixbuf-2.0-0.dll")]
- static extern bool gdk_pixbuf_save_to_bufferv (IntPtr raw, out IntPtr data, out IntPtr length,
- string type,
- string [] keys, string [] values, out IntPtr error);
-
-
- public static byte [] Save (Gdk.Pixbuf pixbuf, string type, string [] options, string [] values)
- {
- IntPtr error = IntPtr.Zero;
- IntPtr data;
- IntPtr length;
-
- bool success = gdk_pixbuf_save_to_bufferv (pixbuf.Handle,
- out data,
- out length,
- type,
- NullTerminateArray (options),
- NullTerminateArray (values),
- out error);
-
- if (error != IntPtr.Zero)
- throw new GLib.GException (error);
-
- if (!success)
- throw new ApplicationException ("Unknown error while saving file");
-
- byte [] content = new byte [(int)length];
- Marshal.Copy (data, content, 0, (int)length);
-
- GLib.Marshaller.Free (data);
-
- return content;
- }
public static Pixbuf TagIconFromPixbuf (Pixbuf source)
{
@@ -317,96 +53,6 @@ public class PixbufUtils {
return icon;
}
-
- static public Pixbuf LoadFromScreen (Gdk.Window win) {
- Gdk.Screen screen = win.Screen;
- Drawable d = screen.RootWindow;
- int monitor = screen.GetMonitorAtWindow (win);
- Gdk.Rectangle geom = screen.GetMonitorGeometry (monitor);
-
- //
- // We use the screen width and height because that reflects
- // the current resolution, the RootWindow can actually be different.
- //
-
- Pixbuf buf = new Pixbuf (Colorspace.Rgb, false, 8, geom.Width, geom.Height);
-
- return buf.GetFromDrawable (d,
- d.Colormap, geom.X, geom.Y, 0, 0,
- geom.Width, geom.Height);
- }
-
- static public Pixbuf LoadFromScreen () {
- Screen screen = Display.Default.GetScreen (0);
- Drawable d = screen.RootWindow;
- int width = screen.Width;
- int height = screen.Height;
-
- //
- // We use the screen width and height because that reflects
- // the current resolution, the RootWindow can actually be different.
- //
-
- Pixbuf buf = new Pixbuf (Colorspace.Rgb, false, 8, width, height);
-
- return buf.GetFromDrawable (d,
- d.Colormap, 0, 0, 0, 0,
- width, height);
- }
-
- static public Pixbuf LoadFromAssembly (string resource)
- {
- try {
- return new Pixbuf (System.Reflection.Assembly.GetEntryAssembly (), resource);
- } catch {
- return null;
- }
- }
-
- [DllImport ("libc")]
- static extern int rename (string oldpath, string newpath);
-
- public static void SaveAtomic (Gdk.Pixbuf src, string filename, string type, string [] keys, string [] values)
- {
- string tmpname = filename + ".tmp";
- src.Savev (tmpname, type, NullTerminateArray (keys), NullTerminateArray (values));
- if (rename (tmpname, filename) < 0)
- throw new Exception ("Error renaming file");
- }
-
- public static Gdk.Pixbuf ScaleToAspect (Gdk.Pixbuf orig, int width, int height)
- {
- Gdk.Rectangle pos;
- double scale = Fit (orig, width, height, false, out pos.Width, out pos.Height);
- pos.X = (width - pos.Width) / 2;
- pos.Y = (height - pos.Height) / 2;
-
- Pixbuf scaled = new Pixbuf (Colorspace.Rgb, false, 8, width, height);
- scaled.Fill (0x000000);
-
- orig.Composite (scaled, pos.X, pos.Y,
- pos.Width, pos.Height,
- pos.X, pos.Y, scale, scale,
- Gdk.InterpType.Bilinear,
- 255);
-
- return scaled;
- }
-
- public static Pixbuf Flatten (Pixbuf pixbuf)
- {
- if (!pixbuf.HasAlpha)
- return null;
-
- Pixbuf flattened = new Pixbuf (Colorspace.Rgb, false, 8, pixbuf.Width, pixbuf.Height);
- pixbuf.CompositeColor (flattened, 0, 0,
- pixbuf.Width, pixbuf.Height,
- 0, 0, 1, 1,
- InterpType.Bilinear,
- 255, 0, 0, 2000, 0xffffff, 0xffffff);
-
- return flattened;
- }
[StructLayout(LayoutKind.Sequential)]
public unsafe struct FPixbufJpegMarker {
@@ -422,13 +68,13 @@ public class PixbufUtils {
{
Pixbuf temp = null;
if (pixbuf.HasAlpha) {
- temp = Flatten (pixbuf);
+ temp = PixbufUtils.Flatten (pixbuf);
pixbuf = temp;
}
// The DCF spec says thumbnails should be 160x120 always
- Pixbuf thumbnail = ScaleToAspect (pixbuf, 160, 120);
- byte [] thumb_data = Save (thumbnail, "jpeg", null, null);
+ Pixbuf thumbnail = PixbufUtils.ScaleToAspect (pixbuf, 160, 120);
+ byte [] thumb_data = PixbufUtils.Save (thumbnail, "jpeg", null, null);
thumbnail.Dispose ();
byte [] data = new byte [0];
@@ -475,271 +121,4 @@ public class PixbufUtils {
if (result == false)
throw new System.Exception ("Error Saving File");
}
-
-
- [DllImport ("libfspot")]
- static extern IntPtr f_pixbuf_unsharp_mask (IntPtr src, double radius, double amount, double threshold);
-
- public static Pixbuf UnsharpMask (Pixbuf src, double radius, double amount, double threshold)
- {
- IntPtr raw_ret = f_pixbuf_unsharp_mask (src.Handle, radius, amount, threshold);
- Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
- return ret;
- }
-
- [DllImport ("libfspot")]
- static extern IntPtr f_pixbuf_blur (IntPtr src, double radius);
-
- public static Pixbuf Blur (Pixbuf src, double radius)
- {
- IntPtr raw_ret = f_pixbuf_blur (src.Handle, radius);
- Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
- return ret;
- }
-
- public unsafe static Gdk.Pixbuf RemoveRedeye (Gdk.Pixbuf src, Gdk.Rectangle area)
- {
- return RemoveRedeye (src, area, -15);
- }
-
- public unsafe static Gdk.Pixbuf RemoveRedeye (Gdk.Pixbuf src, Gdk.Rectangle area, int threshold)
- //threshold, factors and comparisons borrowed from the gimp plugin 'redeye.c' by Robert Merkel
- {
- Gdk.Pixbuf copy = src.Copy ();
- Gdk.Pixbuf selection = new Gdk.Pixbuf (copy, area.X, area.Y, area.Width, area.Height);
- byte *spix = (byte *)selection.Pixels;
- int h = selection.Height;
- int w = selection.Width;
- int channels = src.NChannels;
-
- double RED_FACTOR = 0.5133333;
- double GREEN_FACTOR = 1;
- double BLUE_FACTOR = 0.1933333;
-
- for (int j = 0; j < h; j++) {
- byte *s = spix;
- for (int i = 0; i < w; i++) {
- int adjusted_red = (int)(s[0] * RED_FACTOR);
- int adjusted_green = (int)(s[1] * GREEN_FACTOR);
- int adjusted_blue = (int)(s[2] * BLUE_FACTOR);
-
- if (adjusted_red >= adjusted_green - threshold
- && adjusted_red >= adjusted_blue - threshold)
- s[0] = (byte)(((double)(adjusted_green + adjusted_blue)) / (2.0 * RED_FACTOR));
- s += channels;
- }
- spix += selection.Rowstride;
- }
-
- return copy;
- }
-
- public static unsafe Pixbuf ColorAdjust (Pixbuf src, double brightness, double contrast,
- double hue, double saturation, int src_color, int dest_color)
- {
- Pixbuf adjusted = new Pixbuf (Colorspace.Rgb, src.HasAlpha, 8, src.Width, src.Height);
- PixbufUtils.ColorAdjust (src, adjusted, brightness, contrast, hue, saturation, src_color, dest_color);
- return adjusted;
- }
-
- public static Cms.Format PixbufCmsFormat (Pixbuf buf)
- {
- return buf.HasAlpha ? Cms.Format.Rgba8Planar : Cms.Format.Rgb8;
- }
-
- public static unsafe void ColorAdjust (Pixbuf src, Pixbuf dest,
- double brightness, double contrast,
- double hue, double saturation,
- int src_color, int dest_color)
- {
- if (src.Width != dest.Width || src.Height != dest.Height)
- throw new Exception ("Invalid Dimensions");
-
- //Cms.Profile eos10d = new Cms.Profile ("/home/lewing/ICCProfiles/EOS-10D-True-Color-Non-Linear.icm");
- Cms.Profile srgb = Cms.Profile.CreateStandardRgb ();
-
- Cms.Profile bchsw = Cms.Profile.CreateAbstract (256,
- 0.0,
- brightness, contrast,
- hue, saturation, src_color,
- dest_color);
-
- Cms.Profile [] list = new Cms.Profile [] { srgb, bchsw, srgb };
- Cms.Transform trans = new Cms.Transform (list,
- PixbufCmsFormat (src),
- PixbufCmsFormat (dest),
- Cms.Intent.Perceptual, 0x0100);
-
- ColorAdjust (src, dest, trans);
-
- trans.Dispose ();
- srgb.Dispose ();
- bchsw.Dispose ();
- }
-
-
- public static unsafe void ColorAdjust (Gdk.Pixbuf src, Gdk.Pixbuf dest, Cms.Transform trans)
- {
- int width = src.Width;
- byte * srcpix = (byte *) src.Pixels;
- byte * destpix = (byte *) dest.Pixels;
-
- for (int row = 0; row < src.Height; row++) {
- trans.Apply ((IntPtr) (srcpix + row * src.Rowstride),
- (IntPtr) (destpix + row * dest.Rowstride),
- (uint)width);
- }
-
- }
-
- public static unsafe bool IsGray (Gdk.Pixbuf pixbuf, int max_difference)
- {
- int chan = pixbuf.NChannels;
-
- byte *pix = (byte *)pixbuf.Pixels;
- int h = pixbuf.Height;
- int w = pixbuf.Width;
- int stride = pixbuf.Rowstride;
-
- for (int j = 0; j < h; j++) {
- byte *p = pix;
- for (int i = 0; i < w; i++) {
- if (Math.Abs (p[0] - p[1]) > max_difference || Math.Abs (p[0] - p [2]) > max_difference) {
- goto Found;
- }
- p += chan;
- }
- pix += stride;
- }
-
- return true;
-
- Found:
- return false;
- }
-
- public static unsafe void ReplaceColor (Gdk.Pixbuf src, Gdk.Pixbuf dest)
- {
- if (src.HasAlpha || !dest.HasAlpha || (src.Width != dest.Width) || (src.Height != dest.Height))
- throw new ApplicationException ("invalid pixbufs");
-
- byte *dpix = (byte *)dest.Pixels;
- byte *spix = (byte *)src.Pixels;
- int h = src.Height;
- int w = src.Width;
- for (int j = 0; j < h; j++) {
- byte *d = dpix;
- byte *s = spix;
- for (int i = 0; i < w; i++) {
- d[0] = s[0];
- d[1] = s[1];
- d[2] = s[2];
- d += 4;
- s += 3;
- }
- dpix += dest.Rowstride;
- spix += src.Rowstride;
- }
- }
-
- public static Gdk.Pixbuf GetThumbnail (Exif.ExifData data)
- {
- byte [] thumb_data = data.Data;
- if (thumb_data.Length > 0) {
- PixbufOrientation orientation = GetOrientation (data);
-
- using (MemoryStream mem = new MemoryStream (thumb_data)) {
- Gdk.Pixbuf thumb = new Gdk.Pixbuf (mem);
- Gdk.Pixbuf rotated;
-
- using (thumb)
- rotated = FSpot.Utils.PixbufUtils.TransformOrientation (thumb, orientation);
-
- return rotated;
- }
- }
- return null;
- }
-
- public static PixbufOrientation GetOrientation (Exif.ExifData data)
- {
- PixbufOrientation orientation = PixbufOrientation.TopLeft;
-
- Exif.ExifEntry e = data.GetContents (Exif.Ifd.Zero).Lookup (Exif.Tag.Orientation);
-
- if (e != null) {
- ushort [] value = e.GetDataUShort ();
- orientation = (PixbufOrientation) value [0];
- }
-
- return orientation;
- }
-
- public static PixbufOrientation GetOrientation (System.Uri uri)
- {
- using (FSpot.ImageFile img = FSpot.ImageFile.Create (uri)) {
- return img.Orientation;
- }
- }
-
- [Obsolete ("Use GetOrientation (System.Uri) instead")]
- public static PixbufOrientation GetOrientation (string path)
- {
- using (FSpot.ImageFile img = FSpot.ImageFile.Create (path)) {
- return img.Orientation;
- }
- }
-
- [DllImport("libgnomeui-2-0.dll")]
- static extern IntPtr gnome_thumbnail_scale_down_pixbuf(IntPtr pixbuf, int dest_width, int dest_height);
-
- public static Gdk.Pixbuf ScaleDown (Gdk.Pixbuf src, int width, int height)
- {
- IntPtr raw_ret = gnome_thumbnail_scale_down_pixbuf(src.Handle, width, height);
- Gdk.Pixbuf ret;
- if (raw_ret == IntPtr.Zero)
- ret = null;
- else
- ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
- return ret;
- }
-
- // Bindings from libf.
-
- [DllImport ("libfspot")]
- static extern IntPtr f_pixbuf_copy_apply_brightness_and_contrast (IntPtr src, float brightness, float contrast);
-
- public static Pixbuf ApplyBrightnessAndContrast (Pixbuf src, float brightness, float contrast)
- {
- return new Pixbuf (f_pixbuf_copy_apply_brightness_and_contrast (src.Handle, brightness, contrast));
- }
-
- [DllImport ("libfspot")]
- static extern bool f_pixbuf_save_jpeg_atomic (IntPtr pixbuf, string filename, int quality, out IntPtr error);
-
- public static void SaveAsJpegAtomically (Pixbuf pixbuf, string filename, int quality)
- {
- IntPtr error = IntPtr.Zero;
-
- if (! f_pixbuf_save_jpeg_atomic (pixbuf.Handle, filename, quality, out error)) {
- throw new GLib.GException (error);
- }
- }
-
-// [DllImport ("libfspot")]
-// static extern void f_pixbuf_copy_with_orientation (IntPtr src, IntPtr dest, int orientation);
-//
-// public static void CopyWithOrientation (Gdk.Pixbuf src, Gdk.Pixbuf dest, PixbufOrientation orientation)
-// {
-// f_pixbuf_copy_with_orientation (src.Handle, dest.Handle, (int)orientation);
-// }
-
-#if false
- [DllImport("glibsharpglue")]
- static extern int gtksharp_object_get_ref_count (IntPtr obj);
-
- public static int RefCount (GLib.Object obj) {
- return gtksharp_object_get_ref_count (obj.Handle);
- }
-#endif
}
diff --git a/src/PrintOperation.cs b/src/PrintOperation.cs
index 4be9d4a..83d6b75 100644
--- a/src/PrintOperation.cs
+++ b/src/PrintOperation.cs
@@ -121,9 +121,9 @@ namespace FSpot
} catch (Exception e) {
Log.Exception ("Unable to load image " + selected_photos[p_index].DefaultVersion.Uri + "\n", e);
// If the image is not found load error pixbuf
- pixbuf = new Gdk.Pixbuf (PixbufUtils.ErrorPixbuf, 0, 0,
- PixbufUtils.ErrorPixbuf.Width,
- PixbufUtils.ErrorPixbuf.Height);
+ pixbuf = new Gdk.Pixbuf (FSpotPixbufUtils.ErrorPixbuf, 0, 0,
+ FSpotPixbufUtils.ErrorPixbuf.Width,
+ FSpotPixbufUtils.ErrorPixbuf.Height);
}
//Gdk.Pixbuf pixbuf = img.Load (100, 100);
bool rotated = false;
diff --git a/src/SlideView.cs b/src/SlideView.cs
new file mode 100644
index 0000000..03bdea2
--- /dev/null
+++ b/src/SlideView.cs
@@ -0,0 +1,558 @@
+using Gtk;
+using Gdk;
+using System;
+using GLib;
+using System.Runtime.InteropServices;
+using FSpot;
+using FSpot.Utils;
+
+namespace FSpot {
+ public class XScreenSaverSlide : Gtk.Window {
+ public const string ScreenSaverEnviroment = "XSCREENSAVER_WINDOW";
+
+ public XScreenSaverSlide () : base (String.Empty)
+ {
+ }
+
+ protected override void OnRealized ()
+ {
+ string env = Environment.GetEnvironmentVariable (ScreenSaverEnviroment);
+
+ if (env != null) {
+ try {
+ env = env.ToLower ();
+
+ if (env.StartsWith ("0x"))
+ env = env.Substring (2);
+
+ uint xid = UInt32.Parse (env, System.Globalization.NumberStyles.HexNumber);
+
+ GdkWindow = Gdk.Window.ForeignNew (xid);
+ Style.Attach (GdkWindow);
+ GdkWindow.Events = EventMask.ExposureMask
+ | EventMask.StructureMask
+ | EventMask.EnterNotifyMask
+ | EventMask.LeaveNotifyMask
+ | EventMask.FocusChangeMask;
+
+ Style.SetBackground (GdkWindow, Gtk.StateType.Normal);
+ GdkWindow.SetDecorations ((Gdk.WMDecoration) 0);
+ GdkWindow.UserData = this.Handle;
+ SetFlag (WidgetFlags.Realized);
+ SizeRequest ();
+ Gdk.Rectangle geom;
+ int depth;
+ GdkWindow.GetGeometry (out geom.X, out geom.Y, out geom.Width, out geom.Height, out depth);
+ SizeAllocate (new Gdk.Rectangle (geom.X, geom.Y, geom.Width, geom.Height));
+ Resize (geom.Width, geom.Height);
+ return;
+ } catch (System.Exception e) {
+ System.Console.WriteLine (e);
+ }
+ } else {
+ System.Console.WriteLine ("{0} not set, falling back to window", ScreenSaverEnviroment);
+ }
+
+ SetSizeRequest (640, 480);
+ base.OnRealized ();
+ }
+ }
+
+ public class FullSlide : Gtk.Window {
+ private SlideView slideview;
+ private Gdk.Pixbuf screenshot;
+ private Delay hide;
+ private Gdk.Cursor busy;
+ private Gdk.Cursor none;
+
+ public FullSlide (Gtk.Window parent, IBrowsableItem [] items) : base ("Slideshow")
+ {
+ screenshot = PixbufUtils.LoadFromScreen (parent.GdkWindow);
+
+ this.Destroyed += HandleDestroyed;
+
+ this.TransientFor = parent;
+
+ this.ButtonPressEvent += HandleSlideViewButtonPressEvent;
+ this.KeyPressEvent += HandleSlideViewKeyPressEvent;
+ this.AddEvents ((int) (EventMask.ButtonPressMask | EventMask.KeyPressMask | EventMask.PointerMotionMask));
+ slideview = new SlideView (screenshot, items, 2.0);
+ this.Add (slideview);
+ this.Decorated = false;
+ this.Fullscreen();
+ this.Realize ();
+
+ busy = new Gdk.Cursor (Gdk.CursorType.Watch);
+ this.GdkWindow.Cursor = busy;
+ none = GdkUtils.CreateEmptyCursor (GdkWindow.Display);
+
+ hide = new Delay (2000, new GLib.IdleHandler (HideCursor));
+ }
+
+ public void Play ()
+ {
+ Gdk.GCValues values = new Gdk.GCValues ();
+ values.SubwindowMode = SubwindowMode.IncludeInferiors;
+ Gdk.GC fillgc = new Gdk.GC (this.GdkWindow, values, Gdk.GCValuesMask.Subwindow);
+
+ slideview.Show ();
+ this.GdkWindow.SetBackPixmap (null, false);
+ this.Show ();
+ screenshot.RenderToDrawable (this.GdkWindow, fillgc,
+ 0, 0, 0, 0, -1, -1, RgbDither.Normal, 0, 0);
+
+ slideview.Play ();
+ hide.Start ();
+ }
+
+ [GLib.ConnectBefore]
+ private void HandleSlideViewKeyPressEvent (object sender, KeyPressEventArgs args)
+ {
+ this.Destroy ();
+ args.RetVal = true;
+ }
+
+ protected override bool OnMotionNotifyEvent (Gdk.EventMotion args)
+ {
+ base.OnMotionNotifyEvent (args);
+ this.GdkWindow.Cursor = busy;
+ hide.Start ();
+ return true;
+ }
+
+ private bool HideCursor ()
+ {
+ this.GdkWindow.Cursor = none;
+ return false;
+ }
+
+ private void HandleDestroyed (object sender, System.EventArgs args)
+ {
+ hide.Stop ();
+ }
+
+ private void HandleSlideViewButtonPressEvent (object sender, ButtonPressEventArgs args)
+ {
+ this.Destroy ();
+ args.RetVal = true;
+ }
+ }
+
+ public class SlideView : Gtk.Image {
+ IBrowsableItem [] photos;
+ Pixbuf last;
+ Pixbuf next;
+
+
+ Pixbuf [] tweens = new Pixbuf [10];
+ int current_tween;
+ uint tween_idle;
+ uint resize_idle;
+
+ int current_idx = 0;
+ int next_idx = 0;
+
+ uint flip_timer = 0;
+ uint transition_timer = 0;
+
+ uint fail_count = 0;
+ bool animate = true;
+ uint animate_max = 200;
+
+ bool black = false;
+ uint flip_interval = 2000;
+ uint transition_interval = 75;
+
+ public bool Running {
+ get {
+ return flip_timer != 0 || transition_timer != 0;
+ }
+ }
+
+ public bool Animate {
+ get { return animate; }
+ set { animate = value; }
+ }
+
+ public void Play ()
+ {
+ if (photos.Length < 1)
+ return;
+
+ StopTweenIdle ();
+ if (current_idx >= 0) {
+ Pixbuf frame = GetScaled (photos[current_idx]);
+ this.Pixbuf = frame;
+ frame.Dispose ();
+ }
+
+ if (PreloadNextImage (current_idx + 1))
+ StartFlipTimer ();
+ }
+
+ public void Pause ()
+ {
+ StopTranstionTimer ();
+ StopFlipTimer ();
+ }
+
+ public void Stop ()
+ {
+ StopTweenIdle ();
+ StopTranstionTimer ();
+ StopFlipTimer ();
+ }
+
+ public void Forward ()
+ {
+ if (PreloadNextImage (current_idx + 1))
+ ShowNext ();
+ }
+
+ public void Back ()
+ {
+ if (PreloadNextImage (current_idx - 1))
+ ShowNext ();
+ }
+
+ private void ShowNext ()
+ {
+ StopTweenIdle ();
+
+ if (current_idx != next_idx && next != null)
+ this.Pixbuf = next;
+
+ current_idx = next_idx;
+
+ black = false;
+ }
+
+ private bool PreloadNextImage (int idx)
+ {
+ try {
+ if (idx < photos.Length && idx >= 0) {
+ if (next != null)
+ next.Dispose ();
+
+ next = GetScaled (photos [idx]);
+ if (next == null)
+ next = GetScaled (PixbufUtils.ShallowCopy (FSpotPixbufUtils.ErrorPixbuf));
+
+ next_idx = idx;
+ StartTweenIdle ();
+
+ return true;
+ } else {
+ if (next != null)
+ next.Dispose ();
+
+ next = GetScaled (photos [0]);
+ if (next == null)
+ next = GetScaled (PixbufUtils.ShallowCopy (FSpotPixbufUtils.ErrorPixbuf));
+ next_idx = 0;
+ StartTweenIdle ();
+
+ return false;
+ }
+ } catch (GLib.GException e) {
+ System.Console.WriteLine (e);
+ idx = (idx + 1) % photos.Length;
+ return PreloadNextImage (idx);
+ }
+ }
+
+ private Pixbuf CrossFade (Pixbuf current, Pixbuf prev, Pixbuf next, double percent)
+ {
+ Rectangle area = new Rectangle (0, 0, Allocation.Width, Allocation.Height);
+ BlockProcessor proc = new BlockProcessor (area, 256);
+ Rectangle subarea;
+
+ while (proc.Step (out subarea)) {
+ if (IsRealized)
+ GdkWindow.ProcessUpdates (false);
+
+ prev.CopyArea (subarea.X, subarea.Y, subarea.Width, subarea.Height, current, subarea.X, subarea.Y);
+ next.Composite (current, subarea.X, subarea.Y, subarea.Width, subarea.Height, 0, 0, 1, 1,
+ Gdk.InterpType.Nearest, (int) System.Math.Round (255 * percent));
+ }
+ return current;
+ }
+
+ private Pixbuf BlackFade (Pixbuf current, Pixbuf prev, Pixbuf next, double percent)
+ {
+ int width = Allocation.Width;
+ int height = Allocation.Height;
+
+ current.Fill (0);
+
+ if (percent < 0.5)
+ prev.Composite (current, 0,0, width, height, 0, 0, 1, 1,
+ Gdk.InterpType.Nearest, (int)System.Math.Round (255 * (1 - percent * 2)));
+ else
+ next.Composite (current, 0,0, width, height, 0, 0, 1, 1,
+ Gdk.InterpType.Nearest, (int)System.Math.Round (255 * (percent * 2 - 1)));
+ return current;
+ }
+
+ private Pixbuf Blend (Pixbuf current, Pixbuf prev, Pixbuf next, double percent)
+ {
+ if (black) {
+ return BlackFade (current, prev, next, percent);
+ } else {
+ return CrossFade (current, prev, next, percent);
+ }
+ }
+
+ private Pixbuf GetScaled (Pixbuf orig)
+ {
+ Gdk.Rectangle pos;
+ int width = Allocation.Width;
+ int height = Allocation.Height;
+ double scale = PixbufUtils.Fit (orig, width, height, false, out pos.Width, out pos.Height);
+ pos.X = (width - pos.Width) / 2;
+ pos.Y = (height - pos.Height) / 2;
+
+ Pixbuf scaled = new Pixbuf (Colorspace.Rgb, false, 8, width, height);
+ scaled.Fill (0x000000);
+
+ Rectangle rect = new Rectangle (pos.X, pos.Y, 256, 256);
+ Rectangle subarea;
+
+ while (rect.Top < pos.Bottom) {
+ while (rect.X < pos.Right) {
+ if (IsRealized)
+ GdkWindow.ProcessUpdates (false);
+
+ rect.Intersect (pos, out subarea);
+ orig.Composite (scaled, subarea.X, subarea.Y,
+ subarea.Width, subarea.Height,
+ pos.X, pos.Y, scale, scale,
+ Gdk.InterpType.Bilinear,
+ 255);
+ rect.X += rect.Width;
+ }
+ rect.X = pos.X;
+ rect.Y += rect.Height;
+ }
+
+ orig.Dispose ();
+ return scaled;
+ }
+
+ private Pixbuf GetScaled (IBrowsableItem photo)
+ {
+ Pixbuf orig;
+ try {
+ orig = FSpot.PhotoLoader.LoadAtMaxSize (photo, Allocation.Width, Allocation.Height);
+ } catch {
+ orig = null;
+ }
+
+ if (orig == null)
+ return null;
+
+ Pixbuf result = GetScaled (orig);
+ if (orig != result)
+ orig.Dispose ();
+
+ return result;
+ }
+
+ private bool HandleFlipTimer ()
+ {
+ StopTweenIdle ();
+
+ StartTransitionTimer ();
+
+ flip_timer = 0;
+ return false;
+ }
+
+ private bool HandleTransitionTimer ()
+ {
+ System.DateTime start_time = System.DateTime.Now;
+ transition_timer = 0;
+ if (current_tween-- > 0) {
+ StartTransitionTimer ();
+ this.Pixbuf = tweens[current_tween];
+ GdkWindow.ProcessUpdates (false);
+ System.TimeSpan span = System.DateTime.Now - start_time;
+
+ if (Animate) {
+ if (span.TotalMilliseconds > animate_max) {
+ fail_count++;
+
+ if (fail_count > 3) {
+ Animate = false;
+ System.Console.WriteLine ("Disabling slide animation due to 3 consecutive excessive frame intervals {0}ms",
+ span.TotalMilliseconds);
+ current_tween = 0;
+ }
+ } else {
+ fail_count = 0;
+ }
+ }
+ } else {
+ ShowNext ();
+
+ PreloadNextImage (current_idx + 1);
+ StartFlipTimer ();
+ }
+
+ return false;
+ }
+
+
+ private bool HandleTweenIdle ()
+ {
+ using (Pixbuf prev = this.Pixbuf) {
+ if (!Animate) {
+ ClearTweens ();
+ return false;
+ }
+
+ if (photos.Length < 2) { // Only one photo. Nothing to do
+ ClearTweens ();
+ return false;
+ }
+
+ if (current_tween >= tweens.Length) {
+ tween_idle = 0;
+ return false;
+ }
+
+ if (current_tween < tweens.Length && tweens[current_tween] == null) {
+ tweens[current_tween] = new Pixbuf (Colorspace.Rgb, false, 8,
+ Allocation.Width, Allocation.Height);
+ }
+
+ double blend_val;
+#if USE_EXP
+ double blend_t = (-10 * current_tween) / ((double)tweens.Length - 1);
+ blend_val = 1.0 - (.01 / (.01 + (.99 * Math.Exp(blend_t))));
+#else
+ double [] blends = new double [] { .99, .97, .9, .8, .7, .6, .5, .4, .3, .15};
+ blend_val = blends [current_tween];
+#endif
+ tweens[current_tween] = Blend (tweens[current_tween], prev, next, blend_val);
+ current_tween++;
+ return true;
+ }
+ }
+
+ private void StartTweenIdle ()
+ {
+ if (tween_idle == 0) {
+ current_tween = 0;
+ tween_idle = GLib.Idle.Add (new GLib.IdleHandler (HandleTweenIdle));
+ }
+ }
+
+ private void StopTweenIdle ()
+ {
+ if (tween_idle != 0) {
+ GLib.Source.Remove (tween_idle);
+ }
+ tween_idle = 0;
+
+ }
+
+ private void StartTransitionTimer ()
+ {
+ if (transition_timer == 0)
+ transition_timer = GLib.Timeout.Add (transition_interval,
+ new TimeoutHandler (HandleTransitionTimer));
+ }
+
+ private void StopTranstionTimer ()
+ {
+ if (transition_timer != 0)
+ GLib.Source.Remove (transition_timer);
+
+ transition_timer = 0;
+ }
+
+ private void StartFlipTimer ()
+ {
+ if (flip_timer == 0)
+ flip_timer = GLib.Timeout.Add (flip_interval,
+ new TimeoutHandler (HandleFlipTimer));
+ }
+
+ private void StopFlipTimer ()
+ {
+ if (flip_timer != 0)
+ GLib.Source.Remove (flip_timer);
+
+ flip_timer = 0;
+ }
+
+
+ private void HandleSizeAllocate (object sender, SizeAllocatedArgs args)
+ {
+ Pixbuf current = this.Pixbuf;
+
+ if (current == null)
+ return;
+
+ //
+ // The size has changed so we need to reload the images.
+ //
+ if (current.Width != Allocation.Width || current.Height != Allocation.Height) {
+ bool playing = (flip_timer != 0 || transition_timer != 0);
+
+ if (current_idx < 0) {
+ using (Gdk.Pixbuf old = this.Pixbuf) {
+ this.Pixbuf = GetScaled (old);
+ current.Dispose ();
+ }
+ } else {
+ using (Pixbuf frame = GetScaled (photos[current_idx])) {
+ this.Pixbuf = frame;
+ current.Dispose ();
+ }
+ }
+
+ Stop ();
+
+ ClearTweens ();
+
+ if (playing && current_idx != next_idx)
+ Play ();
+
+
+ }
+ }
+
+ private void ClearTweens () {
+ for (int i = 0; i < tweens.Length; i++) {
+ if (tweens[i] != null)
+ tweens[i].Dispose ();
+ tweens[i] = null;
+ }
+ }
+
+ private void HandleDestroyed (object sender, EventArgs args)
+ {
+ ClearTweens ();
+ Stop ();
+ }
+
+ public SlideView (Pixbuf background, IBrowsableItem [] photos, double delay) : base ()
+ {
+ this.photos = photos;
+
+ if (background != null) {
+ this.Pixbuf = background;
+ background.Dispose ();
+
+ current_idx = -1;
+ black = true;
+ flip_interval = (uint)(delay * 1000);
+ }
+
+ SizeAllocated += new SizeAllocatedHandler (HandleSizeAllocate);
+ Destroyed += new EventHandler (HandleDestroyed);
+ }
+ }
+}
diff --git a/src/ThumbnailGenerator.cs b/src/ThumbnailGenerator.cs
index ae4d408..e4d87a4 100644
--- a/src/ThumbnailGenerator.cs
+++ b/src/ThumbnailGenerator.cs
@@ -41,8 +41,8 @@ namespace FSpot {
GFileInfo info = GLib.FileFactory.NewForUri (uri).QueryInfo ("time::modified", GLib.FileQueryInfoFlags.None, null);
DateTime mtime = NativeConvert.ToDateTime ((long)info.GetAttributeULong ("time::modified"));
- FSpot.Utils.PixbufUtils.SetOption (thumb, ThumbUri, UriUtils.UriToStringEscaped (uri));
- FSpot.Utils.PixbufUtils.SetOption (thumb, ThumbMTime, ((uint)GLib.Marshaller.DateTimeTotime_t (mtime)).ToString ());
+ thumb.SetOption (ThumbUri, UriUtils.UriToStringEscaped (uri));
+ thumb.SetOption (ThumbMTime, ((uint)GLib.Marshaller.DateTimeTotime_t (mtime)).ToString ());
} catch (System.Exception e) {
Log.Exception (e);
}
diff --git a/src/UI.Dialog/EditTagIconDialog.cs b/src/UI.Dialog/EditTagIconDialog.cs
index 954586d..cdcd683 100644
--- a/src/UI.Dialog/EditTagIconDialog.cs
+++ b/src/UI.Dialog/EditTagIconDialog.cs
@@ -161,7 +161,7 @@ namespace FSpot.UI.Dialog
try {
using (FSpot.ImageFile img = FSpot.ImageFile.Create (new Uri(external_photo_chooser.Uri))) {
using (Gdk.Pixbuf external_image = img.Load ()) {
- PreviewPixbuf = PixbufUtils.TagIconFromPixbuf (external_image);
+ PreviewPixbuf = FSpotPixbufUtils.TagIconFromPixbuf (external_image);
}
}
} catch (Exception) {
@@ -190,12 +190,12 @@ namespace FSpot.UI.Dialog
if (image_view.Selection != Gdk.Rectangle.Zero) {
using (var tmp = new Gdk.Pixbuf (image_view.Pixbuf, x, y, width, height)) {
Gdk.Pixbuf transformed = FSpot.Utils.PixbufUtils.TransformOrientation (tmp, image_view.PixbufOrientation);
- PreviewPixbuf = PixbufUtils.TagIconFromPixbuf (transformed);
+ PreviewPixbuf = FSpotPixbufUtils.TagIconFromPixbuf (transformed);
transformed.Dispose ();
}
} else {
Gdk.Pixbuf transformed = FSpot.Utils.PixbufUtils.TransformOrientation (image_view.Pixbuf, image_view.PixbufOrientation);
- PreviewPixbuf = PixbufUtils.TagIconFromPixbuf (transformed);
+ PreviewPixbuf = FSpotPixbufUtils.TagIconFromPixbuf (transformed);
transformed.Dispose ();
}
}
diff --git a/src/Utils/PixbufExtensions.cs b/src/Utils/PixbufExtensions.cs
new file mode 100644
index 0000000..408c50d
--- /dev/null
+++ b/src/Utils/PixbufExtensions.cs
@@ -0,0 +1,49 @@
+//
+// FSpot.Utils.PixbufExtensions.cs
+//
+// Author(s)
+// Ruben Vermeersch <ruben savanne be>
+//
+// This is free software. See COPYING for details.
+//
+
+using Gdk;
+using System;
+using System.Runtime.InteropServices;
+
+namespace FSpot.Utils
+{
+ public static class PixbufExtensions
+ {
+ public static Pixbuf ShallowCopy (this Pixbuf pixbuf)
+ {
+ Pixbuf result = new Pixbuf (pixbuf, 0, 0, pixbuf.Width, pixbuf.Height);
+ result.CopyThumbnailOptionsFrom (pixbuf);
+ return result;
+ }
+
+ //
+ // FIXME this is actually not public api and we should do a verison check,
+ // but frankly I'm irritated that it isn't public so I don't much care.
+ //
+ [DllImport("libgdk_pixbuf-2.0-0.dll")]
+ static extern bool gdk_pixbuf_set_option(IntPtr raw, string key, string value);
+
+ public static bool SetOption(this Gdk.Pixbuf pixbuf, string key, string value)
+ {
+
+ if (value != null)
+ return gdk_pixbuf_set_option(pixbuf.Handle, key, value);
+ else
+ return false;
+ }
+
+ public static void CopyThumbnailOptionsFrom (this Gdk.Pixbuf dest, Gdk.Pixbuf src)
+ {
+ if (src != null && dest != null) {
+ dest.SetOption ("tEXt::Thumb::URI", src.GetOption ("tEXt::Thumb::URI"));
+ dest.SetOption ("tEXt::Thumb::MTime", src.GetOption ("tEXt::Thumb::MTime"));
+ }
+ }
+ }
+}
diff --git a/src/Widgets/Filmstrip.cs b/src/Widgets/Filmstrip.cs
index acf322d..464b121 100644
--- a/src/Widgets/Filmstrip.cs
+++ b/src/Widgets/Filmstrip.cs
@@ -625,7 +625,7 @@ namespace FSpot.Widgets
if (SquaredThumbs) {
using (Pixbuf p = ThumbnailFactory.LoadThumbnail (uri)) {
- current = PixbufUtils.IconFromPixbuf (p, ThumbSize);
+ current = FSpotPixbufUtils.IconFromPixbuf (p, ThumbSize);
}
} else
current = ThumbnailFactory.LoadThumbnail (uri, -1, ThumbSize);
diff --git a/src/Widgets/IconView.cs b/src/Widgets/IconView.cs
index a934624..7eb3a86 100644
--- a/src/Widgets/IconView.cs
+++ b/src/Widgets/IconView.cs
@@ -16,6 +16,7 @@ using System.Reflection;
using System.Collections;
using System.IO;
using FSpot.Platform;
+using FSpot.Utils;
namespace FSpot.Widgets
{
@@ -928,7 +929,7 @@ namespace FSpot.Widgets
InterpType.Bilinear);
}
- FSpot.Utils.PixbufUtils.CopyThumbnailOptions (thumbnail, temp_thumbnail);
+ temp_thumbnail.CopyThumbnailOptionsFrom (thumbnail);
} else
temp_thumbnail = thumbnail;
diff --git a/src/Widgets/PreviewPopup.cs b/src/Widgets/PreviewPopup.cs
index 25a965a..be5fefb 100644
--- a/src/Widgets/PreviewPopup.cs
+++ b/src/Widgets/PreviewPopup.cs
@@ -126,7 +126,7 @@ namespace FSpot {
AddHistogram (pixbuf);
image.Pixbuf = pixbuf;
} else {
- image.Pixbuf = PixbufUtils.ErrorPixbuf;
+ image.Pixbuf = FSpotPixbufUtils.ErrorPixbuf;
}
} else {
image.Pixbuf = pixbuf;
diff --git a/src/Widgets/SlideShow.cs b/src/Widgets/SlideShow.cs
index f6d9d22..2a6430d 100644
--- a/src/Widgets/SlideShow.cs
+++ b/src/Widgets/SlideShow.cs
@@ -128,7 +128,7 @@ namespace FSpot.Widgets
FSpot.ColorManagement.ApplyProfile (next, screen_profile);
loadRetries = 0;
} catch (Exception) {
- next = PixbufUtils.ErrorPixbuf;
+ next = FSpotPixbufUtils.ErrorPixbuf;
if (++loadRetries < 10)
item.MoveNext (true);
else
diff --git a/tests/src/Makefile.am b/tests/src/Makefile.am
index 81fe2a4..bea91f5 100644
--- a/tests/src/Makefile.am
+++ b/tests/src/Makefile.am
@@ -30,6 +30,7 @@ REFS = \
-r:$(top_builddir)/src/FSpot.Query.dll \
-r:$(top_builddir)/src/FSpot.Utils.dll \
-r:$(top_builddir)/src/FSpot.Platform.dll \
+ -r:$(top_builddir)/src/FSpot.Imaging.dll \
-r:$(top_builddir)/src/Cms.dll \
-r:$(top_builddir)/lib/semweb/SemWeb.dll
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]