From: <ny...@us...> - 2007-10-05 17:13:18
|
Revision: 421 http://pmplib.svn.sourceforge.net/pmplib/?rev=421&view=rev Author: nyaochi Date: 2007-10-05 10:13:21 -0700 (Fri, 05 Oct 2007) Log Message: ----------- pmp_ipod now dumps ArtworkDB content. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/artworkdb.c trunk/pmplib/lib/pmp_ipod/artworkdb.h trunk/pmplib/lib/pmp_ipod/chunk.c trunk/pmplib/lib/pmp_ipod/chunk.h trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/pmp_ipod.c Modified: trunk/pmplib/lib/pmp_ipod/artworkdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-05 17:13:21 UTC (rev 421) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -37,16 +37,17 @@ #include "ipod.h" #include "serialize.h" #include "util.h" +#include "chunk.h" #include "artworkdb.h" -static void chunk_finish(artworkdb_chunk_t* chunk) +static void chunk_finish(itunes_chunk_t* chunk) { free(chunk->data); free(chunk->padding); memset(chunk, 0, sizeof(*chunk)); } -static int mhfd_init(artworkdb_chunk_t* chunk, int def) +static int mhfd_init(itunes_chunk_t* chunk, int def) { artworkdb_mhfd_t* mhfd = NULL; @@ -64,19 +65,18 @@ mhfd->num_children = 0; /* to be filled */ mhfd->unknown3 = 0; mhfd->next_nhii = 0; - mhfd->unknown5 = 0; - mhfd->unknown6 = 0; + mhfd->unknown5 = 0x0E777BDE5D06AD9B; + mhfd->unknown6 = 0x368B84B5E61BC6ED; mhfd->unknown7 = 2; mhfd->unknown8 = 0; mhfd->unknown9 = 0; - mhfd->unknown10 = 0; - mhfd->unknown11 = 0; + mhfd->unknown10 = 0x15C516AB8F8EB3A4; } chunk->data = mhfd; return mhfd ? 0 : IPODE_OUTOFMEMORY; } -static int mhfd_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhfd_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhfd_t* mhfd = (artworkdb_mhfd_t*)chunk->data; @@ -91,15 +91,14 @@ if (ret = serialize_uint32le(sio, "unknown7", "%d", &mhfd->unknown7)) return ret; if (ret = serialize_uint32le(sio, "unknown8", "%d", &mhfd->unknown8)) return ret; if (ret = serialize_uint32le(sio, "unknown9", "%d", &mhfd->unknown9)) return ret; - if (ret = serialize_uint32le(sio, "unknown10", "%d", &mhfd->unknown10)) return ret; - if (ret = serialize_uint32le(sio, "unknown11", "%d", &mhfd->unknown10)) return ret; + if (ret = serialize_uint64le(sio, "unknown10", "%016llX", &mhfd->unknown10)) return ret; return 0; } -static mhsd_init(artworkdb_chunk_t* chunk, int def) +static mhsd_init(itunes_chunk_t* chunk, int def) { artworkdb_mhsd_t* mhsd = NULL; @@ -119,7 +118,7 @@ return mhsd ? 0 : IPODE_OUTOFMEMORY; } -static int mhsd_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhsd_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhsd_t* mhsd = (artworkdb_mhsd_t*)chunk->data; @@ -131,12 +130,12 @@ -static mhli_init(artworkdb_chunk_t* chunk, int def) +static mhli_init(itunes_chunk_t* chunk, int def) { if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhli", 4); - chunk->size = 96; + chunk->size = 92; chunk->overall_size = 0; /* to be filled */ } @@ -144,21 +143,21 @@ return 0; } -static int mhli_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhli_serialize(itunes_chunk_t* chunk, serializer_t* sio) { return 0; } -static int mhii_init(artworkdb_chunk_t* chunk, int def) +static int mhii_init(itunes_chunk_t* chunk, int def) { artworkdb_mhii_t* mhii = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhii", 4); - chunk->size = 104; + chunk->size = 152; chunk->overall_size = 0; /* to be filled */ } @@ -178,7 +177,7 @@ return mhii ? 0 : IPODE_OUTOFMEMORY; } -static int mhii_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhii_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhii_t* mhii = (artworkdb_mhii_t*)chunk->data; @@ -192,19 +191,22 @@ if (ret = serialize_uint32le(sio, "ts_file", "%d", &mhii->ts_file)) return ret; if (ret = serialize_uint32le(sio, "ts_import", "%d", &mhii->ts_import)) return ret; if (ret = serialize_uint32le(sio, "original_size", "%d", &mhii->original_size)) return ret; + if (ret = serialize_uint32le(sio, "unknown10", "%d", &mhii->unknown10)) return ret; + if (ret = serialize_uint32le(sio, "unknown11", "%d", &mhii->unknown11)) return ret; + if (ret = serialize_uint32le(sio, "unknown12", "%d", &mhii->unknown12)) return ret; return 0; } -static int mhni_init(artworkdb_chunk_t* chunk, int def) +static int mhni_init(itunes_chunk_t* chunk, int def) { artworkdb_mhni_t* mhni = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhni", 4); - chunk->size = 104; + chunk->size = 76; chunk->overall_size = 0; /* to be filled */ } @@ -223,7 +225,7 @@ return mhni ? 0 : IPODE_OUTOFMEMORY; } -static int mhni_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhni_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhni_t* mhni = (artworkdb_mhni_t*)chunk->data; @@ -244,14 +246,14 @@ -static int mhba_init(artworkdb_chunk_t* chunk, int def) +static int mhba_init(itunes_chunk_t* chunk, int def) { artworkdb_mhba_t* mhba = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhba", 4); - chunk->size = 104; + chunk->size = 104; /* ??? */ chunk->overall_size = 0; /* to be filled */ } @@ -262,7 +264,7 @@ return mhba ? 0 : IPODE_OUTOFMEMORY; } -static int mhba_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhba_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhba_t* mhba = (artworkdb_mhba_t*)chunk->data; @@ -289,15 +291,35 @@ } +static mhla_init(itunes_chunk_t* chunk, int def) +{ + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhla", 4); + chunk->size = 92; + chunk->overall_size = 0; /* to be filled */ + } -static mhia_init(artworkdb_chunk_t* chunk, int def) + chunk->data = 0; + return 0; +} + +static int mhla_serialize(itunes_chunk_t* chunk, serializer_t* sio) { + return 0; +} + + + + +static mhia_init(itunes_chunk_t* chunk, int def) +{ artworkdb_mhia_t* mhia = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhia", 4); - chunk->size = 96; + chunk->size = 96; /* ??? */ chunk->overall_size = 0; /* to be filled */ } @@ -309,7 +331,7 @@ return mhia ? 0 : IPODE_OUTOFMEMORY; } -static int mhia_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhia_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhia_t* mhia = (artworkdb_mhia_t*)chunk->data; @@ -322,12 +344,12 @@ -static mhlf_init(artworkdb_chunk_t* chunk, int def) +static mhlf_init(itunes_chunk_t* chunk, int def) { if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlf", 4); - chunk->size = 96; + chunk->size = 92; chunk->overall_size = 0; /* to be filled */ } @@ -335,21 +357,21 @@ return 0; } -static int mhlf_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhlf_serialize(itunes_chunk_t* chunk, serializer_t* sio) { return 0; } -static mhif_init(artworkdb_chunk_t* chunk, int def) +static mhif_init(itunes_chunk_t* chunk, int def) { artworkdb_mhif_t* mhif = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhif", 4); - chunk->size = 96; + chunk->size = 124; chunk->overall_size = 0; /* to be filled */ } @@ -361,7 +383,7 @@ return mhif ? 0 : IPODE_OUTOFMEMORY; } -static int mhif_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhif_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhif_t* mhif = (artworkdb_mhif_t*)chunk->data; @@ -373,3 +395,140 @@ return 0; } +static void mhod_container_finish(itunes_chunk_t* chunk) +{ + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + memset(mhod, 0, sizeof(*mhod)); +} + +static int mhod_container_serialize(itunes_chunk_t* chunk, const char *name, serializer_t* sio) +{ + return 0; +} + +static void mhod_string_finish(itunes_chunk_t* chunk) +{ + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + artworkdb_mhod_string_t* string = &mhod->data.str; + ucs2free(string->ucs2); + ucs2free(string->utf8); + memset(string, 0, sizeof(*string)); +} + +static int mhod_string_serialize(itunes_chunk_t* chunk, const char *name, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhod_string_t* string = &((artworkdb_mhod_t*)chunk->data)->data.str; + + if (ret = serialize_uint32le(sio, "size", "%u", &string->size)) return ret; + if (ret = serialize_uint32le(sio, "encoding", "%u", &string->encoding)) return ret; + if (ret = serialize_uint32le(sio, "unknown", "%u", &string->unknown)) return ret; + if (string->encoding == 2) { + if (ret = serialize_ucs2lestr_fixed(sio, name, "%s", &string->ucs2, string->size / sizeof(ucs2char_t))) return ret; + } else { + if (ret = serialize_utf8str_fixed(sio, name, "%s", &string->utf8, string->size)) return ret; + } + + return 0; +} + +static const artworkdb_mhoddecl_t mds[] = { + {1, "album", 0, mhod_string_finish, mhod_string_serialize}, + {2, "thumbnail", 1, mhod_container_finish, mhod_container_serialize}, + {3, "filename", 0, mhod_string_finish, mhod_string_serialize}, + {5, "fullsize", 1, mhod_container_finish, mhod_container_serialize}, + {0, NULL, 0, NULL}, +}; + +static const artworkdb_mhoddecl_t* find_mhoddecl(itunes_chunk_t* chunk) +{ + const artworkdb_mhoddecl_t* decl = mds; + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + + while (decl->name) { + if (decl->type == mhod->type) { + return decl; + } + ++decl; + } + return NULL; +} + +static const artworkdb_mhoddecl_t* find_mhoddecl_by_name(const char *name) +{ + const artworkdb_mhoddecl_t* decl = mds; + + while (decl->name) { + if (strcmp(decl->name, name) == 0) { + return decl; + } + ++decl; + } + return NULL; +} + +static int mhod_init(itunes_chunk_t* chunk, int def) +{ + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhod", 4); + chunk->size = 24; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(artworkdb_mhod_t)); + return chunk->data ? 0 : IPODE_OUTOFMEMORY; +} + +static void mhod_finish(itunes_chunk_t* chunk) +{ + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + const artworkdb_mhoddecl_t* decl = NULL; + decl = find_mhoddecl(chunk); + if (decl) { + decl->finish(chunk); + } + chunk_finish(chunk); +} + +static int mhod_serialize(itunes_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + const artworkdb_mhoddecl_t* decl = NULL; + + if (ret = serialize_uint16le(sio, "type", "%u", &mhod->type)) return ret; + if (ret = serialize_uint8(sio, "unknown1", "%u", &mhod->unknown1)) return ret; + if (ret = serialize_uint8(sio, "padding_length", "%u", &mhod->padding_length)) return ret; + if (ret = serialize_uint32le(sio, "unknown2", "%u", &mhod->unknown2)) return ret; + if (ret = serialize_uint32le(sio, "unknown3", "%u", &mhod->unknown2)) return ret; + + decl = find_mhoddecl(chunk); + if (decl) { + if (ret = decl->serialize(chunk, decl->name, sio)) return ret; + if (!decl->is_container) chunk->size = chunk->overall_size; + } else { + if (serialize_dumping(sio)) { + serialize_indent(sio); + fprintf(sio->fp, "!unknown_mhod_type!\n"); + } + chunk->size = chunk->overall_size; + } + + return 0; +} + +const itunes_chunkdecl_t artworkdb_cds[] = { + {"mhfd", 0, mhfd_init, chunk_finish, mhfd_serialize}, + {"mhsd", 0, mhsd_init, chunk_finish, mhsd_serialize}, + {"mhli", 1, mhli_init, chunk_finish, mhli_serialize}, + {"mhii", 0, mhii_init, chunk_finish, mhii_serialize}, + {"mhni", 0, mhni_init, chunk_finish, mhni_serialize}, + {"mhba", 0, mhba_init, chunk_finish, mhba_serialize}, + {"mhla", 1, mhla_init, chunk_finish, mhla_serialize}, + {"mhia", 0, mhia_init, chunk_finish, mhia_serialize}, + {"mhlf", 1, mhlf_init, chunk_finish, mhlf_serialize}, + {"mhif", 0, mhif_init, chunk_finish, mhif_serialize}, + {"mhod", 0, mhod_init, mhod_finish, mhod_serialize}, + {NULL, 0, NULL, NULL, NULL}, +}; + Modified: trunk/pmplib/lib/pmp_ipod/artworkdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-05 17:13:21 UTC (rev 421) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __ARTWORKDB_H__ #define __ARTWORKDB_H__ @@ -35,8 +35,7 @@ uint32_t unknown7; /* always set to 2. */ uint32_t unknown8; /* always set to 0. */ uint32_t unknown9; /* always set to 0. */ - uint32_t unknown10; - uint32_t unknown11; + uint64_t unknown10; } artworkdb_mhfd_t; typedef struct { @@ -57,6 +56,9 @@ uint32_t ts_file; uint32_t ts_import; uint32_t original_size; + uint32_t unknown10; + uint32_t unknown11; + uint32_t unknown12; } artworkdb_mhii_t; typedef struct { @@ -104,80 +106,38 @@ } artworkdb_mhif_t; typedef struct { - uint32_t length; + uint32_t size; uint32_t encoding; uint32_t unknown; - ucs2char_t* value; -} artworkdb_mhod_ucs2string_t; + ucs2char_t* ucs2; + char* utf8; +} artworkdb_mhod_string_t; typedef struct { - uint32_t length; - uint32_t encoding; - uint32_t unknown; - char* value; -} artworkdb_mhod_utf8string_t; - -typedef struct { uint16_t type; - uint16_t unk1; + uint8_t unknown1; + uint8_t padding_length; + uint32_t unknown2; + uint32_t unknown3; union { - artworkdb_mhod_ucs2string_t ucs2str; - artworkdb_mhod_utf8string_t ucs8str; + artworkdb_mhod_string_t str; } data; } artworkdb_mhod_t; -struct tag_artworkdb_chunk { - int8_t id[4]; - uint32_t size; - uint32_t overall_size; - - void* data; - - uint32_t num_children; /* This field does not exist in the actual database. */ - struct tag_artworkdb_chunk* childlen; - - int32_t padding_size; - uint8_t* padding; - - uint32_t offset; /* This field does not exist in the actual database. */ -}; - -typedef struct tag_artworkdb_chunk artworkdb_chunk_t; - typedef struct { uint32_t type; const char* name; - uint32_t overall_size; - void (*finish)(artworkdb_chunk_t* chunk); - int (*serialize)(artworkdb_chunk_t* chunk, const char *name, serializer_t* sio); -} albumartdb_mhoddecl_t; + int is_container; + void (*finish)(itunes_chunk_t* chunk); + int (*serialize)(itunes_chunk_t* chunk, const char *name, serializer_t* sio); +} artworkdb_mhoddecl_t; -typedef struct { - const char* name; - int (*init)(artworkdb_chunk_t* chunk, int dataonly); - void (*finish)(artworkdb_chunk_t* chunk); - int (*serialize)(artworkdb_chunk_t* chunk, serializer_t* sio); -} albumartdb_chunkdecl_t; +int albumartdb_set_mhod_ucs2string(itunes_chunk_t* chunk, const ucs2char_t* str); +int albumartdb_get_mhod_ucs2string(itunes_chunk_t* chunk, ucs2char_t** str); +int albumartdb_set_mhod_utf8string(itunes_chunk_t* chunk, const char* str); +int albumartdb_get_mhod_utf8string(itunes_chunk_t* chunk, char** str); -int albumartdb_init(artworkdb_chunk_t* chunk, const char *identifer, const char *subtype); +extern const itunes_chunkdecl_t artworkdb_cds[]; -int albumartdb_ischunk(artworkdb_chunk_t* chunk, const char *name, const char *subtype); - -artworkdb_chunk_t* albumartdb_new_child(artworkdb_chunk_t* chunk); - -void albumartdb_finish(artworkdb_chunk_t* chunk); - -int albumartdb_set_mhod_ucs2string(artworkdb_chunk_t* chunk, const ucs2char_t* str); - -int albumartdb_get_mhod_ucs2string(artworkdb_chunk_t* chunk, ucs2char_t** str); - -int albumartdb_set_mhod_utf8string(artworkdb_chunk_t* chunk, const char* str); - -int albumartdb_get_mhod_utf8string(artworkdb_chunk_t* chunk, char** str); - -int albumartdb_repr(artworkdb_chunk_t* chunk, size_t index, serializer_t* sio); -int albumartdb_read(artworkdb_chunk_t* chunk, serializer_t* sio); -int albumartdb_write(artworkdb_chunk_t* chunk, serializer_t* sio); - #endif/*__ARTWORKDB_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/chunk.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-05 17:13:21 UTC (rev 421) @@ -222,13 +222,13 @@ } /* Determine the size of padded data for this chunk. */ - if (strncmp(chunk->id, "mhod", 4) == 0) { - next = begin + chunk->overall_size; - chunk->padding_size = next - serialize_tell(sio); - } else { + //if (strncmp(chunk->id, "mhod", 4) == 0) { + // next = begin + chunk->overall_size; + // chunk->padding_size = next - serialize_tell(sio); + //} else { next = begin + chunk->size; chunk->padding_size = next - serialize_tell(sio); - } + //} /* Read the padded data. */ if (0 < chunk->padding_size) { @@ -251,8 +251,8 @@ } /* Read children for this chunk. */ - if (strncmp(chunk->id, "mhla", 4) == 0 || strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { - /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ + if (decl && decl->overall_size_is_num_children) { + /* chunk->overall_size represents the number of children. */ chunk->num_children = chunk->overall_size; chunk->childlen = (itunes_chunk_t*)calloc(chunk->num_children, sizeof(itunes_chunk_t)); for (i = 0;i < chunk->num_children;++i) { @@ -309,8 +309,8 @@ } /* Calculate chunk->overall_size. */ - if (strncmp(chunk->id, "mhla", 4) == 0 || strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { - /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ + if (decl && decl->overall_size_is_num_children) { + /* chunk->overall_size represents the number of children. */ chunk->overall_size = chunk->num_children; } else { /* chunk->overall_size represents the size in bytes of this chunk */ Modified: trunk/pmplib/lib/pmp_ipod/chunk.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-05 17:13:21 UTC (rev 421) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __CHUNK_H__ #define __CHUNK_H__ @@ -41,6 +41,7 @@ typedef struct { const char* name; + int overall_size_is_num_children; int (*init)(itunes_chunk_t* chunk, int dataonly); void (*finish)(itunes_chunk_t* chunk); int (*serialize)(itunes_chunk_t* chunk, serializer_t* sio); Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-05 17:13:21 UTC (rev 421) @@ -43,6 +43,7 @@ #include "ipodserial.h" #include "chunk.h" #include "itunesdb.h" +#include "artworkdb.h" #include "playcounts.h" #define COMP(a, b) ((a)>(b))-((a)<(b)) @@ -52,6 +53,7 @@ "apple_ipod", "Apple", "iPod", "UM", "---", "---", "iPod_Control\\iTunes\\iTunesDB", + "iPod_Control\\Artwork\\ArtworkDB", "iPod_Control\\iTunes\\Play Counts", ".mp3\0.m4a\0", {PMPCODEC_MPEGLAYER3, PMPCODEC_MPEG4AUDIO, 0, 0, 0, 0, 0, 0}, @@ -63,6 +65,7 @@ NULL, NULL, NULL, + NULL, {0, 0, 0, 0, 0, 0, 0, 0}, NULL, NULL, NULL, }, @@ -167,6 +170,10 @@ if (!ipod->itunesdb) { return IPODE_OUTOFMEMORY; } + ipod->artworkdb = (itunes_chunk_t*)calloc(1, sizeof(itunes_chunk_t)); + if (!ipod->artworkdb) { + return IPODE_OUTOFMEMORY; + } ipod->pcs = (playcounts_t*)calloc(1, sizeof(playcounts_t)); if (!ipod->pcs) { return IPODE_OUTOFMEMORY; @@ -178,11 +185,12 @@ { playcounts_finish(ipod->pcs); itunesdb_finish(itunesdb_cds, ipod->itunesdb); + itunesdb_finish(artworkdb_cds, ipod->artworkdb); free(ipod->pcs); free(ipod->itunesdb); } -int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts) +int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts) { int ret = 0; FILE *fp = NULL; @@ -211,6 +219,30 @@ return (IPODC_ITUNESDB|IPODE_FILEOPENFORREAD); } + /* Read ArtworkDB. */ + fp = ucs2fopen(artworkdb, "rb"); + if (fp) { + serializer_t sio; + uint8_t* buffer = NULL; + long size = 0; + + ret = fread_all(fp, &buffer, &size); + if (IPODFAILED(ret)) { + return (IPODC_ITUNESDB|ret); + } + fclose(fp); + + serialize_init_read(&sio, buffer, (size_t)size); + ret = itunesdb_read(artworkdb_cds, ipod->artworkdb, &sio); + if (IPODFAILED(ret)) { + return (IPODC_ITUNESDB|ret); + } + serialize_finish(&sio); + free(buffer); + } else { + return (IPODC_ITUNESDB|IPODE_FILEOPENFORREAD); + } + /* Read "Play Counts". Don't care if this file does not exist. */ fp = ucs2fopen(playcounts, "rb"); if (fp) { @@ -237,7 +269,7 @@ return 0; } -int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts) +int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts) { int ret = 0; FILE *fp = NULL; @@ -264,6 +296,24 @@ serialize_finish(&sio); + serialize_init_write(&sio, 0x10000); + ret = itunesdb_write(artworkdb_cds, ipod->artworkdb, &sio); + if (IPODFAILED(ret)) { + return (IPODC_ITUNESDB|ret); + } + + fp = ucs2fopen(artworkdb, "wb"); + if (fp) { + if (fwrite(sio.base, 1, sio.offset, fp) != sio.offset) { + return (IPODC_ITUNESDB|IPODE_FILEWRITEERROR); + } + fclose(fp); + } else { + ret = (IPODC_ITUNESDB|IPODE_FILEOPENFORWRITE); + } + + serialize_finish(&sio); + /* Remove "Play Counts" file, which is always created by the player. */ filepath_removefile(playcounts); @@ -279,6 +329,10 @@ itunesdb_repr(itunesdb_cds, ipod->itunesdb, 0, &sio); fprintf(fpo, "\n"); + fprintf(fpo, "[ArtworkDB]\n"); + itunesdb_repr(artworkdb_cds, ipod->artworkdb, 0, &sio); + fprintf(fpo, "\n"); + fprintf(fpo, "[Play Counts]\n"); playcounts_serialize(ipod->pcs, &sio); fprintf(fpo, "\n"); Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-10-05 17:13:21 UTC (rev 421) @@ -34,6 +34,7 @@ const char *min_version; const char *max_version; const char *itunesdb_filename; + const char *artworkdb_filename; const char *playcounts_filename; const char *extensions; uint32_t codecs[8]; @@ -50,6 +51,7 @@ typedef struct { itunes_chunk_t* itunesdb; + itunes_chunk_t* artworkdb; playcounts_t* pcs; uint8_t serial[8]; } ipod_t; @@ -59,8 +61,8 @@ int ipod_init(ipod_t* ipod); void ipod_finish(ipod_t* ipod); -int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts); -int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts); +int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts); +int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts); int ipod_dump(ipod_t* ipod, FILE *fpo); int ipod_set( ipod_t* ipod, Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-10-05 17:13:21 UTC (rev 421) @@ -772,21 +772,24 @@ } } + /* The size field in "MHOD" chunk is always 24. */ + chunk->size = chunk->overall_size; + return 0; } const itunes_chunkdecl_t itunesdb_cds[] = { - {"mhbd", mhbd_init, chunk_finish, mhbd_serialize}, - {"mhsd", mhsd_init, chunk_finish, mhsd_serialize}, - {"mhla", mhla_init, chunk_finish, mhla_serialize}, - {"mhia", mhia_init, chunk_finish, mhia_serialize}, - {"mhlt", mhlt_init, chunk_finish, mhlt_serialize}, - {"mhit", mhit_init, chunk_finish, mhit_serialize}, - {"mhlp", mhlp_init, chunk_finish, mhlp_serialize}, - {"mhyp", mhyp_init, chunk_finish, mhyp_serialize}, - {"mhip", mhip_init, chunk_finish, mhip_serialize}, - {"mhod", mhod_init, mhod_finish, mhod_serialize}, - {NULL, NULL, NULL, NULL}, + {"mhbd", 0, mhbd_init, chunk_finish, mhbd_serialize}, + {"mhsd", 0, mhsd_init, chunk_finish, mhsd_serialize}, + {"mhla", 1, mhla_init, chunk_finish, mhla_serialize}, + {"mhia", 0, mhia_init, chunk_finish, mhia_serialize}, + {"mhlt", 1, mhlt_init, chunk_finish, mhlt_serialize}, + {"mhit", 0, mhit_init, chunk_finish, mhit_serialize}, + {"mhlp", 1, mhlp_init, chunk_finish, mhlp_serialize}, + {"mhyp", 0, mhyp_init, chunk_finish, mhyp_serialize}, + {"mhip", 0, mhip_init, chunk_finish, mhip_serialize}, + {"mhod", 0, mhod_init, mhod_finish, mhod_serialize}, + {NULL, 0, NULL, NULL, NULL}, }; int itunesdb_mhod_init( Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-10-05 17:13:21 UTC (rev 421) @@ -145,7 +145,7 @@ memset(info, 0, sizeof(*info)); } -static void set_filenames(ucs2char_t *itunesdb, ucs2char_t* playcounts, pmp_t *pmp) +static void set_filenames(ucs2char_t *itunesdb, ucs2char_t *artworkdb, ucs2char_t* playcounts, pmp_t *pmp) { ucs2char_t* ucs2 = NULL; pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; @@ -157,6 +157,13 @@ ucs2cat(itunesdb, ucs2); ucs2free(ucs2); } + if (artworkdb) { + ucs2cpy(artworkdb, pmp->info.path_to_root); + filepath_addslash(artworkdb); + ucs2 = mbsdupucs2(pmpi->decl->artworkdb_filename); + ucs2cat(artworkdb, ucs2); + ucs2free(ucs2); + } if (playcounts) { ucs2cpy(playcounts, pmp->info.path_to_root); filepath_addslash(playcounts); @@ -331,18 +338,18 @@ result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; - ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, playcounts, music->pmp); + set_filenames(itunesdb, artworkdb, playcounts, music->pmp); if (pmp->flag & (PMPOF_MUSIC_DB_READ|PMPOF_MUSIC_PL_READ)) { int num_records = 0, num_playlists = 0; - ipod_read(&ipod, itunesdb, playcounts); + ipod_read(&ipod, itunesdb, artworkdb, playcounts); ipod_get(&ipod, NULL, &num_records, NULL, &num_playlists, pmp->info.path_to_root); // Allocate records. @@ -393,17 +400,17 @@ result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; - ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, playcounts, music->pmp); + set_filenames(itunesdb, artworkdb, playcounts, music->pmp); if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { ipod_set(&ipod, pmpmi->records, pmpmi->num_records, pmpmi->playlists, pmpmi->num_playlists, pmp->info.path_to_root); - ipod_write(&ipod, itunesdb, playcounts); + ipod_write(&ipod, itunesdb, artworkdb, playcounts); } exit_this: @@ -447,14 +454,14 @@ { ipod_t ipod; result_t ret = 0; - ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize IP3DB. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, playcounts, music->pmp); - ret = ipod_read(&ipod, itunesdb, playcounts); + set_filenames(itunesdb, artworkdb, playcounts, music->pmp); + ret = ipod_read(&ipod, itunesdb, artworkdb, playcounts); if (ret) { goto exit_this; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |