summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--README9
-rw-r--r--configure.ac2
-rw-r--r--src/itdb.h30
-rw-r--r--src/itdb_artwork.c37
-rw-r--r--src/itdb_photoalbum.c35
-rw-r--r--src/itdb_track.c22
-rw-r--r--src/ithumb-writer.c39
-rw-r--r--tests/test-photos.c3
9 files changed, 165 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index 34bf692..ea36804 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2006-11-23 Jorg Schuler <jcsjcs at users.sourceforge.net>
+
+ * When adding photos to the iPod the user may or may not want to
+ rotate the picture shown on the iPod screen, for example
+ deending on EXIF rotation value. This can now be achieved by
+ passing a new parameter 'rotation' to itdb_photodb_add_photo()
+ or itdb_photodb_add_photo_from_data(). (Valid values: 0, 90, 180,
+ 270, rotation is counter-clockwise). These two functions now
+ also accept a GError pointer. As a consequence Itdb_Thumb had to
+ be extended with a field for the rotation value and
+ itdb_artwork_add_thumbnail have been extended to accept
+ @rotation and @error as well.
+
+ The actual rotation is carried out in
+ ithumb-writer.c/ithumb_writer_write_thumbnail() using
+ gdk_pixbuf_rotate_simple() and require gdk-pixbuf V2.6 or
+ higher.
+
+ In contrast, itdb_track_set_thumbnails() and
+ itdb_track_set_thumbnails_from_data have been left unchanged,
+ even though they could be extended to accept @rotation and
+ @error easily. Please let me know if this is wanted.
+
+ * configure.ac
+ src/itdb.h
+ src/itdb_artwork.c
+ src/itdb_photoalbum.c
+ src/itdb_track.c
+ src/ithumb-writer.c: implemented changes outlined above.
+
+ * tests/test-photos.c: added @rotation and @error to the
+ itdb_photodb_add_photo() call.
+
2006-11-12 Jorg Schuler <jcsjcs at users.sourceforge.net>
* ithumb-writer.c (itdb_write_ithumb_files):
diff --git a/README b/README
index 75cea89..ae0c356 100644
--- a/README
+++ b/README
@@ -124,12 +124,7 @@ other songs is not something that is tranparently handled, ie you'll
need to add code either to libgpod or to gtkpod to make that work
properly.
-As for Photo Database handling (which is not dealt with currently), I
-agree it doesn't make sense to associate its parsing with an
-Itdb_ItunesDB object, and that a 'parallel' api mimicking somewhat the
-Track/Playlist stuff with Photo/Album entities would need to be
-designed, but I didn't work on that since, and I probably won't short
-term.
+...
People wanting more info can find lots of details on
http://ipodlinux.org/ITunesDB#Artwork_Database
@@ -137,3 +132,5 @@ http://ipodlinux.org/ITunesDB#Artwork_Database
I hope that's helpful,
Christophe
+
+----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index b1b5851..c010c58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,7 +74,7 @@ AC_ARG_ENABLE(gdk-pixbuf, [AC_HELP_STRING([--disable-gdk-pixbuf],[ArtworkDB will
esac], have_gdkpixbuf=yes)
AH_TEMPLATE([HAVE_GDKPIXBUF], [Whether gdk-pixbuf is installed, ArtworkDB writing support will be disabled if it can't be found])
if test x$have_gdkpixbuf = xyes; then
- PKG_CHECK_MODULES(GDKPIXBUF, gdk-pixbuf-2.0, have_gdkpixbuf=yes, have_gdkpixbuf=no)
+ PKG_CHECK_MODULES(GDKPIXBUF, gdk-pixbuf-2.0 >= 2.6.0, have_gdkpixbuf=yes, have_gdkpixbuf=no)
if test x"$have_gdkpixbuf" = xyes; then
AC_DEFINE_UNQUOTED(HAVE_GDKPIXBUF, 1)
fi
diff --git a/src/itdb.h b/src/itdb.h
index b77743a..5989dcd 100644
--- a/src/itdb.h
+++ b/src/itdb.h
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-11 16:29:02 jcs>
+/* Time-stamp: <2006-11-23 23:27:35 jcs>
|
| Copyright (C) 2002-2006 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -431,17 +431,18 @@ typedef enum {
*/
struct _Itdb_Thumb {
ItdbThumbType type;
- gchar *filename;
- guchar *image_data; /* holds the thumbnail data of
- non-transfered thumbnails when
- filename == NULL */
- gsize image_data_len; /* length of data */
+ gchar *filename;
+ guchar *image_data; /* holds the thumbnail data of
+ non-transfered thumbnails when
+ filename == NULL */
+ gsize image_data_len; /* length of data */
+ gint rotation; /* angle (0, 90, 180, 270) to rotate the image */
guint32 offset;
guint32 size;
- gint16 width;
- gint16 height;
- gint16 horizontal_padding;
- gint16 vertical_padding;
+ gint16 width;
+ gint16 height;
+ gint16 horizontal_padding;
+ gint16 vertical_padding;
};
struct _Itdb_Artwork {
@@ -1004,10 +1005,11 @@ void itdb_track_remove_thumbnails (Itdb_Track *track);
* how to use. */
Itdb_PhotoDB *itdb_photodb_parse (const gchar *mp, GError **error);
Itdb_Artwork *itdb_photodb_add_photo (Itdb_PhotoDB *db, const gchar *filename,
- GError **error);
+ gint rotation, GError **error);
Itdb_Artwork *itdb_photodb_add_photo_from_data (Itdb_PhotoDB *db,
const guchar *image_data,
gsize image_data_len,
+ gint rotation,
GError **error);
void itdb_photodb_photoalbum_add_photo (Itdb_PhotoDB *db,
Itdb_PhotoAlbum *album,
@@ -1039,11 +1041,13 @@ Itdb_Thumb *itdb_artwork_get_thumb_by_type (Itdb_Artwork *artwork,
ItdbThumbType type);
gboolean itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
ItdbThumbType type,
- const gchar *filename);
+ const gchar *filename,
+ gint rotation, GError **error);
gboolean itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
ItdbThumbType type,
const guchar *image_data,
- gsize image_data_len);
+ gsize image_data_len,
+ gint rotation, GError **error);
void itdb_artwork_remove_thumbnail (Itdb_Artwork *artwork,
Itdb_Thumb *thumb);
void itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork);
diff --git a/src/itdb_artwork.c b/src/itdb_artwork.c
index d1b312e..4435a82 100644
--- a/src/itdb_artwork.c
+++ b/src/itdb_artwork.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-12 23:17:20 jcs>
+/* Time-stamp: <2006-11-23 23:27:35 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -163,18 +163,27 @@ itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork)
* @artwork: an #Itdb_Thumbnail
* @type: thumbnail size
* @filename: image file to use to create the thumbnail
+ * @rotation: angle by which the image should be rotated
+ * counterclockwise. Valid values are 0, 90, 180 and 270.
+ * @error: return location for a #GError or NULL
*
* Appends a thumbnail of type @type to existing thumbnails in @artwork. No
* data is read from @filename yet, the file will be when @artwork is saved to
* disk. @filename must still exist when that happens.
*
+ * For the rotation angle you can also use the gdk constants
+ * GDK_PIXBUF_ROTATE_NONE, ..._COUNTERCLOCKWISE, ..._UPSIDEDOWN AND
+ * ..._CLOCKWISE.
+ *
* Return value: TRUE if the thumbnail could be successfully added, FALSE
- * otherwise
+ * otherwise. @error is set appropriately.
**/
gboolean
itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
ItdbThumbType type,
- const gchar *filename)
+ const gchar *filename,
+ gint rotation,
+ GError **error)
{
#ifdef HAVE_GDKPIXBUF
/* This operation doesn't make sense when we can't save thumbnail files */
@@ -185,6 +194,9 @@ itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
g_return_val_if_fail (filename, FALSE);
if (g_stat (filename, &statbuf) != 0) {
+ g_set_error (error, 0, -1,
+ _("Could not access file '%s'."),
+ filename);
return FALSE;
}
@@ -194,10 +206,13 @@ itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
thumb = itdb_thumb_new ();
thumb->filename = g_strdup (filename);
thumb->type = type;
+ thumb->rotation = rotation;
artwork->thumbnails = g_list_append (artwork->thumbnails, thumb);
return TRUE;
#else
+ g_set_error (error, 0, -1,
+ _("Artwork support not compiled into libgpod."));
return FALSE;
#endif
}
@@ -210,19 +225,28 @@ itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
* @image_data: data used to create the thumbnail (the raw contents of
* an image file)
* @image_data_len: length of above data block
+ * @rotation: angle by which the image should be rotated
+ * counterclockwise. Valid values are 0, 90, 180 and 270.
+ * @error: return location for a #GError or NULL
*
* Appends a thumbnail of type @type to existing thumbnails in
* @artwork. No data is processed yet. This will be done when @artwork
* is saved to disk.
*
+ * For the rotation angle you can also use the gdk constants
+ * GDK_PIXBUF_ROTATE_NONE, ..._COUNTERCLOCKWISE, ..._UPSIDEDOWN AND
+ * ..._CLOCKWISE.
+ *
* Return value: TRUE if the thumbnail could be successfully added, FALSE
- * otherwise
+ * otherwise. @error is set appropriately.
**/
gboolean
itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
ItdbThumbType type,
const guchar *image_data,
- gsize image_data_len)
+ gsize image_data_len,
+ gint rotation,
+ GError **error)
{
#ifdef HAVE_GDKPIXBUF
/* This operation doesn't make sense when we can't save thumbnail files */
@@ -243,10 +267,13 @@ itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
memcpy (thumb->image_data, image_data, image_data_len);
thumb->type = type;
+ thumb->rotation = rotation;
artwork->thumbnails = g_list_append (artwork->thumbnails, thumb);
return TRUE;
#else
+ g_set_error (error, 0, -1,
+ _("Artwork support not compiled into libgpod."));
return FALSE;
#endif
}
diff --git a/src/itdb_photoalbum.c b/src/itdb_photoalbum.c
index edc1004..df36a1b 100644
--- a/src/itdb_photoalbum.c
+++ b/src/itdb_photoalbum.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-10-31 21:49:36 jcs>
+/* Time-stamp: <2006-11-23 23:29:44 jcs>
|
| Copyright (C) 2002-2006 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -333,6 +333,7 @@ static Itdb_Artwork *itdb_photodb_add_photo_internal (Itdb_PhotoDB *db,
const gchar *filename,
const guchar *image_data,
gsize image_data_len,
+ gint rotation,
GError **error)
{
#ifdef HAVE_GDKPIXBUF
@@ -408,14 +409,18 @@ static Itdb_Artwork *itdb_photodb_add_photo_internal (Itdb_PhotoDB *db,
{
result = itdb_artwork_add_thumbnail (artwork,
format->type,
- filename);
+ filename,
+ rotation,
+ error);
}
if (image_data)
{
result = itdb_artwork_add_thumbnail_from_data (artwork,
format->type,
image_data,
- image_data_len);
+ image_data_len,
+ rotation,
+ error);
}
}
@@ -453,45 +458,63 @@ static Itdb_Artwork *itdb_photodb_add_photo_internal (Itdb_PhotoDB *db,
* itdb_photodb_add_photo:
* @db: the #Itdb_PhotoDB to add the photo to.
* @filename: file with the photo to add.
+ * @rotation: angle by which the image should be rotated
+ * counterclockwise. Valid values are 0, 90, 180 and 270.
* @error: return location for a #GError or NULL
*
* Add a photo to the PhotoDB. The photo is automatically added to the
* first Photoalbum, which by default contains a list of all photos in
* the database. If no Photoalbums exist one is created automatically.
*
+ * For the rotation angle you can also use the gdk constants
+ * GDK_PIXBUF_ROTATE_NONE, ..._COUNTERCLOCKWISE, ..._UPSIDEDOWN AND
+ * ..._CLOCKWISE.
+ *
* Return value: a pointer to the added photo.
**/
Itdb_Artwork *itdb_photodb_add_photo (Itdb_PhotoDB *db,
const gchar *filename,
+ gint rotation,
GError **error)
{
g_return_val_if_fail (db, FALSE);
g_return_val_if_fail (filename, FALSE);
- return itdb_photodb_add_photo_internal (db, filename, NULL, 0, error);
+ return itdb_photodb_add_photo_internal (db, filename, NULL, 0, rotation, error);
}
/**
* itdb_photodb_add_photo_from_data:
* @db: the #Itdb_PhotoDB to add the photo to.
- * @filename: file with the photo to add.
+ * @image_data: chunk of memory containing the image data (for example
+ * a jpg file)
+ * @image_data_len: length of above chunk of memory
+ * @rotation: angle by which the image should be rotated
+ * counterclockwise. Valid values are 0, 90, 180 and 270.
* @error: return location for a #GError or NULL
*
* Add a photo to the PhotoDB. The photo is automatically added to the
* first Photoalbum, which by default contains a list of all photos in
* the database. If no Photoalbums exist one is created automatically.
+ *
+ * For the rotation angle you can also use the gdk constants
+ * GDK_PIXBUF_ROTATE_NONE, ..._COUNTERCLOCKWISE, ..._UPSIDEDOWN AND
+ * ..._CLOCKWISE.
+ *
+ * Return value: a pointer to the added photo.
**/
Itdb_Artwork *itdb_photodb_add_photo_from_data (Itdb_PhotoDB *db,
const guchar *image_data,
gsize image_data_len,
+ gint rotation,
GError **error)
{
g_return_val_if_fail (db, FALSE);
g_return_val_if_fail (image_data, FALSE);
return itdb_photodb_add_photo_internal (db, NULL, image_data, image_data_len,
- error);
+ rotation, error);
}
diff --git a/src/itdb_track.c b/src/itdb_track.c
index fc66f75..3b8b9c0 100644
--- a/src/itdb_track.c
+++ b/src/itdb_track.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-07 20:54:45 jcs>
+/* Time-stamp: <2006-11-23 23:32:16 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -370,7 +370,9 @@ Itdb_Track *itdb_track_duplicate (Itdb_Track *tr)
static gboolean itdb_track_set_thumbnails_internal (Itdb_Track *track,
const gchar *filename,
const guchar *image_data,
- gsize image_data_len)
+ gsize image_data_len,
+ gint rotation,
+ GError **error)
{
gboolean result = FALSE;
@@ -382,23 +384,25 @@ static gboolean itdb_track_set_thumbnails_internal (Itdb_Track *track,
{
result = itdb_artwork_add_thumbnail (track->artwork,
ITDB_THUMB_COVER_SMALL,
- filename);
+ filename, rotation, error);
if (result == TRUE)
result = itdb_artwork_add_thumbnail (track->artwork,
ITDB_THUMB_COVER_LARGE,
- filename);
+ filename, rotation, error);
}
if (image_data)
{
result = itdb_artwork_add_thumbnail_from_data (track->artwork,
ITDB_THUMB_COVER_SMALL,
image_data,
- image_data_len);
+ image_data_len,
+ rotation, error);
if (result == TRUE)
result = itdb_artwork_add_thumbnail_from_data (track->artwork,
ITDB_THUMB_COVER_LARGE,
image_data,
- image_data_len);
+ image_data_len,
+ rotation, error);
}
if (result == TRUE)
@@ -443,7 +447,8 @@ gboolean itdb_track_set_thumbnails (Itdb_Track *track,
g_return_val_if_fail (track, FALSE);
g_return_val_if_fail (filename, FALSE);
- return itdb_track_set_thumbnails_internal (track, filename, NULL, 0);
+ return itdb_track_set_thumbnails_internal (track, filename, NULL, 0,
+ 0, NULL);
}
@@ -471,7 +476,8 @@ gboolean itdb_track_set_thumbnails_from_data (Itdb_Track *track,
g_return_val_if_fail (image_data, FALSE);
return itdb_track_set_thumbnails_internal (track, NULL,
- image_data, image_data_len);
+ image_data, image_data_len,
+ 0, NULL);
}
diff --git a/src/ithumb-writer.c b/src/ithumb-writer.c
index 060ff2a..f20546f 100644
--- a/src/ithumb-writer.c
+++ b/src/ithumb-writer.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-13 00:03:30 jcs>
+/* Time-stamp: <2006-11-23 23:45:01 jcs>
*
* Copyright (C) 2005 Christophe Fergeau
*
@@ -304,13 +304,32 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer,
gint width, height; /* must be gint -- see comment below */
g_return_val_if_fail (writer, FALSE);
+ g_return_val_if_fail (writer->img_info, FALSE);
g_return_val_if_fail (thumb, FALSE);
+ /* Make sure @rotation is valid (0, 90, 180, 270) */
+ thumb->rotation = thumb->rotation % 360;
+ thumb->rotation /= 90;
+ thumb->rotation *= 90;
+
+ /* If we rotate by 90 or 270 degrees interchange the width and
+ * height */
+
+ if ((thumb->rotation == 0) || (thumb->rotation == 180))
+ {
+ width = writer->img_info->width;
+ height = writer->img_info->height;
+ }
+ else
+ {
+ width = writer->img_info->height;
+ height = writer->img_info->width;
+ }
+
if (thumb->filename)
{ /* read image from filename */
pixbuf = gdk_pixbuf_new_from_file_at_size (thumb->filename,
- writer->img_info->width,
- writer->img_info->height,
+ width, height,
NULL);
g_free (thumb->filename);
@@ -321,8 +340,7 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer,
GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
g_return_val_if_fail (loader, FALSE);
gdk_pixbuf_loader_set_size (loader,
- writer->img_info->width,
- writer->img_info->height);
+ width, height);
gdk_pixbuf_loader_write (loader,
thumb->image_data,
thumb->image_data_len,
@@ -342,6 +360,17 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer,
return FALSE;
}
+ /* Rotate if necessary */
+ if (thumb->rotation != 0)
+ {
+ GdkPixbuf *new_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, thumb->rotation);
+ g_object_unref (pixbuf);
+ pixbuf = new_pixbuf;
+ }
+
+ /* Clean up */
+ thumb->rotation = 0;
+
/* !! cannot write directly to &thumb->width/height because
g_object_get() returns a gint, but thumb->width/height are
gint16 !! */
diff --git a/tests/test-photos.c b/tests/test-photos.c
index 18d364e..fd89aa4 100644
--- a/tests/test-photos.c
+++ b/tests/test-photos.c
@@ -265,7 +265,8 @@ static int do_add (int argc, char **argv)
{
Itdb_Artwork *photo;
- photo = itdb_photodb_add_photo (db, argv[i], &error);
+ photo = itdb_photodb_add_photo (db, argv[i], GDK_PIXBUF_ROTATE_NONE,
+ &error);
if (photo == NULL)
{
if (error)