diff options
author | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2005-12-04 10:26:14 +0000 |
---|---|---|
committer | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2005-12-04 10:26:14 +0000 |
commit | af5b87fa2fca1541a36baa4433bc92c595537468 (patch) | |
tree | 7eac4aa4ced55f837717d3833ffac57cd7eae044 | |
parent | 123e23a6201d1f289f0feee3ffd0e294c9fdfb5a (diff) | |
download | libgpod-af5b87fa2fca1541a36baa4433bc92c595537468.tar.gz libgpod-af5b87fa2fca1541a36baa4433bc92c595537468.tar.xz libgpod-af5b87fa2fca1541a36baa4433bc92c595537468.zip |
* src/itdb_track.c: take care of artwork_size/_count a little
better, take care of dbid2 a little better.
* src/ithumb-writer.c: new ithumb_rearrange_thumbnail_file()
taking into account multiple references to the same slot.
ithumb-writer now cleans up 0 Byte files.
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1187 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/db-artwork-parser.c | 6 | ||||
-rw-r--r-- | src/itdb_itunesdb.c | 2 | ||||
-rw-r--r-- | src/itdb_track.c | 32 | ||||
-rw-r--r-- | src/ithumb-writer.c | 177 |
5 files changed, 160 insertions, 65 deletions
@@ -7,6 +7,14 @@ src/itdb_track.c, src/ithumb-writer.c: handle artwork size and count self-consistently. + * src/itdb_track.c: take care of artwork_size/_count a little + better, take care of dbid2 a little better. + + * src/ithumb-writer.c: new ithumb_rearrange_thumbnail_file() + taking into account multiple references to the same slot. + ithumb-writer now cleans up 0 Byte files. + + 2005-11-30 Christophe Fergeau <teuf@gnome.org> * src/db-artwork-parser.c: (parse_mhni): don't crash if diff --git a/src/db-artwork-parser.c b/src/db-artwork-parser.c index ae7d629..5a9254e 100644 --- a/src/db-artwork-parser.c +++ b/src/db-artwork-parser.c @@ -240,12 +240,12 @@ parse_mhii (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) return -1; } + song->artwork->artwork_size = GINT_FROM_LE (mhii->orig_img_size); if ((song->artwork_size+song->artwork_count) != - GINT_FROM_LE (mhii->orig_img_size)) { - g_warning (_("iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)"), song->artwork_size, song->artwork_count, GINT_FROM_LE (mhii->orig_img_size)); + song->artwork->artwork_size) { + g_warning (_("iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)"), song->artwork_size, song->artwork_count, song->artwork->artwork_size); } - song->artwork->artwork_size = GINT_FROM_LE (mhii->orig_img_size); song->artwork->id = GINT_FROM_LE (mhii->image_id); #endif diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c index de3e844..82c68ea 100644 --- a/src/itdb_itunesdb.c +++ b/src/itdb_itunesdb.c @@ -1,4 +1,4 @@ -/* Time-stamp: <2005-12-01 22:11:33 jcs> +/* Time-stamp: <2005-12-04 19:10:42 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. diff --git a/src/itdb_track.c b/src/itdb_track.c index 747c5fe..a89ea4f 100644 --- a/src/itdb_track.c +++ b/src/itdb_track.c @@ -1,4 +1,4 @@ -/* Time-stamp: <2005-12-04 15:48:57 jcs> +/* Time-stamp: <2005-12-04 19:10:42 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -185,6 +185,7 @@ static void itdb_track_set_defaults (Itdb_Track *tr) } } while (id == 0); tr->dbid = id; + tr->dbid2= id; } if (tr->dbid2 == 0) tr->dbid2 = tr->dbid; } @@ -326,19 +327,24 @@ gboolean itdb_track_set_thumbnails (Itdb_Track *track, result = itdb_artwork_add_thumbnail (track->artwork, ITDB_THUMB_COVER_LARGE, filename); - if (result == FALSE) - itdb_artwork_remove_thumbnails (track->artwork); - /* some black magic :-( */ - /* track->artwork_size should actually be the total size of - artwork packed into MP3 tags. We don't write mp3 tags... */ - track->artwork_size = track->artwork->artwork_size; - /* track->artwork_count should actually be the number of images - packed into MP3 tags. */ - track->artwork_count = 1; - /* for some reason artwork->artwork_size is always - track->artwork_size + track->artwork_count */ - track->artwork->artwork_size += track->artwork_count; + if (result == TRUE) + { + /* some black magic :-( */ + /* track->artwork_size should actually be the total size of + artwork packed into MP3 tags. We don't write mp3 tags... */ + track->artwork_size = track->artwork->artwork_size; + /* track->artwork_count should actually be the number of + images packed into MP3 tags. */ + track->artwork_count = 1; + /* for some reason artwork->artwork_size is always + track->artwork_size + track->artwork_count */ + track->artwork->artwork_size += track->artwork_count; + } + else + { + itdb_artwork_remove_thumbnails (track->artwork); + } return result; } diff --git a/src/ithumb-writer.c b/src/ithumb-writer.c index c440226..d354c32 100644 --- a/src/ithumb-writer.c +++ b/src/ithumb-writer.c @@ -44,6 +44,7 @@ struct _iThumbWriter { off_t cur_offset; FILE *f; + gchar *filename; IpodArtworkFormat *img_info; GHashTable *cache; }; @@ -102,12 +103,12 @@ pack_RGB_565 (GdkPixbuf *pixbuf, int dst_width, int dst_height) static char * -ipod_image_get_ithmb_filename (const char *mount_point, gint correlation_id) +ipod_image_get_ithmb_filename (const char *mount_point, gint correlation_id, gint index) { char *paths[] = {"iPod_Control", "Artwork", NULL, NULL}; char *filename, *buf; - buf = g_strdup_printf ("F%04u_1.ithmb", correlation_id); + buf = g_strdup_printf ("F%04u_%d.ithmb", correlation_id, index); paths[2] = buf; @@ -242,7 +243,8 @@ ithumb_writer_new (const char *mount_point, const IpodArtworkFormat *info) g_free, NULL); filename = ipod_image_get_ithmb_filename (mount_point, - info->correlation_id); + info->correlation_id, + 1); if (filename == NULL) { g_hash_table_destroy (writer->cache); g_free (writer->img_info); @@ -259,7 +261,7 @@ ithumb_writer_new (const char *mount_point, const IpodArtworkFormat *info) return NULL; } writer->cur_offset = ftell (writer->f); - g_free (filename); + writer->filename=filename; return writer; } @@ -268,9 +270,14 @@ static void ithumb_writer_free (iThumbWriter *writer) { g_return_if_fail (writer != NULL); + fclose (writer->f); + if (writer->cur_offset == 0) + { /* Remove empty file */ + unlink (writer->filename); + } g_hash_table_destroy (writer->cache); g_free (writer->img_info); - fclose (writer->f); + g_free (writer->filename); g_free (writer); } @@ -282,17 +289,17 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key, auto gint offset_sort (gconstpointer a, gconstpointer b); gint offset_sort (gconstpointer a, gconstpointer b) { - return (((Itdb_Thumb *)a)->offset - - ((Itdb_Thumb *)b)->offset); + return (-(((Itdb_Thumb *)a)->offset - + ((Itdb_Thumb *)b)->offset)); } - gchar *filename = _key; + const gchar *filename = _key; GList *thumbs = _thumbs; gboolean *result = _user_data; gint fd = -1; guint32 size = 0; - guint32 tnf_num, tn_num, i; GList *gl; struct stat statbuf; + guint32 offset; void *buf = NULL; /* printf ("%s: %d\n", filename, g_list_length (thumbs)); */ @@ -301,6 +308,15 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key, if (*result == FALSE) goto out; + if (thumbs == NULL) + { /* no thumbnails for this file --> remove altogether */ + if (unlink (filename) == -1) + { + *result = FALSE; + goto out; + } + } + /* check if all thumbnails have the same size */ for (gl=thumbs; gl; gl=gl->next) { @@ -314,30 +330,27 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key, goto out; } } + if (size == 0) + { + *result = FALSE; + goto out; + } + /* OK, all thumbs are the same size @size, let's see how many * thumbnails are in the actual file */ -/* printf (" %d\n", size); */ if (g_stat (filename, &statbuf) != 0) { *result = FALSE; goto out; } - tnf_num = statbuf.st_size / size; /* check if the file size is a multiple of @size */ - if (tnf_num*size != statbuf.st_size) + if (((guint32)(statbuf.st_size / size))*size != statbuf.st_size) { *result = FALSE; goto out; } - tn_num = g_list_length (thumbs); - - /* We're finished if the number here and the number of thumbnails - * in our list is the same */ - if (tn_num == tnf_num) - goto out; - fd = open (filename, O_RDWR, 0); if (fd == -1) { @@ -345,34 +358,48 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key, goto out; } - /* Performance note: for performance reaons the list should be - ordered in reverse order of offsets because of frequent use - g_list_last(), and instead of using g_list_nth_data() the list - should be crawled by element from the end -- I will do that - eventually unless someone beats me to it. */ - - /* Sort the list of thumbs according to img->offset */ - thumbs = g_list_sort (thumbs, offset_sort); - /* size is either a value coming from a hardcoded const array from * libipoddevice, or a guint32 read from an iPod file, so no overflow * can occur here */ buf = g_malloc (size); - for (i=0; i<tn_num; ++i) + /* Sort the list of thumbs in reverse order of img->offset */ + thumbs = g_list_sort (thumbs, offset_sort); + + gl = g_list_last (thumbs); + + /* check each thumbnail slot */ + for (offset=0; gl && (offset<statbuf.st_size); offset+=size) { - guint offset = i * size; - Itdb_Thumb *img = g_list_nth_data (thumbs, i); - if (offset != img->offset) - { /* We found an open space -> copy the last element here */ - gl = g_list_last (thumbs); - img = gl->data; - thumbs = g_list_delete_link (thumbs, gl); - thumbs = g_list_insert (thumbs, img, i); + Itdb_Thumb *thumb = gl->data; + g_return_val_if_fail (thumb, FALSE); + + /* Try to find a thumbnail that uses this slot */ + while ((gl != NULL) && (thumb->offset < offset)) + { + gl = gl->prev; + if (gl) + thumb = gl->data; + g_return_val_if_fail (thumb, FALSE); + } + + if (!gl) + break; /* offset now indicates new length of file */ + + if (thumb->offset > offset) + { + /* did not find a thumbnail with matching offset -> copy + data from last slot (== first element) */ + GList *first_gl = g_list_first (thumbs); + Itdb_Thumb *first_thumb = first_gl->data; + guint32 first_offset; + + g_return_val_if_fail (first_thumb, FALSE); + first_offset = first_thumb->offset; /* actually copy the data */ - if (lseek (fd, img->offset, SEEK_SET) != img->offset) + if (lseek (fd, first_offset, SEEK_SET) != first_offset) { *result = FALSE; goto out; @@ -393,19 +420,52 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key, goto out; } - img->offset = offset; + /* Adjust offset of all thumbnails whose offset is + first_offset. Since the list is sorted, they are all at + the beginning of the list. */ + while (first_thumb->offset == first_offset) + { + first_thumb->offset = offset; + /* There's a possibility that gl is the first + element. In that case don't attempt to move it (it + wouldn't work as intended because we access + gl->next after removing it from the list) */ + if (gl != first_gl) + { + thumbs = g_list_delete_link (thumbs, first_gl); + /* Insert /behind/ gl */ + thumbs = g_list_insert_before (thumbs, + gl->next, first_thumb); + first_gl = g_list_first (thumbs); + first_thumb = first_gl->data; + g_return_val_if_fail (first_thumb, FALSE); + } + } } } - /* truncate the file */ - if (ftruncate (fd, tn_num*size) == -1) - { - *result = FALSE; - goto out; + /* offset corresponds to the new length of the file */ + if (offset > 0) + { /* Truncate */ + if (ftruncate (fd, offset) == -1) + { + *result = FALSE; + goto out; + } + } + else + { /* Remove file altogether */ + close (fd); + fd = -1; + if (unlink (filename) == -1) + { + *result = FALSE; + goto out; + } } out: if (fd != -1) close (fd); - if (buf) g_free (buf); + g_free (buf); g_list_free (thumbs); return TRUE; } @@ -435,6 +495,9 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, GList *gl; GHashTable *filenamehash; gboolean result = TRUE; + GList *thumbs; + gint i; + gchar *filename; g_return_val_if_fail (itdb, FALSE); g_return_val_if_fail (info, FALSE); @@ -457,9 +520,8 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, info->type); if (thumb && thumb->filename && (thumb->size != 0)) { - GList *thumbs; - gchar *filename = itdb_thumb_get_filename (itdb->device, - thumb); + filename = itdb_thumb_get_filename (itdb->device, + thumb); if (filename) { thumbs = g_hash_table_lookup (filenamehash, filename); @@ -469,6 +531,25 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, } } + /* Check for files present on the iPod but no longer referenced by + thumbs */ + + for (i=0; i<10; ++i) + { + filename = ipod_image_get_ithmb_filename (itdb->mountpoint, + info->correlation_id, + i); + if (g_file_test (filename, G_FILE_TEST_EXISTS)) + { + if (g_hash_table_lookup (filenamehash, filename) == NULL) + { + g_hash_table_insert (filenamehash, + g_strdup (filename), NULL); + } + } + g_free (filename); + } + g_hash_table_foreach_remove (filenamehash, ithumb_rearrange_thumbnail_file, &result); g_hash_table_destroy (filenamehash); |