summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorteuf <teuf@f01d2545-417e-4e96-918e-98f8d0dbbcb6>2008-05-30 12:00:21 +0000
committerteuf <teuf@f01d2545-417e-4e96-918e-98f8d0dbbcb6>2008-05-30 12:00:21 +0000
commit271b0c73506712135b34478420a6733aa8c41bdd (patch)
tree15322f7006e27473d2c0c69b2d891f26c66cde67
parentead2511a0fa019dc3bbfdd04da80f89da1fb0949 (diff)
downloadlibgpod-271b0c73506712135b34478420a6733aa8c41bdd.tar.gz
libgpod-271b0c73506712135b34478420a6733aa8c41bdd.tar.xz
libgpod-271b0c73506712135b34478420a6733aa8c41bdd.zip
* src/Makefile.am:
* src/db-artwork-parser.c: * src/db-artwork-writer.c: * src/db-image-parser.c: * src/db-image-parser.h: * src/itdb.h: * src/itdb_artwork.c: * src/itdb_device.h: * src/itdb_photoalbum.c: * src/itdb_track.c: * src/ithumb-writer.c: * tests/test-covers.c: * tests/test-photos.c: rework Itdb_Thumb type. Now it's split into different subtypes depending on what it represents (GdkPixbuf, thumbnail read from the ipod, ...). Itdb_Artwork now contains only a pointer to a single Itdb_Thumb (it used to contain a GList * of Itdb_Thumb) since the only time when the list is useful is for thumbs read from the ipod. Using a list for the other types of thumbnails created some complications when trying to set art on an Itdb_Track that wasn't attached to an Itdb_iTunesDB. git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1991 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r--ChangeLog23
-rw-r--r--src/Makefile.am2
-rw-r--r--src/db-artwork-parser.c21
-rw-r--r--src/db-artwork-writer.c124
-rw-r--r--src/db-image-parser.c72
-rw-r--r--src/db-image-parser.h11
-rw-r--r--src/itdb.h75
-rw-r--r--src/itdb_artwork.c531
-rw-r--r--src/itdb_device.h1
-rw-r--r--src/itdb_photoalbum.c48
-rw-r--r--src/itdb_track.c121
-rw-r--r--src/ithumb-writer.c298
-rw-r--r--tests/test-covers.c70
-rw-r--r--tests/test-photos.c33
14 files changed, 524 insertions, 906 deletions
diff --git a/ChangeLog b/ChangeLog
index 3b1dcaf..bab20b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2008-05-30 Christophe Fergeau <teuf@gnome.org>
+
+ * src/Makefile.am:
+ * src/db-artwork-parser.c:
+ * src/db-artwork-writer.c:
+ * src/db-image-parser.c:
+ * src/db-image-parser.h:
+ * src/itdb.h:
+ * src/itdb_artwork.c:
+ * src/itdb_device.h:
+ * src/itdb_photoalbum.c:
+ * src/itdb_track.c:
+ * src/ithumb-writer.c:
+ * tests/test-covers.c:
+ * tests/test-photos.c: rework Itdb_Thumb type. Now it's split into
+ different subtypes depending on what it represents (GdkPixbuf,
+ thumbnail read from the ipod, ...). Itdb_Artwork now contains only a
+ pointer to a single Itdb_Thumb (it used to contain a GList * of
+ Itdb_Thumb) since the only time when the list is useful is for thumbs
+ read from the ipod. Using a list for the other types of thumbnails
+ created some complications when trying to set art on an Itdb_Track that
+ wasn't attached to an Itdb_iTunesDB.
+
2008-05-29 Christophe Fergeau <teuf at gnome.org>
* src/itunesdb.c:
diff --git a/src/Makefile.am b/src/Makefile.am
index 89851f9..49260f5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ libgpod_la_SOURCES = \
itdb_plist.c \
itdb_sha1.c \
itdb_sysinfo_extended_parser.c \
+ itdb_thumb.c \
itdb_track.c \
ithumb-writer.c \
pixmaps.c \
@@ -37,6 +38,7 @@ noinst_HEADERS = \
itdb_private.h \
itdb_sha1.h \
itdb_sysinfo_extended_parser.h \
+ itdb_thumb.h \
pixmaps.h \
sha1.h
diff --git a/src/db-artwork-parser.c b/src/db-artwork-parser.c
index 07b21a9..e993eee 100644
--- a/src/db-artwork-parser.c
+++ b/src/db-artwork-parser.c
@@ -163,7 +163,7 @@ parse_mhod_string (DBParseContext *ctx, GError *error)
static int
parse_mhod_3 (DBParseContext *ctx,
- Itdb_Thumb *thumb, GError *error)
+ Itdb_Thumb_Ipod_Item *thumb, GError *error)
{
struct ParsedMhodString *mhod;
mhod = parse_mhod_string (ctx, error);
@@ -182,11 +182,11 @@ parse_mhod_3 (DBParseContext *ctx,
}
static int
-parse_photo_mhni (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error)
+parse_photo_mhni (DBParseContext *ctx, Itdb_Thumb_Ipod *thumbs, GError *error)
{
MhniHeader *mhni;
DBParseContext *mhod_ctx;
- Itdb_Thumb *thumb;
+ Itdb_Thumb_Ipod_Item *thumb;
mhni = db_parse_context_get_m_header (ctx, MhniHeader, "mhni");
if (mhni == NULL) {
@@ -199,8 +199,8 @@ parse_photo_mhni (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error)
if (thumb == NULL) {
return 0;
}
-
- artwork->thumbnails = g_list_append (artwork->thumbnails, thumb);
+
+ itdb_thumb_ipod_add (thumbs, thumb);
mhod_ctx = db_parse_context_get_sub_context (ctx, ctx->header_len);
if (mhod_ctx == NULL) {
@@ -213,7 +213,7 @@ parse_photo_mhni (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error)
}
static int
-parse_photo_mhod (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error)
+parse_photo_mhod (DBParseContext *ctx, Itdb_Thumb_Ipod *thumbs, GError *error)
{
ArtworkDB_MhodHeader *mhod;
DBParseContext *mhni_ctx;
@@ -235,7 +235,7 @@ parse_photo_mhod (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error)
if (mhni_ctx == NULL) {
return -1;
}
- parse_photo_mhni (mhni_ctx, artwork, NULL);
+ parse_photo_mhni (mhni_ctx, thumbs, NULL);
g_free (mhni_ctx);
}
@@ -253,7 +253,8 @@ parse_mhii (DBParseContext *ctx, GError *error)
Itdb_PhotoDB *photodb;
guint64 mactime;
Itdb_Device *device = db_get_device (ctx->db);
-
+ Itdb_Thumb_Ipod *thumbs;
+
mhii = db_parse_context_get_m_header (ctx, MhiiHeader, "mhii");
if (mhii == NULL)
{
@@ -275,12 +276,14 @@ parse_mhii (DBParseContext *ctx, GError *error)
artwork->artwork_size = get_gint32 (mhii->orig_img_size, ctx->byte_order);
artwork->dbid = get_gint64 (mhii->song_id, ctx->byte_order);
+ thumbs = (Itdb_Thumb_Ipod *)itdb_thumb_ipod_new ();
+ artwork->thumbnail = (Itdb_Thumb *)thumbs;
cur_offset = ctx->header_len;
mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset);
num_children = get_gint32 (mhii->num_children, ctx->byte_order);
while ((num_children > 0) && (mhod_ctx != NULL))
{
- parse_photo_mhod (mhod_ctx, artwork, NULL);
+ parse_photo_mhod (mhod_ctx, thumbs, NULL);
num_children--;
cur_offset += mhod_ctx->total_len;
g_free (mhod_ctx);
diff --git a/src/db-artwork-writer.c b/src/db-artwork-writer.c
index b2a0ab4..a24b0fd 100644
--- a/src/db-artwork-writer.c
+++ b/src/db-artwork-writer.c
@@ -357,14 +357,15 @@ write_mhod_type_3 (gchar *string, iPodBuffer *buffer)
}
static int
-write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int format_id, iPodBuffer *buffer)
+write_mhni (Itdb_DB *db, Itdb_Thumb_Ipod_Item *item, iPodBuffer *buffer)
{
MhniHeader *mhni;
unsigned int total_bytes;
int bytes_written;
iPodBuffer *sub_buffer;
+ const Itdb_ArtworkFormat *format;
- if (thumb == NULL) {
+ if (item == NULL) {
return -1;
}
@@ -377,21 +378,22 @@ write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int format_id, iPodBuffer *buffer)
buffer->byte_order);
mhni->total_len = get_gint32 (total_bytes,
buffer->byte_order);
- mhni->format_id = get_gint32 (format_id, buffer->byte_order);
- mhni->image_width = get_gint16 (thumb->width, buffer->byte_order);
- mhni->image_height = get_gint16 (thumb->height, buffer->byte_order);
- mhni->image_size = get_gint32 (thumb->size, buffer->byte_order);
- mhni->ithmb_offset = get_gint32 (thumb->offset, buffer->byte_order);
- mhni->vertical_padding = get_gint16 (thumb->vertical_padding,
+ format = item->format;
+ mhni->format_id = get_gint32 (format->format_id, buffer->byte_order);
+ mhni->image_width = get_gint16 (item->width, buffer->byte_order);
+ mhni->image_height = get_gint16 (item->height, buffer->byte_order);
+ mhni->image_size = get_gint32 (item->size, buffer->byte_order);
+ mhni->ithmb_offset = get_gint32 (item->offset, buffer->byte_order);
+ mhni->vertical_padding = get_gint16 (item->vertical_padding,
buffer->byte_order);
- mhni->horizontal_padding = get_gint16 (thumb->horizontal_padding,
+ mhni->horizontal_padding = get_gint16 (item->horizontal_padding,
buffer->byte_order);
sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes);
if (sub_buffer == NULL) {
return -1;
}
- bytes_written = write_mhod_type_3 (thumb->filename, sub_buffer);
+ bytes_written = write_mhod_type_3 (item->filename, sub_buffer);
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
@@ -410,7 +412,7 @@ write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int format_id, iPodBuffer *buffer)
}
static int
-write_mhod (Itdb_DB *db, Itdb_Thumb *thumb, int format_id, iPodBuffer *buffer)
+write_mhod (Itdb_DB *db, Itdb_Thumb_Ipod_Item *thumb, iPodBuffer *buffer)
{
ArtworkDB_MhodHeader *mhod;
unsigned int total_bytes;
@@ -434,7 +436,7 @@ write_mhod (Itdb_DB *db, Itdb_Thumb *thumb, int format_id, iPodBuffer *buffer)
if (sub_buffer == NULL) {
return -1;
}
- bytes_written = write_mhni (db, thumb, format_id, sub_buffer);
+ bytes_written = write_mhni (db, thumb, sub_buffer);
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
@@ -455,7 +457,7 @@ write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer)
unsigned int total_bytes;
int bytes_written;
int num_children;
- GList *it = NULL;
+ const GList *it = NULL;
Itdb_Track *song;
Itdb_Artwork *artwork;
guint64 mactime;
@@ -493,16 +495,20 @@ write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer)
mhii->orig_img_size = get_gint32 (artwork->artwork_size, buffer->byte_order);
num_children = 0;
- for (it=artwork->thumbnails; it!=NULL; it=it->next)
+ /* Before trying to write the artwork or photo database, the ithmb
+ * files have been written, which will have converted all thumbnails
+ * attached to the tracks to ITDB_THUMB_TYPE_IPOD thumbnails.
+ */
+ g_assert (artwork->thumbnail->data_type == ITDB_THUMB_TYPE_IPOD);
+ for (it=itdb_thumb_ipod_get_thumbs ((Itdb_Thumb_Ipod *)artwork->thumbnail);
+ it!=NULL;
+ it=it->next)
{
iPodBuffer *sub_buffer;
- Itdb_Thumb *thumb;
- const Itdb_ArtworkFormat *img_info;
+ Itdb_Thumb_Ipod_Item *thumb;
- thumb = (Itdb_Thumb *)it->data;
- img_info = itdb_get_artwork_info_from_type (
- db_get_device(db), thumb->type);
- if (img_info == NULL) {
+ thumb = (Itdb_Thumb_Ipod_Item *)it->data;
+ if (thumb->format == NULL) {
/* skip this thumb */
continue;
}
@@ -514,8 +520,7 @@ write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer)
if (sub_buffer == NULL) {
return -1;
}
- bytes_written = write_mhod (db, thumb, img_info->format_id,
- sub_buffer);
+ bytes_written = write_mhod (db, thumb, sub_buffer);
ipod_buffer_destroy (sub_buffer);
if (bytes_written == -1) {
return -1;
@@ -564,7 +569,7 @@ write_mhli (Itdb_DB *db, iPodBuffer *buffer )
iPodBuffer *sub_buffer;
if (buffer->db_type == DB_TYPE_ITUNES) {
song = (Itdb_Track*)it->data;
- if (!song->artwork->thumbnails || (song->artwork->id == 0)) {
+ if (!song->artwork->thumbnail || (song->artwork->id == 0)) {
it = it->next;
continue;
}
@@ -743,9 +748,10 @@ write_mhif (Itdb_DB *db, iPodBuffer *buffer,
}
G_GNUC_INTERNAL gboolean
-itdb_thumb_type_is_valid_for_db (const ItdbThumbType thumb_type, DbType db_type)
+itdb_thumb_type_is_valid_for_db (const Itdb_ArtworkFormat *format,
+ DbType db_type)
{
- switch (thumb_type) {
+ switch (format->type) {
case ITDB_THUMB_COVER_SMALL:
case ITDB_THUMB_COVER_LARGE:
case ITDB_THUMB_COVER_XLARGE:
@@ -791,7 +797,7 @@ write_mhlf (Itdb_DB *db, iPodBuffer *buffer)
while (formats->type != -1) {
iPodBuffer *sub_buffer;
- if (!itdb_thumb_type_is_valid_for_db (formats->type, buffer->db_type)) {
+ if (!itdb_thumb_type_is_valid_for_db (formats, buffer->db_type)) {
formats++;
continue;
}
@@ -932,7 +938,7 @@ ipod_artwork_db_set_ids (Itdb_iTunesDB *db)
if (max_id <= song->id) {
max_id = song->id;
}
- if (song->artwork->thumbnails != NULL) {
+ if (song->artwork->thumbnail != NULL) {
song->artwork->id = song->id;
}
}
@@ -940,67 +946,6 @@ ipod_artwork_db_set_ids (Itdb_iTunesDB *db)
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_remove_thumbnails (track->artwork);
- 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;
- }
- }
- }
-
- 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)
{
@@ -1013,9 +958,6 @@ 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 */
diff --git a/src/db-image-parser.c b/src/db-image-parser.c
index dfc7d5d..8128e19 100644
--- a/src/db-image-parser.c
+++ b/src/db-image-parser.c
@@ -35,66 +35,51 @@
#include "db-image-parser.h"
#include <glib/gi18n-lib.h>
-static int
-image_type_from_format_id (Itdb_Device *device, gint16 format_id)
+static const Itdb_ArtworkFormat *
+image_format_from_id (Itdb_Device *device, gint16 format_id)
{
const Itdb_ArtworkFormat *formats;
if (device == NULL) {
- return -1;
+ return NULL;
}
formats = itdb_device_get_artwork_formats (device);
if (formats == NULL) {
- return -1;
+ return NULL;
}
while (formats->type != -1) {
if (formats->format_id == format_id) {
- return formats->type;
+ return formats;
}
formats++;
}
- return -1;
-}
-
-
-G_GNUC_INTERNAL const Itdb_ArtworkFormat *
-itdb_get_artwork_info_from_type (Itdb_Device *device,
- ItdbThumbType image_type)
-{
- const Itdb_ArtworkFormat *formats;
-
- if (device == NULL) {
- return NULL;
- }
-
- formats = itdb_device_get_artwork_formats (device);
- if (formats == NULL) {
- return NULL;
- }
-
- while ((formats->type != -1) && (formats->type != image_type)) {
- formats++;
- }
-
- if (formats->type == -1) {
- return NULL;
- }
-
- return formats;
+ return NULL;
}
-G_GNUC_INTERNAL Itdb_Thumb *
+G_GNUC_INTERNAL Itdb_Thumb_Ipod_Item *
ipod_image_new_from_mhni (MhniHeader *mhni, Itdb_DB *db)
{
- Itdb_Thumb *img;
+ Itdb_Thumb_Ipod_Item *img;
+ const Itdb_ArtworkFormat *format;
gint16 format_id;
Itdb_Device *device = NULL;
- img = g_new0 (Itdb_Thumb, 1);
+ device = db_get_device (db);
+ g_return_val_if_fail (device, NULL);
+
+ format_id = get_gint32_db (db, mhni->format_id);
+ format = image_format_from_id (device, format_id);
+ if (format == NULL) {
+ g_warning (_("Unexpected image type in mhni: %d, offset: %d\n"),
+ format_id, get_guint32_db (db, mhni->ithmb_offset));
+ return NULL;
+ }
+
+ img = itdb_thumb_new_item_from_ipod (format);
if (img == NULL) {
return NULL;
}
@@ -107,25 +92,10 @@ ipod_image_new_from_mhni (MhniHeader *mhni, Itdb_DB *db)
img->vertical_padding =
get_gint16_db (db, mhni->vertical_padding);
- device = db_get_device (db);
- g_return_val_if_fail (device, NULL);
-
- format_id = get_gint32_db (db, mhni->format_id);
- img->type = image_type_from_format_id (device, format_id);
-
#if DEBUG_ARTWORK
printf ("format_id: %d, of: %6d sz: %6d, x: %3d, y: %3d, xpad: %3d, ypad: %3d\n",
format_id, img->offset, img->size, img->width, img->height, img->horizontal_padding, img->vertical_padding);
#endif
- if (img->type == -1)
- {
- g_warning (_("Unexpected image type in mhni: size: %ux%u (%d), offset: %d\n"),
- img->width, img->height,
- format_id, img->offset);
- g_free (img);
- return NULL;
- }
-
return img;
}
diff --git a/src/db-image-parser.h b/src/db-image-parser.h
index a9a3862..c8fbbe4 100644
--- a/src/db-image-parser.h
+++ b/src/db-image-parser.h
@@ -29,6 +29,7 @@
#include "db-itunes-parser.h"
#include "itdb_device.h"
#include "itdb_private.h"
+#include "itdb_thumb.h"
#include "itdb.h"
#define DEBUG_ARTWORK 0
@@ -77,16 +78,12 @@
#define BLUE_SHIFT_888 0
#define BLUE_MASK_888 (((1 << BLUE_BITS_888)-1) << BLUE_SHIFT_888)
-G_GNUC_INTERNAL Itdb_Thumb *ipod_image_new_from_mhni (MhniHeader *mhni,
- Itdb_DB *db);
+G_GNUC_INTERNAL Itdb_Thumb_Ipod_Item *ipod_image_new_from_mhni (MhniHeader *mhni,
+ Itdb_DB *db);
G_GNUC_INTERNAL int itdb_write_ithumb_files (Itdb_DB *db);
G_GNUC_INTERNAL gboolean
-itdb_thumb_type_is_valid_for_db (const ItdbThumbType thumb_type, DbType db_type);
-
-G_GNUC_INTERNAL
-const Itdb_ArtworkFormat *itdb_get_artwork_info_from_type (
- Itdb_Device *ipod, ItdbThumbType image_type);
+itdb_thumb_type_is_valid_for_db (const Itdb_ArtworkFormat *format, DbType db_type);
#endif
diff --git a/src/itdb.h b/src/itdb.h
index 90dd5d4..3ef593d 100644
--- a/src/itdb.h
+++ b/src/itdb.h
@@ -57,6 +57,7 @@ typedef gpointer (* ItdbUserDataDuplicateFunc) (gpointer userdata);
typedef struct _Itdb_Device Itdb_Device;
typedef struct _Itdb_IpodInfo Itdb_IpodInfo;
typedef struct _Itdb_Artwork Itdb_Artwork;
+typedef struct _Itdb_ArtworkFormat Itdb_ArtworkFormat;
typedef struct _Itdb_Thumb Itdb_Thumb;
typedef struct _Itdb_SPLPref Itdb_SPLPref;
typedef struct _Itdb_SPLRule Itdb_SPLRule;
@@ -494,51 +495,19 @@ typedef enum {
ITDB_THUMB_CHAPTER_LARGE, /* classic -- not supported yet */
} ItdbThumbType;
-
-/* The Itdb_Thumb structure can represent two slightly different
- thumbnails:
-
- a) a thumbnail before it's transferred to the iPod.
-
- offset and size are 0
-
- width and height, if unequal 0, will indicate the size on the
- iPod. width and height are set the first time a pixbuf is
- requested for this thumbnail.
-
- type is set according to the type this thumbnail represents
-
- filename point to a 'real' image file OR image_data and
- image_data_len are set.
-
- b) a thumbnail (big or small) stored on a database in the iPod. In
- these cases, id corresponds to the ID originally used in the
- database, filename points to a .ithmb file on the iPod
- */
-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 */
- gpointer pixbuf;
- 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;
- /* reserved for future use */
- gint32 reserved_int1;
- gint32 reserved_int2;
- gpointer reserved1;
- gpointer reserved2;
+enum _ItdbThumbDataType {
+ ITDB_THUMB_TYPE_INVALID,
+ ITDB_THUMB_TYPE_FILE,
+ ITDB_THUMB_TYPE_MEMORY,
+ ITDB_THUMB_TYPE_PIXBUF,
+ ITDB_THUMB_TYPE_IPOD
};
+typedef enum _ItdbThumbDataType ItdbThumbDataType;
+
+
struct _Itdb_Artwork {
- GList *thumbnails; /* list of Itdb_Thumbs */
+ Itdb_Thumb *thumbnail;
guint32 id; /* Artwork id used by photoalbums, starts at
* 0x40... libgpod will set this on sync. */
guint64 dbid; /* dbid of associated track. used
@@ -1190,8 +1159,9 @@ gboolean itdb_track_set_thumbnails_from_data (Itdb_Track *track,
gsize image_data_len);
gboolean itdb_track_set_thumbnails_from_pixbuf (Itdb_Track *track,
gpointer pixbuf);
-
+gboolean itdb_track_has_thumbnails (Itdb_Track *track);
void itdb_track_remove_thumbnails (Itdb_Track *track);
+gpointer itdb_track_get_thumbnail (Itdb_Track *track, gint width, gint height);
/* photoalbum functions -- see itdb_photoalbum.c for instructions on
* how to use. */
@@ -1237,25 +1207,21 @@ Itdb_PhotoAlbum *itdb_photodb_photoalbum_by_name(Itdb_PhotoDB *db,
Itdb_Artwork *itdb_artwork_new (void);
Itdb_Artwork *itdb_artwork_duplicate (Itdb_Artwork *artwork);
void itdb_artwork_free (Itdb_Artwork *artwork);
-Itdb_Thumb *itdb_artwork_get_thumb_by_type (Itdb_Artwork *artwork,
- ItdbThumbType type);
-gboolean itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
- ItdbThumbType type,
+gboolean itdb_artwork_set_thumbnail (Itdb_Artwork *artwork,
const gchar *filename,
gint rotation, GError **error);
-gboolean itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
- ItdbThumbType type,
+gboolean itdb_artwork_set_thumbnail_from_data (Itdb_Artwork *artwork,
const guchar *image_data,
gsize image_data_len,
gint rotation, GError **error);
-gboolean itdb_artwork_add_thumbnail_from_pixbuf (Itdb_Artwork *artwork,
- ItdbThumbType type,
+gboolean itdb_artwork_set_thumbnail_from_pixbuf (Itdb_Artwork *artwork,
gpointer pixbuf,
gint rotation,
GError **error);
-void itdb_artwork_remove_thumbnail (Itdb_Artwork *artwork,
- Itdb_Thumb *thumb);
void itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork);
+gpointer itdb_artwork_get_pixbuf (Itdb_Device *device, Itdb_Artwork *artwork,
+ gint width, gint height);
+
/* itdb_thumb_... */
/* the following function returns a pointer to a GdkPixbuf if
gdk-pixbuf is installed -- a NULL pointer otherwise. */
@@ -1263,8 +1229,7 @@ gpointer itdb_thumb_get_gdk_pixbuf (Itdb_Device *device,
Itdb_Thumb *thumb);
Itdb_Thumb *itdb_thumb_duplicate (Itdb_Thumb *thumb);
void itdb_thumb_free (Itdb_Thumb *thumb);
-Itdb_Thumb *itdb_thumb_new (void);
-gchar *itdb_thumb_get_filename (Itdb_Device *device, Itdb_Thumb *thumb);
+
/* itdb_chapterdata_... */
Itdb_Chapterdata *itdb_chapterdata_new (void);
void itdb_chapterdata_free (Itdb_Chapterdata *chapterdata);
diff --git a/src/itdb_artwork.c b/src/itdb_artwork.c
index acdbc7e..7891775 100644
--- a/src/itdb_artwork.c
+++ b/src/itdb_artwork.c
@@ -30,6 +30,7 @@
#include "itdb_device.h"
#include "itdb_private.h"
+#include "itdb_thumb.h"
#include "db-image-parser.h"
#include "itdb_endianness.h"
#include <errno.h>
@@ -71,29 +72,6 @@ void itdb_artwork_free (Itdb_Artwork *artwork)
g_free (artwork);
}
-
-static GList *dup_thumbnails (GList *thumbnails)
-{
- GList *it;
- GList *result;
-
- result = NULL;
- for (it = thumbnails; it != NULL; it = it->next)
- {
- Itdb_Thumb *new_thumb;
- Itdb_Thumb *thumb;
-
- thumb = (Itdb_Thumb *)it->data;
- g_return_val_if_fail (thumb, NULL);
-
- new_thumb = itdb_thumb_duplicate (thumb);
-
- result = g_list_prepend (result, new_thumb);
- }
-
- return g_list_reverse (result);
-}
-
/**
* itdb_artwork_duplicate:
* @artwork: an #Itdb_Artwork
@@ -111,30 +89,13 @@ Itdb_Artwork *itdb_artwork_duplicate (Itdb_Artwork *artwork)
memcpy (dup, artwork, sizeof (Itdb_Artwork));
- dup->thumbnails = dup_thumbnails (artwork->thumbnails);
+ if (artwork->thumbnail != NULL) {
+ dup->thumbnail = itdb_thumb_duplicate (artwork->thumbnail);
+ }
return dup;
}
-
-/**
- * itdb_artwork_remove_thumbnail:
- * @artwork: an #Itdb_Artwork
- * @thumb: an #Itdb_Thumb
- *
- * Removes @thumb from @artwork. The memory used by @thumb is freed.
- **/
-void
-itdb_artwork_remove_thumbnail (Itdb_Artwork *artwork, Itdb_Thumb *thumb)
-{
- g_return_if_fail (artwork);
- g_return_if_fail (thumb);
-
- artwork->thumbnails = g_list_remove (artwork->thumbnails, thumb);
- itdb_thumb_free (thumb);
-}
-
-
/**
* itdb_artwork_remove_thumbnails:
* @artwork: an #Itdb_Artwork
@@ -146,12 +107,10 @@ itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork)
{
g_return_if_fail (artwork);
- while (artwork->thumbnails)
- {
- Itdb_Thumb *thumb = artwork->thumbnails->data;
- g_return_if_fail (thumb);
- itdb_artwork_remove_thumbnail (artwork, thumb);
+ if (artwork->thumbnail != NULL) {
+ itdb_thumb_free (artwork->thumbnail);
}
+ artwork->thumbnail = NULL;
artwork->artwork_size = 0;
artwork->id = 0;
}
@@ -160,7 +119,7 @@ itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork)
/**
- * itdb_artwork_add_thumbnail
+ * itdb_artwork_set_thumbnail
* @artwork: an #Itdb_Thumbnail
* @type: thumbnail size
* @filename: image file to use to create the thumbnail
@@ -180,8 +139,7 @@ itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork)
* otherwise. @error is set appropriately.
**/
gboolean
-itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
- ItdbThumbType type,
+itdb_artwork_set_thumbnail (Itdb_Artwork *artwork,
const gchar *filename,
gint rotation,
GError **error)
@@ -204,11 +162,12 @@ itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
artwork->artwork_size = statbuf.st_size;
artwork->creation_date = statbuf.st_mtime;
- thumb = itdb_thumb_new ();
- thumb->filename = g_strdup (filename);
- thumb->type = type;
- thumb->rotation = rotation;
- artwork->thumbnails = g_list_append (artwork->thumbnails, thumb);
+ thumb = itdb_thumb_new_from_file (filename);
+ itdb_thumb_set_rotation (thumb, rotation);
+ if (artwork->thumbnail != NULL) {
+ itdb_thumb_free (artwork->thumbnail);
+ }
+ artwork->thumbnail = thumb;
return TRUE;
#else
@@ -240,8 +199,7 @@ itdb_artwork_add_thumbnail (Itdb_Artwork *artwork,
* otherwise. @error is set appropriately.
**/
gboolean
-itdb_artwork_add_thumbnail_from_pixbuf (Itdb_Artwork *artwork,
- ItdbThumbType type,
+itdb_artwork_set_thumbnail_from_pixbuf (Itdb_Artwork *artwork,
gpointer pixbuf,
gint rotation,
GError **error)
@@ -264,12 +222,12 @@ itdb_artwork_add_thumbnail_from_pixbuf (Itdb_Artwork *artwork,
artwork->artwork_size = rowstride * height;
artwork->creation_date = time.tv_sec;
- thumb = itdb_thumb_new ();
- g_object_ref (G_OBJECT (pixbuf));
- thumb->pixbuf = pixbuf;
- thumb->type = type;
- thumb->rotation = rotation;
- artwork->thumbnails = g_list_append (artwork->thumbnails, thumb);
+ thumb = itdb_thumb_new_from_pixbuf (pixbuf);
+ itdb_thumb_set_rotation (thumb, rotation);
+ if (artwork->thumbnail != NULL) {
+ itdb_thumb_free (artwork->thumbnail);
+ }
+ artwork->thumbnail = thumb;
return TRUE;
#else
@@ -302,8 +260,7 @@ itdb_artwork_add_thumbnail_from_pixbuf (Itdb_Artwork *artwork,
* otherwise. @error is set appropriately.
**/
gboolean
-itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
- ItdbThumbType type,
+itdb_artwork_set_thumbnail_from_data (Itdb_Artwork *artwork,
const guchar *image_data,
gsize image_data_len,
gint rotation,
@@ -322,14 +279,12 @@ itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
artwork->artwork_size = image_data_len;
artwork->creation_date = time.tv_sec;
- thumb = itdb_thumb_new ();
- thumb->image_data = g_malloc (image_data_len);
- thumb->image_data_len = image_data_len;
- memcpy (thumb->image_data, image_data, image_data_len);
-
- thumb->type = type;
- thumb->rotation = rotation;
- artwork->thumbnails = g_list_append (artwork->thumbnails, thumb);
+ thumb = itdb_thumb_new_from_data (image_data, image_data_len);
+ itdb_thumb_set_rotation (thumb, rotation);
+ if (artwork->thumbnail != NULL) {
+ itdb_thumb_free (artwork->thumbnail);
+ }
+ artwork->thumbnail = thumb;
return TRUE;
#else
@@ -339,93 +294,6 @@ itdb_artwork_add_thumbnail_from_data (Itdb_Artwork *artwork,
#endif
}
-
-/**
- * itdb_artwork_get_thumb_by_type:
- * @artwork: an #Itdb_Artwork
- * @type: type of the #Itdb_Thumb to retrieve
- *
- * Searches @artwork for an #Itdb_Thumb of type @type.
- *
- * Returns: an #Itdb_Thumb of type @type, or NULL if such a thumbnail couldn't
- * be found
- **/
-Itdb_Thumb *itdb_artwork_get_thumb_by_type (Itdb_Artwork *artwork,
- ItdbThumbType type)
-{
- GList *gl;
-
- g_return_val_if_fail (artwork, NULL);
-
- for (gl=artwork->thumbnails; gl; gl=gl->next)
- {
- Itdb_Thumb *thumb = gl->data;
- g_return_val_if_fail (thumb, NULL);
- if (thumb->type == type) return thumb;
- }
- return NULL;
-}
-
-
-/**
- * itdb_thumb_get_filename:
- * @device: an #Itdb_Device
- * @thumb: an #Itdb_Thumb
- *
- * Get filename of thumbnail. If it's a thumbnail on the iPod, return
- * the full path to the ithmb file. Otherwise return the full path to
- * the original file.
- *
- * Return value: newly allocated string containing the absolute path to the
- * thumbnail file.
- **/
-gchar *itdb_thumb_get_filename (Itdb_Device *device, Itdb_Thumb *thumb)
-{
- gchar *artwork_dir, *filename=NULL;
-
- g_return_val_if_fail (device, NULL);
- g_return_val_if_fail (thumb, NULL);
-
- /* thumbnail not transferred to the iPod */
- if (thumb->size == 0)
- return g_strdup (thumb->filename);
-
- if (strlen (thumb->filename) < 2)
- {
- g_print (_("Illegal filename: '%s'.\n"), thumb->filename);
- return NULL;
- }
-
- if (!device->mountpoint)
- {
- g_print (_("Mountpoint not set.\n"));
- return NULL;
- }
- artwork_dir = itdb_get_artwork_dir (device->mountpoint);
- if (artwork_dir)
- {
- filename = itdb_get_path (artwork_dir, thumb->filename+1);
- g_free (artwork_dir);
- }
- /* FIXME: Hack */
- if( !filename ) {
- artwork_dir = itdb_get_photos_thumb_dir (device->mountpoint);
-
- if (artwork_dir)
- {
- const gchar *name_on_disk = strchr( thumb->filename+1, ':');
- if (name_on_disk)
- {
- filename = itdb_get_path (artwork_dir, name_on_disk + 1);
- }
- g_free (artwork_dir);
- }
-
- }
- return filename;
-}
-
-
#if HAVE_GDKPIXBUF
static guchar *
unpack_RGB_565 (guint16 *pixels, guint bytes_len, guint byte_order)
@@ -772,7 +640,7 @@ unpack_UYVY (guchar *yuvdata, gint bytes_len, guint byte_order,
}
static guchar *
-get_pixel_data (Itdb_Device *device, Itdb_Thumb *thumb)
+get_pixel_data (Itdb_Device *device, Itdb_Thumb_Ipod_Item *thumb)
{
gchar *filename = NULL;
guchar *result = NULL;
@@ -787,7 +655,7 @@ get_pixel_data (Itdb_Device *device, Itdb_Thumb *thumb)
*/
result = g_malloc (thumb->size);
- filename = itdb_thumb_get_filename (device, thumb);
+ filename = itdb_thumb_ipod_get_filename (device, thumb);
if (!filename)
{
@@ -832,7 +700,7 @@ get_pixel_data (Itdb_Device *device, Itdb_Thumb *thumb)
}
static guchar *
-itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
+itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb_Ipod_Item *item)
{
#if 0
#include <unistd.h>
@@ -843,15 +711,16 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
#endif
void *pixels_raw;
guchar *pixels=NULL;
- const Itdb_ArtworkFormat *img_info;
-
+
g_return_val_if_fail (device, NULL);
- g_return_val_if_fail (thumb, NULL);
- g_return_val_if_fail (thumb->size != 0, NULL);
- img_info = itdb_get_artwork_info_from_type (device, thumb->type);
- g_return_val_if_fail (img_info, NULL);
+ g_return_val_if_fail (item, NULL);
+ g_return_val_if_fail (item->size != 0, NULL);
- pixels_raw = get_pixel_data (device, thumb);
+ if (item->format == NULL) {
+ return NULL;
+ }
+
+ pixels_raw = get_pixel_data (device, item);
#if 0
name = g_strdup_printf ("thumb_%03d.raw", i++);
@@ -864,7 +733,7 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
return NULL;
}
- switch (img_info->format)
+ switch (item->format->format)
{
case THUMB_FORMAT_RGB565_LE_90:
case THUMB_FORMAT_RGB565_BE_90:
@@ -873,8 +742,8 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
screen photo thumbnail) */
case THUMB_FORMAT_RGB565_LE:
case THUMB_FORMAT_RGB565_BE:
- pixels = unpack_RGB_565 (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format));
+ pixels = unpack_RGB_565 (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format));
break;
case THUMB_FORMAT_RGB555_LE_90:
case THUMB_FORMAT_RGB555_BE_90:
@@ -883,8 +752,8 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
screen photo thumbnail) */
case THUMB_FORMAT_RGB555_LE:
case THUMB_FORMAT_RGB555_BE:
- pixels = unpack_RGB_555 (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format));
+ pixels = unpack_RGB_555 (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format));
break;
case THUMB_FORMAT_RGB888_LE_90:
case THUMB_FORMAT_RGB888_BE_90:
@@ -892,8 +761,8 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
different treatment */
case THUMB_FORMAT_RGB888_LE:
case THUMB_FORMAT_RGB888_BE:
- pixels = unpack_RGB_888 (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format));
+ pixels = unpack_RGB_888 (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format));
break;
case THUMB_FORMAT_REC_RGB555_LE_90:
case THUMB_FORMAT_REC_RGB555_BE_90:
@@ -902,29 +771,29 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
screen photo thumbnail) */
case THUMB_FORMAT_REC_RGB555_LE:
case THUMB_FORMAT_REC_RGB555_BE:
- pixels = unpack_rec_RGB_555 (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format),
- img_info->width, img_info->height);
+ pixels = unpack_rec_RGB_555 (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format),
+ item->format->width, item->format->height);
break;
case THUMB_FORMAT_EXPERIMENTAL_LE:
case THUMB_FORMAT_EXPERIMENTAL_BE:
#if DEBUG_ARTWORK
- pixels = unpack_experimental (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format),
- img_info->width, img_info->height);
+ pixels = unpack_experimental (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format),
+ item->format->width, item->format->height);
break;
#endif
case THUMB_FORMAT_UYVY_LE:
case THUMB_FORMAT_UYVY_BE:
- pixels = unpack_UYVY (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format),
- img_info->width, img_info->height);
+ pixels = unpack_UYVY (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format),
+ item->format->width, item->format->height);
break;
case THUMB_FORMAT_I420_LE:
case THUMB_FORMAT_I420_BE:
- pixels = unpack_I420 (pixels_raw, thumb->size,
- itdb_thumb_get_byteorder (img_info->format),
- img_info->width, img_info->height);
+ pixels = unpack_I420 (pixels_raw, item->size,
+ itdb_thumb_get_byteorder (item->format->format),
+ item->format->width, item->format->height);
break;
}
g_free (pixels_raw);
@@ -932,158 +801,29 @@ itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
return pixels;
}
-#endif
-
-
-/**
- * itdb_thumb_get_gdk_pixbuf:
- * @device: an #Itdb_Device
- * @thumb: an #Itdb_Thumb
- *
- * Converts @thumb to a #GdkPixbuf.
- * Since we want to have gdk-pixbuf dependency optional, a generic
- * gpointer is returned which you have to cast to a #GdkPixbuf using
- * GDK_PIXBUF() yourself.
- *
- * Return value: a #GdkPixbuf that must be unreffed with gdk_pixbuf_unref()
- * after use, or NULL if the creation of the gdk-pixbuf failed or if
- * libgpod was compiled without gdk-pixbuf support.
- **/
-gpointer
-itdb_thumb_get_gdk_pixbuf (Itdb_Device *device, Itdb_Thumb *thumb)
+gpointer itdb_thumb_ipod_item_to_pixbuf (Itdb_Device *device,
+ Itdb_Thumb_Ipod_Item *item)
{
-#if HAVE_GDKPIXBUF
- GdkPixbuf *pixbuf=NULL;
- guchar *pixels;
- const Itdb_ArtworkFormat *img_info=NULL;
-
- g_return_val_if_fail (thumb, NULL);
-
- /* If we are dealing with an iPod (device != NULL), use default
- image dimensions as used on the iPod in question.
-
- If we are not dealing with an iPod, we can only return a pixmap
- for thumbnails "not transferred to the iPod" (thumb->size ==
- 0).
- */
- if (device != NULL)
- {
- img_info = itdb_get_artwork_info_from_type (device, thumb->type);
- }
-
- if (thumb->size == 0)
- { /* thumbnail has not yet been transferred to the iPod */
- gint width=0, height=0;
-
- if (img_info != NULL)
- { /* use image dimensions from iPod */
- width = img_info->width;
- height = img_info->height;
- }
- else
- { /* use default dimensions */
- /* FIXME: better way to use the ipod_color dimensions? */
- switch (thumb->type)
- {
- case ITDB_THUMB_COVER_SMALL:
- width = 56; height = 56; break;
- case ITDB_THUMB_COVER_LARGE:
- width = 140; height = 140; break;
- case ITDB_THUMB_PHOTO_SMALL:
- width = 42; height = 30; break;
- case ITDB_THUMB_PHOTO_LARGE:
- width = 130; height = 88; break;
- case ITDB_THUMB_PHOTO_FULL_SCREEN:
- width = 220; height = 176; break;
- case ITDB_THUMB_PHOTO_TV_SCREEN:
- width = 720; height = 480; break;
- case ITDB_THUMB_COVER_XLARGE:
- width = 320; height = 320; break;
- case ITDB_THUMB_COVER_MEDIUM:
- width = 128; height = 128; break;
- case ITDB_THUMB_COVER_SMEDIUM:
- width = 88; height = 88; break;
- case ITDB_THUMB_COVER_XSMALL:
- width = 56; height = 56; break;
- case ITDB_THUMB_CHAPTER_SMALL:
- width = 100; height = 100; break;
- case ITDB_THUMB_CHAPTER_LARGE:
- width = 200; height = 200; break;
- }
- if (width == 0)
- {
- width = 140;
- height = 140;
- }
- }
-
- if (thumb->filename)
- { /* read data from filename */
- pixbuf = gdk_pixbuf_new_from_file_at_size (thumb->filename,
- width, height,
- NULL);
- }
- else if (thumb->image_data)
- { /* use data stored in image_data */
- GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
- g_return_val_if_fail (loader, FALSE);
- gdk_pixbuf_loader_set_size (loader,
- width, height);
- gdk_pixbuf_loader_write (loader,
- thumb->image_data,
- thumb->image_data_len,
- NULL);
- gdk_pixbuf_loader_close (loader, NULL);
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
- if (pixbuf)
- g_object_ref (pixbuf);
- g_object_unref (loader);
- }
- else if (thumb->pixbuf)
- { /* use pixbuf data */
- pixbuf = gdk_pixbuf_scale_simple (thumb->pixbuf,
- width, height,
- GDK_INTERP_BILINEAR);
- }
-
- if (!pixbuf)
- {
- return NULL;
- }
-
- /* !! cannot write directly to &thumb->width/height because
- g_object_get() returns a gint, but thumb->width/height are
- gint16 !! */
- g_object_get (G_OBJECT (pixbuf),
- "width", &width,
- "height", &height,
- NULL);
-
- thumb->width = width;
- thumb->height = height;
- }
- else
- {
/* pixbuf is already on the iPod -> read from there */
GdkPixbuf *pixbuf_full;
GdkPixbuf *pixbuf_sub;
- gint pad_x = thumb->horizontal_padding;
- gint pad_y = thumb->vertical_padding;
- gint width = thumb->width;
- gint height = thumb->height;
+ GdkPixbuf *pixbuf;
+ gint pad_x = item->horizontal_padding;
+ gint pad_y = item->vertical_padding;
+ gint width = item->width;
+ gint height = item->height;
+ const Itdb_ArtworkFormat *img_info = item->format;
+ guchar *pixels;
/* printf ("hp%d vp%d w%d h%d\n",
pad_x, pad_y, width, height);*/
-
- if (img_info == NULL)
- {
- g_print (_("Unable to retrieve thumbnail (appears to be on iPod, but no image info available): type: %d, filename: '%s'\n"),
- thumb->type, thumb->filename);
- return NULL;
- }
-
- pixels = itdb_thumb_get_rgb_data (device, thumb);
+ if (item->format == NULL) {
+ g_warning (_("Unable to retrieve thumbnail (appears to be on iPod, but no image info available): filename: '%s'\n"),
+ item->filename);
+ return NULL;
+ }
+ pixels = itdb_thumb_get_rgb_data (device, item);
if (pixels == NULL)
{
return NULL;
@@ -1097,6 +837,7 @@ itdb_thumb_get_gdk_pixbuf (Itdb_Device *device, Itdb_Thumb *thumb)
img_info->width*3,
(GdkPixbufDestroyNotify)g_free,
NULL);
+
/* !! do not g_free(pixels) here: it will be freed when doing a
* gdk_pixbuf_unref() on the GdkPixbuf !! */
@@ -1133,113 +874,39 @@ itdb_thumb_get_gdk_pixbuf (Itdb_Device *device, Itdb_Thumb *thumb)
pixbuf = gdk_pixbuf_copy (pixbuf_sub);
gdk_pixbuf_unref (pixbuf_full);
gdk_pixbuf_unref (pixbuf_sub);
- }
- return pixbuf;
-#else
- return NULL;
-#endif
+ return pixbuf;
}
-
-/**
- * itdb_thumb_new:
- *
- * Creates a new #Itdb_Thumb
- *
- * Return Value: newly allocated #Itdb_Thumb to be freed with itdb_thumb_free()
- * after use
- **/
-Itdb_Thumb *itdb_thumb_new (void)
+#else
+gpointer itdb_thumb_ipod_item_to_pixbuf (Itdb_Thumb_Ipod_Item *item)
{
- Itdb_Thumb *thumb = g_new0 (Itdb_Thumb, 1);
- return thumb;
+ return NULL;
}
-
-/**
- * itdb_thumb_free:
- * @thumb: an #Itdb_Thumb
- *
- * Frees the memory used by @thumb
- **/
-void itdb_thumb_free (Itdb_Thumb *thumb)
-{
- g_return_if_fail (thumb);
-
- g_free (thumb->image_data);
-#ifdef HAVE_GDKPIXBUF
- if (thumb->pixbuf) {
- g_object_unref (G_OBJECT (thumb->pixbuf));
- }
#endif
- g_free (thumb->filename);
- g_free (thumb);
-}
-
-/**
- * itdb_thumb_duplicate:
- * @thumb: an #Itdb_Thumb
+/**
+ * itdb_artwork_get_thumbnail!
+ * @artwork: an #Itdb_Artwork
+ * @width: width of the pixbuf to retrieve, -1 for the biggest possible size
+ * (with no scaling)
+ * @height: height of the pixbuf to retrieve, -1 for the biggest possible size
+ * (with no scaling)
*
- * Duplicates the data contained in @thumb
+ * Returns a #GdkPixbuf representing the thumbnail stored in @artwork
+ * scaling it if appropriate. If either height or width is -1, then the
+ * biggest unscaled thumbnail available will be returned
*
- * Return value: a newly allocated copy of @thumb to be freed with
- * itdb_thumb_free() after use
+ * Return value: a #GdkPixbuf that must be unreffed when no longer used, NULL
+ * if no artwork could be found or if libgpod is compiled without GdkPixbuf
+ * support
**/
-Itdb_Thumb *itdb_thumb_duplicate (Itdb_Thumb *thumb)
-{
- Itdb_Thumb *new_thumb;
-
- g_return_val_if_fail (thumb, NULL);
-
- new_thumb = itdb_thumb_new ();
- memcpy (new_thumb, thumb, sizeof (Itdb_Thumb));
- new_thumb->filename = g_strdup (thumb->filename);
-
- if (thumb->image_data)
- {
- /* image_data_len already copied with the memcpy above */
- new_thumb->image_data = g_malloc (thumb->image_data_len);
- memcpy (new_thumb->image_data, thumb->image_data,
- new_thumb->image_data_len);
- }
-#ifdef HAVE_GDKPIXBUF
- if (thumb->pixbuf) {
- g_object_ref (G_OBJECT (thumb->pixbuf));
- }
-#endif
- return new_thumb;
-}
-
-
-G_GNUC_INTERNAL gint
-itdb_thumb_get_byteorder (const ItdbThumbFormat format)
+gpointer itdb_artwork_get_pixbuf (Itdb_Device *device, Itdb_Artwork *artwork,
+ gint width, gint height)
{
- switch (format)
- {
- case THUMB_FORMAT_UYVY_LE:
- case THUMB_FORMAT_I420_LE:
- case THUMB_FORMAT_RGB565_LE:
- case THUMB_FORMAT_RGB565_LE_90:
- case THUMB_FORMAT_RGB555_LE:
- case THUMB_FORMAT_RGB555_LE_90:
- case THUMB_FORMAT_RGB888_LE:
- case THUMB_FORMAT_RGB888_LE_90:
- case THUMB_FORMAT_REC_RGB555_LE:
- case THUMB_FORMAT_REC_RGB555_LE_90:
- case THUMB_FORMAT_EXPERIMENTAL_LE:
- return G_LITTLE_ENDIAN;
- case THUMB_FORMAT_UYVY_BE:
- case THUMB_FORMAT_I420_BE:
- case THUMB_FORMAT_RGB565_BE:
- case THUMB_FORMAT_RGB565_BE_90:
- case THUMB_FORMAT_RGB555_BE:
- case THUMB_FORMAT_RGB555_BE_90:
- case THUMB_FORMAT_RGB888_BE:
- case THUMB_FORMAT_RGB888_BE_90:
- case THUMB_FORMAT_REC_RGB555_BE:
- case THUMB_FORMAT_REC_RGB555_BE_90:
- case THUMB_FORMAT_EXPERIMENTAL_BE:
- return G_BIG_ENDIAN;
+ g_return_val_if_fail (artwork != NULL, NULL);
+ if (artwork->thumbnail == NULL) {
+ return NULL;
}
- g_return_val_if_reached (-1);
+ return itdb_thumb_to_pixbuf_at_size (device, artwork->thumbnail,
+ width, height);
}
diff --git a/src/itdb_device.h b/src/itdb_device.h
index 1a8a70a..f6aaf14 100644
--- a/src/itdb_device.h
+++ b/src/itdb_device.h
@@ -46,7 +46,6 @@
G_BEGIN_DECLS
-typedef struct _Itdb_ArtworkFormat Itdb_ArtworkFormat;
typedef enum _ItdbThumbFormat ItdbThumbFormat;
enum _ItdbThumbFormat
diff --git a/src/itdb_photoalbum.c b/src/itdb_photoalbum.c
index b55c4d0..614236f 100644
--- a/src/itdb_photoalbum.c
+++ b/src/itdb_photoalbum.c
@@ -361,7 +361,6 @@ static Itdb_Artwork *itdb_photodb_add_photo_internal (Itdb_PhotoDB *db,
gboolean result;
Itdb_Artwork *artwork;
Itdb_PhotoAlbum *album;
- const Itdb_ArtworkFormat *format;
g_return_val_if_fail (db, NULL);
g_return_val_if_fail (db->device, NULL);
@@ -418,40 +417,21 @@ static Itdb_Artwork *itdb_photodb_add_photo_internal (Itdb_PhotoDB *db,
artwork = itdb_artwork_new ();
- /* Add a thumbnail for every supported format */
- format = itdb_device_get_artwork_formats (db->device);
- g_return_val_if_fail (format, NULL);
-
- for(result = TRUE; format->type != -1 && result == TRUE; format++)
+ if (filename)
{
- if (itdb_thumb_type_is_valid_for_db (format->type, DB_TYPE_PHOTO))
- {
- if (filename)
- {
- result = itdb_artwork_add_thumbnail (artwork,
- format->type,
- filename,
- rotation,
- error);
- }
- if (image_data)
- {
- result = itdb_artwork_add_thumbnail_from_data (artwork,
- format->type,
- image_data,
- image_data_len,
- rotation,
- error);
- }
- if (pixbuf)
- {
- result = itdb_artwork_add_thumbnail_from_pixbuf (artwork,
- format->type,
- pixbuf,
- rotation,
- error);
- }
- }
+ result = itdb_artwork_set_thumbnail (artwork, filename,
+ rotation, error);
+ }
+ if (image_data)
+ {
+ result = itdb_artwork_set_thumbnail_from_data (artwork, image_data,
+ image_data_len,
+ rotation, error);
+ }
+ if (pixbuf)
+ {
+ result = itdb_artwork_set_thumbnail_from_pixbuf (artwork, pixbuf,
+ rotation, error);
}
if (result != TRUE)
diff --git a/src/itdb_track.c b/src/itdb_track.c
index c09b9ae..163ace5 100644
--- a/src/itdb_track.c
+++ b/src/itdb_track.c
@@ -30,6 +30,7 @@
#include "itdb_private.h"
#include "itdb_device.h"
+#include "itdb_thumb.h"
#include <string.h>
static gboolean is_video_ipod (Itdb_Device *device)
@@ -376,7 +377,9 @@ Itdb_Track *itdb_track_duplicate (Itdb_Track *tr)
tr_dup->chapterdata = itdb_chapterdata_duplicate (tr->chapterdata);
/* Copy thumbnail data */
- tr_dup->artwork = itdb_artwork_duplicate (tr->artwork);
+ if (tr->artwork != NULL) {
+ tr_dup->artwork = itdb_artwork_duplicate (tr->artwork);
+ }
/* Copy userdata */
if (tr->userdata && tr->userdata_duplicate)
@@ -395,66 +398,33 @@ static gboolean itdb_track_set_thumbnails_internal (Itdb_Track *track,
gpointer *pixbuf,
gint rotation,
GError **error)
-{
- /* gtkpod calls this function mostly with tracks that are not yet
- * part of an iTunesDB. This means it is not known which
- * thumbnails are required.
- *
- * Our solution is to add all kinds of cover thumbs and weed out
- * the ones not supported when the ArtworkDB is written.
- *
- * Suggestions welcome!
- */
-
+{
gboolean result = FALSE;
- ItdbThumbType thumbtypes[] =
- { ITDB_THUMB_COVER_SMALL,
- ITDB_THUMB_COVER_LARGE,
- ITDB_THUMB_COVER_XLARGE,
- ITDB_THUMB_COVER_MEDIUM,
- ITDB_THUMB_COVER_SMEDIUM,
- ITDB_THUMB_COVER_XSMALL,
- -1 };
- ItdbThumbType *thumbtype;
- const Itdb_ArtworkFormat *formats=NULL;
g_return_val_if_fail (track, FALSE);
g_return_val_if_fail (filename || image_data || pixbuf, FALSE);
- if (track->itdb && track->itdb->device)
- {
- formats = itdb_device_get_artwork_formats (track->itdb->device);
- }
-
itdb_artwork_remove_thumbnails (track->artwork);
/* clear artwork id */
track->artwork->id = 0;
- for (thumbtype=thumbtypes; *thumbtype!=-1; ++thumbtype)
+ if (filename)
{
- if (filename)
- {
- result = itdb_artwork_add_thumbnail (track->artwork,
- *thumbtype,
- filename, rotation, error);
- }
- if (image_data)
- {
- result = itdb_artwork_add_thumbnail_from_data (track->artwork,
- *thumbtype,
- image_data,
- image_data_len,
- rotation, error);
- }
- if (pixbuf)
- {
- result = itdb_artwork_add_thumbnail_from_pixbuf (track->artwork,
- *thumbtype,
- pixbuf, rotation,
- error);
- }
- if (result == FALSE)
- break; /* for (thumbtype=...) */
+ result = itdb_artwork_set_thumbnail (track->artwork, filename,
+ rotation, error);
+ }
+ if (image_data)
+ {
+ result = itdb_artwork_set_thumbnail_from_data (track->artwork,
+ image_data,
+ image_data_len,
+ rotation, error);
+ }
+ if (pixbuf)
+ {
+ result = itdb_artwork_set_thumbnail_from_pixbuf (track->artwork,
+ pixbuf, rotation,
+ error);
}
if (result == TRUE)
@@ -480,7 +450,6 @@ static gboolean itdb_track_set_thumbnails_internal (Itdb_Track *track,
return result;
}
-
/**
* itdb_track_set_thumbnails:
* @track: an #Itdb_Track
@@ -503,9 +472,6 @@ gboolean itdb_track_set_thumbnails (Itdb_Track *track,
0, NULL);
}
-
-
-
/**
* itdb_track_set_thumbnails_from_data:
* @track: an #Itdb_Track
@@ -570,7 +536,6 @@ void itdb_track_remove_thumbnails (Itdb_Track *track)
track->has_artwork = 0x02;
}
-
/**
* itdb_track_by_id:
* @itdb: an #Itdb_iTunesDB
@@ -611,7 +576,6 @@ static gint track_id_compare (gconstpointer a, gconstpointer b)
return -1;
}
-
/**
* itdb_track_id_tree_create:
* @itdb: an #Itdb_iTunesDB
@@ -671,4 +635,47 @@ Itdb_Track *itdb_track_id_tree_by_id (GTree *idtree, guint32 id)
return (Itdb_Track *)g_tree_lookup (idtree, &id);
}
+/**
+ * itdb_track_has_thumbnails:
+ * @track: an #Itdb_Track
+ *
+ * Return value: TRUE if @track has artwork available, FALSE otherwise
+ **/
+gboolean itdb_track_has_thumbnails (Itdb_Track *track)
+{
+ g_return_val_if_fail (track != NULL, FALSE);
+ return ((track->artwork) && (track->artwork->thumbnail));
+}
+
+/**
+ * itdb_track_get_thumbnail!
+ * @track: an #Itdb_Track
+ * @width: width of the pixbuf to retrieve, -1 for the biggest possible size
+ * (with no scaling)
+ * @height: height of the pixbuf to retrieve, -1 for the biggest possible size
+ * (with no scaling)
+ *
+ * Returns a #GdkPixbuf representing the cover associated with the current
+ * track, scaling it if appropriate. If either height or width is -1, then the
+ * biggest unscaled thumbnail available will be returned
+ *
+ * Return value: a #GdkPixbuf that must be unreffed when no longer used, NULL
+ * if no artwork could be found or if libgpod is compiled without GdkPixbuf
+ * support
+ **/
+gpointer itdb_track_get_thumbnail (Itdb_Track *track, gint width, gint height)
+{
+ g_return_val_if_fail (track != NULL, NULL);
+ if (!itdb_track_has_thumbnails (track)) {
+ return NULL;
+ }
+ if (track->itdb != NULL) {
+ return itdb_thumb_to_pixbuf_at_size (track->itdb->device,
+ track->artwork->thumbnail,
+ width, height);
+ } else {
+ return itdb_thumb_to_pixbuf_at_size (NULL, track->artwork->thumbnail,
+ width, height);
+ }
+}
diff --git a/src/ithumb-writer.c b/src/ithumb-writer.c
index ae8630f..a123285 100644
--- a/src/ithumb-writer.c
+++ b/src/ithumb-writer.c
@@ -559,32 +559,27 @@ ipod_image_get_ithmb_filename (const char *mount_point, gint format_id, gint ind
/* If appropriate, rotate thumb->pixbuf by the value specified in
* thumb->rotation or thumb->pixbuf's EXIF orientation value. */
-static void
-ithumb_writer_handle_rotation (Itdb_Thumb *thumb) {
- /* Make sure @rotation is valid (0, 90, 180, 270) */
- thumb->rotation = thumb->rotation % 360;
- thumb->rotation /= 90;
- thumb->rotation *= 90;
-
-
+static GdkPixbuf *
+ithumb_writer_handle_rotation (GdkPixbuf *pixbuf, guint *rotation)
+{
/* If the caller did not specify a rotation, and there is an orientation header
present in the pixbuf (from EXIF), use that to choose a rotation.
NOTE: Do this before doing any transforms on the pixbuf, or you will lose
the EXIF metadata.
List of orientation values: http://sylvana.net/jpegcrop/exif_orientation.html */
- if (thumb->rotation == 0) {
+ if (*rotation == 0) {
/* In GdkPixbuf 2.12 or above, this returns the EXIF orientation value. */
- const char* exif_orientation = gdk_pixbuf_get_option(thumb->pixbuf, "orientation");
+ const char* exif_orientation = gdk_pixbuf_get_option(pixbuf, "orientation");
if (exif_orientation != NULL) {
switch (exif_orientation[0]) {
case '3':
- thumb->rotation = 180;
+ *rotation = 180;
break;
case '6':
- thumb->rotation = 270;
+ *rotation = 270;
break;
case '8':
- thumb->rotation = 90;
+ *rotation = 90;
break;
/* '1' means no rotation. The other four values are all various
transpositions, which are rare in real photos so we don't
@@ -594,21 +589,18 @@ ithumb_writer_handle_rotation (Itdb_Thumb *thumb) {
}
/* Rotate if necessary */
- if (thumb->rotation != 0)
+ if (*rotation != 0)
{
- GdkPixbuf *new_pixbuf = gdk_pixbuf_rotate_simple (thumb->pixbuf, thumb->rotation);
- g_object_unref (thumb->pixbuf);
- thumb->pixbuf = new_pixbuf;
- /* Clean up */
- thumb->rotation = 0;
+ return gdk_pixbuf_rotate_simple (pixbuf, *rotation);
}
+ return g_object_ref (G_OBJECT (pixbuf));
}
/* On the iPhone, thumbnails are presented as squares in a grid.
In order to fit the grid, they have to be cropped as well as
scaled. */
static GdkPixbuf *
-ithumb_writer_scale_and_crop (Itdb_Thumb *thumb,
+ithumb_writer_scale_and_crop (GdkPixbuf *input_pixbuf,
gint width, gint height,
gboolean crop)
{
@@ -618,9 +610,8 @@ ithumb_writer_scale_and_crop (Itdb_Thumb *thumb,
gint offset_x, offset_y;
gint border_width = 0;
- GdkPixbuf *input_pixbuf, *output_pixbuf;
+ GdkPixbuf *output_pixbuf;
- input_pixbuf = GDK_PIXBUF(thumb->pixbuf);
g_object_get (G_OBJECT (input_pixbuf),
"width", &input_width,
"height", &input_height,
@@ -675,7 +666,38 @@ ithumb_writer_scale_and_crop (Itdb_Thumb *thumb,
return output_pixbuf;
}
-static void *pack_thumbnail (iThumbWriter *writer, Itdb_Thumb *thumb,
+static GdkPixbuf *
+ithumb_writer_handle_pixbuf_transform (iThumbWriter *writer,
+ GdkPixbuf *pixbuf, guint rotation)
+{
+ GdkPixbuf *rotated_pixbuf;
+ GdkPixbuf *scaled_pixbuf;
+
+ guint width;
+ guint height;
+
+ rotated_pixbuf = ithumb_writer_handle_rotation (pixbuf, &rotation);
+
+ if ((rotation == 0) || (rotation == 180))
+ {
+ width = writer->img_info->width;
+ height = writer->img_info->height;
+ }
+ else
+ {
+ width = writer->img_info->height;
+ height = writer->img_info->width;
+ }
+
+ scaled_pixbuf = ithumb_writer_scale_and_crop (rotated_pixbuf, width, height,
+ writer->img_info->crop);
+ g_object_unref (rotated_pixbuf);
+ rotated_pixbuf = NULL;
+
+ return scaled_pixbuf;
+}
+
+static void *pack_thumbnail (iThumbWriter *writer, Itdb_Thumb_Ipod_Item *thumb,
GdkPixbuf *pixbuf)
{
typedef void *(*PackerFunc)(GdkPixbuf *pixbuf,
@@ -726,7 +748,7 @@ static void *pack_thumbnail (iThumbWriter *writer, Itdb_Thumb *thumb,
thumb->vertical_padding,
&thumb->size);
}
-static gboolean write_pixels (iThumbWriter *writer, Itdb_Thumb *thumb,
+static gboolean write_pixels (iThumbWriter *writer, Itdb_Thumb_Ipod_Item *thumb,
void *pixels)
{
if (pixels == NULL)
@@ -760,9 +782,10 @@ static gboolean write_pixels (iThumbWriter *writer, Itdb_Thumb *thumb,
return TRUE;
}
-static char *get_ithmb_filename (iThumbWriter *writer, Itdb_Thumb *thumb)
+static char *get_ithmb_filename (iThumbWriter *writer,
+ const Itdb_ArtworkFormat *format)
{
- switch (thumb->type)
+ switch (format->type)
{
case ITDB_THUMB_PHOTO_LARGE:
case ITDB_THUMB_PHOTO_SMALL:
@@ -788,7 +811,8 @@ static char *get_ithmb_filename (iThumbWriter *writer, Itdb_Thumb *thumb)
g_return_val_if_reached (NULL);
}
-static void set_thumb_padding (iThumbWriter *writer, Itdb_Thumb *thumb,
+static void set_thumb_padding (iThumbWriter *writer,
+ Itdb_Thumb_Ipod_Item *thumb,
gint width, gint height)
{
switch (writer->db_type)
@@ -826,18 +850,20 @@ static GdkPixbuf *pixbuf_from_image_data (guchar *image_data, gsize len)
return pixbuf;
}
-static gboolean
+static Itdb_Thumb_Ipod_Item *
ithumb_writer_write_thumbnail (iThumbWriter *writer,
Itdb_Thumb *thumb)
{
GdkPixbuf *pixbuf = NULL;
void *pixels = NULL;
gint width, height; /* must be gint -- see comment below */
+ Itdb_Thumb_Ipod_Item *thumb_ipod;
+ GdkPixbuf *scaled_pixbuf;
gboolean result;
- g_return_val_if_fail (writer, FALSE);
- g_return_val_if_fail (writer->img_info, FALSE);
- g_return_val_if_fail (thumb, FALSE);
+ g_return_val_if_fail (writer, NULL);
+ g_return_val_if_fail (writer->img_info, NULL);
+ g_return_val_if_fail (thumb, NULL);
/* An thumb can start with one of:
1. a filename
@@ -846,84 +872,78 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer,
In case 1 and 2, we load the relevant data into a GdkPixbuf and proceed
with case 3.
*/
- if (thumb->filename)
- { /* read image from filename */
- thumb->pixbuf = gdk_pixbuf_new_from_file (thumb->filename, NULL);
- g_free (thumb->filename);
- thumb->filename = NULL;
+ if (thumb->data_type == ITDB_THUMB_TYPE_FILE)
+ {
+ Itdb_Thumb_File *thumb_file = (Itdb_Thumb_File *)thumb;
+ pixbuf = gdk_pixbuf_new_from_file (thumb_file->filename, NULL);
}
- else if (thumb->image_data)
- { /* image data is stored in image_data and image_data_len */
- thumb->pixbuf = pixbuf_from_image_data (thumb->image_data,
- thumb->image_data_len);
- g_free (thumb->image_data);
- thumb->image_data = NULL;
- thumb->image_data_len = 0;
+ else if (thumb->data_type == ITDB_THUMB_TYPE_MEMORY)
+ {
+ Itdb_Thumb_Memory *thumb_mem = (Itdb_Thumb_Memory *)thumb;
+ pixbuf = pixbuf_from_image_data (thumb_mem->image_data,
+ thumb_mem->image_data_len);
+ }
+ else if (thumb->data_type == ITDB_THUMB_TYPE_PIXBUF)
+ {
+ Itdb_Thumb_Pixbuf *thumb_pixbuf = (Itdb_Thumb_Pixbuf *)thumb;
+ pixbuf = g_object_ref (G_OBJECT (thumb_pixbuf->pixbuf));
}
- if (thumb->pixbuf == NULL)
+ if (pixbuf == NULL)
{
/* This is quite bad... if we just return FALSE the ArtworkDB
gets messed up. */
- thumb->pixbuf = gdk_pixbuf_from_pixdata (&questionmark_pixdata, FALSE, NULL);
+ pixbuf = gdk_pixbuf_from_pixdata (&questionmark_pixdata, FALSE, NULL);
- if (!thumb->pixbuf)
+ if (!pixbuf)
{
/* Somethin went wrong. let's insert a red thumbnail */
- thumb->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
writer->img_info->width,
writer->img_info->height);
- gdk_pixbuf_fill (thumb->pixbuf, 0xff000000);
+ gdk_pixbuf_fill (pixbuf, 0xff000000);
}
/* avoid rotation */
- thumb->rotation = 0;
+ itdb_thumb_set_rotation (thumb, 0);
}
- g_assert(thumb->pixbuf);
-
- ithumb_writer_handle_rotation(thumb);
+ g_assert(pixbuf);
- /* 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;
- }
-
- pixbuf = ithumb_writer_scale_and_crop (thumb, width, height,
- writer->img_info->crop);
- g_object_unref (thumb->pixbuf);
- thumb->pixbuf = NULL;
+ scaled_pixbuf = ithumb_writer_handle_pixbuf_transform (writer, pixbuf, itdb_thumb_get_rotation (thumb));
+ g_object_unref (pixbuf);
+ pixbuf = NULL;
/* !! cannot write directly to &thumb->width/height because
g_object_get() returns a gint, but thumb->width/height are
gint16 !! */
- g_object_get (G_OBJECT (pixbuf),
+ g_object_get (G_OBJECT (scaled_pixbuf),
"width", &width,
"height", &height,
NULL);
- set_thumb_padding (writer, thumb, width, height);
+ thumb_ipod = itdb_thumb_new_item_from_ipod (writer->img_info);
+ g_assert (thumb_ipod != NULL);
+
+ set_thumb_padding (writer, thumb_ipod, width, height);
/* The thumbnail width/height is inclusive padding */
- thumb->width = thumb->horizontal_padding + width;
- thumb->height = thumb->vertical_padding + height;
- thumb->offset = writer->cur_offset;
+ thumb_ipod->width = thumb_ipod->horizontal_padding + width;
+ thumb_ipod->height = thumb_ipod->vertical_padding + height;
+ thumb_ipod->offset = writer->cur_offset;
- pixels = pack_thumbnail (writer, thumb, pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
+ pixels = pack_thumbnail (writer, thumb_ipod, scaled_pixbuf);
+ g_object_unref (G_OBJECT (scaled_pixbuf));
- thumb->filename = get_ithmb_filename (writer, thumb);
- result = write_pixels (writer, thumb, pixels);
+ thumb_ipod->filename = get_ithmb_filename (writer, writer->img_info);
+ result = write_pixels (writer, thumb_ipod, pixels);
g_free (pixels);
- return result;
+ if (result == FALSE) {
+ itdb_thumb_free ((Itdb_Thumb*)thumb_ipod);
+ return NULL;
+ }
+
+ return thumb_ipod;
}
static gboolean
@@ -968,22 +988,24 @@ ithumb_writer_update (iThumbWriter *writer)
static void
-write_thumbnail (gpointer _writer, gpointer _artwork)
+write_thumbnail (iThumbWriter *writer,
+ Itdb_Artwork *artwork,
+ Itdb_Thumb_Ipod *thumb_ipod)
{
- iThumbWriter *writer = _writer;
- Itdb_Artwork *artwork = _artwork;
- Itdb_Thumb *thumb;
-
- thumb = itdb_artwork_get_thumb_by_type (artwork,
- writer->img_info->type);
+ g_assert (artwork->thumbnail->data_type != ITDB_THUMB_TYPE_IPOD);
- /* size == 0 indicates a thumbnail not yet written to the
- thumbnail file */
- if (thumb && (thumb->size == 0))
+ if (artwork->thumbnail)
{
/* check if new thumbnail file has to be started */
- if (ithumb_writer_update (writer))
- ithumb_writer_write_thumbnail (writer, thumb);
+ if (ithumb_writer_update (writer)) {
+ Itdb_Thumb_Ipod_Item *item;
+ item = ithumb_writer_write_thumbnail (writer,
+ artwork->thumbnail);
+ if (item != NULL) {
+ itdb_thumb_ipod_add (thumb_ipod, item);
+ }
+
+ }
}
}
@@ -1035,7 +1057,7 @@ ithumb_writer_new (const char *mount_point,
static gint offset_sort (gconstpointer a, gconstpointer b);
static gint offset_sort (gconstpointer a, gconstpointer b)
{
- return (-(((Itdb_Thumb *)a)->offset - ((Itdb_Thumb *)b)->offset));
+ return (-(((Itdb_Thumb_Ipod_Item *)a)->offset - ((Itdb_Thumb_Ipod_Item *)b)->offset));
}
static gboolean ithumb_rearrange_thumbnail_file (gpointer _key,
@@ -1070,7 +1092,7 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key,
/* check if all thumbnails have the same size */
for (gl=thumbs; gl; gl=gl->next)
{
- Itdb_Thumb *img = gl->data;
+ Itdb_Thumb_Ipod_Item *img = gl->data;
if (size == 0)
size = img->size;
@@ -1122,7 +1144,7 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key,
/* check each thumbnail slot */
for (offset=0; gl && (offset<statbuf.st_size); offset+=size)
{
- Itdb_Thumb *thumb = gl->data;
+ Itdb_Thumb_Ipod_Item *thumb = gl->data;
g_return_val_if_fail (thumb, FALSE);
/* Try to find a thumbnail that uses this slot */
@@ -1142,7 +1164,7 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key,
/* 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;
+ Itdb_Thumb_Ipod_Item *first_thumb = first_gl->data;
guint32 first_offset;
g_return_val_if_fail (first_thumb, FALSE);
@@ -1269,46 +1291,53 @@ ithmb_rearrange_existing_thumbnails (Itdb_DB *db,
case DB_TYPE_ITUNES:
for (gl=db_get_itunesdb(db)->tracks; gl; gl=gl->next)
{
- Itdb_Thumb *thumb;
- Itdb_Track *track = gl->data;
+ Itdb_Track *track = gl->data;
g_return_val_if_fail (track, FALSE);
-
- thumb = itdb_artwork_get_thumb_by_type (track->artwork,
- info->type);
- if (thumb && thumb->filename && (thumb->size != 0))
- {
- filename = itdb_thumb_get_filename (
+ Itdb_Thumb *thumb = track->artwork->thumbnail;
+ if (!itdb_track_has_thumbnails (track)) {
+ continue;
+ }
+ if (thumb->data_type == ITDB_THUMB_TYPE_IPOD) {
+ Itdb_Thumb_Ipod_Item *item;
+ item = itdb_thumb_ipod_get_item_by_type (thumb,
+ info);
+ if (item) {
+ filename = itdb_thumb_ipod_get_filename (
db_get_device(db),
- thumb);
+ item);
if (filename)
{
thumbs = g_hash_table_lookup (filenamehash, filename);
thumbs = g_list_append (thumbs, thumb);
g_hash_table_insert (filenamehash, filename, thumbs);
}
- }
- }
+ }
+ }
+ }
break;
case DB_TYPE_PHOTO:
for (gl=db_get_photodb(db)->photos; gl; gl=gl->next)
{
- Itdb_Thumb *thumb;
Itdb_Artwork *artwork = gl->data;
-
- thumb = itdb_artwork_get_thumb_by_type (artwork,
- info->type);
- if (thumb && thumb->filename && (thumb->size != 0))
- {
- filename = itdb_thumb_get_filename (
- db_get_device (db),
- thumb);
+ Itdb_Thumb *thumb = artwork->thumbnail;
+ if (thumb == NULL) {
+ continue;
+ }
+ if (thumb->data_type == ITDB_THUMB_TYPE_IPOD) {
+ Itdb_Thumb_Ipod_Item *item;
+ item = itdb_thumb_ipod_get_item_by_type (thumb, info);
+ if (item)
+ {
+ filename = itdb_thumb_ipod_get_filename (
+ db_get_device (db), item);
if (filename)
{
thumbs = g_hash_table_lookup (filenamehash, filename);
thumbs = g_list_append (thumbs, thumb);
g_hash_table_insert (filenamehash, filename, thumbs);
}
- }
+ }
+ }
}
break;
default:
@@ -1381,7 +1410,7 @@ itdb_write_ithumb_files (Itdb_DB *db)
while (format->type != -1) {
iThumbWriter *writer;
- if (itdb_thumb_type_is_valid_for_db (format->type, db->db_type))
+ if (itdb_thumb_type_is_valid_for_db (format, db->db_type))
{
ithmb_rearrange_existing_thumbnails (db, format );
writer = ithumb_writer_new (mount_point,
@@ -1401,21 +1430,48 @@ itdb_write_ithumb_files (Itdb_DB *db)
case DB_TYPE_ITUNES:
for (it = db_get_itunesdb(db)->tracks; it != NULL; it = it->next) {
Itdb_Track *track;
+ Itdb_Thumb_Ipod *thumb_ipod;
+ ItdbThumbDataType type;
track = it->data;
g_return_val_if_fail (track, -1);
-
- g_list_foreach (writers, write_thumbnail, track->artwork);
+ if (!itdb_track_has_thumbnails (track)) {
+ continue;
+ }
+ type = track->artwork->thumbnail->data_type;
+ if (type != ITDB_THUMB_TYPE_IPOD) {
+ GList *it;
+ thumb_ipod = (Itdb_Thumb_Ipod *)itdb_thumb_ipod_new ();
+ for (it = writers; it != NULL; it = it->next) {
+ write_thumbnail (it->data,
+ track->artwork,
+ thumb_ipod);
+ }
+ itdb_thumb_free (track->artwork->thumbnail);
+ track->artwork->thumbnail = (Itdb_Thumb *)thumb_ipod;
+ }
}
break;
case DB_TYPE_PHOTO:
for (it = db_get_photodb(db)->photos; it != NULL; it = it->next) {
Itdb_Artwork *photo;
+ Itdb_Thumb_Ipod *thumb_ipod;
+ ItdbThumbDataType type;
photo = it->data;
g_return_val_if_fail (photo, -1);
-
- g_list_foreach (writers, write_thumbnail, photo);
+ if (photo->thumbnail == NULL) {
+ continue;
+ }
+ type = photo->thumbnail->data_type;
+ if (type != ITDB_THUMB_TYPE_IPOD) {
+ thumb_ipod = (Itdb_Thumb_Ipod *)itdb_thumb_ipod_new ();
+ for (it = writers; it != NULL; it = it->next) {
+ write_thumbnail (it->data, photo, thumb_ipod);
+ }
+ itdb_thumb_free (photo->thumbnail);
+ photo->thumbnail = (Itdb_Thumb *)thumb_ipod;
+ }
}
break;
default:
diff --git a/tests/test-covers.c b/tests/test-covers.c
index 36a87fa..195f907 100644
--- a/tests/test-covers.c
+++ b/tests/test-covers.c
@@ -30,43 +30,55 @@
#include <locale.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-
+#include "itdb_thumb.h"
static void
-save_itdb_thumb (Itdb_iTunesDB *itdb, Itdb_Thumb *thumb, const char *filename)
+save_itdb_thumb (Itdb_Track *track, GdkPixbuf *pixbuf, guint id)
{
- GdkPixbuf *pixbuf;
-
- pixbuf = itdb_thumb_get_gdk_pixbuf (itdb->device, thumb);
- if (pixbuf != NULL) {
- gdk_pixbuf_save (pixbuf, filename, "png", NULL, NULL);
- gdk_pixbuf_unref (pixbuf);
-/* g_print ("Saved %s\n", filename); */
- }
+ char *filename;
+ gint width;
+ gint height;
+
+ g_object_get (G_OBJECT (pixbuf),
+ "width", &width,
+ "height", &height,
+ NULL);
+ filename = g_strdup_printf ("%03d_%s-%s-%s-%xx%x-%016"G_GINT64_MODIFIER"x.png",
+ id,
+ track->artist, track->album,
+ track->title, width, height,
+ track->dbid);
+ if (filename == NULL) {
+ return;
+ }
+ g_print (" %s\n", filename);
+ gdk_pixbuf_save (pixbuf, filename, "png", NULL, NULL);
+ gdk_pixbuf_unref (pixbuf);
+ /* g_print ("Saved %s\n", filename); */
+ g_free (filename);
}
+
static void
save_song_thumbnails (Itdb_Track *song)
{
- static gint count = 0;
- GList *it;
- for (it = song->artwork->thumbnails; it != NULL; it = it->next) {
- Itdb_Thumb *thumb;
- gchar *filename;
-
- thumb = (Itdb_Thumb *)it->data;
- g_return_if_fail (thumb);
-
- filename = g_strdup_printf ("%03d_%s-%s-%s-%d-%016"G_GINT64_MODIFIER"x.png",
- count++,
- song->artist, song->album,
- song->title, thumb->type,
- song->dbid);
- if (filename != NULL) {
- g_print (" %s\n", filename);
- save_itdb_thumb (song->itdb, thumb, filename);
- g_free (filename);
- }
+ static guint count = 0;
+ GList *it;
+ GList *thumbs;
+ Itdb_Thumb_Ipod *thumb = (Itdb_Thumb_Ipod*)song->artwork->thumbnail;
+ if (thumb == NULL) {
+ return;
+ }
+ thumbs = itdb_thumb_ipod_to_pixbufs (song->itdb->device, thumb);
+ for (it = thumbs; it != NULL; it = it->next) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = GDK_PIXBUF (it->data);
+ g_return_if_fail (pixbuf);
+
+ save_itdb_thumb (song, pixbuf, count);
+ count++;
}
+ g_list_free (thumbs);
}
diff --git a/tests/test-photos.c b/tests/test-photos.c
index af98b1c..02ecaa3 100644
--- a/tests/test-photos.c
+++ b/tests/test-photos.c
@@ -31,6 +31,8 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib/gi18n-lib.h>
+#include "itdb_thumb.h"
+
static void usage (int argc, char **argv)
{
/* gchar *name = argv[0];*/
@@ -60,40 +62,33 @@ static Itdb_Artwork *get_photo_by_id (Itdb_PhotoDB *db, guint32 id)
}
static void
-save_itdb_thumb (Itdb_PhotoDB *itdb, Itdb_Thumb *thumb,
- const gchar *filename)
-{
- GdkPixbuf *pixbuf;
-
- pixbuf = itdb_thumb_get_gdk_pixbuf (itdb->device, thumb);
-
- if (pixbuf != NULL) {
- gdk_pixbuf_save (pixbuf, filename, "png", NULL, NULL);
- gdk_pixbuf_unref (pixbuf);
- }
-}
-
-static void
dump_thumbs (Itdb_PhotoDB *db, Itdb_Artwork *artwork,
const gchar *album_name, const gchar *dir)
{
GList *it;
gint i = 0;
+ GList *thumbnails;
+ Itdb_Thumb_Ipod *thumb;
- for (it = artwork->thumbnails; it != NULL; it = it->next, i++) {
- Itdb_Thumb *thumb;
+ thumb = (Itdb_Thumb_Ipod *)artwork->thumbnail;
+ thumbnails = itdb_thumb_ipod_to_pixbufs (db->device, thumb);
+ for (it = thumbnails; it != NULL; it = it->next, i++) {
gchar *filename, *path;
+ GdkPixbuf *pixbuf;
- thumb = (Itdb_Thumb *)it->data;
- g_return_if_fail (thumb);
+ pixbuf = GDK_PIXBUF (it->data);
+
+ g_return_if_fail (pixbuf);
filename = g_strdup_printf ("%s-%d-%d.png",
album_name, artwork->id, i );
path = g_build_filename (dir, filename, NULL);
g_free (filename);
- save_itdb_thumb (db, thumb, path);
+ gdk_pixbuf_save (pixbuf, path, "png", NULL, NULL);
+ gdk_pixbuf_unref (pixbuf);
g_free (path);
}
+ g_list_free (thumbnails);
}
static void