[f-spot/taglib-metadata] Handle creation of derived versions with Taglib#.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/taglib-metadata] Handle creation of derived versions with Taglib#.
- Date: Fri, 2 Jul 2010 08:41:07 +0000 (UTC)
commit ebb689cf75d915b6458e55fb45026d0cdfea008d
Author: Ruben Vermeersch <ruben savanne be>
Date: Fri Jul 2 10:39:37 2010 +0200
Handle creation of derived versions with Taglib#.
This means copying metadata from one file to another, even if the format
changes.
lib/TagLib/TagLib | 2 +-
lib/libfspot/f-jpeg-utils.c | 20 -----
lib/libfspot/f-pixbuf-utils.c | 153 ----------------------------------
lib/libfspot/f-pixbuf-utils.h | 11 ---
src/Core/Photo.cs | 4 +-
src/Filters/JpegFilter.cs | 70 ++++++----------
src/Filters/ResizeFilter.cs | 98 +++++++++-------------
src/Filters/SharpFilter.cs | 75 +++++++-----------
src/Imaging/Exif.cs | 19 -----
src/Imaging/ImageFile.cs | 5 -
src/Imaging/IptcFile.cs | 24 ------
src/Imaging/JpegFile.cs | 64 ---------------
src/Imaging/PngFile.cs | 123 ----------------------------
src/Imaging/PnmFile.cs | 33 --------
src/Imaging/XmpFile.cs | 49 -----------
src/PixbufUtils.cs | 180 ++++++++++++++++++-----------------------
16 files changed, 177 insertions(+), 753 deletions(-)
---
diff --git a/lib/TagLib/TagLib b/lib/TagLib/TagLib
index 2a46d11..600a7b2 160000
--- a/lib/TagLib/TagLib
+++ b/lib/TagLib/TagLib
@@ -1 +1 @@
-Subproject commit 2a46d11248d2d02e8b4bc280093d40b72a2929d8
+Subproject commit 600a7b29dbccbc8d75aa0ddb4a20b1fc816ef285
diff --git a/lib/libfspot/f-jpeg-utils.c b/lib/libfspot/f-jpeg-utils.c
index 0c1fdf8..b83848a 100644
--- a/lib/libfspot/f-jpeg-utils.c
+++ b/lib/libfspot/f-jpeg-utils.c
@@ -315,26 +315,6 @@ f_get_jpeg_size (const char *path,
}
-void
-f_save_jpeg_exif (const char *filename, ExifData *exif_data)
-{
- JPEGData *jdata;
-
- g_warning ("exif = %p", exif_data);
- jdata = jpeg_data_new_from_file (filename);
- if (jdata == NULL) {
- g_warning ("unable to parse jpeg file");
- return;
- }
- if (exif_data == NULL) {
- g_warning ("missing exif data");
- }
- jpeg_data_set_exif_data (jdata, exif_data);
- jpeg_data_save_file (jdata, filename);
-
- jpeg_data_unref (jdata);
-}
-
/* Implementation of non-lossy JPEG file transformations, based on GThumb code
by Paolo Bacchilega. */
diff --git a/lib/libfspot/f-pixbuf-utils.c b/lib/libfspot/f-pixbuf-utils.c
index d87e01f..32d59d1 100644
--- a/lib/libfspot/f-pixbuf-utils.c
+++ b/lib/libfspot/f-pixbuf-utils.c
@@ -45,64 +45,6 @@
#include <gdk/gdk.h>
#include "f-image-surface.h"
-
-/* Helper functions. */
-
-static unsigned char
-apply_brightness_and_contrast (unsigned char u_value,
- float brightness,
- float contrast)
-{
- float nvalue;
- double power;
- float value;
-
- value = (float) u_value / 255.0;
-
- /* apply brightness */
- if (brightness < 0.0)
- value = value * (1.0 + brightness);
- else
- value = value + ((1.0 - value) * brightness);
-
- /* apply contrast */
- if (contrast < 0.0) {
- if (value > 0.5)
- nvalue = 1.0 - value;
- else
- nvalue = value;
-
- if (nvalue < 0.0)
- nvalue = 0.0;
-
- nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + contrast));
-
- if (value > 0.5)
- value = 1.0 - nvalue;
- else
- value = nvalue;
- } else {
- if (value > 0.5)
- nvalue = 1.0 - value;
- else
- nvalue = value;
-
- if (nvalue < 0.0)
- nvalue = 0.0;
-
- power = (contrast == 1.0) ? 127 : 1.0 / (1.0 - contrast);
- nvalue = 0.5 * pow (2.0 * nvalue, power);
-
- if (value > 0.5)
- value = 1.0 - nvalue;
- else
- value = nvalue;
- }
-
- return (guchar) (value * 255);
-}
-
-
/* Public functions. */
int
@@ -146,68 +88,6 @@ f_pixbuf_get_scaled_height (GdkPixbuf *pixbuf,
return size;
}
-/* Return a new GdkPixbuf enhancing/reducing brightness and contrast according
- to the specified values (from -1.0 to +1.0). */
-GdkPixbuf *
-f_pixbuf_copy_apply_brightness_and_contrast (GdkPixbuf *src,
- float brightness,
- float contrast)
-{
- GdkPixbuf *result_pixbuf;
- char *sp, *dp;
- int width, height;
- int line;
- int result_rowstride, src_rowstride;
- int bytes_per_pixel;
-
- g_return_val_if_fail ((brightness > -1.0 || F_DOUBLE_EQUAL (brightness, -1.0))
- && (brightness < 1.0 || F_DOUBLE_EQUAL (brightness, 1.0)),
- NULL);
- g_return_val_if_fail ((contrast > -1.0 || F_DOUBLE_EQUAL (contrast, -1.0))
- && (contrast < 1.0 || F_DOUBLE_EQUAL (contrast, 1.0)),
- NULL);
-
- if (F_DOUBLE_EQUAL (brightness, 0.0) && F_DOUBLE_EQUAL (contrast, 0.0))
- return gdk_pixbuf_copy (src);
-
- result_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
- gdk_pixbuf_get_has_alpha (src),
- gdk_pixbuf_get_bits_per_sample (src),
- gdk_pixbuf_get_width (src),
- gdk_pixbuf_get_height (src));
-
- width = gdk_pixbuf_get_width (result_pixbuf);
- height = gdk_pixbuf_get_height (result_pixbuf);
-
- result_rowstride = gdk_pixbuf_get_rowstride (result_pixbuf);
- src_rowstride = gdk_pixbuf_get_rowstride (src);
-
- bytes_per_pixel = gdk_pixbuf_get_has_alpha (result_pixbuf) ? 4 : 3;
-
- sp = gdk_pixbuf_get_pixels (src);
- dp = gdk_pixbuf_get_pixels (result_pixbuf);
-
- for (line = 0; line < height; line ++) {
- char *sq = sp;
- char *dq = dp;
- int i;
-
- for (i = 0; i < width; i ++) {
- dq[0] = apply_brightness_and_contrast (sq[0], brightness, contrast);
- dq[1] = apply_brightness_and_contrast (sq[1], brightness, contrast);
- dq[2] = apply_brightness_and_contrast (sq[2], brightness, contrast);
-
- dq += bytes_per_pixel;
- sq += bytes_per_pixel;
- }
-
- sp += src_rowstride;
- dp += result_rowstride;
- }
-
- return result_pixbuf;
-}
-
cairo_surface_t *
f_pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
{
@@ -347,36 +227,3 @@ f_pixbuf_from_cairo_surface (cairo_surface_t *source)
cairo_surface_destroy (surface);
return pixbuf;
}
-
-gboolean
-f_pixbuf_save_jpeg_atomic (GdkPixbuf *pixbuf,
- const char *file_name,
- int quality,
- GError **error)
-{
- char *tmp_file_name = g_strconcat (file_name, ".tmp", NULL);
- char *quality_string = g_strdup_printf ("%d", quality);
- gboolean success;
-
- if (! gdk_pixbuf_save (pixbuf, tmp_file_name, "jpeg", error,
- "quality", quality_string, NULL)) {
- success = FALSE;
- goto end;
- }
-
- if (rename (tmp_file_name, file_name) != 0) {
- char *error_message = g_strdup_printf ("Atomic rename failed: %s", g_strerror (errno));
- g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, error_message);
- g_free (error_message);
-
- success = FALSE;
- goto end;
- }
-
- success = TRUE;
-
- end:
- g_free (quality_string);
- g_free (tmp_file_name);
- return TRUE;
-}
diff --git a/lib/libfspot/f-pixbuf-utils.h b/lib/libfspot/f-pixbuf-utils.h
index 443be87..a0ae7dd 100644
--- a/lib/libfspot/f-pixbuf-utils.h
+++ b/lib/libfspot/f-pixbuf-utils.h
@@ -38,15 +38,4 @@ int f_pixbuf_get_scaled_width (GdkPixbuf *pixbuf, int size);
thumbnail SIZE. */
int f_pixbuf_get_scaled_height (GdkPixbuf *pixbuf, int size);
-
-/* Picture ops. */
-GdkPixbuf *f_pixbuf_copy_apply_brightness_and_contrast (GdkPixbuf *src,
- float brightness,
- float contrast);
-
-gboolean f_pixbuf_save_jpeg_atomic (GdkPixbuf *pixbuf,
- const char *filename,
- int quality,
- GError **error);
-
#endif
diff --git a/src/Core/Photo.cs b/src/Core/Photo.cs
index 6c56316..3980df8 100644
--- a/src/Core/Photo.cs
+++ b/src/Core/Photo.cs
@@ -231,9 +231,7 @@ namespace FSpot
try {
var versionUri = VersionUri (version);
- using (Stream stream = System.IO.File.OpenWrite (versionUri.LocalPath)) {
- img.Save (buffer, stream);
- }
+ PixbufUtils.CreateDerivedVersion (DefaultVersion.Uri, versionUri, 95, buffer);
(GetVersion (version) as PhotoVersion).ImportMD5 = HashUtils.GenerateMD5 (VersionUri (version));
DefaultVersionId = version;
} catch (System.Exception e) {
diff --git a/src/Filters/JpegFilter.cs b/src/Filters/JpegFilter.cs
index d315d1f..6c2b48e 100644
--- a/src/Filters/JpegFilter.cs
+++ b/src/Filters/JpegFilter.cs
@@ -9,50 +9,34 @@
*/
using System;
+using FSpot.Utils;
using FSpot.Imaging;
-using FSpot.Imaging.Exif;
namespace FSpot.Filters {
- public class JpegFilter : IFilter {
- private uint quality = 95;
- public uint Quality {
- get { return quality; }
- set { quality = value; }
- }
-
- public JpegFilter (uint quality)
- {
- this.quality = quality;
- }
-
- public JpegFilter()
- {
- }
-
- public bool Convert (FilterRequest req)
- {
- // FIXME this should copy metadata from the original
- // even when the source is not a jpeg
- string source = req.Current.LocalPath;
-
- using (ImageFile img = ImageFile.Create (req.Current)) {
- if (img is Imaging.JpegFile)
- return false;
-
- req.Current = req.TempUri ("jpg");
- string dest = req.Current.LocalPath;
-
- ExifData exif_data;
- try {
- exif_data = new ExifData (source);
- } catch (Exception) {
- exif_data = new ExifData();
- }
-
- PixbufUtils.SaveJpeg (img.Load(), dest, (int) quality, exif_data);
- }
-
- return true;
- }
- }
+ public class JpegFilter : IFilter {
+ private uint quality = 95;
+ public uint Quality {
+ get { return quality; }
+ set { quality = value; }
+ }
+
+ public JpegFilter (uint quality)
+ {
+ this.quality = quality;
+ }
+
+ public JpegFilter()
+ {
+ }
+
+ public bool Convert (FilterRequest req)
+ {
+ var source = req.Current;
+ req.Current = req.TempUri ("jpg");
+
+ PixbufUtils.CreateDerivedVersion (source, req.Current, quality);
+
+ return true;
+ }
+ }
}
diff --git a/src/Filters/ResizeFilter.cs b/src/Filters/ResizeFilter.cs
index ea8dbc4..050c977 100644
--- a/src/Filters/ResizeFilter.cs
+++ b/src/Filters/ResizeFilter.cs
@@ -12,69 +12,51 @@
using System;
using System.IO;
+using FSpot.Utils;
using FSpot.Imaging;
-using FSpot.Imaging.Exif;
using Mono.Unix;
using Gdk;
namespace FSpot.Filters {
- public class ResizeFilter : IFilter
- {
- public ResizeFilter ()
- {
- }
-
- public ResizeFilter (uint size)
- {
- this.size = size;
- }
-
- private uint size = 600;
-
- public uint Size {
- get { return size; }
- set { size = value; }
- }
-
- public bool Convert (FilterRequest req)
- {
- string source = req.Current.LocalPath;
- var dest_uri = req.TempUri (System.IO.Path.GetExtension (source));
- string dest = dest_uri.LocalPath;
-
- using (ImageFile img = ImageFile.Create (req.Current)) {
-
- using (Pixbuf pixbuf = img.Load ()) {
- if (pixbuf.Width < size && pixbuf.Height < size)
- return false;
- }
-
- using (Pixbuf pixbuf = img.Load ((int)size, (int)size)) {
- string destination_extension = Path.GetExtension (dest);
-
- if (Path.GetExtension (source).ToLower () == Path.GetExtension (dest).ToLower ()) {
- using (Stream output = File.OpenWrite (dest)) {
- img.Save (pixbuf, output);
- }
- } else if (destination_extension == ".jpg") {
- // FIXME this is a bit of a nasty hack to work around
- // the lack of being able to change the path in this filter
- // and the lack of proper metadata copying yuck
- ExifData exif_data;
-
- exif_data = new ExifData (source);
-
- PixbufUtils.SaveJpeg (pixbuf, dest, 95, exif_data);
- } else
- throw new NotImplementedException (String.Format (Catalog.GetString ("No way to save files of type \"{0}\""), destination_extension));
- }
- }
-
- req.Current = dest_uri;
- return true;
- }
- }
+ public class ResizeFilter : IFilter
+ {
+ public ResizeFilter ()
+ {
+ }
+
+ public ResizeFilter (uint size)
+ {
+ this.size = size;
+ }
+
+ private uint size = 600;
+
+ public uint Size {
+ get { return size; }
+ set { size = value; }
+ }
+
+ public bool Convert (FilterRequest req)
+ {
+ string source = req.Current.LocalPath;
+ var dest_uri = req.TempUri (System.IO.Path.GetExtension (source));
+
+ using (ImageFile img = ImageFile.Create (req.Current)) {
+
+ using (Pixbuf pixbuf = img.Load ()) {
+ if (pixbuf.Width < size && pixbuf.Height < size)
+ return false;
+ }
+
+ using (Pixbuf pixbuf = img.Load ((int)size, (int)size)) {
+ PixbufUtils.CreateDerivedVersion (req.Current, dest_uri, 95, pixbuf);
+ }
+ }
+
+ req.Current = dest_uri;
+ return true;
+ }
+ }
}
-
diff --git a/src/Filters/SharpFilter.cs b/src/Filters/SharpFilter.cs
index 2959738..a90591a 100644
--- a/src/Filters/SharpFilter.cs
+++ b/src/Filters/SharpFilter.cs
@@ -14,54 +14,35 @@ using Gdk;
using Mono.Unix;
+using FSpot.Utils;
using FSpot.Imaging;
-using FSpot.Imaging.Exif;
namespace FSpot.Filters {
- public class SharpFilter : IFilter
- {
- double radius, amount, threshold;
-
- public SharpFilter (double radius, double amount, double threshold)
- {
- this.radius = radius;
- this.amount = amount;
- this.threshold = threshold;
- }
-
- public bool Convert (FilterRequest req)
- {
- var dest_uri = req.TempUri (System.IO.Path.GetExtension (req.Current.LocalPath));
-
- using (ImageFile img = ImageFile.Create (req.Current)) {
- using (Pixbuf in_pixbuf = img.Load ()) {
- 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 ()) {
- using (Stream output = File.OpenWrite (dest_uri.LocalPath)) {
- img.Save (out_pixbuf, output);
- }
- } else if (destination_extension == ".jpg") {
- // FIXME this is a bit of a nasty hack to work around
- // the lack of being able to change the path in this filter
- // and the lack of proper metadata copying yuck
- ExifData exif_data;
-
- exif_data = new ExifData (req.Current.LocalPath);
-
- PixbufUtils.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));
-
- }
- }
- }
-
- req.Current = dest_uri;
- return true;
- }
-
- }
+ public class SharpFilter : IFilter
+ {
+ double radius, amount, threshold;
+
+ public SharpFilter (double radius, double amount, double threshold)
+ {
+ this.radius = radius;
+ this.amount = amount;
+ this.threshold = threshold;
+ }
+
+ public bool Convert (FilterRequest req)
+ {
+ var dest_uri = req.TempUri (req.Current.GetExtension ());
+
+ using (ImageFile img = ImageFile.Create (req.Current)) {
+ using (Pixbuf in_pixbuf = img.Load ()) {
+ using (Pixbuf out_pixbuf = PixbufUtils.UnsharpMask (in_pixbuf, radius, amount, threshold)) {
+ PixbufUtils.CreateDerivedVersion (req.Current, dest_uri, 95, out_pixbuf);
+ }
+ }
+ }
+
+ req.Current = dest_uri;
+ return true;
+ }
+ }
}
-
diff --git a/src/Imaging/Exif.cs b/src/Imaging/Exif.cs
index 76c754f..b11c1f2 100644
--- a/src/Imaging/Exif.cs
+++ b/src/Imaging/Exif.cs
@@ -789,25 +789,6 @@ namespace FSpot.Imaging.Exif {
internal static extern IntPtr malloc (uint size);
[DllImport ("libexif.dll")]
- private static extern void exif_data_save_data (HandleRef handle, out IntPtr content, out uint size);
- public byte [] Save ()
- {
- Byte [] content = null;
- uint size;
- IntPtr data;
- unsafe {
- exif_data_save_data (handle, out data, out size);
-
- content = new byte [size];
- Marshal.Copy (data, content, 0, (int)size);
- free (data);
- }
-
- Log.DebugFormat ("Saved {0} bytes", content.Length);
- return content;
- }
-
- [DllImport ("libexif.dll")]
internal static extern void exif_data_unref (HandleRef data);
[DllImport ("libexif.dll")]
diff --git a/src/Imaging/ImageFile.cs b/src/Imaging/ImageFile.cs
index 2990a90..bffa1a2 100644
--- a/src/Imaging/ImageFile.cs
+++ b/src/Imaging/ImageFile.cs
@@ -111,11 +111,6 @@ namespace FSpot.Imaging {
get { return GetOrientation (); }
}
- 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)
{
if (orig == null)
diff --git a/src/Imaging/IptcFile.cs b/src/Imaging/IptcFile.cs
index 3058d71..b53dd75 100644
--- a/src/Imaging/IptcFile.cs
+++ b/src/Imaging/IptcFile.cs
@@ -314,23 +314,6 @@ namespace FSpot.Imaging.Iptc {
}
}
- public void Save (System.IO.Stream stream)
- {
- stream.WriteByte (TagMarker);
- stream.WriteByte (RecordNumber);
- stream.WriteByte (DataSetNumber);
- if (Data.Length < LengthMask) {
- byte [] len = FSpot.BitConverter.GetBytes ((ushort)Data.Length, false);
- stream.Write (len, 0, len.Length);
- } else {
- byte [] len = FSpot.BitConverter.GetBytes ((ushort)LengthMask & 8, false);
- stream.Write (len, 0, len.Length);
- len = FSpot.BitConverter.GetBytes ((ulong) Data.Length, false);
- stream.Write (len, 0, len.Length);
- }
- stream.Write (Data, 0, Data.Length);
- }
-
public string XmpObject
{
get {
@@ -419,12 +402,5 @@ namespace FSpot.Imaging.Iptc {
sets.Add (data);
}
}
-
- public void Save (System.IO.Stream stream)
- {
- foreach (DataSet data in sets) {
- data.Save (stream);
- }
- }
}
}
diff --git a/src/Imaging/JpegFile.cs b/src/Imaging/JpegFile.cs
index 097a4e4..2b6e948 100644
--- a/src/Imaging/JpegFile.cs
+++ b/src/Imaging/JpegFile.cs
@@ -31,70 +31,6 @@ namespace FSpot.Imaging {
return null;
}
- public void SetThumbnail (Gdk.Pixbuf source)
- {
- /*// Then create the thumbnail
- // The DCF spec says thumbnails should be 160x120 always
- Gdk.Pixbuf thumbnail = PixbufUtils.ScaleToAspect (source, 160, 120);
- byte [] thumb_data = PixbufUtils.Save (thumbnail, "jpeg", null, null);
-
- // System.Console.WriteLine ("saving thumbnail");
-
- // now update the exif data
- ExifData.Data = thumb_data;*/
- // FIXME: needs to be readded https://bugzilla.gnome.org/show_bug.cgi?id=618769
- }
-
- public void SetDimensions (int width, int height)
- {
- /* FIXME: disabled, related to metadata copying
- * https://bugzilla.gnome.org/show_bug.cgi?id=618770
- * Exif.ExifEntry e;
- Exif.ExifContent thumb_content;
-
- // update the thumbnail related image fields if they exist.
- thumb_content = this.ExifData.GetContents (Exif.Ifd.One);
- e = thumb_content.Lookup (Exif.Tag.RelatedImageWidth);
- if (e != null)
- e.SetData ((uint)width);
-
- e = thumb_content.Lookup (Exif.Tag.RelatedImageHeight);
- if (e != null)
- e.SetData ((uint)height);
-
- Exif.ExifContent image_content;
- image_content = this.ExifData.GetContents (Exif.Ifd.Zero);
- image_content.GetEntry (Exif.Tag.Orientation).SetData ((ushort)PixbufOrientation.TopLeft);
- //image_content.GetEntry (Exif.Tag.ImageWidth).SetData ((uint)pixbuf.Width);
- //image_content.GetEntry (Exif.Tag.ImageHeight).SetData ((uint)pixbuf.Height);
- image_content.GetEntry (Exif.Tag.PixelXDimension).SetData ((uint)width);
- image_content.GetEntry (Exif.Tag.PixelYDimension).SetData ((uint)height);*/
- }
-
- public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
- {
-
- // Console.WriteLine ("starting save");
- // First save the imagedata
- int quality = metadata_file.Properties.PhotoQuality;
- quality = quality == 0 ? 75 : quality;
- byte [] image_data = PixbufUtils.Save (pixbuf, "jpeg", new string [] {"quality" }, new string [] { quality.ToString () });
- System.IO.MemoryStream buffer = new System.IO.MemoryStream ();
- buffer.Write (image_data, 0, image_data.Length);
-/* FIXME: Metadata copying doesn't work yet https://bugzilla.gnome.org/show_bug.cgi?id=618770
- buffer.Position = 0;
-
- // Console.WriteLine ("setting thumbnail");
- SetThumbnail (pixbuf);
- SetDimensions (pixbuf.Width, pixbuf.Height);
- pixbuf.Dispose ();
-
- // Console.WriteLine ("saving metatdata");
- SaveMetaData (buffer, stream);
- // Console.WriteLine ("done");*/
- buffer.Close ();
- }
-
public Gdk.Pixbuf GetEmbeddedThumbnail ()
{
/*if (this.ExifData.Data.Length > 0) {
diff --git a/src/Imaging/PngFile.cs b/src/Imaging/PngFile.cs
index 1f37b97..eb2a0c2 100644
--- a/src/Imaging/PngFile.cs
+++ b/src/Imaging/PngFile.cs
@@ -294,9 +294,6 @@ namespace FSpot.Imaging.Png {
public class ItxtChunk : ZtxtChunk{
//public static string Name = "zTXt";
- string Language;
- string LocalizedKeyword;
-
public override void Load (byte [] data)
{
int i = 0;
@@ -304,9 +301,7 @@ namespace FSpot.Imaging.Png {
i++;
compressed = (data [i++] != 0);
i++;
- Language = GetString (ref i);
i++;
- LocalizedKeyword = GetString (ref i, System.Text.Encoding.UTF8);
i++;
if (Compressed) {
@@ -318,48 +313,6 @@ namespace FSpot.Imaging.Png {
}
}
- public override void SetText (string text)
- {
- byte [] raw = System.Text.Encoding.UTF8.GetBytes (text);
- SetText (raw);
- }
-
- public void SetText (byte [] raw)
- {
- using (MemoryStream stream = new MemoryStream ()) {
- byte [] tmp;
-
- text_data = raw;
-
- tmp = Latin1.GetBytes (keyword);
- stream.Write (tmp, 0, tmp.Length);
- stream.WriteByte (0);
-
- stream.WriteByte ((byte)(compressed ? 1 : 0));
- stream.WriteByte (0);
-
- if (Language != null && Language != System.String.Empty) {
- tmp = Latin1.GetBytes (Language);
- stream.Write (tmp, 0, tmp.Length);
- }
- stream.WriteByte (0);
-
- if (LocalizedKeyword != null && LocalizedKeyword != System.String.Empty) {
- tmp = System.Text.Encoding.UTF8.GetBytes (LocalizedKeyword);
- stream.Write (tmp, 0, tmp.Length);
- }
- stream.WriteByte (0);
-
- if (compressed) {
- tmp = Deflate (text_data, 0, text_data.Length);
- stream.Write (tmp, 0, tmp.Length);
- } else {
- stream.Write (text_data, 0, text_data.Length);
- }
- this.data = stream.ToArray ();
- }
- }
-
public ItxtChunk (string name, byte [] data) : base (name, data)
{
this.Name = name;
@@ -371,8 +324,6 @@ namespace FSpot.Imaging.Png {
encoding = System.Text.Encoding.UTF8;
this.Name = "iTXt";
this.keyword = keyword;
- this.Language = language;
- this.LocalizedKeyword = System.String.Empty;
this.compressed = compressed;
}
}
@@ -698,17 +649,6 @@ namespace FSpot.Imaging.Png {
}
- public virtual void Save (System.IO.Stream stream)
- {
- byte [] name_bytes = System.Text.Encoding.ASCII.GetBytes (Name);
- byte [] length_bytes = BitConverter.GetBytes ((uint)data.Length, false);
- stream.Write (length_bytes, 0, length_bytes.Length);
- Crc crc = new Crc (stream);
- crc.Write (name_bytes);
- crc.Write (data);
- crc.WriteSum ();
- }
-
public bool Critical {
get {
return !System.Char.IsLower (Name, 0);
@@ -1217,49 +1157,6 @@ namespace FSpot.Imaging.Png {
else
throw new System.Exception ("Uknown ordering for chunk");
}
-
- public void Save (System.IO.Stream stream)
- {
- stream.Write (magic, 0, magic.Length);
- foreach (Chunk chunk in Chunks) {
- chunk.Save (stream);
- }
- }
- }
-
-
- public void Save (System.IO.Stream stream)
- {
- Header.Save (stream);
- }
-
- public void Save (string path)
- {
- string temp_path = path + ".tmp.png";
- using (System.IO.Stream output = System.IO.File.OpenWrite (temp_path)) {
- Save (output);
- }
- if (FSpot.Utils.Unix.Rename (temp_path, path) < 0) {
- System.IO.File.Delete (temp_path);
- throw new System.Exception (System.String.Format ("Unable to rename {0} to {1}", temp_path, path));
- }
- }
-
- public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
- {
- byte [] buffer = PixbufUtils.Save (pixbuf, "png", null, null);
- using (MemoryStream mem = new MemoryStream (buffer)) {
- PngHeader converted = new PngHeader (mem);
-
- /* FIXME we need to update the XMP metadata here */
- foreach (Chunk c in Chunks) {
- if (c is TextChunk) {
- converted.Insert (c);
- }
- }
-
- converted.Save (stream);
- }
}
public override Cms.Profile GetProfile ()
@@ -1333,25 +1230,5 @@ namespace FSpot.Imaging.Png {
return new XmpFile (stream);
}
}
-
- public void SetXmp (XmpFile xmp)
- {
- TextChunk text = null;
-
- text = Header.LookupTextChunk ("XML:com.adobe.xmp");
- if (text != null)
- Chunks.Remove (text);
-
- text = Header.LookupTextChunk ("XMP");
- if (text != null)
- Chunks.Remove (text);
-
- ItxtChunk itext = new ItxtChunk ("XML:com.adobe.xmp", "en", false);
- using (MemoryStream stream = new MemoryStream ()) {
- xmp.Save (stream);
- itext.SetText (stream.ToArray ());
- }
- Header.Insert (itext);
- }
}
}
diff --git a/src/Imaging/PnmFile.cs b/src/Imaging/PnmFile.cs
index b2d2275..231e7a0 100644
--- a/src/Imaging/PnmFile.cs
+++ b/src/Imaging/PnmFile.cs
@@ -199,39 +199,6 @@ namespace FSpot.Imaging.Pnm {
return PixbufUtils.ScaleToMaxSize (this.Load (), width, height);
}
- public override void Save (Gdk.Pixbuf pixbuf, System.IO.Stream stream)
- {
- if (pixbuf.HasAlpha)
- throw new NotImplementedException ();
-
- // FIXME this should be part of the header class
- string header = String.Format ("P6\n"
- + "#Software: {0} {1}\n"
- + "{2} {3} #Width and Height\n"
- + "255\n",
- FSpot.Defines.PACKAGE,
- FSpot.Defines.VERSION,
- pixbuf.Width,
- pixbuf.Height);
-
- byte [] header_bytes = System.Text.Encoding.UTF8.GetBytes (header);
- stream.Write (header_bytes, 0, header.Length);
-
- unsafe {
- byte * src_pixels = (byte *) pixbuf.Pixels;
- int src_stride = pixbuf.Rowstride;
- int count = pixbuf.Width * pixbuf.NChannels;
- int height = pixbuf.Height;
-
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < count; x++) {
- stream.WriteByte (* (src_pixels + x));
- }
- src_pixels += src_stride;
- }
- }
- }
-
public static Gdk.Pixbuf Load (Stream stream)
{
Header header = new Header (stream);
diff --git a/src/Imaging/XmpFile.cs b/src/Imaging/XmpFile.cs
index ff20334..42b8015 100644
--- a/src/Imaging/XmpFile.cs
+++ b/src/Imaging/XmpFile.cs
@@ -62,40 +62,6 @@ namespace FSpot.Imaging.Xmp {
}
}
- public void Save (System.IO.Stream stream)
- {
- try {
- XmlTextWriter text;
- RdfXmlWriter writer;
- XmlDocument rdfdoc = new XmlDocument();
-
- // first, construct the rdf guts, semweb style
- writer = new XmpWriter (rdfdoc);
- //writer.Namespaces.Parent = MetadataStore.Namespaces;
- writer.Write (store);
- writer.Close ();
-
- // now construct the xmp wrapper packet
- text = new XmlTextWriter (stream, System.Text.Encoding.UTF8);
- text.Formatting = Formatting.Indented;
-
- text.WriteProcessingInstruction ("xpacket", "begin=\"\ufeff\" id=\"W5M0MpCehiHzreSzNTczkc9d\"");
- text.WriteStartElement ("x:xmpmeta");
- text.WriteAttributeString ("xmlns", "x", null, "adobe:ns:meta/");
-
- ((XmlElement)rdfdoc.ChildNodes[1]).RemoveAttribute ("xml:base");
- rdfdoc.ChildNodes[1].WriteTo (text);
-
- // now close off the xmp packet
- text.WriteEndElement ();
- text.WriteProcessingInstruction ("xpacket", "end=\"r\"");
- text.Close ();
-
- } catch (System.Exception e) {
- Log.Exception (e);
- }
- }
-
public bool Add (Statement stmt)
{
return ((SemWeb.StatementSink)store).Add (stmt);
@@ -112,20 +78,5 @@ namespace FSpot.Imaging.Xmp {
Log.Debug(stmt.ToString());
}
}
-
-#if TEST_XMP
- static void Main (string [] args)
- {
- XmpFile xmp = new XmpFile (System.IO.File.OpenRead (args [0]));
- //xmp.Store.Dump ();
-#if false
- System.IO.StreamReader stream = new System.IO.StreamReader (System.IO.File.OpenRead (args [0]));
-
- while (stream.BaseStream.Position < stream.BaseStream.Length) {
- System.Console.WriteLine (stream.ReadLine ());
- }
-#endif
- }
-#endif
}
}
diff --git a/src/PixbufUtils.cs b/src/PixbufUtils.cs
index 7b44a92..1d3dc62 100644
--- a/src/PixbufUtils.cs
+++ b/src/PixbufUtils.cs
@@ -21,7 +21,7 @@ using FSpot.Imaging.Exif;
using Hyena;
using TagLib.Image;
-public class PixbufUtils {
+public static class PixbufUtils {
static Pixbuf error_pixbuf = null;
public static Pixbuf ErrorPixbuf {
get {
@@ -407,75 +407,6 @@ public class PixbufUtils {
return flattened;
}
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct FPixbufJpegMarker {
- public int type;
- public byte *data;
- public int length;
- }
-
- [DllImport ("libfspot")]
- static extern bool f_pixbuf_save_jpeg (IntPtr src, string path, int quality, FPixbufJpegMarker [] markers, int num_markers);
-
- public static void SaveJpeg (Pixbuf pixbuf, string path, int quality, ExifData exif_data)
- {
- Pixbuf temp = null;
- if (pixbuf.HasAlpha) {
- temp = 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);
- thumbnail.Dispose ();
-
- byte [] data = new byte [0];
- FPixbufJpegMarker [] marker = new FPixbufJpegMarker [0];
- bool result = false;
-
- if (exif_data != null && exif_data.Handle.Handle != IntPtr.Zero) {
- exif_data.Data = thumb_data;
-
- // Most of the things we will set will be in the 0th ifd
- var content = exif_data.GetContents (FSpot.Imaging.Exif.Ifd.Zero);
-
- // reset the orientation tag the default is top/left
- content.GetEntry (FSpot.Imaging.Exif.Tag.Orientation).Reset ();
-
- // set the write time in the datetime tag
- content.GetEntry (FSpot.Imaging.Exif.Tag.DateTime).Reset ();
-
- // set the software tag
- content.GetEntry (FSpot.Imaging.Exif.Tag.Software).SetData (FSpot.Defines.PACKAGE + " version " + FSpot.Defines.VERSION);
-
- data = exif_data.Save ();
- }
-
- unsafe {
- if (data.Length > 0) {
-
- fixed (byte *p = data) {
- marker = new FPixbufJpegMarker [1];
- marker [0].type = 0xe1; // APP1 marker
- marker [0].data = p;
- marker [0].length = data.Length;
-
- result = f_pixbuf_save_jpeg (pixbuf.Handle, path, quality, marker, marker.Length);
- }
- } else
- result = f_pixbuf_save_jpeg (pixbuf.Handle, path, quality, marker, marker.Length);
-
- }
-
- if (temp != null)
- temp.Dispose ();
-
- 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);
@@ -484,7 +415,7 @@ public class PixbufUtils {
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);
@@ -701,33 +632,82 @@ public class PixbufUtils {
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);
-// }
+ public static void CreateDerivedVersion (SafeUri source, SafeUri destination)
+ {
+ CreateDerivedVersion (source, destination, 95);
+ }
+
+ public static void CreateDerivedVersion (SafeUri source, SafeUri destination, uint jpeg_quality)
+ {
+ if (source.GetExtension () == destination.GetExtension ()) {
+ // Simple copy will do!
+ var file_from = GLib.FileFactory.NewForUri (source);
+ var file_to = GLib.FileFactory.NewForUri (destination);
+ file_from.Copy (file_to, GLib.FileCopyFlags.AllMetadata | GLib.FileCopyFlags.Overwrite, null, null);
+ return;
+ }
+
+ // Else make a derived copy with metadata copied
+ using (ImageFile img = ImageFile.Create (source)) {
+ using (var pixbuf = img.Load ()) {
+ CreateDerivedVersion (source, destination, jpeg_quality, pixbuf);
+ }
+ }
+ }
+
+ public static void CreateDerivedVersion (SafeUri source, SafeUri destination, uint jpeg_quality, Pixbuf pixbuf)
+ {
+ SaveToSuitableFormat (destination, pixbuf, jpeg_quality);
+
+ var res_from = new GIOTagLibFileAbstraction () { Uri = source };
+ var res_to = new GIOTagLibFileAbstraction () { Uri = destination };
+ using (var metadata_from = TagLib.File.Create (res_from) as TagLib.Image.File) {
+ using (var metadata_to = TagLib.File.Create (res_to) as TagLib.Image.File) {
+ metadata_to.CopyFrom (metadata_from);
+ metadata_to.Save ();
+ }
+ }
+ }
+
+ private static void SaveToSuitableFormat (SafeUri destination, Pixbuf pixbuf, uint jpeg_quality)
+ {
+ // FIXME: this needs to work on streams rather than filenames. Do that when we switch to
+ // newer GDK.
+ var extension = destination.GetExtension ().ToLower ();
+ if (extension == ".png") {
+ pixbuf.Save (destination.LocalPath, "png");
+ } else if (extension == ".jpg" || extension == ".jpeg") {
+ pixbuf.Save (destination.LocalPath, "jpeg", jpeg_quality);
+ } else {
+ throw new NotImplementedException ("Saving this file format is not supported");
+ }
+ }
+
+#region Gdk hackery
+
+ // This hack below is needed because there is no wrapped version of
+ // Save which allows specifying the variable arguments (it's not
+ // possible with p/invoke).
+
+ [DllImport("libgdk_pixbuf-2.0-0.dll")]
+ static extern bool gdk_pixbuf_save(IntPtr raw, IntPtr filename, IntPtr type, out IntPtr error,
+ IntPtr optlabel1, IntPtr optvalue1, IntPtr dummy);
+
+ private static bool Save (this Pixbuf pixbuf, string filename, string type, uint jpeg_quality)
+ {
+ IntPtr error = IntPtr.Zero;
+ IntPtr nfilename = GLib.Marshaller.StringToPtrGStrdup (filename);
+ IntPtr ntype = GLib.Marshaller.StringToPtrGStrdup (type);
+ IntPtr optlabel1 = GLib.Marshaller.StringToPtrGStrdup ("quality");
+ IntPtr optvalue1 = GLib.Marshaller.StringToPtrGStrdup (jpeg_quality.ToString ());
+ bool ret = gdk_pixbuf_save(pixbuf.Handle, nfilename, ntype, out error, optlabel1, optvalue1, IntPtr.Zero);
+ GLib.Marshaller.Free (nfilename);
+ GLib.Marshaller.Free (ntype);
+ GLib.Marshaller.Free (optlabel1);
+ GLib.Marshaller.Free (optvalue1);
+ if (error != IntPtr.Zero) throw new GLib.GException (error);
+ return ret;
+ }
+
+#endregion
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]