|
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.
|