summaryrefslogtreecommitdiffstats
path: root/src/itdb_photoalbum.c
diff options
context:
space:
mode:
authorJorg Schuler <jcsjcs@users.sourceforge.net>2006-05-30 14:09:44 +0000
committerJorg Schuler <jcsjcs@users.sourceforge.net>2006-05-30 14:09:44 +0000
commit355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17 (patch)
tree64cc40dc42c33925c6183222667354276479c362 /src/itdb_photoalbum.c
parent58503e6e5b6ef315f37fe859baaf0f5216fc8f5c (diff)
downloadlibgpod-tmz-355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17.tar.gz
libgpod-tmz-355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17.tar.xz
libgpod-tmz-355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17.zip
***** merged photo-support branch back to MAIN. branch is tagged
photo-support-merged_00 ipod.py will need minor patching (flag2, flag3). git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1292 f01d2545-417e-4e96-918e-98f8d0dbbcb6
Diffstat (limited to 'src/itdb_photoalbum.c')
-rw-r--r--src/itdb_photoalbum.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/src/itdb_photoalbum.c b/src/itdb_photoalbum.c
new file mode 100644
index 0000000..3351da0
--- /dev/null
+++ b/src/itdb_photoalbum.c
@@ -0,0 +1,375 @@
+#include <config.h>
+
+#include "itdb_private.h"
+#include "itdb_device.h"
+#include "db-artwork-parser.h"
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+
+
+/* Set @error with standard error message */
+static void error_no_photos_dir (const gchar *mp, GError **error)
+{
+ gchar *str;
+
+ g_return_if_fail (mp);
+
+ if (error)
+ {
+ str = g_build_filename (mp, "iPod_Control", "Photos", NULL);
+ g_set_error (error,
+ ITDB_FILE_ERROR,
+ ITDB_FILE_ERROR_NOTFOUND,
+ _("Photos directory not found: '%s' (or similar)."),
+ str);
+ g_free (str);
+ }
+}
+
+
+/**
+ * itdb_get_photos_dir:
+ * @mountpoint: mountpoint of iPod
+ *
+ * Retrieve the Photo directory by
+ * first calling itdb_get_control_dir() and then adding 'Photos'
+ *
+ * Return value: path to the Artwork directory or NULL of
+ * non-existent. Must g_free() after use.
+ */
+gchar *itdb_get_photos_dir (const gchar *mountpoint)
+{
+ gchar *p_ipod[] = {"Photos", NULL};
+ /* Use an array with all possibilities, so further extension will
+ be easy */
+ gchar **paths[] = {p_ipod, NULL};
+ gchar ***ptr;
+ gchar *result = NULL;
+
+ g_return_val_if_fail (mountpoint, NULL);
+
+ for (ptr=paths; *ptr && !result; ++ptr)
+ {
+ result = itdb_resolve_path (mountpoint, (const gchar **)*ptr);
+ }
+ return result;
+}
+
+/**
+ * itdb_get_photodb_path:
+ * @mountpoint: the iPod mountpoint
+ *
+ * Retrieve a path to the Photo DB
+ *
+ * Return value: path to the PhotoDB or NULL if non-existent. Must
+ * g_free() after use.
+ **/
+gchar *itdb_get_photodb_path (const gchar *mountpoint)
+{
+ gchar *photo_dir, *path=NULL;
+
+ g_return_val_if_fail (mountpoint, NULL);
+
+ photo_dir = itdb_get_photos_dir (mountpoint);
+
+ if (photo_dir)
+ {
+ path = itdb_get_path (photo_dir, "Photo Database");
+ g_free (photo_dir);
+ }
+
+ return path;
+}
+
+/**
+ * itdb_get_photos_thumb_dir:
+ * @mountpoint: the iPod mountpoint
+ *
+ * Retrieve the Photo Thumbnail directory by
+ * first calling itdb_get_control_dir() and then adding 'Photos/Thumbs'
+ *
+ * Return value: path to the Artwork directory or NULL of
+ * non-existent. Must g_free() after use.
+ */
+gchar *itdb_get_photos_thumb_dir (const gchar *mountpoint)
+{
+ gchar *control_dir;
+ gchar *result = NULL;
+ gchar *dir = "Thumbs";
+
+ g_return_val_if_fail (mountpoint, NULL);
+ g_return_val_if_fail (dir, NULL);
+
+ control_dir = itdb_get_photos_dir (mountpoint);
+ if (control_dir)
+ {
+ const gchar *p_dir[] = {NULL, NULL};
+ p_dir[0] = dir;
+ result = itdb_resolve_path (control_dir, p_dir);
+ g_free (control_dir);
+ }
+ return result;
+}
+
+
+/**
+ * itdb_photodb_parse:
+ *
+ * Parses the photo database of an iPod mounted at @mp.
+ *
+ * @mp: mountpoint of the iPod
+ * @error: will contain the error description when an error occured.
+ *
+ * Return value: the imported PhotoDB or NULL in case of an error.
+ **/
+Itdb_PhotoDB *itdb_photodb_parse (const gchar *mp, GError **error)
+{
+ gchar *photos_dir;
+ Itdb_PhotoDB *photodb = NULL;
+
+ photos_dir = itdb_get_photos_dir (mp);
+
+ if (!photos_dir)
+ {
+ error_no_photos_dir (mp, error);
+ return NULL;
+ }
+ g_free (photos_dir);
+
+ photodb = itdb_photodb_new ();
+ itdb_device_set_mountpoint (photodb->device, mp);
+ ipod_parse_photo_db (photodb);
+ return photodb;
+}
+
+
+/**
+ * itdb_photodb_new:
+ *
+ * Creates a new Itdb_PhotoDB
+ *
+ * Return value: a newly created Itdb_PhotoDB to be freed with
+ * itdb_photodb_free() when it's no longer needed
+ **/
+Itdb_PhotoDB *itdb_photodb_new (void)
+{
+ Itdb_PhotoDB *photodb;
+
+ photodb = g_new0 (Itdb_PhotoDB, 1);
+ photodb->device = itdb_device_new ();
+
+ return photodb;
+}
+
+
+/**
+ * itdb_photodb_free:
+ * @photodb: an #Itdb_PhotoDB
+ *
+ * Free the memory taken by @photodb.
+ **/
+void itdb_photodb_free (Itdb_PhotoDB *photodb)
+{
+ if (photodb)
+ {
+ g_list_foreach (photodb->photoalbums,
+ (GFunc)(itdb_photodb_photoalbum_free), NULL);
+ g_list_free (photodb->photoalbums);
+ g_list_foreach (photodb->photos,
+ (GFunc)(itdb_artwork_free), NULL);
+ g_list_free (photodb->photos);
+ itdb_device_free (photodb->device);
+
+ if (photodb->userdata && photodb->userdata_destroy)
+ (*photodb->userdata_destroy) (photodb->userdata);
+
+ g_free (photodb);
+ }
+}
+
+
+
+
+G_GNUC_INTERNAL gint itdb_get_free_photo_id ( Itdb_PhotoDB *db )
+{
+ gint photo_id = 0;
+ GList *it;
+
+ for (it = db->photos; it != NULL; it = it->next) {
+ Itdb_Artwork *artwork;
+
+ artwork = (Itdb_Artwork *)it->data;
+ if( artwork->id > photo_id )
+ photo_id = artwork->id;
+ }
+ return photo_id + 1;
+}
+
+static gint itdb_get_free_photoalbum_id ( Itdb_PhotoDB *db )
+{
+ gint album_id = 0;
+ GList *it;
+
+ for (it = db->photoalbums; it != NULL; it = it->next) {
+ Itdb_PhotoAlbum *album;
+
+ album = (Itdb_PhotoAlbum *)it->data;
+ if( album->album_id > album_id )
+ album_id = album->album_id;
+ }
+ return album_id + 1;
+}
+
+static Itdb_PhotoAlbum *itdb_get_photoalbum ( Itdb_PhotoDB *db, const gchar *albumname )
+{
+ GList *it;
+
+ if( strcmp( albumname, "master" ) == 0 )
+ return g_list_nth_data (db->photoalbums, 0);
+
+ for (it = db->photoalbums; it != NULL; it = it->next) {
+ Itdb_PhotoAlbum *album;
+
+ album = (Itdb_PhotoAlbum *)it->data;
+ if( strcmp(album->name, albumname) == 0 )
+ return album;
+ }
+ return (Itdb_PhotoAlbum *)NULL;
+}
+
+
+void itdb_photodb_photoalbum_free (Itdb_PhotoAlbum *pa)
+{
+ if (pa)
+ {
+ g_free (pa->name);
+ g_list_free (pa->members);
+
+ if (pa->userdata && pa->userdata_destroy)
+ (*pa->userdata_destroy) (pa->userdata);
+
+ g_free (pa);
+ }
+}
+
+gboolean itdb_photodb_add_photo (Itdb_PhotoDB *db,
+ const gchar *albumname,
+ const gchar *filename)
+{
+ gboolean result;
+ Itdb_Artwork *artwork;
+ Itdb_PhotoAlbum *photoalbum;
+ const Itdb_ArtworkFormat *format;
+ gint photo_id;
+
+ g_return_val_if_fail (db, FALSE);
+ g_return_val_if_fail (filename, FALSE);
+ artwork = itdb_artwork_new ();
+
+ photo_id = itdb_get_free_photo_id( db );
+ artwork->id = photo_id;
+ /* Add a thumbnail for every supported format */
+ format = itdb_device_get_artwork_formats(db->device);
+ for( result = TRUE; format->type != -1 && result == TRUE; format++) {
+ if( format->type == IPOD_COVER_SMALL
+ || format->type == IPOD_COVER_LARGE )
+ continue;
+ result = itdb_artwork_add_thumbnail (artwork,
+ format->type,
+ filename);
+ }
+
+ if (result != TRUE)
+ {
+ itdb_artwork_remove_thumbnails (artwork);
+ return result;
+ }
+ db->photos = g_list_append (db->photos, artwork);
+
+ photoalbum = itdb_get_photoalbum( db, albumname );
+ if( photoalbum == NULL )
+ photoalbum = itdb_photodb_photoalbum_new( db, albumname );
+ photoalbum->num_images++;
+ photoalbum->members = g_list_append (photoalbum->members, GINT_TO_POINTER(photo_id));
+
+ return result;
+}
+
+gboolean itdb_photodb_remove_photo (Itdb_PhotoDB *db,
+ const gint photo_id )
+{
+ gboolean result = TRUE;
+ GList *it;
+
+ g_return_val_if_fail (db, FALSE);
+
+ /* Remove the photo from the image list */
+ for (it = db->photos; it != NULL; it = it->next) {
+ Itdb_Artwork *artwork;
+
+ artwork = (Itdb_Artwork *)it->data;
+ if( artwork->id == photo_id ) {
+ db->photos = g_list_remove (db->photos, artwork);
+ break;
+ }
+ }
+
+ /* Remove the photo from any albums containing it */
+ for (it = db->photoalbums; it != NULL; it = it->next) {
+ Itdb_PhotoAlbum *album;
+
+ album = (Itdb_PhotoAlbum *)it->data;
+ album->members = g_list_remove (album->members, GINT_TO_POINTER(photo_id));
+ album->num_images = g_list_length( album->members );
+ }
+ return result;
+}
+
+Itdb_PhotoAlbum *itdb_photodb_photoalbum_new (Itdb_PhotoDB *db,
+ const gchar *album_name)
+{
+ Itdb_PhotoAlbum *photoalbum;
+
+ g_return_val_if_fail (db, FALSE);
+ g_return_val_if_fail (album_name, FALSE);
+
+ photoalbum = g_new0 (Itdb_PhotoAlbum, 1);
+ photoalbum->album_id = itdb_get_free_photoalbum_id( db );
+ photoalbum->prev_album_id = photoalbum->album_id - 1;
+ photoalbum->name = g_strdup( album_name );
+ db->photoalbums = g_list_append (db->photoalbums, photoalbum);
+
+ return photoalbum;
+}
+
+/**
+ * itdb_photodb_write:
+ * @photodb: the #Itdb_PhotoDB to write to disk
+ * @error: return location for a #GError or NULL
+ *
+ * Write out a PhotoDB.
+ *
+ * FIXME: error is not set yet.
+ *
+ * Return value: TRUE on success, FALSE on error, in which case @error is
+ * set accordingly.
+ **/
+gboolean itdb_photodb_write (Itdb_PhotoDB *photodb, GError **error)
+{
+ gboolean result;
+
+ g_return_val_if_fail (photodb, FALSE);
+ g_return_val_if_fail (photodb->device, FALSE);
+
+ if (photodb->device->byte_order == 0)
+ itdb_device_autodetect_endianess (photodb->device);
+
+ result = ipod_write_photo_db (photodb);
+
+ if (result == -1)
+ return FALSE;
+ else
+ return TRUE;
+}