summaryrefslogtreecommitdiffstats
path: root/src/db-artwork-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/db-artwork-parser.c')
-rw-r--r--src/db-artwork-parser.c99
1 files changed, 86 insertions, 13 deletions
diff --git a/src/db-artwork-parser.c b/src/db-artwork-parser.c
index 99473e8..2b05eaa 100644
--- a/src/db-artwork-parser.c
+++ b/src/db-artwork-parser.c
@@ -64,6 +64,20 @@ parse_mhif (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error)
return 0;
}
+static int
+parse_mhia (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error)
+{
+ MhiaHeader *mhia;
+
+ mhia = db_parse_context_get_m_header (ctx, MhiaHeader, "mhia");
+ if (mhia == NULL) {
+ return -1;
+ }
+ dump_mhia (mhia);
+ db_parse_context_set_total_len (ctx, GINT_FROM_LE (mhia->total_len));
+ return 0;
+}
+
#ifdef DEBUG_ARTWORKDB
static int
parse_mhod_3 (DBParseContext *ctx, GError *error)
@@ -81,11 +95,11 @@ parse_mhod_3 (DBParseContext *ctx, GError *error)
return -1;
}
mhod3 = (MhodHeaderArtworkType3*)mhod;
- dump_mhod_type_3 (mhod3);
- if ((GINT_FROM_LE (mhod3->type) & 0xff) != MHOD_TYPE_ALBUM) {
+ if ((GINT_FROM_LE (mhod3->type) & 0x00FFFFFF) != MHOD_ARTWORK_TYPE_FILE_NAME) {
return -1;
}
+ dump_mhod_type_3 (mhod3);
return 0;
}
#endif
@@ -111,6 +125,9 @@ parse_mhni (DBParseContext *ctx, iPodSong *song, GError *error)
/* No information useful to us in mhod type 3, do not parse
* it in non-debug mode
+ * FIXME: really? it contains the thumbnail file name!
+ * we infer it from the correlation id, but is this
+ * always The Right Thing to do?
*/
mhod_ctx = db_parse_context_get_sub_context (ctx, ctx->header_len);
if (mhod_ctx == NULL) {
@@ -133,24 +150,35 @@ parse_mhod (DBParseContext *ctx, iPodSong *song, GError *error)
{
MhodHeader *mhod;
DBParseContext *mhni_ctx;
+ int type;
mhod = db_parse_context_get_m_header (ctx, MhodHeader, "mhod");
if (mhod == NULL) {
return -1;
}
db_parse_context_set_total_len (ctx, GINT_FROM_LE (mhod->total_len));
- dump_mhod (mhod);
- if (GINT_FROM_LE (mhod->type) != MHOD_TYPE_LOCATION) {
- return -1;
- }
-
- mhni_ctx = db_parse_context_get_sub_context (ctx, ctx->header_len);
- if (mhni_ctx == NULL) {
- return -1;
+ /* The MHODs found in the ArtworkDB and Photo Database files are
+ * significantly different than those found in the iTunesDB.
+ * For example, the "type" is split like this:
+ * - low 3 bytes are actual type;
+ * - high byte is padding length of string (0-3).
+ */
+ type = GINT_FROM_LE (mhod->type) & 0x00FFFFFF;
+ if (type == MHOD_ARTWORK_TYPE_ALBUM_NAME)
+ dump_mhod_type_1 ((MhodHeaderArtworkType1 *)mhod);
+ else
+ dump_mhod (mhod);
+
+ /* if this is a container... */
+ if (type == MHOD_ARTWORK_TYPE_THUMBNAIL) {
+ mhni_ctx = db_parse_context_get_sub_context (ctx, ctx->header_len);
+ if (mhni_ctx == NULL) {
+ return -1;
+ }
+ parse_mhni (mhni_ctx, song, NULL);
+ g_free (mhni_ctx);
}
- parse_mhni (mhni_ctx, song, NULL);
- g_free (mhni_ctx);
return 0;
}
@@ -205,6 +233,47 @@ parse_mhii (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error)
static int
+parse_mhba (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error)
+{
+ MhbaHeader *mhba;
+ DBParseContext *mhod_ctx;
+ DBParseContext *mhia_ctx;
+ int num_children;
+ off_t cur_offset;
+
+ mhba = db_parse_context_get_m_header (ctx, MhbaHeader, "mhba");
+ if (mhba == NULL) {
+ return -1;
+ }
+ db_parse_context_set_total_len (ctx, GINT_FROM_LE (mhba->total_len));
+
+ dump_mhba (mhba);
+
+ cur_offset = ctx->header_len;
+ mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset);
+ num_children = GINT_FROM_LE (mhba->num_mhods);
+ while ((num_children > 0) && (mhod_ctx != NULL)) {
+ parse_mhod (mhod_ctx, NULL, NULL);
+ num_children--;
+ cur_offset += mhod_ctx->total_len;
+ g_free (mhod_ctx);
+ mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset);
+ }
+ mhia_ctx = db_parse_context_get_sub_context (ctx, cur_offset);
+ num_children = GINT_FROM_LE (mhba->num_mhias);
+ while ((num_children > 0) && (mhia_ctx != NULL)) {
+ parse_mhia (mhia_ctx, db, NULL);
+ num_children--;
+ cur_offset += mhia_ctx->total_len;
+ g_free (mhia_ctx);
+ mhia_ctx = db_parse_context_get_sub_context (ctx, cur_offset);
+ }
+
+ return 0;
+}
+
+
+static int
parse_mhl (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error,
const char *id, ParseListItem parse_child)
{
@@ -265,7 +334,7 @@ parse_mhsd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error)
case MHSD_ALBUM_LIST: {
DBParseContext *mhla_context;
mhla_context = db_parse_context_get_next_child (ctx);
- parse_mhl (mhla_context, db, NULL, "mhla", NULL);
+ parse_mhl (mhla_context, db, NULL, "mhla", parse_mhba);
g_free (mhla_context);
break;
}
@@ -304,6 +373,10 @@ parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error)
dump_mhfd (mhfd);
cur_pos = ctx->header_len;
+ /* The mhfd record always has 3 mhsd children, so it's hardcoded here.
+ * It could be replaced with a loop using the nb_children field from
+ * the mhfd record. [explanation by Christophe]
+ */
mhsd_context = db_parse_context_get_sub_context (ctx, cur_pos);
if (mhsd_context == NULL) {
return -1;