summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--src/db-artwork-writer.c176
-rw-r--r--src/itdb_track.c21
3 files changed, 139 insertions, 74 deletions
diff --git a/ChangeLog b/ChangeLog
index 971ebb3..1751b8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2007-10-05 Christophe Fergeau <teuf@gnome.org
+
+ * src/db-artwork-writer.c: (itdb_track_filter_thumbnails),
+ (itdb_filter_thumbnails), (ipod_write_artwork_db):
+ * src/itdb_track.c: (itdb_track_set_thumbnails_internal):
+ Set thumbnails for all known cover types in itdb_track_set_thumbnails
+
+ itdb_track_set_thumbnails can be called when the track isn't attached
+ to any device (eg it's natural to create a track, fill its metadata
+ including the cover art, and then add it to an iTunesDB and its
+ associated device). This means we can't know which artwork types the
+ iPod corresponding to the iTunesDB will be able to handle. i
+ Consequently, we create Itdb_Thumb objects for all known cover types,
+ and we filter that list when we don't have a choice (ie when we're
+ about to write the ArtworkDB and the thumbnails)
+
2007-10-05 Christophe Fergeau <teuf@gnome.org>
* src/itdb_itunesdb.c: (itdb_write_file): set Itdb_Track::id
diff --git a/src/db-artwork-writer.c b/src/db-artwork-writer.c
index e11d87d..240617b 100644
--- a/src/db-artwork-writer.c
+++ b/src/db-artwork-writer.c
@@ -1,23 +1,23 @@
/*
* Copyright (C) 2005-2007 Christophe Fergeau
*
- *
+ *
* The code contained in this file is free software; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
- *
+ *
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* iTunes and iPod are trademarks of Apple
- *
+ *
* This product is not supported/written/published by Apple!
*
*/
@@ -85,7 +85,7 @@ ipod_buffer_destroy (iPodBuffer *buffer)
static void *
-ipod_buffer_get_pointer (iPodBuffer *buffer)
+ipod_buffer_get_pointer (iPodBuffer *buffer)
{
return &((unsigned char *)buffer->mmap->mmap_area)[buffer->offset];
}
@@ -97,14 +97,14 @@ ipod_buffer_grow_file (struct iPodMmapBuffer *mmap_buf, off_t new_size)
result = lseek (mmap_buf->fd, new_size, SEEK_SET);
if (result == (off_t)-1) {
- g_print ("Failed to grow file to %lu: %s\n",
+ g_print ("Failed to grow file to %lu: %s\n",
(unsigned long)new_size, strerror (errno));
return -1;
}
result = 0;
result = write (mmap_buf->fd, &result, 1);
if (result != 1) {
- g_print ("Failed to write a byte at %lu: %s\n",
+ g_print ("Failed to write a byte at %lu: %s\n",
(unsigned long)new_size, strerror (errno));
return -1;
}
@@ -113,18 +113,18 @@ ipod_buffer_grow_file (struct iPodMmapBuffer *mmap_buf, off_t new_size)
}
-static void *
+static void *
ipod_buffer_grow_mapping (iPodBuffer *buffer, size_t size)
{
void *new_address;
#ifdef HAVE_MREMAP
-
+
new_address = mremap (buffer->mmap->mmap_area, buffer->mmap->size,
buffer->mmap->size + size, 0);
#else
munmap (buffer->mmap->mmap_area, buffer->mmap->size);
new_address = mmap (buffer->mmap->mmap_area, buffer->mmap->size + size,
- PROT_READ | PROT_WRITE, MAP_SHARED,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
buffer->mmap->fd, 0);
#endif
/* Don't allow libc to move the current mapping since this would
@@ -153,7 +153,7 @@ ipod_buffer_maybe_grow (iPodBuffer *buffer, off_t offset)
return -1;
}
- if (ipod_buffer_grow_file (buffer->mmap,
+ if (ipod_buffer_grow_file (buffer->mmap,
buffer->mmap->size + IPOD_MMAP_SIZE) != 0) {
return -1;
}
@@ -192,18 +192,18 @@ ipod_buffer_new (const char *filename, guint byte_order, DbType db_type)
iPodBuffer *buffer;
void *mmap_area;
- fd = open (filename, O_RDWR | O_CREAT | O_TRUNC,
+ fd = open (filename, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1) {
- g_print ("Failed to open %s: %s\n",
+ g_print ("Failed to open %s: %s\n",
filename, strerror (errno));
return NULL;
}
-
+
mmap_area = mmap (0, IPOD_MMAP_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (mmap_area == MAP_FAILED) {
- g_print ("Failed to mmap %s in memory: %s\n", filename,
+ g_print ("Failed to mmap %s in memory: %s\n", filename,
strerror (errno));
close (fd);
return NULL;
@@ -254,7 +254,7 @@ enum iPodThumbnailType {
-/* Returns the "real" size for a header, ie the size iTunes uses for it
+/* Returns the "real" size for a header, ie the size iTunes uses for it
* (padding included)
*/
static int
@@ -303,7 +303,7 @@ init_header (iPodBuffer *buffer, gchar _header_id[4], guint header_len)
}
-static int
+static int
write_mhod_type_1 (gchar *string, iPodBuffer *buffer)
{
MhodHeaderArtworkType1 *mhod;
@@ -313,14 +313,14 @@ write_mhod_type_1 (gchar *string, iPodBuffer *buffer)
g_assert (string != NULL);
- mhod = (MhodHeaderArtworkType1 *)init_header (buffer, "mhod",
+ mhod = (MhodHeaderArtworkType1 *)init_header (buffer, "mhod",
sizeof (MhodHeaderArtworkType1));
if (mhod == NULL) {
return -1;
}
total_bytes = sizeof (MhodHeaderArtworkType1);
mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
- /* Modify header length, since iTunes only puts the length of
+ /* Modify header length, since iTunes only puts the length of
* MhodHeader in header_len
*/
mhod->header_len = get_gint32 (sizeof (ArtworkDB_MhodHeader), buffer->byte_order);
@@ -340,14 +340,14 @@ write_mhod_type_1 (gchar *string, iPodBuffer *buffer)
}
memcpy (mhod->string, string, len);
total_bytes += len + padding;
- mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
+ mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
dump_mhod_type_1 (mhod);
return total_bytes;
}
-static int
+static int
write_mhod_type_3 (gchar *string, iPodBuffer *buffer)
{
ArtworkDB_MhodHeaderArtworkType3 *mhod;
@@ -360,17 +360,17 @@ write_mhod_type_3 (gchar *string, iPodBuffer *buffer)
g_assert (string != NULL);
mhod = (ArtworkDB_MhodHeaderArtworkType3 *)
- init_header (buffer, "mhod",
+ init_header (buffer, "mhod",
sizeof (ArtworkDB_MhodHeaderArtworkType3));
if (mhod == NULL) {
return -1;
}
total_bytes = sizeof (ArtworkDB_MhodHeaderArtworkType3);
mhod->total_len = get_gint32 (total_bytes, buffer->byte_order);
- /* Modify header length, since iTunes only puts the length of
+ /* Modify header length, since iTunes only puts the length of
* MhodHeader in header_len
*/
- mhod->header_len = get_gint32 (sizeof (ArtworkDB_MhodHeader),
+ mhod->header_len = get_gint32 (sizeof (ArtworkDB_MhodHeader),
buffer->byte_order);
mhod->type = get_gint16 (3, buffer->byte_order);
@@ -431,7 +431,7 @@ write_mhod_type_3 (gchar *string, iPodBuffer *buffer)
return total_bytes;
}
-static int
+static int
write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer)
{
MhniHeader *mhni;
@@ -443,7 +443,7 @@ write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buff
return -1;
}
- mhni = (MhniHeader *)init_header (buffer, "mhni",
+ mhni = (MhniHeader *)init_header (buffer, "mhni",
sizeof (MhniHeader));
if (mhni == NULL) {
return -1;
@@ -465,7 +465,7 @@ write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buff
mhni->vertical_padding =
get_gint16 (thumb->vertical_padding, buffer->byte_order);
- mhni->horizontal_padding =
+ mhni->horizontal_padding =
get_gint16 (thumb->horizontal_padding, buffer->byte_order);
sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
@@ -480,10 +480,10 @@ write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buff
total_bytes += bytes_written;
mhni->total_len = get_gint32 (total_bytes, buffer->byte_order);
/* Only update number of children when all went well to try to get
- * something somewhat consistent when there are errors
+ * something somewhat consistent when there are errors
*/
mhni->num_children = get_gint32 (1, buffer->byte_order);
-
+
dump_mhni (mhni);
return total_bytes;
@@ -502,7 +502,7 @@ write_mhod (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buff
}
mhod = (ArtworkDB_MhodHeader *)
- init_header (buffer, "mhod",
+ init_header (buffer, "mhod",
sizeof (ArtworkDB_MhodHeader));
if (mhod == NULL) {
return -1;
@@ -578,7 +578,7 @@ write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer)
Itdb_Thumb *thumb;
const Itdb_ArtworkFormat *img_info;
- mhii->num_children = get_gint32 (num_children,
+ mhii->num_children = get_gint32 (num_children,
buffer->byte_order);
mhii->total_len = get_gint32 (total_bytes, buffer->byte_order);
sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
@@ -591,7 +591,7 @@ write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer)
if (img_info == NULL) {
return -1;
}
- bytes_written = write_mhod (db, thumb, img_info->correlation_id,
+ bytes_written = write_mhod (db, thumb, img_info->correlation_id,
sub_buffer);
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
@@ -656,7 +656,7 @@ write_mhli (Itdb_DB *db, iPodBuffer *buffer )
if (bytes_written != -1) {
num_thumbs++;
total_bytes += bytes_written;
- }
+ }
it = it->next;
}
mhli->num_children = get_gint32 (num_thumbs, buffer->byte_order);
@@ -731,7 +731,7 @@ write_mhba (Itdb_PhotoAlbum *album, iPodBuffer *buffer)
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
- }
+ }
total_bytes += bytes_written;
for (it = album->members; it != NULL; it = it->next) {
@@ -746,7 +746,7 @@ write_mhba (Itdb_PhotoAlbum *album, iPodBuffer *buffer)
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
- }
+ }
total_bytes += bytes_written;
}
mhba->total_len = get_gint32( total_bytes, buffer->byte_order );
@@ -781,7 +781,7 @@ write_mhla (Itdb_DB *db, iPodBuffer *buffer)
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
- }
+ }
total_bytes += bytes_written;
mhla->num_children++;
}
@@ -797,24 +797,24 @@ write_mhif (Itdb_DB *db, iPodBuffer *buffer, enum iPodThumbnailType type)
{
MhifHeader *mhif;
const Itdb_ArtworkFormat *img_info;
-
+
mhif = (MhifHeader *)init_header (buffer, "mhif", sizeof (MhifHeader));
if (mhif == NULL) {
return -1;
}
mhif->total_len = mhif->header_len;
-
+
img_info = itdb_get_artwork_info_from_type (db_get_device(db), type);
if (img_info == NULL) {
return -1;
}
- mhif->correlation_id = get_gint32 (img_info->correlation_id,
+ mhif->correlation_id = get_gint32 (img_info->correlation_id,
buffer->byte_order);
mhif->image_size = get_gint32 (img_info->height * img_info->width * 2,
buffer->byte_order);
dump_mhif (mhif);
-
+
return get_gint32 (mhif->header_len, buffer->byte_order);
}
@@ -853,11 +853,11 @@ write_mhlf (Itdb_DB *db, iPodBuffer *buffer)
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
- }
+ }
total_bytes += bytes_written;
-
+
/* Only update number of children when all went well to try to get
- * something somewhat consistent when there are errors
+ * something somewhat consistent when there are errors
*/
/* For the ArworkDB file, there are only 2 physical file storing
* thumbnails: F1016_1.ithmb for the bigger thumbnails (39200 bytes)
@@ -884,11 +884,11 @@ write_mhlf (Itdb_DB *db, iPodBuffer *buffer)
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
- }
+ }
total_bytes += bytes_written;
/* Only update number of children when all went well to try to get
- * something somewhat consistent when there are errors
+ * something somewhat consistent when there are errors
*/
/* For the ArworkDB file, there are only 2 physical file storing
* thumbnails: F1016_1.ithmb for the bigger thumbnails (39200 bytes)
@@ -902,7 +902,7 @@ write_mhlf (Itdb_DB *db, iPodBuffer *buffer)
}
-static int
+static int
write_mhsd (Itdb_DB *db, iPodBuffer *buffer, enum MhsdType type)
{
ArtworkDB_MhsdHeader *mhsd;
@@ -982,7 +982,7 @@ write_mhfd (Itdb_DB *db, iPodBuffer *buffer, int id_max)
}
bytes_written = write_mhsd (db, sub_buffer, i);
ipod_buffer_destroy (sub_buffer);
- if (bytes_written == -1) {
+ if (bytes_written == -1) {
return -1;
}
total_bytes += bytes_written;
@@ -1013,10 +1013,77 @@ ipod_artwork_db_set_ids (Itdb_iTunesDB *db)
song->artwork->id = song->id;
}
}
-
+
return max_id;
}
+
+static void
+itdb_track_filter_thumbnails (Itdb_iTunesDB *itdb, Itdb_Track *track)
+{
+ const Itdb_ArtworkFormat *formats;
+ const Itdb_ArtworkFormat *format;
+ GList *it;
+ GList *supported_thumbs;
+
+ if (track->artwork == NULL) {
+ return;
+ }
+
+ if (track->artwork->thumbnails == NULL) {
+ return;
+ }
+
+ if (itdb->device == NULL) {
+ itdb_artwork_free (track->artwork);
+ track->artwork = NULL;
+ return;
+ }
+
+ formats = itdb_device_get_artwork_formats (itdb->device);
+ if (formats == NULL) {
+ itdb_artwork_free (track->artwork);
+ track->artwork = NULL;
+ return;
+ }
+
+ supported_thumbs = NULL;
+ for (format = formats; format->type != -1; format++) {
+ for (it = track->artwork->thumbnails; it != NULL; it = it->next) {
+ Itdb_Thumb *thumb = (Itdb_Thumb *)it->data;
+
+ if (thumb->type == format->type) {
+ supported_thumbs = g_list_prepend (supported_thumbs, it->data);
+ /* Remove element from the original list, there will
+ * be less work next time we iterate over the thumbnails
+ */
+ track->artwork->thumbnails = g_list_remove_link (track->artwork->thumbnails, it);
+ break;
+ }
+ }
+ }
+
+ if (supported_thumbs == NULL) {
+ itdb_artwork_free (track->artwork);
+ track->artwork = NULL;
+ return;
+ }
+ g_list_free (track->artwork->thumbnails);
+ track->artwork->thumbnails = supported_thumbs;
+}
+
+static void
+itdb_filter_thumbnails (Itdb_iTunesDB *itdb)
+{
+ GList *it;
+
+ for (it = itdb->tracks; it != NULL; it = it->next) {
+ itdb_track_filter_thumbnails (itdb, (Itdb_Track *)it->data);
+ }
+}
+
+
+
int
ipod_write_artwork_db (Itdb_iTunesDB *itdb)
{
@@ -1030,6 +1097,9 @@ ipod_write_artwork_db (Itdb_iTunesDB *itdb)
db.db_type = DB_TYPE_ITUNES;
db.db.itdb = itdb;
+
+ itdb_filter_thumbnails (itdb);
+
/* First, let's write the .ithmb files, this will create the
* various thumbnails as well */
@@ -1069,9 +1139,9 @@ ipod_write_artwork_db (Itdb_iTunesDB *itdb)
result = truncate (filename, bytes_written);
if (result != 0) {
- g_print ("Failed to truncate %s: %s\n",
+ g_print ("Failed to truncate %s: %s\n",
filename, strerror (errno));
- g_free (filename);
+ g_free (filename);
return -1;
}
g_free (filename);
@@ -1123,9 +1193,9 @@ ipod_write_photo_db (Itdb_PhotoDB *photodb)
result = truncate (filename, bytes_written);
if (result != 0) {
- g_print ("Failed to truncate %s: %s\n",
+ g_print ("Failed to truncate %s: %s\n",
filename, strerror (errno));
- g_free (filename);
+ g_free (filename);
return -1;
}
g_free (filename);
diff --git a/src/itdb_track.c b/src/itdb_track.c
index e1216f5..976a714 100644
--- a/src/itdb_track.c
+++ b/src/itdb_track.c
@@ -435,27 +435,6 @@ static gboolean itdb_track_set_thumbnails_internal (Itdb_Track *track,
for (thumbtype=thumbtypes; *thumbtype!=-1; ++thumbtype)
{
- if (formats)
- { /* check if thumbnail type is supported */
- const Itdb_ArtworkFormat *imgp=formats;
- for (imgp=formats; imgp->type!=-1; ++imgp)
- {
- if (imgp->type == *thumbtype) break;
- }
- if (imgp->type == -1)
- {
- continue; /* for (thumbtype=...) */
- }
- }
- else
- { /* only add COVER_SMALL and COVER_LARGE */
- if ((*thumbtype != ITDB_THUMB_COVER_SMALL) &&
- (*thumbtype != ITDB_THUMB_COVER_LARGE))
- {
- continue; /* for (thumbtype=...) */
- }
- }
-
if (filename)
{
result = itdb_artwork_add_thumbnail (track->artwork,