diff options
author | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2008-01-26 08:54:48 +0000 |
---|---|---|
committer | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2008-01-26 08:54:48 +0000 |
commit | 96ffb9e31fcc6bea55e42c7fed1445d51b788bf8 (patch) | |
tree | 67f31e5a4e2b79566abd05606fc0aaa330025a62 | |
parent | 522917910980dcf4c3d07537d65949b8f6ca1483 (diff) | |
download | libgpod-tmz-96ffb9e31fcc6bea55e42c7fed1445d51b788bf8.tar.gz libgpod-tmz-96ffb9e31fcc6bea55e42c7fed1445d51b788bf8.tar.xz libgpod-tmz-96ffb9e31fcc6bea55e42c7fed1445d51b788bf8.zip |
* src/itdb_track.c
* src/itdb_itunesdb.c
* src/itdb_chapterdata
* src/itdb.h
* src/Makefile.am: applied chapterdata patch by Michael Tiffany.
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1936 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/itdb.h | 47 | ||||
-rw-r--r-- | src/itdb_itunesdb.c | 138 | ||||
-rw-r--r-- | src/itdb_track.c | 10 |
5 files changed, 164 insertions, 40 deletions
@@ -1,3 +1,11 @@ +2007-11-17 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/itdb_track.c + * src/itdb_itunesdb.c + * src/itdb_chapterdata + * src/itdb.h + * src/Makefile.am: applied chapterdata patch by Michael Tiffany. + 2008-01-02 Christophe Fergeau <teuf@gnome.org> * src/itdb_device.c: fix ITDB_THUMB_PHOTO_FULL_SCREEN format on diff --git a/src/Makefile.am b/src/Makefile.am index 0d7d58e..1e5315b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ libgpod_la_SOURCES = \ db-image-parser.c \ db-parse-context.c \ itdb_artwork.c \ + itdb_chapterdata.c \ itdb_device.c \ itdb_itunesdb.c \ itdb_photoalbum.c \ @@ -66,6 +66,8 @@ typedef struct _Itdb_PhotoDB Itdb_PhotoDB; typedef struct _Itdb_Playlist Itdb_Playlist; typedef struct _Itdb_PhotoAlbum Itdb_PhotoAlbum; typedef struct _Itdb_Track Itdb_Track; +typedef struct _Itdb_Chapter Itdb_Chapter; +typedef struct _Itdb_Chapterdata Itdb_Chapterdata; /* ------------------------------------------------------------ *\ @@ -435,6 +437,37 @@ struct _Itdb_SPLRules }; +/* ------------------------------------------------------------ *\ + * + * Chapters + * +\* ------------------------------------------------------------ */ + +struct _Itdb_Chapter +{ + guint32 startpos; + gchar *chaptertitle; /* data in UTF8 */ + /* reserved for future use */ + gint32 reserved_int1; + gint32 reserved_int2; + gpointer reserved1; + gpointer reserved2; +}; + + +struct _Itdb_Chapterdata +{ + GList *chapters; + guint32 unk024; + guint32 unk028; + guint32 unk032; + /* reserved for future use */ + gint32 reserved_int1; + gint32 reserved_int2; + gpointer reserved1; + gpointer reserved2; +}; + /* ------------------------------------------------------------ *\ * @@ -741,7 +774,7 @@ struct _Itdb_Track gchar *description; /* see note for MHOD_ID in itdb_itunesdb.c */ gchar *podcasturl; /* see note for MHOD_ID in itdb_itunesdb.c */ gchar *podcastrss; /* see note for MHOD_ID in itdb_itunesdb.c */ - gpointer chapterdata; /* not yet supported. Help welcome. */ + Itdb_Chapterdata *chapterdata; /* see note for MHOD_ID in itdb_itunesdb.c */ gchar *subtitle; /* see note for MHOD_ID in itdb_itunesdb.c */ /* the following 6 are new in libgpod 0.4.2... */ gchar *tvshow; /* see note for MHOD_ID in itdb_itunesdb.c */ @@ -1225,6 +1258,18 @@ 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); +Itdb_Chapterdata *itdb_chapterdata_duplicate (Itdb_Chapterdata *chapterdata); +void itdb_chapterdata_remove_chapter (Itdb_Chapterdata *chapterdata, Itdb_Chapter *chapter); +void itdb_chapterdata_remove_chapters (Itdb_Chapterdata *chapterdata); +Itdb_Chapter *itdb_chapter_new (void); +void itdb_chapter_free (Itdb_Chapter *chapter); +Itdb_Chapter *itdb_chapter_duplicate (Itdb_Chapter *chapter); +gboolean itdb_chapterdata_add_chapter (Itdb_Chapterdata *chapterdata, + gint32 startpos, + gchar *chaptertitle); #ifndef LIBGPOD_DISABLE_DEPRECATED /* time functions */ diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c index 42749f3..cbd4cc9 100644 --- a/src/itdb_itunesdb.c +++ b/src/itdb_itunesdb.c @@ -258,8 +258,7 @@ struct _MHODData { gint32 track_pos; gchar *string; - gchar *chapterdata_raw; - Itdb_Track *chapterdata_track; /* for writing chapterdata */ + Itdb_Chapterdata *chapterdata; Itdb_SPLPref *splpref; Itdb_SPLRules *splrules; GList *mhod52coltracks; @@ -766,7 +765,6 @@ static guint64 get64lint (FContents *cts, glong seek) Reversed Endian Sensitive (big endian) ------------------------------------------------------------ */ -#if 0 static guint16 get16bint (FContents *cts, glong seek) { g_return_val_if_fail (cts, 0); @@ -775,7 +773,7 @@ static guint16 get16bint (FContents *cts, glong seek) else return raw_get16lint (cts, seek); } -#endif + static guint32 get32bint (FContents *cts, glong seek) { g_return_val_if_fail (cts, 0); @@ -827,7 +825,7 @@ static gunichar2 *fixup_little_utf16 (gunichar2 *utf16_string) } /* Fix big endian UTF16 String to correct byteorder if necessary (only - * strings in smart playlists are big endian) */ + * strings in smart playlists and chapter data are big endian) */ static gunichar2 *fixup_big_utf16 (gunichar2 *utf16_string) { # if (G_BYTE_ORDER == G_LITTLE_ENDIAN) @@ -1419,14 +1417,52 @@ static MHODData get_mhod (FImport *fimp, glong mhod_seek, guint32 *ml) return result; /* *ml==-1, result.valid==FALSE */ } break; - case MHOD_ID_CHAPTERDATA: - /* we'll just copy the entire data section */ - xl = mhod_len - header_length; - result.data.chapterdata_raw = g_new0 (gchar, xl); - if (!seek_get_n_bytes (cts, result.data.chapterdata_raw, seek, xl)) + case MHOD_ID_CHAPTERDATA: + result.data.chapterdata = itdb_chapterdata_new(); + result.data.chapterdata->unk024 = get32lint (cts, seek); + result.data.chapterdata->unk028 = get32lint (cts, seek+4); + result.data.chapterdata->unk032 = get32lint (cts, seek+8); + seek += 12; /* get past unks */ + if (check_header_seek (cts, "sean", seek+4)) { - g_free (result.data.chapterdata_raw); - return result; /* *ml==-1, result.valid==FALSE */ + gint i; + guint32 numchapters; + numchapters = get32bint (cts, seek+12) - 1; /* minus 1 for hedr atom */ + seek += 20; /* move to atom data */ + for (i=0; i<numchapters; ++i) + { + if (check_header_seek (cts, "chap", seek+4)) + { + guint32 length; + guint32 startpos; + gunichar2 *string_utf16; + startpos = get32bint (cts, seek+8); + seek += 20; + if (check_header_seek (cts, "name", seek+4)) + { + length = get16bint (cts, seek+20); + string_utf16 = g_new0 (gunichar2, (length+1)); + if (!seek_get_n_bytes (cts, (gchar *)string_utf16, + seek+22, length*2)) + { + g_free (string_utf16); + itdb_chapterdata_free (result.data.chapterdata); + return result; /* *ml==-1, result.valid==FALSE */ + } + fixup_big_utf16 (string_utf16); + itdb_chapterdata_add_chapter(result.data.chapterdata,startpos,g_utf16_to_utf8 ( + string_utf16, -1, NULL, NULL, NULL)); + g_free (string_utf16); + seek += length * 2 + 22; + } + } + } + if (check_header_seek (cts, "hedr", seek+4)) + { + guint32 hedrlength = get32bint(cts, seek); + seek += hedrlength; + } + } break; case MHOD_ID_SPLPREF: /* Settings for smart playlist */ @@ -2406,14 +2442,10 @@ static glong get_mhit (FImport *fimp, glong mhit_seek) switch (type) { case MHOD_ID_CHAPTERDATA: - /* we just read the entire chapterdata info until we - have a better way to parse and represent it */ mhod = get_mhod (fimp, seek, &zip); - if (mhod.valid && mhod.data.chapterdata_raw) + if (mhod.valid && mhod.data.chapterdata) { - track->chapterdata_raw = mhod.data.chapterdata_raw; - track->chapterdata_raw_length = - zip - get32lint (cts, seek+4); + track->chapterdata = mhod.data.chapterdata; mhod.valid = FALSE; } break; @@ -3347,7 +3379,6 @@ static void put64lint (WContents *cts, guint64 n) /* ------------------------------------------------------------ Reversed Endian Sensitive (big endian) ------------------------------------------------------------ */ -#if 0 static void put16bint (WContents *cts, guint16 n) { if (cts->reversed) @@ -3355,7 +3386,7 @@ static void put16bint (WContents *cts, guint16 n) else raw_put16bint (cts, n); } -#endif + static void put24bint (WContents *cts, guint32 n) { if (cts->reversed) @@ -3379,6 +3410,7 @@ static void put32bfloat (WContents *cts, float f) else raw_put32bfloat (cts, f); } +#endif static void put32bint_seek (WContents *cts, guint32 n, gulong seek) { @@ -3387,7 +3419,7 @@ static void put32bint_seek (WContents *cts, guint32 n, gulong seek) else raw_put32bint_seek (cts, n, seek); } -#endif + static void put64bint (WContents *cts, guint64 n) { if (cts->reversed) @@ -3934,16 +3966,58 @@ static void mk_mhod (FExport *fexp, MHODData *mhod) put32_n0 (cts, 4); /* unknown */ break; case MHOD_ID_CHAPTERDATA: - g_return_if_fail (mhod->data.chapterdata_track); + g_return_if_fail (mhod->data.chapterdata); { - Itdb_Track *track = mhod->data.chapterdata_track; - put_header (cts, "mhod"); /* header */ - put32lint (cts, 24); /* size of header */ - put32lint (cts, 24+track->chapterdata_raw_length); /*size */ - put32lint (cts, mhod->type); /* type of the entry */ - put32_n0 (cts, 2); /* unknown */ - put_data (cts, track->chapterdata_raw, - track->chapterdata_raw_length); + gulong header_seek = cts->pos; /* needed to fix length */ + GList *gl; + gint numchapters = g_list_length (mhod->data.chapterdata->chapters); + put_header (cts, "mhod"); /* header */ + put32lint (cts, 24); /* header size */ + put32lint (cts, -1); /* total length, fix later */ + put32lint (cts, mhod->type); /* entry type */ + put32_n0 (cts, 2); /* unknown */ + put32lint (cts, mhod->data.chapterdata->unk024); /* unknown */ + put32lint (cts, mhod->data.chapterdata->unk028); /* unknown */ + put32lint (cts, mhod->data.chapterdata->unk032); /* unknown */ + put32bint (cts, -1); /* total length of sean atom, fix later */ + put_header (cts, "sean"); + put32bint (cts, 1); /* unknown */ + put32bint (cts, numchapters+1); /* children */ + put32bint (cts, 0); /* unknown */ + for (gl=mhod->data.chapterdata->chapters; gl; gl=gl->next) + { + gunichar2 *title_utf16; + Itdb_Chapter *chapter = gl->data; +/* gint len = strlen(chapter->chaptertitle); */ + glong len; + title_utf16 = NULL; + title_utf16 = g_utf8_to_utf16 (chapter->chaptertitle, + -1,NULL,&len,NULL); + fixup_big_utf16 (title_utf16); + put32bint (cts, 42+2*len); /* total length */ + put_header (cts, "chap"); + put32bint (cts, chapter->startpos); /* should we check if startpos=0 here? */ + put32bint (cts, 1); /* children */ + put32bint (cts, 0); /* unknown */ + put32bint (cts, 22+2*len); /* length */ + put_header (cts, "name"); + put32bint (cts, 1); /* unknown */ + put32_n0 (cts, 2); /* unknown */ + put16bint (cts, len); + put_data (cts, (gchar *)title_utf16, 2*len); + g_free (title_utf16); + + } + put32bint (cts, 28); /* size */ + put_header (cts, "hedr"); + put32bint (cts, 1); /* unknown */ + put32bint (cts, 0); /* children */ + put32_n0 (cts, 2); /* unknown */ + put32bint (cts, 1); /* unknown */ + + + put32bint_seek (cts, cts->pos-(header_seek+36), header_seek+36); /* fix length of sean atom */ + fix_header (cts, header_seek); } break; case MHOD_ID_SPLPREF: @@ -4427,10 +4501,10 @@ static gboolean write_mhsd_tracks (FExport *fexp) mk_mhod (fexp, &mhod); ++mhod_num; } - if (track->chapterdata_raw && track->chapterdata_raw_length) + if (track->chapterdata && track->chapterdata->chapters) { mhod.type = MHOD_ID_CHAPTERDATA; - mhod.data.chapterdata_track = track; + mhod.data.chapterdata = track->chapterdata; mk_mhod (fexp, &mhod); ++mhod_num; } diff --git a/src/itdb_track.c b/src/itdb_track.c index 976a714..470f92d 100644 --- a/src/itdb_track.c +++ b/src/itdb_track.c @@ -63,6 +63,7 @@ Itdb_Track *itdb_track_new (void) Itdb_Track *track = g_new0 (Itdb_Track, 1); track->artwork = itdb_artwork_new (); + track->chapterdata = itdb_chapterdata_new (); track->visible = 1; return track; @@ -272,7 +273,7 @@ void itdb_track_free (Itdb_Track *track) g_free (track->sort_composer); g_free (track->sort_tvshow); - g_free (track->chapterdata_raw); + itdb_chapterdata_free (track->chapterdata); itdb_artwork_free (track->artwork); @@ -372,12 +373,7 @@ Itdb_Track *itdb_track_duplicate (Itdb_Track *tr) /* Copy chapterdata */ - if (tr->chapterdata_raw) - { - tr_dup->chapterdata_raw = g_new (gchar, tr->chapterdata_raw_length); - memcpy (tr_dup->chapterdata_raw, tr->chapterdata_raw, - tr->chapterdata_raw_length); - } + tr_dup->chapterdata = itdb_chapterdata_duplicate (tr->chapterdata); /* Copy thumbnail data */ tr_dup->artwork = itdb_artwork_duplicate (tr->artwork); |