diff options
author | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2006-11-12 10:13:58 +0000 |
---|---|---|
committer | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2006-11-12 10:13:58 +0000 |
commit | fed103e2a5d89739f0dffd2489ae38cc772bb0d8 (patch) | |
tree | 3346a6aaf2b52823d743afc586be0553e6fac4fb /src/ithumb-writer.c | |
parent | 2cb1582ee12c459686deaef20647a2d5fa08f403 (diff) | |
download | libgpod-tmz-fed103e2a5d89739f0dffd2489ae38cc772bb0d8.tar.gz libgpod-tmz-fed103e2a5d89739f0dffd2489ae38cc772bb0d8.tar.xz libgpod-tmz-fed103e2a5d89739f0dffd2489ae38cc772bb0d8.zip |
* ithumb-writer.c (itdb_write_ithumb_files):
ITDB_THUMB_PHOTO_TV_SCREEN type thumbnails were not "rearranged"
(i.e. deleted photos were not removed).
(ipod_image_get_ithmb_filename, ithmb_writer_write_thumbnail):
changed "F%u04_%d.ithmb" to "F%d_%d.ithmb" as this format string
is used by the iPod.
NEW: start new thumbnail file F%d_2/3/4... if the size of the
current thumbnail file is larger than ITHUMB_MAX_SIZE (currently
500 MB). Existing thumbnail files with a length larger than this
will NOT be truncated. Patches are welcome (probably add code at
the end of ithumb_rearrange_thumbnail_file()) :-)
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1336 f01d2545-417e-4e96-918e-98f8d0dbbcb6
Diffstat (limited to 'src/ithumb-writer.c')
-rw-r--r-- | src/ithumb-writer.c | 178 |
1 files changed, 115 insertions, 63 deletions
diff --git a/src/ithumb-writer.c b/src/ithumb-writer.c index 1de075a..3b6a6ec 100644 --- a/src/ithumb-writer.c +++ b/src/ithumb-writer.c @@ -1,6 +1,9 @@ -/* +/* Time-stamp: <2006-11-12 19:07:29 jcs> + * * Copyright (C) 2005 Christophe Fergeau * + * URL: http://www.gtkpod.org/libgpod.html + * URL: http://gtkpod.sourceforge.net/ * * 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 @@ -20,6 +23,7 @@ * * This product is not supported/written/published by Apple! * + * $Id$ */ #include <config.h> @@ -42,11 +46,17 @@ #include <fcntl.h> +#define ITHUMB_MAX_SIZE (500L*1000L*1000L) +/* for testing: */ +/*#define ITHUMB_MAX_SIZE (1L*1000L*1000L)*/ + struct _iThumbWriter { off_t cur_offset; FILE *f; + gchar *mountpoint; gchar *filename; - Itdb_ArtworkFormat *img_info; + gint current_file_index; + const Itdb_ArtworkFormat *img_info; DbType db_type; guint byte_order; }; @@ -172,7 +182,7 @@ ipod_image_get_ithmb_filename (const char *mount_point, gint correlation_id, gin } } - buf = g_strdup_printf ("F%04u_%d.ithmb", correlation_id, index); + buf = g_strdup_printf ("F%d_%d.ithmb", correlation_id, index); filename = itdb_get_path (artwork_dir, buf); @@ -196,7 +206,7 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer, { GdkPixbuf *pixbuf = NULL; guint16 *pixels; - gint width, height; + gint width, height; /* must be gint -- see comment below */ g_return_val_if_fail (writer, FALSE); g_return_val_if_fail (thumb, FALSE); @@ -208,6 +218,8 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer, writer->img_info->height, NULL); + g_free (thumb->filename); + thumb->filename = NULL; } else if (thumb->image_data) { /* image data is stored in image_data and image_data_len */ @@ -243,23 +255,22 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer, "height", &height, NULL); - g_free (thumb->filename); - thumb->filename = NULL; - - /* FIXME: under certain conditions (probably related to - * writer->offset getting too big), this should be :F%04u_2.ithmb - * and so on - */ - if( thumb->type == ITDB_THUMB_PHOTO_LARGE || - thumb->type == ITDB_THUMB_PHOTO_SMALL || - thumb->type == ITDB_THUMB_PHOTO_FULL_SCREEN ) + switch (thumb->type) { - thumb->filename = g_strdup_printf (":Thumbs:F%04u_1.ithmb", - writer->img_info->correlation_id); - - } else { - thumb->filename = g_strdup_printf (":F%04u_1.ithmb", - writer->img_info->correlation_id); + case ITDB_THUMB_PHOTO_LARGE: + case ITDB_THUMB_PHOTO_SMALL: + case ITDB_THUMB_PHOTO_FULL_SCREEN: + case ITDB_THUMB_PHOTO_TV_SCREEN: + thumb->filename = g_strdup_printf (":Thumbs:F%d_%d.ithmb", + writer->img_info->correlation_id, + writer->current_file_index); + break; + case ITDB_THUMB_COVER_LARGE: + case ITDB_THUMB_COVER_SMALL: + thumb->filename = g_strdup_printf (":F%d_%d.ithmb", + writer->img_info->correlation_id, + writer->current_file_index); + break; } switch (writer->db_type) @@ -307,6 +318,47 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer, return TRUE; } +static gboolean +ithumb_writer_update (iThumbWriter *writer) +{ + while ((writer->f == NULL) || (writer->cur_offset >= ITHUMB_MAX_SIZE)) + { + if (writer->f) + { + fclose (writer->f); + writer->f = NULL; + } + g_free (writer->filename); + writer->filename = NULL; + + /* increment index for filename */ + ++writer->current_file_index; + + writer->filename = + ipod_image_get_ithmb_filename (writer->mountpoint, + writer->img_info->correlation_id, + writer->current_file_index, + writer->db_type); + if (writer->filename == NULL) + { + return FALSE; + } + writer->f = fopen (writer->filename, "ab"); + if (writer->f == NULL) + { + g_print ("Error opening %s: %s\n", writer->filename, strerror (errno)); + g_free (writer->filename); + writer->filename = NULL; + return FALSE; + } + writer->cur_offset = ftell (writer->f); + } + + return TRUE; +} + + + static void write_thumbnail (gpointer _writer, gpointer _artwork) { @@ -321,64 +373,57 @@ write_thumbnail (gpointer _writer, gpointer _artwork) thumbnail file */ if (thumb && (thumb->size == 0)) { - ithumb_writer_write_thumbnail (writer, thumb); + /* check if new thumbnail file has to be started */ + if (ithumb_writer_update (writer)) + ithumb_writer_write_thumbnail (writer, thumb); } } + +static void +ithumb_writer_free (iThumbWriter *writer) +{ + g_return_if_fail (writer != NULL); + if (writer->f) + { + fclose (writer->f); + if (writer->filename && (writer->cur_offset == 0)) + { /* Remove empty file */ + unlink (writer->filename); + } + } + g_free (writer->filename); + g_free (writer->mountpoint); + g_free (writer); +} + + static iThumbWriter * ithumb_writer_new (const char *mount_point, const Itdb_ArtworkFormat *info, DbType db_type, guint byte_order) { - char *filename; iThumbWriter *writer; writer = g_new0 (iThumbWriter, 1); - writer->img_info = g_memdup (info, sizeof (Itdb_ArtworkFormat)); + writer->img_info = info; writer->byte_order = byte_order; writer->db_type = db_type; + writer->mountpoint = g_strdup (mount_point); + writer->current_file_index = 0; - filename = ipod_image_get_ithmb_filename (mount_point, - info->correlation_id, - 1, - db_type); - if (filename == NULL) { - g_free (writer->img_info); - g_free (writer); - return NULL; - } - writer->f = fopen (filename, "ab"); - if (writer->f == NULL) { - g_print ("Error opening %s: %s\n", filename, strerror (errno)); - g_free (filename); - g_free (writer->img_info); - g_free (writer); - return NULL; + if (!ithumb_writer_update (writer)) + { + ithumb_writer_free (writer); + return NULL; } - writer->cur_offset = ftell (writer->f); - writer->filename=filename; - - return writer; -} -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_free (writer->img_info); - g_free (writer->filename); - g_free (writer); + return writer; } - gint offset_sort (gconstpointer a, gconstpointer b); gint offset_sort (gconstpointer a, gconstpointer b) { @@ -609,7 +654,7 @@ ithmb_rearrange_existing_thumbnails (Itdb_DB *db, g_free, NULL); /* Create a hash with all filenames used for thumbnails. - This will usually be a number of "F%04d_%d.ithmb" files. A + This will usually be a number of "F%d_%d.ithmb" files. A GList is kept with pointers to all images in a given file which allows to adjust the offset pointers */ switch (db->db_type) { @@ -665,7 +710,7 @@ ithmb_rearrange_existing_thumbnails (Itdb_DB *db, /* Check for files present on the iPod but no longer referenced by thumbs */ - for (i=0; i<10; ++i) + for (i=0; i<50; ++i) { filename = ipod_image_get_ithmb_filename (mountpoint, info->correlation_id, @@ -682,6 +727,15 @@ ithmb_rearrange_existing_thumbnails (Itdb_DB *db, g_free (filename); } + /* I'm using the _foreach_remove variant here because the + thumbnail GList may get changed while calling + ithumb_rearrange_thumbnail_file but cannot be written back into + the hash table. Using the _foreach_remove variant here will + ensure that it will not be possible to access the invalid + thumbnail GList. The only proper operation after the + _foreach_remove is a call to g_hash_table_destroy(). + For the same reasons the thumb GList gets free'd in + ithumb_rearrange_thumbnail_file() */ g_hash_table_foreach_remove (filenamehash, ithumb_rearrange_thumbnail_file, &result); g_hash_table_destroy (filenamehash); @@ -725,8 +779,8 @@ itdb_write_ithumb_files (Itdb_DB *db) case ITDB_THUMB_PHOTO_SMALL: case ITDB_THUMB_PHOTO_LARGE: case ITDB_THUMB_PHOTO_FULL_SCREEN: - ithmb_rearrange_existing_thumbnails (db, - format ); + case ITDB_THUMB_PHOTO_TV_SCREEN: + ithmb_rearrange_existing_thumbnails (db, format ); writer = ithumb_writer_new (mount_point, format, db->db_type, @@ -735,8 +789,6 @@ itdb_write_ithumb_files (Itdb_DB *db) writers = g_list_prepend (writers, writer); } break; - default: - break; } format++; } |