diff options
author | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2006-05-30 14:09:44 +0000 |
---|---|---|
committer | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2006-05-30 14:09:44 +0000 |
commit | 355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17 (patch) | |
tree | 64cc40dc42c33925c6183222667354276479c362 | |
parent | 58503e6e5b6ef315f37fe859baaf0f5216fc8f5c (diff) | |
download | libgpod-tmz-355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17.tar.gz libgpod-tmz-355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17.tar.xz libgpod-tmz-355d9e38ac7d87b345e70d8d9a7ee78a30ba8c17.zip |
***** merged photo-support branch back to MAIN. branch is tagged
photo-support-merged_00
ipod.py will need minor patching (flag2, flag3).
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1292 f01d2545-417e-4e96-918e-98f8d0dbbcb6
39 files changed, 3188 insertions, 902 deletions
@@ -1,11 +1,217 @@ +2006-05-30 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/itdb_itunesdb.c (itdb_create_directories): applied + Christophe's cleanup-patch, 'normalized' indenting. Function + made 'static'. + + * src/itdb_itunesdb.c (itdb_init_ipod): fixed segfault. + + * m4/python: default configure option --with_python to 'yes' + (Nicholas Piper) + + ***** merged photo-support branch back to MAIN. branch is tagged + photo-support-merged_00 + +2006-05-29 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * tests/test-photos.c: removed unneeded #include. + + * configure.ac: print configuration summary -- thanks to Todd + Zullinger + + * itdb.h: + itdb_itunesdb.c: + added itdb_init_ipod() -- thanks to P.G. Richardson. + + * src/itdb_itunesdb.c (itdb_write_file): only write artwork if + supported by the iPod -- thanks to P.G. Richardson. + + * src/itdb_itunesdb.c: + src/itdb_photoalbum.c: + src/itdb_playlist.c: + + fixed some comments so the doc subsystem won't complain. + + * tests/Makefile.am: + tests/test-init-ipod.c + + added new test for itdb_init_ipod(). The test also demonstrates + how to 'autodetect' the iPod model number. + + * src/itdb_photoalbum.c: + src/ithumb-writer.c: + src/itdb_artwork.c: + src/itdb.h: + src/db-itunes-parser.h: + src/db-artwork-writer.c: + src/db-artwork-parser.c: + src/db-artwork-debug.c: + + Patch by Michael McLellan: + + Doesn't automatically make the first photoalbum the + 'master'. However, if a master already exists it will remain the + master. + + Sets the creation date of a new image to the modification time + of the image file. + + Centers new images. + + Introduces itdb_photodb_remove_photo(). + + +2006-05-29 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/itdb.h: + src/itunesdb.c: (Itdb_Track) + flag2 -> skip_when_shuffling + flag3 -> remember_playback_position + + * src/itunesdb.c: playlist flags 1,2,3 were not read correctly. + +2006-05-28 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/db-parse-context.c (db_parse_context_new_from_file): + Detect endianess if not already set. + + * src/itdb_device.c (itdb_device_autodetect_endianess): try + reading the first for bytes of iTunesDB, ArtworkDB or Photos + Database in order to reliably detect the endianess of the + connected iPod. + + * src/itdb_photoalbum.c: (itdb_photodb_parse): will fail again if + no photos dir is available. + + * tests/test-photos.c: takes into consideration the possibility + that an iPod does not have a Photos Database and creates a new + one in that case. (I think it's safer that way -- the + application is forced to 'think' about the fact that no database + is available and either warn the user or create one. If + itdb_photodb_parse() simply returns an empty database in case + none could be found, the application might not become aware of + the fact.) + + * renamed itdb_get_mountpoint_photo to + itdb_photodb_get_mountpoint. + + * tests/test-photos.c: added g_error_free() + + * src/itdb_device.c + src/itdb_device.h: added number of musicdirs (Fnn dirs) to the + model descriptions. The exact number seems to be version + dependent. Therefore, the numbers here represent a mixture of + reported values and common sense. + +2006-05-27 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/itdb_photoalbum.c: itdb_photodb_parse() would fail if no + photos dir is available. Quick fix for now (I mean, why + SHOULDN'T it fail if no photos dir is available??). + +2006-05-26 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/itdb.h: + src/itdb_photoalbum.c: + src/itdb_artwork.c: + Added userdata/usertype fields to Itdb_PhotoDB, Itdb_PhotoAlbum, + Itdb_Artwork. + +2006-05-25 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * Slight cleanup, make PhotoDB API more consistent with iTunesDB + API: + + * src/db-artwork-parser.h: declared ipod_write_photo_db() as + G_GNUC_INTERNAL + + * src/db-artwork-writer.c (ipod_write_photo_db for non-gdk): + Itdb_iTunesDB -> Itdb_PhotoDB + + * src/itdb.h: + Itdb_ItunesDB: removed photoalbums and photos. + renamed: + itdb_parse_photo -> itdb_photodb_parse + itdb_add_photo_to_photoalbum -> itdb_photodb_add_photo + itdb_create_new_photoalbum -> itdb_photodb_photoalbum_new + itdb_free_photodb -> itdb_photodb_free + itdb_write_photo_db -> itdb_photodb_write + new: itdb_photodb_new() + + * src/itdb_itunesdb.c (itdb_parse_photo, itdb_get_photos_dir, + itdb_get_photodb_path, itdb_get_photos_thumb_dir): moved to + itdb_photoalbum.c + + * src/itdb_photoalbum.c: + new: error_no_photos_dir, itdb_photodb_new, itdb_photodb_write + moved: itdb_get_photos_dir, itdb_get_photodb_path, + itdb_get_photos_thumb_dir + rewrote: + itdb_photodb_parse + (itdb_photodb_free): free device struct as well. + + * tests/test-photos.c: change to new API. + + * src/itdb.h: applied Christophe's patch to fix compile time + error. + + * po/sv.po: updated Swedish translation (thanks to Stefan + Asserhall) + +2006-05-20 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * po/POTFILES.in: updated file list -> updated .po files. + +2006-05-15 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/db-image-parser.c + * src/itdb_photoalbum.c + * src/ithumb-writer.c + Michael McLellan patch for photo support on iPod Videos + +2006-05-11 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/itdb.h + * src/itdb_itunesdb.c + * src/itdb_private.h + * src/db-artwork-parser.c + * src/db-artwork-parser.h + * src/db-itunes-parser.h + * src/db-artwork-writer.c + * src/itdb_photoalbum.c + Make sure Photos and Photos/Thumbs directories are created. New: + itdb_get_photodb_path(). + + +2006-05-06 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * src/db-artwork-parser.c: + * src/db-itunes-parser.h: + * src/db-artwork-writer.c: + * src/itdb_photoalbum.c: + * src/itdb.h: + * src/itdb_private.h: + * tests/test-photos.c: + Applied Mikey's second patch for photo support. test-photos now + comes with support for photo albums! + 2006-05-07 Jorg Schuler <jcsjcs at users.sourceforge.net> * Created new branch "photo-support" for testing of photo support. Comes complete with a test program to add photos to your iPod. Works great for me -- thanks to Mikey! - Update your repository with the "-r photo-support" option to get - a copy and help testing. + --- 2006-05-30: merged back to MAIN. + +2006-05-06 Jorg Schuler <jcsjcs at users.sourceforge.net> + + * Applied Mikey's patch for photo support. + + * src/itdb_photoalbum.c: new. + + * tests/test-photo.c: test program to add photos to your iPod. + + * Created branch for this patch: 'photo-support'. 2006-05-05 Jorg Schuler <jcsjcs at users.sourceforge.net> diff --git a/configure.ac b/configure.ac index 1ad397c..dbd622e 100644 --- a/configure.ac +++ b/configure.ac @@ -175,3 +175,20 @@ src/Makefile tests/Makefile libgpod-1.0.pc ]) + +echo " +Configuration for $PACKAGE $VERSION : +-------------------------------- + + Host System Type .....: $host + Install path .........: $prefix + Preprocessor .........: $CC $CPPFLAGS + Compiler .............: $CC $CFLAGS $PACKAGE_CFLAGS + Linker ...............: $CC $LDFLAGS $LIBS $PACKAGE_LIBS + ArtworkDB support ....: $have_gdkpixbuf + Python bindings ......: $with_python + + Now type 'make' to build $PACKAGE $VERSION, + and then 'make install' for installation. +" + diff --git a/docs/reference/tmpl/artwork.sgml b/docs/reference/tmpl/artwork.sgml index a7ce2a5..9d0005b 100644 --- a/docs/reference/tmpl/artwork.sgml +++ b/docs/reference/tmpl/artwork.sgml @@ -24,7 +24,13 @@ Data structure to store iPod artwork (cover and photos) @thumbnails: @artwork_size: +@type: @id: +@creation_date: +@usertype: +@userdata: +@userdata_duplicate: +@userdata_destroy: <!-- ##### STRUCT Itdb_Thumb ##### --> <para> diff --git a/docs/reference/tmpl/device.sgml b/docs/reference/tmpl/device.sgml index 07090ed..8852576 100644 --- a/docs/reference/tmpl/device.sgml +++ b/docs/reference/tmpl/device.sgml @@ -25,7 +25,7 @@ Data structure holding information about the iPod (model, mount point, ...) @mountpoint: @musicdirs: @byte_order: -@endianess_reversed: +@sysinfo: <!-- ##### FUNCTION itdb_device_new ##### --> <para> @@ -80,6 +80,7 @@ Data structure holding information about the iPod (model, mount point, ...) @capacity: @model_type: @generation: +@musicdirs: <!-- ##### STRUCT Itdb_ArtworkFormat ##### --> <para> diff --git a/docs/reference/tmpl/itunesdb-db.sgml b/docs/reference/tmpl/itunesdb-db.sgml index 37fc775..6ec61bb 100644 --- a/docs/reference/tmpl/itunesdb-db.sgml +++ b/docs/reference/tmpl/itunesdb-db.sgml @@ -81,7 +81,7 @@ Functions to create, read, write the iPod database </para> -@itdb: +@db: @error: @Returns: diff --git a/docs/reference/tmpl/track.sgml b/docs/reference/tmpl/track.sgml index a96c52f..274b1d0 100644 --- a/docs/reference/tmpl/track.sgml +++ b/docs/reference/tmpl/track.sgml @@ -85,8 +85,8 @@ Data structure to store metadata about an iPod track @unk156: @unk160: @has_artwork: -@flag2: -@flag3: +@skip_when_shuffling: +@remember_playback_position: @flag4: @dbid2: @lyrics_flag: diff --git a/m4/python.m4 b/m4/python.m4 index 032334b..28bdaa3 100644 --- a/m4/python.m4 +++ b/m4/python.m4 @@ -30,8 +30,8 @@ AC_DEFUN([LIBGPOD_CHECK_PYTHON], [ AC_ARG_WITH(python, AC_HELP_STRING([--with-python=PATH], - [build python bindings [[default=no]]]), - [with_python=$withval],[with_python=no]) + [build python bindings [[default=yes]]]), + [with_python=$withval],[with_python=yes]) AC_MSG_CHECKING(whether to build python bindings) if test "X$with_python" != Xno; then diff --git a/po/POTFILES.in b/po/POTFILES.in index a16c5ce..edf8c27 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,6 +1,21 @@ -src/itdb.h +# List of source files containing translatable strings (output of +# ls src/*.c tests/*.c) + + +src/db-artwork-debug.c +src/db-artwork-parser.c +src/db-artwork-writer.c +src/db-image-parser.c +src/db-parse-context.c +src/itdb_artwork.c +src/itdb_device.c src/itdb_itunesdb.c +src/itdb_photoalbum.c src/itdb_playlist.c -src/itdb_private.h src/itdb_track.c +src/ithumb-writer.c tests/itdb_main.c +tests/test-covers.c +tests/test-ls.c +tests/test-photos.c +tests/test-write-covers.c @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gtkpod 0.52\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" "PO-Revision-Date: 2005-09-14 22:01+0900\n" "Last-Translator: Jörg Schuler <jcsjcs at users.sourceforge.net>\n" "Language-Team: none\n" @@ -16,39 +16,75 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "" + +#: ../src/itdb_artwork.c:334 +#, fuzzy, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "Datei nicht gefunden: '%s'." + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "Illegaler seek bei Offset %ld (Länge %ld) in Datei '%s'." -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "Keine Play Counts Datei: '%s' (mhdp-Header fehlt)." -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "Play Counts Datei ('%s'): Headerlänge kleiner als erwarted (%d<96)." -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "" "Play Counts Datei ('%s'): Länge der Einträge kleiner als erwartet (%d<12)." -#: ../src/itdb_itunesdb.c:921 +#: ../src/itdb_itunesdb.c:926 #, fuzzy, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." msgstr "" "Play Counts Datei ('%s'): Länge der Einträge kleiner als erwartet (%d<12)." -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "iTunesDB beschädigt: kein MHOD bei Offset %ld in Datei '%s'." -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -57,12 +93,12 @@ msgstr "" "Die Länge einer Regel (%d) einer intelligenten Wiedergabeliste weicht von " "der erwarteten Länge ab. Es wird versucht fortzufahren.\n" -#: ../src/itdb_itunesdb.c:1386 +#: ../src/itdb_itunesdb.c:1434 #, fuzzy, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." msgstr "iTunesDB beschädigt: kein MHOD bei Offset %ld in Datei '%s'." -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -72,20 +108,20 @@ msgstr "" "versucht fortzufahren.\n" "\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." msgstr "" "iTunesDB beschädigt: Hunklänge ist Null für den Hunk an Offset %ld in Datei " "'%s'." -#: ../src/itdb_itunesdb.c:1474 +#: ../src/itdb_itunesdb.c:1522 #, fuzzy, c-format msgid "" "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." msgstr "iTunesDB beschädigt: kein MHOD bei Offset %ld in Datei '%s'." -#: ../src/itdb_itunesdb.c:1488 +#: ../src/itdb_itunesdb.c:1536 #, fuzzy, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " @@ -94,12 +130,12 @@ msgstr "" "iTunesDB ('%s'): Headerlänge des mhsd-Hunks is kleiner als erwartet (%" "ld<32). Breche ab." -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "Keine iTunesDB Datei: '%s' (kein mhdb-Header)." -#: ../src/itdb_itunesdb.c:1590 +#: ../src/itdb_itunesdb.c:1638 #, fuzzy, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " @@ -108,62 +144,62 @@ msgstr "" "iTunesDB ('%s'): Headerlänge des mhsd-Hunks is kleiner als erwartet (%" "ld<32). Breche ab." -#: ../src/itdb_itunesdb.c:1611 +#: ../src/itdb_itunesdb.c:1659 #, fuzzy, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." msgstr "iTunesDB beschädigt: mhyp bei Offset %ld in Datei '%s' gefunden." -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "Itdb_Track ID '%d' nicht gefunden.\n" -#: ../src/itdb_itunesdb.c:1903 +#: ../src/itdb_itunesdb.c:1951 #, fuzzy, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." msgstr "iTunesDB beschädigt: mhyp bei Offset %ld in Datei '%s' gefunden." -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "Haupt-PL" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" msgstr "" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "Wiedergabeliste" -#: ../src/itdb_itunesdb.c:1941 +#: ../src/itdb_itunesdb.c:1989 #, fuzzy, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" "ld in file '%s'." msgstr "iTunesDB beschädigt: mhyp bei Offset %ld in Datei '%s' gefunden." -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "OTG-Wiedergabeliste" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "Keine OTG (On-The-Go) Wiedergabelistendatei: '%s' (mhpo-Header fehlt)." -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "" "OTG (On-The-Go) Wiedergabelistendatei ('%s'): Headerlänger kleiner als " "erwartet (%d<20)." -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format msgid "" "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." @@ -171,20 +207,20 @@ msgstr "" "OTG (On-The-Go) Wiedergabelistendatei ('%s'): Länge der Einträge kleiner als " "erwartet (%d<4)." -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "" "OTG (On-The-Go) Wiedergabelistendateii '%s' bezieht sich auf ein nicht " "existierendes Stück (%d)." -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "OTG-Wiedergabeliste %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 +#: ../src/itdb_itunesdb.c:2466 #, fuzzy msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " @@ -194,7 +230,7 @@ msgstr "" "konsistent. Versuche fortzufahren.\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -202,7 +238,7 @@ msgstr "" "iTunesDB möglicherweise beschädigt: Anzahl der Wiedergabelisten (mhyp-Hunks) " "ist nicht konsistent. Versuche fortzufahren.\n" -#: ../src/itdb_itunesdb.c:2524 +#: ../src/itdb_itunesdb.c:2576 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " @@ -211,7 +247,7 @@ msgstr "" "iTunesDB '%s' beschädigt: bereits zwei Wiedergabelisten mhsds-Hunks " "gefunden. Breche ab." -#: ../src/itdb_itunesdb.c:2553 +#: ../src/itdb_itunesdb.c:2605 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " @@ -220,98 +256,98 @@ msgstr "" "iTunesDB '%s' beschädigt: bereits zwei Wiedergabelisten mhsds-Hunks " "gefunden. Breche ab." -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "Datei nicht gefunden: '%s'." -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "Schreiben eines mhod-Hunks vom Typ %d ist nicht unterstützt.\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "Öffnen der Datei '%s' zum Schreiben ist fehlgeschlagen." -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "Fehler beim Schreiben in die Datei '%s'." -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "Schreiben in die Datei '%s' ist fehlgeschlagen (%s)." -#: ../src/itdb_itunesdb.c:4370 +#: ../src/itdb_itunesdb.c:4524 #, fuzzy, c-format msgid "Path not found: '%s' (or similar)." msgstr "Pfad nicht gefunden: '%s'." -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "Fehler beim Umbenennen von '%s' nach '%s' (%s)." -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "Fehler beim Entfernen von '%s' (%s)." -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." msgstr "No 'F..' directories were found in '%s'." -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "Pfad nicht gefunden: '%s'." -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "Fehler beim Öffnen von '%s' zum Lesen (%s)." -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "Fehler beim Öffnen von '%s' zum Schreiben (%s)." -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "Fehler beim Lesen aus '%s' (%s)." -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "Fehler beim Schreiben in die Datei '%s' (%s)." -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "Fehler beim Schließen der Datei '%s' (%s)." #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: es_ES\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" "PO-Revision-Date: 2006-03-30 02:00+0200\n" "Last-Translator: Alejandro Lamas Daviña <alejandro.lamas@ific.uv.es>\n" "Language-Team: <es_ES>\n" @@ -18,44 +18,80 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: KBabel 1.9.1\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "" + +#: ../src/itdb_artwork.c:334 +#, fuzzy, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "Fichero no encontrado: '%s'." + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "Acceso ilegal al desplazamiento %ld (tamaño %ld) en el fichero '%s'." -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "No es un fichero cuenta reproducciones: '%s' (falta cabecera mhdp)." -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "" "Fichero cuenta reproducciones ('%s'): tamaño de la cabecera menor del " "esperado (%d<96)." -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "" "Fichero cuenta reproducciones ('%s'): tamaño de la entrada menor del " "esperado (%d<12)." -#: ../src/itdb_itunesdb.c:921 +#: ../src/itdb_itunesdb.c:926 #, fuzzy, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." msgstr "" "Fichero cuenta reproducciones ('%s'): tamaño de la entrada menor del " "esperado (%d<12)." -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "" "iTunesDB corrupta: no hay MHOD en el desplazamiento %ld del fichero '%s'." -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -64,13 +100,13 @@ msgstr "" "La longitud del campo de reglas (%d) de la lista de reproducción inteligente " "no es la esperada. Intentando continuar.\n" -#: ../src/itdb_itunesdb.c:1386 +#: ../src/itdb_itunesdb.c:1434 #, fuzzy, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." msgstr "" "iTunesDB corrupta: no hay MHOD en el desplazamiento %ld del fichero '%s'." -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -80,19 +116,19 @@ msgstr "" "Ignorando.\n" "\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." msgstr "iTunesDB corrupta: tamaño 0 para la zona %ld en el fichero '%s'." -#: ../src/itdb_itunesdb.c:1474 +#: ../src/itdb_itunesdb.c:1522 #, fuzzy, c-format msgid "" "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." msgstr "" "iTunesDB corrupta: no hay MHOD en el desplazamiento %ld del fichero '%s'." -#: ../src/itdb_itunesdb.c:1488 +#: ../src/itdb_itunesdb.c:1536 #, fuzzy, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " @@ -101,12 +137,12 @@ msgstr "" "iTunesDB ('%s'): tamaño de la cabecera de la zona mhsd menor del esperado (%" "ld<32). Cancelando." -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "No es un fichero iTunesDB: '%s' (falta la cabecera mhdb)." -#: ../src/itdb_itunesdb.c:1590 +#: ../src/itdb_itunesdb.c:1638 #, fuzzy, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " @@ -115,62 +151,62 @@ msgstr "" "iTunesDB ('%s'): tamaño de la cabecera de la zona mhsd menor del esperado (%" "ld<32). Cancelando." -#: ../src/itdb_itunesdb.c:1611 +#: ../src/itdb_itunesdb.c:1659 #, fuzzy, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." msgstr "iTunesDB corrupta: se ha encontrado mhyp en %ld en el fichero '%s'." -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "Itdb_Track ID '%d' no encontrada.\n" -#: ../src/itdb_itunesdb.c:1903 +#: ../src/itdb_itunesdb.c:1951 #, fuzzy, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." msgstr "iTunesDB corrupta: se ha encontrado mhyp en %ld en el fichero '%s'." -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "Lista de reproducción principal" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" msgstr "" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "Lista de reproducción" -#: ../src/itdb_itunesdb.c:1941 +#: ../src/itdb_itunesdb.c:1989 #, fuzzy, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" "ld in file '%s'." msgstr "iTunesDB corrupta: se ha encontrado mhyp en %ld en el fichero '%s'." -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "Lista de reproducción OTG" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "No es una lista de reproducción: '%s' (falta la cabecera mhpo)." -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "" "Fichero de lista de reproducción OTG ('%s'): tamaño de la cabecera menor del " "esperado (%d<20)." -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format msgid "" "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." @@ -178,20 +214,20 @@ msgstr "" "Fichero de lista de reproducción OTG ('%s'): tamaño de la entrada menor del " "esperado (%d<4)." -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "" "La lista de reproducción OTG '%s': hace referencia a una pista no existente " "(%d)." -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "Lista de reproducción OTG %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 +#: ../src/itdb_itunesdb.c:2466 #, fuzzy msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " @@ -201,7 +237,7 @@ msgstr "" "es consistente. Intentando continuar.\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -209,7 +245,7 @@ msgstr "" "Es posible que iTunesDB esté corrupta: el número de listas de reproducción " "(zonas mhyp) no es consistente. Intentando continuar.\n" -#: ../src/itdb_itunesdb.c:2524 +#: ../src/itdb_itunesdb.c:2576 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " @@ -218,7 +254,7 @@ msgstr "" "iTunesDB '%s' corrputa: se han encontrado dos listas de reproducción mhsds " "-- Deteniendo." -#: ../src/itdb_itunesdb.c:2553 +#: ../src/itdb_itunesdb.c:2605 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " @@ -227,98 +263,98 @@ msgstr "" "iTunesDB '%s' corrputa: se han encontrado dos listas de reproducción mhsds " "-- Deteniendo." -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "Fichero no encontrado: '%s'." -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "No se puede escribir el mhod de tipo %d\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "No se ha podido abrir '%s' para su escritura." -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "No se ha podido escribir '%s'." -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "No se ha podido escribir '%s' (%s)." -#: ../src/itdb_itunesdb.c:4370 +#: ../src/itdb_itunesdb.c:4524 #, fuzzy, c-format msgid "Path not found: '%s' (or similar)." msgstr "Ruta no encontrada: '%s'." -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "Error al renombrar '%s' a '%s' (%s)." -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "Error al borrar '%s' (%s)." -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." msgstr "No se ha encontrado ningún directorio en '%s'." -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "Ruta no encontrada: '%s'." -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "Error al abrir '%s' para su lectura (%s)." -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "Error al abrir '%s' para su escritura (%s)." -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "Error durante la lectura de '%s' (%s)." -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "Error durante la escritura de '%s' (%s)." -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "Error al cerrar '%s' (%s)." #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "" @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gtkpod 0.94\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" "PO-Revision-Date: 2005-09-14 21:46+0900\n" "Last-Translator: Éric Lassauge <lassauge@users.sf.net>\n" "Language-Team: FR\n" @@ -18,43 +18,79 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "" + +#: ../src/itdb_artwork.c:334 +#, fuzzy, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "Fichier introuvable : «%s»." + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "Erreur de flux à l'offset %ld (longueur %ld) dans le fichier «%s»." -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "«%s» n»est pas un fichier de compteurs (entête mhdp manquant)" -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "" "Fichier de compteurs ('%s') : longueur de l'entête plus petite que prévue (%" "d<96)." -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "" "Fichier de compteur ('%s') : longueur des données plus petite que prévue (%" "d<12)." -#: ../src/itdb_itunesdb.c:921 +#: ../src/itdb_itunesdb.c:926 #, fuzzy, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." msgstr "" "Fichier de compteur ('%s') : longueur des données plus petite que prévue (%" "d<12)." -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "Corruption d'iTunesDB : pas de MHOD à l'offset %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -63,12 +99,12 @@ msgstr "" "Longueur du champ de la règle (%d) de la liste intelligente inattendue. " "Tentative pour continuer quand même.\n" -#: ../src/itdb_itunesdb.c:1386 +#: ../src/itdb_itunesdb.c:1434 #, fuzzy, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." msgstr "Corruption d'iTunesDB : pas de MHOD à l'offset %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -76,18 +112,18 @@ msgid "" msgstr "" "Type MHOD inconnu (%d) lors du parcours de iTunesDB. Ignorance de l'erreur.\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." msgstr "Corruption d'iTunesDB : longueur 0 à %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:1474 +#: ../src/itdb_itunesdb.c:1522 #, fuzzy, c-format msgid "" "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." msgstr "Corruption d'iTunesDB : pas de MHOD à l'offset %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:1488 +#: ../src/itdb_itunesdb.c:1536 #, fuzzy, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " @@ -96,12 +132,12 @@ msgstr "" "iTunesDB ('%s') : longueur de l'entête mhsd plus petite que prévue (%ld<32). " "Interruption." -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "«%s» n»est pas un fichier iTunesDB (entête mhdb manquante)" -#: ../src/itdb_itunesdb.c:1590 +#: ../src/itdb_itunesdb.c:1638 #, fuzzy, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " @@ -110,61 +146,61 @@ msgstr "" "iTunesDB ('%s') : longueur de l'entête mhsd plus petite que prévue (%ld<32). " "Interruption." -#: ../src/itdb_itunesdb.c:1611 +#: ../src/itdb_itunesdb.c:1659 #, fuzzy, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." msgstr "Corruption d'iTunesDB : trouvé mhyp à %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "Itdb_Track ID «%d» non trouvé.\n" -#: ../src/itdb_itunesdb.c:1903 +#: ../src/itdb_itunesdb.c:1951 #, fuzzy, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." msgstr "Corruption d'iTunesDB : trouvé mhyp à %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "Liste principale" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" msgstr "" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "Liste de lecture" -#: ../src/itdb_itunesdb.c:1941 +#: ../src/itdb_itunesdb.c:1989 #, fuzzy, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" "ld in file '%s'." msgstr "Corruption d'iTunesDB : trouvé mhyp à %ld du fichier «%s»." -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "Liste de lecture OTG" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "" "Le fichier '%s' n'est pas un fichier de liste OTG (entête mhpo manquant)." -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "Fichier de liste OTG («%s») : entête plus petit que prévu (%d<20)." -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format msgid "" "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." @@ -172,18 +208,18 @@ msgstr "" "Fichier de liste OTG ('%s') : longueur de données plus petite que prévue (%" "d<4)." -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "Fichier de liste OTG «%s» : référence à un morceau inexistant (%d)." -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "Liste de lecture OTG %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 +#: ../src/itdb_itunesdb.c:2466 #, fuzzy msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " @@ -193,7 +229,7 @@ msgstr "" "Tentative pour continuer quand même.\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -201,7 +237,7 @@ msgstr "" "Corruption possible d'iTunesDB : nombre de listes (mhyp) incohérent. " "Tentative pour continuer quand même.\n" -#: ../src/itdb_itunesdb.c:2524 +#: ../src/itdb_itunesdb.c:2576 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " @@ -209,7 +245,7 @@ msgid "" msgstr "" "Corruption de iTunesDB ('%s') : déjà trouvés deux listes mhsds -- abandon." -#: ../src/itdb_itunesdb.c:2553 +#: ../src/itdb_itunesdb.c:2605 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " @@ -217,98 +253,98 @@ msgid "" msgstr "" "Corruption de iTunesDB ('%s') : déjà trouvés deux listes mhsds -- abandon." -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "Fichier introuvable : «%s»." -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "Impossible d'écrire mhod du type %d\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "Échec de l'ouverture en écriture de «%s»." -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "Erreur d'écriture du fichier «%s»." -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "Échec de l'écriture dans «%s» (%s)." -#: ../src/itdb_itunesdb.c:4370 +#: ../src/itdb_itunesdb.c:4524 #, fuzzy, c-format msgid "Path not found: '%s' (or similar)." msgstr "Chemin non trouvé : «%s»." -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "Impossible de renommer «%s» en «%s» (%s)." -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "Erreur de suppression du fichier «%s» (%s)." -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "Chemin non trouvé : «%s»." -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "Ne peut ouvrir en lecture le fichier «%s» (%s)." -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "Ne peut ouvrir en écriture le fichier «%s» (%s)." -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "Erreur lors de la lecture à partir de : %s (%s)." -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "Erreur d'écriture dans «%s» (%s)." -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "Erreur à la fermeture «%s» (%s)." #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "L'action inconnue (%d) dans la liste intelligente sera ignorée.\n" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gtkpod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" "PO-Revision-Date: 2005-08-02 21:19+0300\n" "Last-Translator: Assaf Gillat\n" "Language-Team: HEBREW <kde-il@yahoogroups.com>\n" @@ -17,37 +17,73 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: KBabel 1.9.1\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "" + +#: ../src/itdb_artwork.c:334 +#, fuzzy, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "קובץ לא קיים: '%s'." + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "חיפוש לא חוקי בהיסט %ld (אורך %ld) בקובץ '%s'." -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "זהו לא קובץ ספירת השמעה: '%s' (חסר תחילית mhdp)" -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "קובץ ספירת השמעה ('%s'): אורך תחילית קטן מהצפוי (%d<96)." -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "קובץ ספירת השמעה ('%s'): אורך רשומה קטן מהצפוי (%d<12)." -#: ../src/itdb_itunesdb.c:921 +#: ../src/itdb_itunesdb.c:926 #, fuzzy, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." msgstr "קובץ ספירת השמעה ('%s'): אורך רשומה קטן מהצפוי (%d<12)." -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "iTunesDB שבור: אין MHOD בהיסט %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -55,12 +91,12 @@ msgid "" msgstr "" "אורך שדה של חוק (%d) רשימת השמעה חכמה הוא לא כצפוי. מנסה להמשיך בכל זאת.\n" -#: ../src/itdb_itunesdb.c:1386 +#: ../src/itdb_itunesdb.c:1434 #, fuzzy, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." msgstr "iTunesDB שבור: אין MHOD בהיסט %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -69,18 +105,18 @@ msgstr "" "נתקלנו בסוג לא ידוע של MHOD (%d) בזמן ניתוח ה-iTuneDB. מתעלם.\n" "\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." msgstr "iTunesDB שבור: אורך חתיכה 0 בחתיכה %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:1474 +#: ../src/itdb_itunesdb.c:1522 #, fuzzy, c-format msgid "" "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." msgstr "iTunesDB שבור: אין MHOD בהיסט %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:1488 +#: ../src/itdb_itunesdb.c:1536 #, fuzzy, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " @@ -88,12 +124,12 @@ msgid "" msgstr "" "iTunesDB ('%s'): גודל תחילית של החתיכה mhsd קטנה מהצפוי (%ld<32). מבטל." -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "זהו לא iTunesDB: '%s' (חסרה תחילית mhdb)." -#: ../src/itdb_itunesdb.c:1590 +#: ../src/itdb_itunesdb.c:1638 #, fuzzy, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " @@ -101,77 +137,77 @@ msgid "" msgstr "" "iTunesDB ('%s'): גודל תחילית של החתיכה mhsd קטנה מהצפוי (%ld<32). מבטל." -#: ../src/itdb_itunesdb.c:1611 +#: ../src/itdb_itunesdb.c:1659 #, fuzzy, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." msgstr "iTunesDB שבור: נמצא mhyp ב %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "מזהה Itdb_Track '%d' לא נמצא.\n" -#: ../src/itdb_itunesdb.c:1903 +#: ../src/itdb_itunesdb.c:1951 #, fuzzy, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." msgstr "iTunesDB שבור: נמצא mhyp ב %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "רשימת ראשית" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" msgstr "" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "רשימת השמעה" -#: ../src/itdb_itunesdb.c:1941 +#: ../src/itdb_itunesdb.c:1989 #, fuzzy, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" "ld in file '%s'." msgstr "iTunesDB שבור: נמצא mhyp ב %ld בקובץ '%s'." -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "רשימת השמעה OTG" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "זהו לא קובץ רשימת השמעה OTG: '%s' (חסרה תחילת קובץ mhpo)." -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "קובץ רשימת השמעה OTG ('%s'): גודל תחילית קטן מהצפוי (%d<20)." -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format msgid "" "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." msgstr "קובץ רשימת השמעה OTG ('%s'): גודל רשומה קטן מהצפוי (%d<4)." -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "רשימת השמעה OTG '%s': התייחסות לרצועה לא קיימת (%d)." -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "רשימת השמעה OTG %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 +#: ../src/itdb_itunesdb.c:2466 #, fuzzy msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " @@ -181,7 +217,7 @@ msgstr "" "להמשיך.\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -189,112 +225,112 @@ msgstr "" "יכול להיות ש-iTuneDB שבור: מספר רשימות השמעה (mhyp חתיכות) לא עקביות. מנסה " "להמשיך.\n" -#: ../src/itdb_itunesdb.c:2524 +#: ../src/itdb_itunesdb.c:2576 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " "found)" msgstr "iTunesDB '%s' שבור: כבר מצאנו mhsds של שתי רשימות השמעה -- מוותר." -#: ../src/itdb_itunesdb.c:2553 +#: ../src/itdb_itunesdb.c:2605 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " "sections found)" msgstr "iTunesDB '%s' שבור: כבר מצאנו mhsds של שתי רשימות השמעה -- מוותר." -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "קובץ לא קיים: '%s'." -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "לא יכול לכתוב mhod של סוג %d\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "פתיחת '%s' לכתיבה נכשלה." -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "נכשלה כתיבה ל '%s'." -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "נכשלה כתיבה ל '%s' (%s)." -#: ../src/itdb_itunesdb.c:4370 +#: ../src/itdb_itunesdb.c:4524 #, fuzzy, c-format msgid "Path not found: '%s' (or similar)." msgstr "נתיב לא נמצא: '%s'." -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "תקלה בשינוי שם '%s' ל '%s' (%s)." -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "תקלה בהסרת '%s' (%s)" -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "נתיב לא נמצא: '%s'." -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "תקלה בפתיחת '%s' לקריאה (%s)." -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "תקלה בפתיחת '%s' לכתיבה (%s)." -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "תקלה בזמן קריאה מ '%s' (%s)." -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "תקלה בזמן כתיבה ל '%s' (%s)." -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "תקלה בזמן סגירה '%s' (%s)." #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "התעלמות מפעולה לא ידועה (%d) ברשימת השמעה חכמה.\n" @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: it2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" "PO-Revision-Date: 2005-06-20 23:25+0900\n" "Last-Translator: \n" "Language-Team: <it@li.org>\n" @@ -21,43 +21,79 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: KBabel 1.9.1\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "" + +#: ../src/itdb_artwork.c:334 +#, fuzzy, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "file non trovato: '%s'." + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "ricerca illegale all'offest %ld (lunghezza %ld) nel file '%s'" -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "Non è un file conta riproduzioni: '%s' (intestazione mhdp mancante)" -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "" "File conta-riproduzioni ('%s'): lunghezza della intestazione più piccolo di " "quanto ci si aspettava (%d<96)" -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "" "File conta-riproduzioni ('%s'): lunghezza della voce più piccoladi quanto ci " "si aspettava (%d<12)" -#: ../src/itdb_itunesdb.c:921 +#: ../src/itdb_itunesdb.c:926 #, fuzzy, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." msgstr "" "File conta-riproduzioni ('%s'): lunghezza della voce più piccoladi quanto ci " "si aspettava (%d<12)" -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "iTunesDB corrotto: nessun MHOD all'offest %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -66,12 +102,12 @@ msgstr "" "La lunghezza del campo della regola della playlist intelligente (%d) non è " "come la si aspettava. Si prova a continuare.\n" -#: ../src/itdb_itunesdb.c:1386 +#: ../src/itdb_itunesdb.c:1434 #, fuzzy, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." msgstr "iTunesDB corrotto: nessun MHOD all'offest %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -81,18 +117,18 @@ msgstr "" "Ignorato.\n" "\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." msgstr "iTunesDB corrotto: hunk di lunghezza 0 per l'hunk %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:1474 +#: ../src/itdb_itunesdb.c:1522 #, fuzzy, c-format msgid "" "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." msgstr "iTunesDB corrotto: nessun MHOD all'offest %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:1488 +#: ../src/itdb_itunesdb.c:1536 #, fuzzy, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " @@ -101,12 +137,12 @@ msgstr "" "iTunesDB ('%s'): lunghezza della intestazione del hunk mhsd più piccolo " "delle aspettative (%ld<32). Interrompo." -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "Non è un file iTunesDB: '%s' (intestazione mhdb mancante)" -#: ../src/itdb_itunesdb.c:1590 +#: ../src/itdb_itunesdb.c:1638 #, fuzzy, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " @@ -115,62 +151,62 @@ msgstr "" "iTunesDB ('%s'): lunghezza della intestazione del hunk mhsd più piccolo " "delle aspettative (%ld<32). Interrompo." -#: ../src/itdb_itunesdb.c:1611 +#: ../src/itdb_itunesdb.c:1659 #, fuzzy, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." msgstr "iTunesDB corrotto: trovato mhyp a %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." msgstr "" -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "itDB_Track ID '%d' non trovato.\n" -#: ../src/itdb_itunesdb.c:1903 +#: ../src/itdb_itunesdb.c:1951 #, fuzzy, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." msgstr "iTunesDB corrotto: trovato mhyp a %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "PL principale" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" msgstr "" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "Playlist" -#: ../src/itdb_itunesdb.c:1941 +#: ../src/itdb_itunesdb.c:1989 #, fuzzy, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" "ld in file '%s'." msgstr "iTunesDB corrotto: trovato mhyp a %ld nel file '%s'." -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "Playlist OTG" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "Non è una file playlist OTG: '%s' (manca l'intestazione mhpo)" -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "" "File playlist OTG ('%s'): lunghezza della intestazione più piccola delle " "aspettative (%d<20)" -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format msgid "" "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." @@ -178,18 +214,18 @@ msgstr "" "File playlist OTG ('%s'): lunghezza della voce più piccola delle aspettative " "(%d<4)" -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "Playlist OTG '%s': Punta ad una traccia non esistente (%d)." -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "Playlist OTG %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 +#: ../src/itdb_itunesdb.c:2466 #, fuzzy msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " @@ -199,7 +235,7 @@ msgstr "" "inconsistente. Provo a continuare.\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -207,112 +243,112 @@ msgstr "" "L'iTunes è probabilmente corrotto: il numero di playlist (mhyp hunks) è " "inconsistente. Provo a continuare.\n" -#: ../src/itdb_itunesdb.c:2524 +#: ../src/itdb_itunesdb.c:2576 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " "found)" msgstr "iTunesDB '%s' corrotto: trovate già due playlist mhsds -- ci rinuncio." -#: ../src/itdb_itunesdb.c:2553 +#: ../src/itdb_itunesdb.c:2605 #, fuzzy, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " "sections found)" msgstr "iTunesDB '%s' corrotto: trovate già due playlist mhsds -- ci rinuncio." -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "file non trovato: '%s'." -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "Impossibile scrivere il mhod del tipo %d\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "Apertura di '%s' in scrittura fallita." -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "Scrittura verso '%s' fallita." -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "Scrittura verso '%s' falita (%s)." -#: ../src/itdb_itunesdb.c:4370 +#: ../src/itdb_itunesdb.c:4524 #, fuzzy, c-format msgid "Path not found: '%s' (or similar)." msgstr "Percorso non trovato: '%s'." -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "Errore nella rinominazione da '%s' a '%s' (%s)." -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "Errore nella rimozione di '%s' (%s)." -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." msgstr "Nessuna directory 'F..' trovata in '%s'" -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "Percorso non trovato: '%s'." -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "Errore nell'apertura in lettura di '%s' (%s)." -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "Errore nell'apertura in scrittura di '%s' (%s)." -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "Errore nella lettura da '%s' (%s)." -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "Errore nella scrittura verso '%s' (%s)." -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "Errore nella chiusura di '%s' (%s)." #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "Azione sconosciuta (%d) nella playlist intelligente verrà ignorata.\n" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gtkpod 0.40\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" "PO-Revision-Date: 2006-02-14 16:48+0900\n" "Last-Translator: Kentaro Fukuchi <fukuchi@users.sourceforge.net>\n" "Language-Team: n/a\n" @@ -16,39 +16,75 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "" + +#: ../src/itdb_artwork.c:334 +#, fuzzy, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "ե뤬Ĥޤ: '%s'" + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "ʥ: '%3$s', եå %1$ld, Ĺ (%2$ld)" -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "եǤϤޤ: '%s' (mhdp إå̵)" -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "ե ('%s'): إåĹޤ(%d<96)" -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "ե ('%s'): ȥĹޤ(%d<12)" -#: ../src/itdb_itunesdb.c:921 +#: ../src/itdb_itunesdb.c:926 #, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." msgstr "iTunesStats ե ('%s'): ȥĹޤ(%d<18)" -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "" "iTunesDB Ƥޤ: MHOD դޤ(ե '%2$s', եå " "%1$ld)" -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -57,14 +93,14 @@ msgstr "" "ޡȥץ쥤ꥹȤΥ롼Ĺ (%d) ԤĹȰۤʤޤ" "³ޤ\n" -#: ../src/itdb_itunesdb.c:1386 +#: ../src/itdb_itunesdb.c:1434 #, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." msgstr "" "iTunesDB Ƥޤ: SLst դޤ(ե '%2$s', եå " "%1$ld)" -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -74,14 +110,14 @@ msgstr "" "\n" "\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." msgstr "" "iTunesDB Ƥޤ: hunk Ĺ 0 Ǥ(ե '%2$s', եå %" "1$ld)" -#: ../src/itdb_itunesdb.c:1474 +#: ../src/itdb_itunesdb.c:1522 #, c-format msgid "" "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." @@ -89,7 +125,7 @@ msgstr "" "iTunesDB Ƥޤ: %3$ld ΰ֤ˤ륻 '%2$s' ˥" " '%1$s' Ϥޤ" -#: ../src/itdb_itunesdb.c:1488 +#: ../src/itdb_itunesdb.c:1536 #, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " @@ -98,53 +134,53 @@ msgstr "" "'%1$s' ΥإåĹޤ (%2$d < %3$d) (ե '%5$s', եå " "%4$ld)" -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "iTunesDB ǤϤޤ: '%s' (mhdb إå̵)" -#: ../src/itdb_itunesdb.c:1590 +#: ../src/itdb_itunesdb.c:1638 #, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " "Aborting." msgstr "iTunesDB ('%s'): mhsd ΥإåĹޤ(%d<32)ߤޤ" -#: ../src/itdb_itunesdb.c:1611 +#: ../src/itdb_itunesdb.c:1659 #, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." msgstr "iTunesDB '%s' Ƥޤ: mhsd %ld ΰ֤˸դޤ" -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." msgstr "" "mhip MHOD οäƤޤ(ե '%2$s', եå %1$ld)" -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "Itdb_Track ID '%d' դޤ\n" -#: ../src/itdb_itunesdb.c:1903 +#: ../src/itdb_itunesdb.c:1951 #, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." msgstr "" "mhyp MHOD οäƤޤ(ե '%2$s', եå %1$ld)" -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" msgstr "" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "ץ쥤ꥹ" -#: ../src/itdb_itunesdb.c:1941 +#: ../src/itdb_itunesdb.c:1989 #, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" @@ -153,39 +189,39 @@ msgstr "" "iTunesDB Ƥޤ: mhyp mhip οäƤޤ" "(ե '%2$s', եå %1$ld)" -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "OTG ץ쥤ꥹ" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "OTG ץ쥤ꥹȤΥեǤϤޤ: '%s' (mhpo إå̵)" -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "OTG ץ쥤ꥹȥե ('%s'): إåĹޤ(%d<20)" -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format msgid "" "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." msgstr "OTG ץ쥤ꥹȥե ('%s'): ȥĹޤ(%d<4)" -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "" "OTG ץ쥤ꥹȥե ('%s'): ¸ߤʤֹ (%d) ؤλȤޤ" -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "OTG ץ쥤ꥹ %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 +#: ../src/itdb_itunesdb.c:2466 msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " "continue.\n" @@ -194,7 +230,7 @@ msgstr "" "\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -202,7 +238,7 @@ msgstr "" "iTunesDB ¿ʬƤޤ: ץ쥤ꥹȤο (mhyp ο) äƤ" "³ޤ\n" -#: ../src/itdb_itunesdb.c:2524 +#: ../src/itdb_itunesdb.c:2576 #, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " @@ -211,7 +247,7 @@ msgstr "" "iTunesDB '%s' Ƥޤ: ʥꥹȤդޤ(mhsd 1 " "դʤ)" -#: ../src/itdb_itunesdb.c:2553 +#: ../src/itdb_itunesdb.c:2605 #, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " @@ -220,98 +256,98 @@ msgstr "" "iTunesDB '%s' Ƥޤ: ץ쥤ꥹȤդޤ(mhsd 2 " " 3 Υդʤ)" -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." msgstr "" -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "ե뤬Ĥޤ: '%s'" -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "mhod %d ޤ\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "'%s' Ѥ˳ȤǤޤ" -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "'%s'νߤ˼Ԥޤ" -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "'%s'νߤ˼Ԥޤ(%s)" -#: ../src/itdb_itunesdb.c:4370 +#: ../src/itdb_itunesdb.c:4524 #, fuzzy, c-format msgid "Path not found: '%s' (or similar)." msgstr "ѥĤޤ: '%s'" -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "'%s' '%s' ѹ뤳ȤǤޤ(%s)" -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "'%s' κ˥顼ȯޤ(%s)" -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." msgstr "'F..' ǥ쥯ȥ꤬ '%s' ˤޤ" -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "ѥĤޤ: '%s'" -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "'%s' ɤ߹Ѥ˳ȤǤޤ(%s)" -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "'%s' Ѥ˳ȤǤޤ(%s)" -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "'%s' ɤ߹˥顼ȯޤ(%s)" -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "'%s' ν˥顼ȯޤ(%s)" -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "'%s' Ĥݤ˥顼ȯޤ(%s)" #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "ޡȥץ쥤ꥹ̤ΤΥ (%d) ̵뤵ޤ\n" @@ -6,47 +6,85 @@ msgid "" msgstr "" "Project-Id-Version: sv\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-03-31 23:04+0900\n" -"PO-Revision-Date: 2005-06-22 17:56+0200\n" +"POT-Creation-Date: 2006-05-20 14:24+0900\n" +"PO-Revision-Date: 2006-05-26 00:41+0900\n" "Last-Translator: Stefan Asserhäll <stefan.asserhall@comhem.se>\n" "Language-Team: Svenska <sv@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: KBabel 1.11\n" +"X-Generator: KBabel 1.11.2\n" -#: ../src/itdb_itunesdb.c:361 +#: ../src/db-artwork-parser.c:132 +#, c-format +msgid "Unexpected mhod3 string type: %d\n" +msgstr "Oväntad mhod3 strängtyp; %d\n" + +#: ../src/db-artwork-parser.c:350 +#, c-format +msgid "iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)" +msgstr "Grafikstorlekar i iTunes databas och grafikdatabas inte konseventa (%d + %d != %d)" + +#: ../src/db-artwork-parser.c:499 +#, c-format +msgid "Unexpected mhsd index: %d\n" +msgstr "Oväntat mhsd index: %d\n" + +#: ../src/itdb_artwork.c:253 +#, c-format +msgid "Illegal filename: '%s'.\n" +msgstr "Ogiltigt filnamn: '%s'.\n" + +#: ../src/itdb_artwork.c:259 +msgid "Mountpoint not set.\n" +msgstr "Monteringsplats inte inställd.\n" + +#: ../src/itdb_artwork.c:334 +#, c-format +msgid "Could not find on iPod: '%s'\n" +msgstr "Kunde inte hitta på iPod: '%s'\n" + +#: ../src/itdb_artwork.c:495 +#, c-format +msgid "" +"Unable to retreive thumbnail (appears to be on iPod, but no image info " +"available): type: %d, filename: '%s'\n" +msgstr "" +"Kunde inte hämta miniatyrbild (verkar finnas på iPod, men någon bildinformation " +"är inte tillgänglig): typ: %d, filnamne: '%s'\n" + +#: ../src/itdb_itunesdb.c:366 #, c-format msgid "Illegal seek to offset %ld (length %ld) in file '%s'." msgstr "Ogiltig sökning till position %ld (längd %ld) i filen '%s'." -#: ../src/itdb_itunesdb.c:815 +#: ../src/itdb_itunesdb.c:820 #, c-format msgid "Not a Play Counts file: '%s' (missing mhdp header)." msgstr "Inte en uppspelningsdatafil: '%s' (saknar mhdp-huvud)." -#: ../src/itdb_itunesdb.c:830 +#: ../src/itdb_itunesdb.c:835 #, c-format msgid "Play Counts file ('%s'): header length smaller than expected (%d<96)." msgstr "Uppspelningsdatafil ('%s'): Huvudlängd mindre än väntat (%d < 96)" -#: ../src/itdb_itunesdb.c:843 +#: ../src/itdb_itunesdb.c:848 #, c-format msgid "Play Counts file ('%s'): entry length smaller than expected (%d<12)." msgstr "Uppspelningsdatafil ('%s'): Postlängd mindre än väntat (%d < 12)" -#: ../src/itdb_itunesdb.c:921 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:926 +#, c-format msgid "iTunesStats file ('%s'): entry length smaller than expected (%d<18)." -msgstr "Uppspelningsdatafil ('%s'): Postlängd mindre än väntat (%d < 12)" +msgstr "iTunes statistikfil ('%s'): Postlängd mindre än väntat (%d < 18)" -#: ../src/itdb_itunesdb.c:1197 +#: ../src/itdb_itunesdb.c:1245 #, c-format msgid "iTunesDB corrupt: no MHOD at offset %ld in file '%s'." msgstr "iTunes databas skadad: Ingen MHOD på position %ld i filen '%s'." -#: ../src/itdb_itunesdb.c:1354 +#: ../src/itdb_itunesdb.c:1402 #, c-format msgid "" "Length of smart playlist rule field (%d) not as expected. Trying to continue " @@ -55,12 +93,12 @@ msgstr "" "Regelfältets längd (%d) i den smarta spellistan är inte den förväntade. " "Försöker fortsätta ändå.\n" -#: ../src/itdb_itunesdb.c:1386 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:1434 +#, c-format msgid "iTunesDB corrupt: no SLst at offset %ld in file '%s'." -msgstr "iTunes databas skadad: Ingen MHOD på position %ld i filen '%s'." +msgstr "iTunes databas skadad: Ingen SLst på position %ld i filen '%s'." -#: ../src/itdb_itunesdb.c:1399 +#: ../src/itdb_itunesdb.c:1447 #, c-format msgid "" "Encountered unknown MHOD type (%d) while parsing the iTunesDB. Ignoring.\n" @@ -70,122 +108,118 @@ msgstr "" "den.\n" "\n" -#: ../src/itdb_itunesdb.c:1461 +#: ../src/itdb_itunesdb.c:1509 #, c-format msgid "iTunesDB corrupt: hunk length 0 for hunk at %ld in file '%s'." -msgstr "" -"iTunes databas skadad: Datalängd 0 för data på position %ld i filen '%s'." +msgstr "iTunes databas skadad: Datalängd 0 för data på position %ld i filen '%s'." -#: ../src/itdb_itunesdb.c:1474 -#, fuzzy, c-format -msgid "" -"iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." -msgstr "iTunes databas skadad: Ingen MHOD på position %ld i filen '%s'." +#: ../src/itdb_itunesdb.c:1522 +#, c-format +msgid "iTunesDB corrupt: no section '%s' found in section '%s' starting at %ld." +msgstr "" +"iTunes databas skadad: Någon sektion '%s' hittades inte i sektion '%s' med " +"början på %ld." -#: ../src/itdb_itunesdb.c:1488 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:1536 +#, c-format msgid "" "header length of '%s' smaller than expected (%d < %d) at offset %ld in file " "'%s'." -msgstr "" -"iTunes databas (%s): Huvudlängd för mhsd-data mindre än väntat (%ld < 32). " -"Avbryter." +msgstr "Huvudlängd för '%s' mindre än väntat (%d < %d) på position %ld i filen '%s'." -#: ../src/itdb_itunesdb.c:1573 +#: ../src/itdb_itunesdb.c:1621 #, c-format msgid "Not a iTunesDB: '%s' (missing mhdb header)." msgstr "Inte en iTunes databas: '%s' (saknar mhdb-huvud)." -#: ../src/itdb_itunesdb.c:1590 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:1638 +#, c-format msgid "" "iTunesDB ('%s'): header length of mhsd hunk smaller than expected (%d<32). " "Aborting." -msgstr "" -"iTunes databas (%s): Huvudlängd för mhsd-data mindre än väntat (%ld < 32). " -"Avbryter." +msgstr "iTunes databas ('%s'): Huvudlängd för mhsd-data mindre än väntat (%d < 32). Avbryter." -#: ../src/itdb_itunesdb.c:1611 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:1659 +#, c-format msgid "iTunesDB '%s' corrupt: mhsd expected at %ld." -msgstr "iTunes databas skadad: Hittade mhyp på position %ld i filen '%s'." +msgstr "iTunes databas '%s' skadad: Förväntade mhsd på position %ld." -#: ../src/itdb_itunesdb.c:1728 +#: ../src/itdb_itunesdb.c:1776 #, c-format msgid "Number of MHODs in mhip at %ld inconsistent in file '%s'." -msgstr "" +msgstr "Antal MHOD i mhip på position %ld inte konsekvent i filen '%s'." -#: ../src/itdb_itunesdb.c:1746 +#: ../src/itdb_itunesdb.c:1794 #, c-format msgid "Itdb_Track ID '%d' not found.\n" msgstr "ITunes databas spår-id '%d' hittades inte.\n" -#: ../src/itdb_itunesdb.c:1903 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:1951 +#, c-format msgid "Number of MHODs in mhyp at %ld inconsistent in file '%s'." -msgstr "iTunes databas skadad: Hittade mhyp på position %ld i filen '%s'." +msgstr "Antal MHOD i mhyp på position %ld inte konsekvent i filen '%s'." -#: ../src/itdb_itunesdb.c:1913 +#: ../src/itdb_itunesdb.c:1961 msgid "Master-PL" msgstr "Huvudspellista" -#: ../src/itdb_itunesdb.c:1917 +#: ../src/itdb_itunesdb.c:1965 msgid "Podcasts" -msgstr "" +msgstr "Podradiosändningar" -#: ../src/itdb_itunesdb.c:1919 +#: ../src/itdb_itunesdb.c:1967 msgid "Playlist" msgstr "Spellista" -#: ../src/itdb_itunesdb.c:1941 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:1989 +#, c-format msgid "" "iTunesDB corrupt: number of mhip sections inconsistent in mhyp starting at %" "ld in file '%s'." -msgstr "iTunes databas skadad: Hittade mhyp på position %ld i filen '%s'." +msgstr "" +"iTunes databas skadad: Antal mhip sektioner inte konsekvent i mhyp med " +"början på %ld i filen '%s'." -#: ../src/itdb_itunesdb.c:2222 +#: ../src/itdb_itunesdb.c:2274 msgid "OTG Playlist" msgstr "OTG-spellista" -#: ../src/itdb_itunesdb.c:2240 +#: ../src/itdb_itunesdb.c:2292 #, c-format msgid "Not a OTG playlist file: '%s' (missing mhpo header)." msgstr "Inte en OTG-spellistefil: '%s' (saknar mhpo-huvud)." -#: ../src/itdb_itunesdb.c:2254 +#: ../src/itdb_itunesdb.c:2306 #, c-format msgid "OTG playlist file ('%s'): header length smaller than expected (%d<20)." msgstr "OTG-spellistefil ('%s'): Huvudlängd mindre än väntat (%d < 20)" -#: ../src/itdb_itunesdb.c:2266 +#: ../src/itdb_itunesdb.c:2318 #, c-format -msgid "" -"OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." +msgid "OTG playlist file file ('%s'): entry length smaller than expected (%d<4)." msgstr "OTG-spellistefil ('%s'): Postlängd mindre än väntat (%d < 4)" -#: ../src/itdb_itunesdb.c:2301 +#: ../src/itdb_itunesdb.c:2353 #, c-format msgid "OTG playlist file '%s': reference to non-existent track (%d)." msgstr "OTG-spellistefil '%s': Referens till spår som inte finns (%d)." -#: ../src/itdb_itunesdb.c:2346 +#: ../src/itdb_itunesdb.c:2398 #, c-format msgid "OTG Playlist %d" msgstr "OTG-spellista %d" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2414 -#, fuzzy +#: ../src/itdb_itunesdb.c:2466 msgid "" "iTunesDB corrupt: number of tracks (mhit hunks) inconsistent. Trying to " "continue.\n" msgstr "" -"iTunes databas möjligen skadad: Antal spår (mhit-data) inte konsekvent. " +"iTunes databas skadad: Antal spår (mhit-data) inte konsekvent. " "Försöker fortsätta.\n" #. this should not be -- issue warning -#: ../src/itdb_itunesdb.c:2477 +#: ../src/itdb_itunesdb.c:2529 msgid "" "iTunesDB possibly corrupt: number of playlists (mhyp hunks) inconsistent. " "Trying to continue.\n" @@ -193,124 +227,117 @@ msgstr "" "iTunes databas möjligen skadad: Antal spellistor (mhyp-data) inte " "konsekvent. Försöker fortsätta.\n" -#: ../src/itdb_itunesdb.c:2524 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:2576 +#, c-format msgid "" "iTunesDB '%s' corrupt: Could not find tracklist (no mhsd type 1 section " "found)" msgstr "" -"iTunes databas '%s' skadad: Två mhsd för spellistor redan hittade. Ger upp." +"iTunes databas '%s' skadad: Kunde inte hitta spårlista (någon mhsd av typ 1 " +"hittades inte)" -#: ../src/itdb_itunesdb.c:2553 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:2605 +#, c-format msgid "" "iTunesDB '%s' corrupt: Could not find playlists (no mhsd type 2 or type 3 " "sections found)" msgstr "" -"iTunes databas '%s' skadad: Två mhsd för spellistor redan hittade. Ger upp." +"iTunes databas '%s' skadad: Kunde inte hitta spellistor (någon mhsd av typ 2 " +"eller typ 3 hittades)" -#: ../src/itdb_itunesdb.c:2575 +#: ../src/itdb_itunesdb.c:2627 #, c-format msgid "iTunes directory not found: '%s' (or similar)." -msgstr "" +msgstr "iTunes katalog hittades inte: '%s' (eller liknande)." -#: ../src/itdb_itunesdb.c:2592 +#: ../src/itdb_itunesdb.c:2644 #, c-format msgid "Music directory not found: '%s' (or similar)." -msgstr "" +msgstr "Musikkatalog hittades inte: '%s' (eller liknande)." -#: ../src/itdb_itunesdb.c:2610 +#: ../src/itdb_itunesdb.c:2662 #, c-format msgid "Control directory not found: '%s' (or similar)." -msgstr "" +msgstr "Styrkatalog hittades inte: '%s' (eller liknande)." -#: ../src/itdb_itunesdb.c:2677 +#: ../src/itdb_itunesdb.c:2735 ../src/itdb_itunesdb.c:2801 #, c-format msgid "File not found: '%s'." msgstr "Filen hittades inte: '%s'." -#: ../src/itdb_itunesdb.c:3465 +#: ../src/itdb_itunesdb.c:3604 #, c-format msgid "Cannot write mhod of type %d\n" msgstr "Kan inte skriva mhod av typen %d\n" -#: ../src/itdb_itunesdb.c:4014 +#: ../src/itdb_itunesdb.c:4160 #, c-format msgid "Opening of '%s' for writing failed." msgstr "Fel när '%s' skulle öppnas för skrivning." -#: ../src/itdb_itunesdb.c:4025 +#: ../src/itdb_itunesdb.c:4171 #, c-format msgid "Writing to '%s' failed." msgstr "Fel vid skrivning till '%s'." -#: ../src/itdb_itunesdb.c:4036 +#: ../src/itdb_itunesdb.c:4182 #, c-format msgid "Writing to '%s' failed (%s)." msgstr "Fel vid skrivning till '%s' (%s)." -#: ../src/itdb_itunesdb.c:4370 -#, fuzzy, c-format +#: ../src/itdb_itunesdb.c:4524 +#, c-format msgid "Path not found: '%s' (or similar)." -msgstr "Sökväg hittades inte: '%s'." +msgstr "Sökväg hittades inte: '%s' (eller liknande)." -#: ../src/itdb_itunesdb.c:4573 +#: ../src/itdb_itunesdb.c:4743 #, c-format msgid "Error renaming '%s' to '%s' (%s)." msgstr "Fel vid byte av namn på '%s' till '%s' (%s)." -#: ../src/itdb_itunesdb.c:4590 ../src/itdb_itunesdb.c:4607 +#: ../src/itdb_itunesdb.c:4760 ../src/itdb_itunesdb.c:4777 #, c-format msgid "Error removing '%s' (%s)." msgstr "Fel vid borttagning av '%s' (%s)." -#: ../src/itdb_itunesdb.c:4747 +#: ../src/itdb_itunesdb.c:4995 #, c-format msgid "No 'F..' directories found in '%s'." -msgstr "" +msgstr "Några 'F..'-kataloger hittades inte i '%s'." -#: ../src/itdb_itunesdb.c:4775 +#: ../src/itdb_itunesdb.c:5023 #, c-format msgid "Path not found: '%s'." msgstr "Sökväg hittades inte: '%s'." -#: ../src/itdb_itunesdb.c:4925 +#: ../src/itdb_itunesdb.c:5182 #, c-format msgid "Error opening '%s' for reading (%s)." msgstr "Fel när '%s' skulle öppnas för läsning (%s)." -#: ../src/itdb_itunesdb.c:4936 +#: ../src/itdb_itunesdb.c:5193 #, c-format msgid "Error opening '%s' for writing (%s)." msgstr "Fel när '%s' skulle öppnas för skrivning (%s)." -#: ../src/itdb_itunesdb.c:4953 +#: ../src/itdb_itunesdb.c:5210 #, c-format msgid "Error while reading from '%s' (%s)." msgstr "Fel vid läsning från '%s' (%s)." -#: ../src/itdb_itunesdb.c:4969 +#: ../src/itdb_itunesdb.c:5226 #, c-format msgid "Error while writing to '%s' (%s)." msgstr "Fel vid skrivning till '%s' (%s)." -#: ../src/itdb_itunesdb.c:4982 ../src/itdb_itunesdb.c:4992 +#: ../src/itdb_itunesdb.c:5239 ../src/itdb_itunesdb.c:5249 #, c-format msgid "Error when closing '%s' (%s)." msgstr "Fel när '%s' skulle stängas (%s)." #. New action! -#: ../src/itdb_playlist.c:71 +#: ../src/itdb_playlist.c:78 #, c-format msgid "Unknown action (%d) in smart playlist will be ignored.\n" msgstr "Okänd åtgärd (%d) i smart spellista kommer att ignoreras.\n" -#~ msgid "Did not find SLst hunk as expected. Trying to continue.\n" -#~ msgstr "Hittade inte SLst data som förväntat. Försöker fortsätta ändå.\n" - -#~ msgid "Database in memory corrupt (track pointer == NULL). Aborting export." -#~ msgstr "Databas i minnet skadad (spårpekare == NULL). Avbryter export." - -#~ msgid "" -#~ "Database in memory corrupt (playlist pointer == NULL). Aborting export." -#~ msgstr "Databas i minnet skadad (spårlistepekare == NULL). Avbryter export." diff --git a/src/Makefile.am b/src/Makefile.am index b2c70d4..5d6de47 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,7 @@ libgpod_la_SOURCES = \ itdb_itunesdb.c \ itdb_playlist.c \ itdb_private.h \ + itdb_photoalbum.c \ itdb_track.c \ db-artwork-parser.c \ db-artwork-parser.h \ diff --git a/src/db-artwork-debug.c b/src/db-artwork-debug.c index 5d8d3b8..e632db3 100644 --- a/src/db-artwork-debug.c +++ b/src/db-artwork-debug.c @@ -76,7 +76,8 @@ dump_mhod_type_1 (MhodHeaderArtworkType1 *mhod1) g_print ("MHOD [artwork type 1] (%d):\n", sizeof (MhodHeaderArtworkType1)); g_print ("\tHeader length: %d\n", GINT_FROM_LE (mhod1->header_len)); g_print ("\tTotal length: %d\n", GINT_FROM_LE (mhod1->total_len)); - g_print ("\tType: %08x\n", GINT_FROM_LE (mhod1->type)); + g_print ("\tPadding: %04x\n", GINT_FROM_LE (mhod1->padding)); + g_print ("\tType: %04x\n", GINT_FROM_LE (mhod1->type)); g_print ("\tUnknown1: %08x\n", GINT_FROM_LE (mhod1->unknown1)); g_print ("\tUnknown2: %08x\n", GINT_FROM_LE (mhod1->unknown2)); g_print ("\tString length: %u\n", GINT_FROM_LE (mhod1->string_len)); @@ -87,14 +88,15 @@ dump_mhod_type_1 (MhodHeaderArtworkType1 *mhod1) } G_GNUC_INTERNAL void -dump_mhod_type_3 (MhodHeaderArtworkType3 *mhod3) +dump_mhod_type_3 (ArtworkDB_MhodHeaderArtworkType3 *mhod3) { gchar *str; - g_print ("MHOD [artwork type 3] (%d):\n", sizeof (MhodHeaderArtworkType3)); + g_print ("MHOD [artwork type 3] (%d):\n", sizeof (ArtworkDB_MhodHeaderArtworkType3)); g_print ("\tHeader length: %d\n", GINT_FROM_LE (mhod3->header_len)); g_print ("\tTotal length: %d\n", GINT_FROM_LE (mhod3->total_len)); - g_print ("\tType: %08x\n", GINT_FROM_LE (mhod3->type)); + g_print ("\tPadding: %04x\n", GINT_FROM_LE (mhod3->padding)); + g_print ("\tType: %04x\n", GINT_FROM_LE (mhod3->type)); g_print ("\tUnknown1: %08x\n", GINT_FROM_LE (mhod3->unknown1)); g_print ("\tUnknown2: %08x\n", GINT_FROM_LE (mhod3->unknown2)); g_print ("\tString length: %u\n", GINT_FROM_LE (mhod3->string_len)); @@ -120,14 +122,15 @@ dump_mhni (MhniHeader *mhni) GINT_FROM_LE (mhni->correlation_id)); g_print ("\tithmb offset: %u bytes\n", GINT_FROM_LE (mhni->ithmb_offset)); g_print ("\tImage size: %u bytes\n", GINT_FROM_LE (mhni->image_size)); - g_print ("\tUnknown3: %08x\n", GINT_FROM_LE (mhni->unknown3)); + g_print ("\tVertical padding: %d\n", GINT_FROM_LE (mhni->vertical_padding)); + g_print ("\tHorizontal padding: %d\n", GINT_FROM_LE (mhni->horizontal_padding)); g_print ("\tImage dimensions: %ux%u\n", width, height); } G_GNUC_INTERNAL void -dump_mhod (MhodHeader *mhod) +dump_mhod (ArtworkDB_MhodHeader *mhod) { - g_print ("MHOD (%d):\n", sizeof (MhodHeader)); + g_print ("MHOD (%d):\n", sizeof (ArtworkDB_MhodHeader)); g_print ("\tHeader length: %d\n", GINT_FROM_LE (mhod->header_len)); g_print ("\tTotal length: %d\n", GINT_FROM_LE (mhod->total_len)); g_print ("\tType: %08x\n", GINT_FROM_LE (mhod->type)); @@ -147,8 +150,8 @@ dump_mhii (MhiiHeader *mhii) g_print ("\tUnknown4: %08x\n", GINT_FROM_LE (mhii->unknown4)); g_print ("\tUnknown5: %08x\n", GINT_FROM_LE (mhii->unknown5)); g_print ("\tUnknown6: %08x\n", GINT_FROM_LE (mhii->unknown6)); - g_print ("\tUnknown7: %08x\n", GINT_FROM_LE (mhii->unknown7)); - g_print ("\tUnknown8: %08x\n", GINT_FROM_LE (mhii->unknown8)); + g_print ("\tOrig Date: %08x\n", GINT_FROM_LE (mhii->orig_date)); + g_print ("\tDigitised Date: %08x\n", GINT_FROM_LE (mhii->digitised_date)); g_print ("\tImage size: %d bytes\n", GINT_FROM_LE (mhii->orig_img_size)); } @@ -166,9 +169,9 @@ dump_mhl (MhlHeader *mhl, const char *id) } G_GNUC_INTERNAL void -dump_mhsd (MhsdHeader *mhsd) +dump_mhsd (ArtworkDB_MhsdHeader *mhsd) { - g_print ("MHSD (%d):\n", sizeof (MhsdHeader)); + g_print ("MHSD (%d):\n", sizeof (ArtworkDB_MhsdHeader)); g_print ("\tHeader length: %d\n", GINT_FROM_LE (mhsd->header_len)); g_print ("\tTotal length: %d\n", GINT_FROM_LE (mhsd->total_len)); g_print ("\tIndex: %d ", GINT16_FROM_LE (mhsd->index)); @@ -199,10 +202,10 @@ dump_mhfd (MhfdHeader *mhfd) g_print ("\tUnknown2: %08x\n", GINT_FROM_LE (mhfd->unknown2)); g_print ("\tNumber of children: %d\n", GINT_FROM_LE (mhfd->num_children)); g_print ("\tUnknown3: %08x\n", GINT_FROM_LE (mhfd->unknown3)); - g_print ("\tUnknown4: %08x\n", GINT_FROM_LE (mhfd->unknown4)); + g_print ("\tNext id: %08x\n", GINT_FROM_LE (mhfd->next_id)); g_print ("\tUnknown5: %016llx\n", GINT64_FROM_LE (mhfd->unknown5)); g_print ("\tUnknown6: %016llx\n", GINT64_FROM_LE (mhfd->unknown6)); - g_print ("\tUnknown7: %08x\n", GINT_FROM_LE (mhfd->unknown7)); + g_print ("\tunknown_flag1: %04x\n", GINT_FROM_LE (mhfd->unknown_flag1)); g_print ("\tUnknown8: %08x\n", GINT_FROM_LE (mhfd->unknown8)); g_print ("\tUnknown9: %08x\n", GINT_FROM_LE (mhfd->unknown9)); g_print ("\tUnknown10: %08x\n", GINT_FROM_LE (mhfd->unknown10)); @@ -212,8 +215,6 @@ dump_mhfd (MhfdHeader *mhfd) G_GNUC_INTERNAL void dump_mhba (MhbaHeader *mhba) { - int i; - g_print ("MHBA (%d):\n", sizeof (MhbaHeader)); g_print ("\tHeader length: %d\n", GINT_FROM_LE (mhba->header_len)); g_print ("\tTotal length: %d\n", GINT_FROM_LE (mhba->total_len)); @@ -221,9 +222,12 @@ dump_mhba (MhbaHeader *mhba) g_print ("\tNumber of pictures in the album: %d\n", GINT_FROM_LE (mhba->num_mhias)); g_print ("\tPlaylist ID: %08x\n", GINT_FROM_LE (mhba->playlist_id)); g_print ("\tUnknown2: %08x\n", GINT_FROM_LE (mhba->unknown2)); - g_print ("\tUnknown3: %08x\n", GINT_FROM_LE (mhba->unknown3)); - for (i = 0; i < 7; i++) - g_print ("\tUnknown[%d]: %08x\n", i, GINT_FROM_LE (mhba->unknown[i])); + g_print ("\tUnknown3: %04x\n", GINT_FROM_LE (mhba->unknown3)); + g_print ("\tMaster playlist: %02x\n", GINT_FROM_LE (mhba->master)); + g_print ("\tRepeat: %02x\n", GINT_FROM_LE (mhba->repeat)); + g_print ("\tRandom: %02x\n", GINT_FROM_LE (mhba->random)); + g_print ("\tTransition direction: %02x\n", GINT_FROM_LE (mhba->transition_direction)); + g_print ("\tSlide duration: %08x\n", GINT_FROM_LE (mhba->slide_duration)); g_print ("\tPrev playlist ID: %08x\n", GINT_FROM_LE (mhba->prev_playlist_id)); } diff --git a/src/db-artwork-debug.h b/src/db-artwork-debug.h index df35058..cd4d4d3 100644 --- a/src/db-artwork-debug.h +++ b/src/db-artwork-debug.h @@ -32,12 +32,12 @@ extern G_GNUC_INTERNAL void dump_mhif (MhifHeader *mhif); extern G_GNUC_INTERNAL void dump_mhia (MhiaHeader *mhia); extern G_GNUC_INTERNAL void dump_mhod_type_1 (MhodHeaderArtworkType1 *mhod); -extern G_GNUC_INTERNAL void dump_mhod_type_3 (MhodHeaderArtworkType3 *mhod); +extern G_GNUC_INTERNAL void dump_mhod_type_3 (ArtworkDB_MhodHeaderArtworkType3 *mhod); extern G_GNUC_INTERNAL void dump_mhni (MhniHeader *mhni); -extern G_GNUC_INTERNAL void dump_mhod (MhodHeader *mhod); +extern G_GNUC_INTERNAL void dump_mhod (ArtworkDB_MhodHeader *mhod); extern G_GNUC_INTERNAL void dump_mhii (MhiiHeader *mhii); extern G_GNUC_INTERNAL void dump_mhl (MhlHeader *mhl, const char *id); -extern G_GNUC_INTERNAL void dump_mhsd (MhsdHeader *mhsd); +extern G_GNUC_INTERNAL void dump_mhsd (ArtworkDB_MhsdHeader *mhsd); extern G_GNUC_INTERNAL void dump_mhfd (MhfdHeader *mhfd); extern G_GNUC_INTERNAL void dump_mhba (MhbaHeader *mhba); #else diff --git a/src/db-artwork-parser.c b/src/db-artwork-parser.c index 17dd390..df80305 100644 --- a/src/db-artwork-parser.c +++ b/src/db-artwork-parser.c @@ -31,6 +31,7 @@ #include <sys/types.h> #include "itdb.h" +#include "itdb_private.h" #include "itdb_endianness.h" #include "db-artwork-debug.h" #include "db-artwork-parser.h" @@ -39,9 +40,9 @@ #include "db-parse-context.h" #include <glib/gi18n-lib.h> -typedef int (*ParseListItem)(DBParseContext *ctx, Itdb_iTunesDB *db, GError *error); +typedef int (*ParseListItem)(DBParseContext *ctx, GError *error); -#ifndef DEBUG_ARTWORKDB +#ifndef NOT_DEFINED_DEBUG_ARTWORKDB static Itdb_Track * get_song_by_dbid (Itdb_iTunesDB *db, guint64 id) { @@ -61,7 +62,7 @@ get_song_by_dbid (Itdb_iTunesDB *db, guint64 id) static int -parse_mhif (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) +parse_mhif (DBParseContext *ctx, GError *error) { MhifHeader *mhif; @@ -70,21 +71,25 @@ parse_mhif (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) return -1; } dump_mhif (mhif); - db_parse_context_set_total_len (ctx, get_gint32_db (db, mhif->total_len)); + db_parse_context_set_total_len (ctx, get_gint32 (mhif->total_len, ctx->byte_order)); return 0; } static int -parse_mhia (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) +parse_mhia (DBParseContext *ctx, Itdb_PhotoAlbum *photo_album, GError *error) { MhiaHeader *mhia; + gint image_id; 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, get_gint32_db (db, mhia->total_len)); + image_id = get_gint32 (mhia->image_id, ctx->byte_order); + photo_album->members = g_list_append (photo_album->members + , GINT_TO_POINTER(image_id)); + db_parse_context_set_total_len (ctx, get_gint32_db (ctx->db, mhia->total_len)); return 0; } @@ -109,22 +114,20 @@ get_utf16_string (void* buffer, gint length, guint byte_order) } static char * -mhod3_get_ithmb_filename (ArtworkDB_MhodHeaderArtworkType3 *mhod3, - Itdb_iTunesDB *db) +mhod3_get_ithmb_filename (DBParseContext *ctx, ArtworkDB_MhodHeaderArtworkType3 *mhod3) { char *filename=NULL; g_assert (mhod3 != NULL); - g_assert (db != NULL); if (mhod3->mhod_version == 2) filename = get_utf16_string ((gunichar2 *)mhod3->string, - get_gint32_db (db, mhod3->string_len), - db->device->byte_order); + get_gint32 (mhod3->string_len, ctx->byte_order), + ctx->byte_order); else if ((mhod3->mhod_version == 0) || (mhod3->mhod_version == 1)) filename = g_strndup (mhod3->string, - get_gint32_db (db, mhod3->string_len)); + get_gint32 (mhod3->string_len, ctx->byte_order)); else g_warning (_("Unexpected mhod3 string type: %d\n"), mhod3->mhod_version); @@ -133,7 +136,7 @@ mhod3_get_ithmb_filename (ArtworkDB_MhodHeaderArtworkType3 *mhod3, static int -parse_mhod_3 (DBParseContext *ctx, Itdb_iTunesDB *db, +parse_mhod_3 (DBParseContext *ctx, Itdb_Thumb *thumb, GError *error) { ArtworkDB_MhodHeader *mhod; @@ -144,23 +147,23 @@ parse_mhod_3 (DBParseContext *ctx, Itdb_iTunesDB *db, if (mhod == NULL) { return -1; } - db_parse_context_set_total_len (ctx, get_gint32_db (db, mhod->total_len)); + db_parse_context_set_total_len (ctx, get_gint32 (mhod->total_len, ctx->byte_order)); - if (get_gint32_db (db, mhod->total_len) < sizeof (ArtworkDB_MhodHeaderArtworkType3)){ + if (get_gint32 (mhod->total_len, ctx->byte_order) < sizeof (ArtworkDB_MhodHeaderArtworkType3)){ return -1; } mhod3 = (ArtworkDB_MhodHeaderArtworkType3*)mhod; - mhod3_type = get_gint16_db (db, mhod3->type); + mhod3_type = get_gint16 (mhod3->type, ctx->byte_order); if (mhod3_type != MHOD_ARTWORK_TYPE_FILE_NAME) { return -1; } - thumb->filename = mhod3_get_ithmb_filename (mhod3, db); + thumb->filename = mhod3_get_ithmb_filename (ctx, mhod3); dump_mhod_type_3 (mhod3); return 0; } static int -parse_mhni (DBParseContext *ctx, iPodSong *song, GError *error) +parse_photo_mhni (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error) { MhniHeader *mhni; DBParseContext *mhod_ctx; @@ -170,10 +173,40 @@ parse_mhni (DBParseContext *ctx, iPodSong *song, GError *error) if (mhni == NULL) { return -1; } - db_parse_context_set_total_len (ctx, get_gint32_db (song->itdb, mhni->total_len)); + db_parse_context_set_total_len (ctx, get_gint32 (mhni->total_len, ctx->byte_order)); dump_mhni (mhni); - thumb = ipod_image_new_from_mhni (mhni, song->itdb); + thumb = ipod_image_new_from_mhni (mhni, ctx->db); + if (thumb == NULL) { + return 0; + } + + artwork->thumbnails = g_list_append (artwork->thumbnails, thumb); + + mhod_ctx = db_parse_context_get_sub_context (ctx, ctx->header_len); + if (mhod_ctx == NULL) { + return -1; + } + parse_mhod_3 (mhod_ctx, thumb, error); + g_free (mhod_ctx); + + return 0; +} + +static int +parse_mhni (DBParseContext *ctx, iPodSong *song, GError *error) +{ + MhniHeader *mhni; + DBParseContext *mhod_ctx; + Itdb_Thumb *thumb; + + mhni = db_parse_context_get_m_header (ctx, MhniHeader, "mhni"); + if (mhni == NULL) { + return -1; + } + db_parse_context_set_total_len (ctx, get_gint32 (mhni->total_len, ctx->byte_order)); + dump_mhni (mhni); + thumb = ipod_image_new_from_mhni (mhni, ctx->db); if (thumb == NULL) { return 0; } @@ -185,26 +218,24 @@ parse_mhni (DBParseContext *ctx, iPodSong *song, GError *error) if (mhod_ctx == NULL) { return -1; } - parse_mhod_3 (mhod_ctx, song->itdb, thumb, error); + parse_mhod_3 (mhod_ctx, thumb, error); g_free (mhod_ctx); return 0; } static int -parse_mhod (DBParseContext *ctx, iPodSong *song, GError *error) +parse_photo_mhod (DBParseContext *ctx, Itdb_Artwork *artwork, GError *error) { ArtworkDB_MhodHeader *mhod; DBParseContext *mhni_ctx; int type; - gint32 total_len; mhod = db_parse_context_get_m_header (ctx, ArtworkDB_MhodHeader, "mhod"); if (mhod == NULL) { return -1; } - total_len = get_gint32_db (song->itdb, mhod->total_len); - db_parse_context_set_total_len (ctx, total_len); + db_parse_context_set_total_len (ctx, get_gint32 (mhod->total_len, ctx->byte_order)); /* The MHODs found in the ArtworkDB and Photo Database files are * significantly different than those found in the iTunesDB. @@ -212,11 +243,48 @@ parse_mhod (DBParseContext *ctx, iPodSong *song, GError *error) * - low 3 bytes are actual type; * - high byte is padding length of string (0-3). */ - type = get_gint16_db (song->itdb, mhod->type); - if (type == MHOD_ARTWORK_TYPE_ALBUM_NAME) + type = get_gint16 (mhod->type, ctx->byte_order) & 0x00FFFFFF; + + if ( type == MHOD_ARTWORK_TYPE_ALBUM_NAME) { dump_mhod_type_1 ((MhodHeaderArtworkType1 *)mhod); - else + } 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_photo_mhni (mhni_ctx, artwork, NULL); + g_free (mhni_ctx); + } + + return 0; +} +static int +parse_mhod (DBParseContext *ctx, iPodSong *song, GError *error) +{ + ArtworkDB_MhodHeader *mhod; + DBParseContext *mhni_ctx; + int type; + gint32 total_len; + + mhod = db_parse_context_get_m_header (ctx, ArtworkDB_MhodHeader, "mhod"); + if (mhod == NULL) { + return -1; + } + total_len = get_gint32 (mhod->total_len, ctx->byte_order); + db_parse_context_set_total_len (ctx, total_len); + + type = get_gint16 (mhod->type, ctx->byte_order); + + 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) { @@ -233,60 +301,81 @@ parse_mhod (DBParseContext *ctx, iPodSong *song, GError *error) static int -parse_mhii (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) +parse_mhii (DBParseContext *ctx, GError *error) { MhiiHeader *mhii; DBParseContext *mhod_ctx; int num_children; off_t cur_offset; iPodSong *song; + Itdb_Artwork *artwork; mhii = db_parse_context_get_m_header (ctx, MhiiHeader, "mhii"); if (mhii == NULL) { return -1; } - db_parse_context_set_total_len (ctx, get_gint32_db (db, mhii->total_len)); - + db_parse_context_set_total_len (ctx, get_gint32 (mhii->total_len, ctx->byte_order)); dump_mhii (mhii); -#ifdef DEBUG_ARTWORKDB - song = NULL; -#else - song = get_song_by_dbid (db, get_gint64_db (db, mhii->song_id)); - if (song == NULL) { - return -1; - } - - song->artwork->artwork_size = get_gint32_db (db, mhii->orig_img_size); - if ((song->artwork_size+song->artwork_count) != - song->artwork->artwork_size) { - g_warning (_("iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)"), song->artwork_size, song->artwork_count, song->artwork->artwork_size); - } + switch (ctx->db->db_type) { + case DB_TYPE_PHOTO: + artwork = g_new0( Itdb_Artwork, 1 ); + artwork->type = ITDB_PHOTO; + artwork->artwork_size = get_gint32 (mhii->orig_img_size, ctx->byte_order); + artwork->id = get_gint32 (mhii->image_id, ctx->byte_order); + artwork->creation_date = itdb_time_mac_to_host( get_gint32 (mhii->digitised_date, ctx->byte_order) ); - song->artwork->id = get_gint32_db (db, mhii->image_id); + 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); + num_children--; + cur_offset += mhod_ctx->total_len; + g_free (mhod_ctx); + mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset); + } + ctx->db->db.photodb->photos = g_list_append (ctx->db->db.photodb->photos, artwork); + break; + case DB_TYPE_ITUNES: +#ifdef NOT_DEFINED_DEBUG_ARTWORKDB + song = NULL; +#else + song = get_song_by_dbid (ctx->db->db.itdb, get_gint64 (mhii->song_id, ctx->byte_order)); + if (song == NULL) { + return -1; + } + song->artwork->artwork_size = get_gint32 (mhii->orig_img_size, ctx->byte_order); + if ((song->artwork_size+song->artwork_count) != + song->artwork->artwork_size) { + g_warning (_("iTunesDB and ArtworkDB artwork sizes inconsistent (%d+%d != %d)"), song->artwork_size, song->artwork_count, song->artwork->artwork_size); + } + song->artwork->id = get_gint32 (mhii->image_id, ctx->byte_order); #endif - cur_offset = ctx->header_len; - mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset); - num_children = get_gint32_db (db, mhii->num_children); - while ((num_children > 0) && (mhod_ctx != NULL)) { - parse_mhod (mhod_ctx, song, NULL); - num_children--; - cur_offset += mhod_ctx->total_len; - g_free (mhod_ctx); + 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_mhod (mhod_ctx, song, NULL); + num_children--; + cur_offset += mhod_ctx->total_len; + g_free (mhod_ctx); + mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset); + } + break; } - return 0; } - static int -parse_mhba (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) +parse_mhba (DBParseContext *ctx, GError *error) { MhbaHeader *mhba; + ArtworkDB_MhodHeader *mhod; DBParseContext *mhod_ctx; DBParseContext *mhia_ctx; + Itdb_PhotoAlbum *photo_album; int num_children; off_t cur_offset; @@ -294,36 +383,49 @@ parse_mhba (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error) if (mhba == NULL) { return -1; } - db_parse_context_set_total_len (ctx, get_gint32_db (db, mhba->total_len)); + db_parse_context_set_total_len (ctx, get_gint32 (mhba->total_len, ctx->byte_order)); dump_mhba (mhba); + photo_album = g_new0 (Itdb_PhotoAlbum, 1); + photo_album->num_images = get_gint32( mhba->num_mhias, ctx->byte_order); + photo_album->album_id = get_gint32( mhba->playlist_id, ctx->byte_order); + photo_album->master = get_gint32( mhba->master, ctx->byte_order); + photo_album->prev_album_id = get_gint32( mhba->prev_playlist_id, ctx->byte_order); + cur_offset = ctx->header_len; mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset); - num_children = get_gint32_db (db, mhba->num_mhods); + num_children = get_gint32 (mhba->num_mhods, ctx->byte_order); while ((num_children > 0) && (mhod_ctx != NULL)) { - parse_mhod (mhod_ctx, NULL, NULL); - num_children--; + /* FIXME: First mhod is album name, whats the others for? */ + mhod = db_parse_context_get_m_header (mhod_ctx, ArtworkDB_MhodHeader, "mhod"); + if (mhod == NULL) { + return -1; + } + db_parse_context_set_total_len (mhod_ctx, get_gint32(mhod->total_len, ctx->byte_order)); + photo_album->name = g_strdup( (char *)((MhodHeaderArtworkType1*)mhod)->string ); cur_offset += mhod_ctx->total_len; + dump_mhod_type_1 ((MhodHeaderArtworkType1*)mhod); g_free (mhod_ctx); - mhod_ctx = db_parse_context_get_sub_context (ctx, cur_offset); + num_children--; } + mhia_ctx = db_parse_context_get_sub_context (ctx, cur_offset); - num_children = get_gint32_db (db, mhba->num_mhias); + num_children = get_gint32 (mhba->num_mhias, ctx->byte_order); while ((num_children > 0) && (mhia_ctx != NULL)) { - parse_mhia (mhia_ctx, db, NULL); + parse_mhia (mhia_ctx, photo_album, NULL); num_children--; cur_offset += mhia_ctx->total_len; g_free (mhia_ctx); mhia_ctx = db_parse_context_get_sub_context (ctx, cur_offset); } - + ctx->db->db.photodb->photoalbums = g_list_append (ctx->db->db.photodb->photoalbums, photo_album); return 0; } static int -parse_mhl (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error, +parse_mhl (DBParseContext *ctx, GError *error, const char *id, ParseListItem parse_child) { MhlHeader *mhl; @@ -338,7 +440,7 @@ parse_mhl (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error, dump_mhl (mhl, id); - num_children = get_gint32_db (db, mhl->num_children); + num_children = get_gint32 (mhl->num_children, ctx->byte_order); if (num_children < 0) { return -1; } @@ -347,7 +449,7 @@ parse_mhl (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error, mhi_ctx = db_parse_context_get_sub_context (ctx, cur_offset); while ((num_children > 0) && (mhi_ctx != NULL)) { if (parse_child != NULL) { - parse_child (mhi_ctx, db, NULL); + parse_child (mhi_ctx, NULL); } num_children--; cur_offset += mhi_ctx->total_len; @@ -361,7 +463,7 @@ parse_mhl (DBParseContext *ctx, Itdb_iTunesDB *db, GError *error, static int -parse_mhsd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) +parse_mhsd (DBParseContext *ctx, GError **error) { ArtworkDB_MhsdHeader *mhsd; @@ -370,33 +472,33 @@ parse_mhsd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) return -1; } - db_parse_context_set_total_len (ctx, get_gint32_db (db, mhsd->total_len)); + db_parse_context_set_total_len (ctx, get_gint32 (mhsd->total_len, ctx->byte_order)); dump_mhsd (mhsd); - switch (get_gint16_db (db, mhsd->index)) { + switch (get_gint16_db (ctx->db, mhsd->index)) { case MHSD_IMAGE_LIST: { DBParseContext *mhli_context; mhli_context = db_parse_context_get_next_child (ctx); - parse_mhl (mhli_context, db, NULL, "mhli", parse_mhii); + parse_mhl (mhli_context, NULL, "mhli", parse_mhii); g_free (mhli_context); break; } case MHSD_ALBUM_LIST: { DBParseContext *mhla_context; mhla_context = db_parse_context_get_next_child (ctx); - parse_mhl (mhla_context, db, NULL, "mhla", parse_mhba); + parse_mhl (mhla_context, NULL, "mhla", parse_mhba); g_free (mhla_context); break; } case MHSD_FILE_LIST: { DBParseContext *mhlf_context; mhlf_context = db_parse_context_get_next_child (ctx); - parse_mhl (mhlf_context, db, NULL, "mhlf", parse_mhif); + parse_mhl (mhlf_context, NULL, "mhlf", parse_mhif); g_free (mhlf_context); break; } default: g_warning (_("Unexpected mhsd index: %d\n"), - get_gint16_db (db, mhsd->index)); + get_gint16_db (ctx->db, mhsd->index)); return -1; break; } @@ -406,7 +508,7 @@ parse_mhsd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) /* Database Object */ static int -parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) +parse_mhfd (DBParseContext *ctx, GError **error) { MhfdHeader *mhfd; DBParseContext *mhsd_context; @@ -419,7 +521,7 @@ parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) } /* Sanity check */ - total_len = get_gint32_db (db, mhfd->total_len); + total_len = get_gint32_db (ctx->db, mhfd->total_len); g_return_val_if_fail (total_len == ctx->total_len, -1); dump_mhfd (mhfd); cur_pos = ctx->header_len; @@ -432,7 +534,7 @@ parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) if (mhsd_context == NULL) { return -1; } - parse_mhsd (mhsd_context, db, NULL); + parse_mhsd (mhsd_context, NULL); cur_pos += mhsd_context->total_len; g_free (mhsd_context); @@ -440,7 +542,7 @@ parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) if (mhsd_context == NULL) { return -1; } - parse_mhsd (mhsd_context, db, NULL); + parse_mhsd (mhsd_context, NULL); cur_pos += mhsd_context->total_len; g_free (mhsd_context); @@ -448,7 +550,7 @@ parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error) if (mhsd_context == NULL) { return -1; } - parse_mhsd (mhsd_context, db, NULL); + parse_mhsd (mhsd_context, NULL); cur_pos += mhsd_context->total_len; g_free (mhsd_context); @@ -476,13 +578,13 @@ ipod_db_get_artwork_db_path (const char *mount_point) { /* attempt to create Artwork dir */ gchar *control_dir = itdb_get_control_dir (mount_point); - gchar *dir; if (control_dir) { - dir = g_build_filename (control_dir, "Artwork", NULL); + gchar *dir = g_build_filename (control_dir, "Artwork", NULL); mkdir (dir, 0777); - g_free (dir); g_free (control_dir); + g_free (dir); + artwork_dir = itdb_get_artwork_dir (mount_point); } } if (artwork_dir) @@ -496,7 +598,6 @@ ipod_db_get_artwork_db_path (const char *mount_point) return filename; } - static gboolean ipod_supports_cover_art (Itdb_Device *device) { @@ -523,19 +624,22 @@ ipod_supports_cover_art (Itdb_Device *device) } int -ipod_parse_artwork_db (Itdb_iTunesDB *db) +ipod_parse_artwork_db (Itdb_iTunesDB *itdb) { DBParseContext *ctx; char *filename; + Itdb_DB db; + + db.db.itdb = itdb; + db.db_type = DB_TYPE_ITUNES; - g_return_val_if_fail (db, -1); - g_return_val_if_fail (db->device, -1); + g_return_val_if_fail (itdb, -1); - if (!ipod_supports_cover_art (db->device)) { + if (!ipod_supports_cover_art (db.db.itdb->device)) { return -1; } ctx = NULL; - filename = ipod_db_get_artwork_db_path (itdb_get_mountpoint (db)); + filename = ipod_db_get_artwork_db_path (itdb_get_mountpoint (db.db.itdb)); if (filename == NULL) { goto error; } @@ -544,14 +648,13 @@ ipod_parse_artwork_db (Itdb_iTunesDB *db) goto error; } - ctx = db_parse_context_new_from_file (filename, - db->device->byte_order); + ctx = db_parse_context_new_from_file (filename, &db); g_free (filename); if (ctx == NULL) { goto error; } - parse_mhfd (ctx, db, NULL); + parse_mhfd (ctx, NULL); db_parse_context_destroy (ctx, TRUE); return 0; @@ -562,35 +665,68 @@ ipod_parse_artwork_db (Itdb_iTunesDB *db) return -1; } -#if 0 -static char * -ipod_db_get_photo_db_path (const char *mount_point) + +G_GNUC_INTERNAL char * +ipod_db_get_photos_db_path (const char *mount_point) { - const char *paths[] = {"Photos", "Photo Database", NULL}; - g_return_val_if_fail (mount_point != NULL, NULL); - return itdb_resolve_path (mount_point, paths); - + gchar *filename=NULL; + + /* fail silently if no mount point given */ + if (!mount_point) return NULL; + + filename = itdb_get_photodb_path (mount_point); + + /* itdb_resolve_path() only returns existing paths */ + if (!filename) + { + gchar *photos_dir; + + photos_dir = itdb_get_photos_dir (mount_point); + if (!photos_dir) + { + /* attempt to create Photos dir */ + gchar *dir = g_build_filename (mount_point, "Photos", NULL); + mkdir (dir, 0777); + g_free (dir); + photos_dir = itdb_get_photos_dir (mount_point); + } + if (photos_dir) + { + filename = g_build_filename (photos_dir, + "Photo Database", NULL); + g_free (photos_dir); + } + } + + return filename; } + int -ipod_parse_photo_db (const char *mount_point) +ipod_parse_photo_db (Itdb_PhotoDB *photodb) { DBParseContext *ctx; char *filename; + Itdb_DB db; + + db.db.photodb = photodb; + db.db_type = DB_TYPE_PHOTO; - filename = ipod_db_get_photo_db_path (mount_point); + + filename = itdb_get_photodb_path ( + itdb_photodb_get_mountpoint (photodb)); if (filename == NULL) { return -1; } - ctx = db_parse_context_new_from_file (filename); + + ctx = db_parse_context_new_from_file (filename, &db ); g_free (filename); if (ctx == NULL) { return -1; } - - parse_mhfd (ctx, NULL, NULL); + parse_mhfd (ctx, NULL); db_parse_context_destroy (ctx, TRUE); return 0; } -#endif + diff --git a/src/db-artwork-parser.h b/src/db-artwork-parser.h index c97ee17..eb84e8d 100644 --- a/src/db-artwork-parser.h +++ b/src/db-artwork-parser.h @@ -30,11 +30,10 @@ #define iPodSong Itdb_Track -G_GNUC_INTERNAL char *ipod_db_get_artwork_db_path (const char *mount_point); G_GNUC_INTERNAL int ipod_parse_artwork_db (Itdb_iTunesDB *db); -G_GNUC_INTERNAL int ipod_write_artwork_db (Itdb_iTunesDB *db); - -#if 0 -G_GNUC_INTERNAL int ipod_parse_photo_db (const char *filename); -#endif +G_GNUC_INTERNAL int ipod_write_artwork_db (Itdb_iTunesDB *itdb); +G_GNUC_INTERNAL char *ipod_db_get_artwork_db_path (const char *mount_point); +G_GNUC_INTERNAL char *ipod_db_get_photos_db_path (const char *mount_point); +G_GNUC_INTERNAL int ipod_parse_photo_db (Itdb_PhotoDB *photodb); +G_GNUC_INTERNAL int ipod_write_photo_db (Itdb_PhotoDB *db); #endif diff --git a/src/db-artwork-writer.c b/src/db-artwork-writer.c index 2b8d91b..079644c 100644 --- a/src/db-artwork-writer.c +++ b/src/db-artwork-writer.c @@ -24,6 +24,7 @@ #include <config.h> #include "itdb.h" +#include "itdb_private.h" #include "db-artwork-parser.h" #if HAVE_GDKPIXBUF @@ -59,6 +60,7 @@ struct _iPodBuffer { struct iPodMmapBuffer *mmap; off_t offset; guint byte_order; + DbType db_type; }; typedef struct _iPodBuffer iPodBuffer; @@ -175,6 +177,7 @@ ipod_buffer_get_sub_buffer (iPodBuffer *buffer, off_t offset) sub_buffer->mmap = buffer->mmap; sub_buffer->offset = buffer->offset + offset; sub_buffer->byte_order = buffer->byte_order; + sub_buffer->db_type = buffer->db_type; buffer->mmap->ref_count++; @@ -182,7 +185,7 @@ ipod_buffer_get_sub_buffer (iPodBuffer *buffer, off_t offset) } static iPodBuffer * -ipod_buffer_new (const char *filename, guint byte_order) +ipod_buffer_new (const char *filename, guint byte_order, DbType db_type) { int fd; struct iPodMmapBuffer *mmap_buf; @@ -228,6 +231,7 @@ ipod_buffer_new (const char *filename, guint byte_order) } buffer->mmap = mmap_buf; buffer->byte_order = byte_order; + buffer->db_type = db_type; return buffer; } @@ -239,8 +243,10 @@ enum MhsdType { }; enum iPodThumbnailType { - IPOD_THUMBNAIL_FULL_SIZE, - IPOD_THUMBNAIL_NOW_PLAYING + IPOD_THUMBNAIL_FULL_SIZE = 0, + IPOD_THUMBNAIL_NOW_PLAYING = 1, + IPOD_PHOTO_LITTLE = 3, + IPOD_PHOTO_FULL_SIZE = 4 }; @@ -262,6 +268,7 @@ get_padded_header_size (gchar header_id[4]) RETURN_SIZE_FOR ("mhla", 0x5c); RETURN_SIZE_FOR ("mhlf", 0x5c); RETURN_SIZE_FOR ("mhif", 0x7c); + RETURN_SIZE_FOR ("mhba", 0x94); return 0; } @@ -297,15 +304,57 @@ init_header (iPodBuffer *buffer, gchar _header_id[4], guint header_len) static int -write_mhod_type_3 (Itdb_Thumb *thumb, iPodBuffer *buffer) +write_mhod_type_1 (gchar *string, iPodBuffer *buffer) +{ + MhodHeaderArtworkType1 *mhod; + unsigned int total_bytes; + int len; + int padding; + + g_assert (string != NULL); + + mhod = (MhodHeaderArtworkType1 *)init_header (buffer, "mhod", + sizeof (MhodHeaderArtworkType1)); + if (mhod == NULL) { + return -1; + } + total_bytes = sizeof (MhodHeaderArtworkType1); + mhod->total_len = get_gint32 (total_bytes, buffer->byte_order); + /* Modify header length, since iTunes only puts the length of + * MhodHeader in header_len + */ + mhod->header_len = get_gint32 (sizeof (ArtworkDB_MhodHeader), buffer->byte_order); + mhod->unknown3 = get_gint32 (0x01, buffer->byte_order); + len = strlen (string); + mhod->string_len = get_gint32 (len, buffer->byte_order); + + padding = 4 - ( (total_bytes + len) % 4 ); + mhod->padding = padding; + mhod->type = get_gint32 (0x0001, buffer->byte_order); + + /* Make sure we have enough free space to write the string */ + if (ipod_buffer_maybe_grow (buffer, total_bytes + len + padding ) != 0) { + return -1; + } + memcpy (mhod->string, string, len); + total_bytes += len + padding; + mhod->total_len = get_gint32 (total_bytes, buffer->byte_order); + + dump_mhod_type_1 (mhod); + + return total_bytes; +} + +static int +write_mhod_type_3 (gchar *string, iPodBuffer *buffer) { ArtworkDB_MhodHeaderArtworkType3 *mhod; unsigned int total_bytes; int len; gunichar2 *utf16, *strp; - int i, pad; + int i, padding; - g_assert (thumb->filename != NULL); + g_assert (string != NULL); mhod = (ArtworkDB_MhodHeaderArtworkType3 *) init_header (buffer, "mhod", @@ -322,26 +371,27 @@ write_mhod_type_3 (Itdb_Thumb *thumb, iPodBuffer *buffer) buffer->byte_order); mhod->type = get_gint16 (3, buffer->byte_order); - len = strlen (thumb->filename); - - /* Make sure we have enough free space to write the string */ - if (ipod_buffer_maybe_grow (buffer, total_bytes + 2*len+2) != 0) { - return -1; - } + len = strlen (string); + /* FIXME: Tidy this up, combine cases more */ /* Some magic: endianess-reversed (BE) mobile phones use UTF8 * (version 1) with padding, standard iPods (LE) use UTF16 * (version 2).*/ - switch (buffer->byte_order) { case G_LITTLE_ENDIAN: mhod->mhod_version = 2; - /* number of bytes of the string encoded in UTF-16 */ mhod->string_len = get_gint32 (2*len, buffer->byte_order); + padding = 4 - ( (total_bytes + 2*len) % 4 ); + mhod->padding = padding; /* high byte is padding length (0-3) */ - utf16 = g_utf8_to_utf16 (thumb->filename, -1, NULL, NULL, NULL); + /* Make sure we have enough free space to write the string */ + if (ipod_buffer_maybe_grow (buffer, total_bytes + 2*len+padding) != 0) { + return -1; + } + + utf16 = g_utf8_to_utf16 (string, -1, NULL, NULL, NULL); if (utf16 == NULL) { return -1; } @@ -351,25 +401,23 @@ write_mhod_type_3 (Itdb_Thumb *thumb, iPodBuffer *buffer) for (i = 0; i < len; i++) { strp[i] = get_gint16 (strp[i], buffer->byte_order); } - total_bytes += 2*len; + total_bytes += 2*len+padding; break; case G_BIG_ENDIAN: mhod->mhod_version = 1; mhod->string_len = get_gint32 (len, buffer->byte_order); - memcpy (mhod->string, thumb->filename, len); /* pad string if necessary */ /* e.g. len = 7 bytes, len%4 = 3, 4-3=1 -> requires 1 byte padding */ - pad = 4 - (len % 4); - if (pad == 4) pad = 0; - for (i=0; i<pad; ++i) - { - mhod->string[len+i] = 0; + padding = 4 - ( (total_bytes + len) % 4 ); + mhod->padding = padding; /* high byte is padding length (0-3) */ + /* Make sure we have enough free space to write the string */ + if (ipod_buffer_maybe_grow (buffer, total_bytes + 2*len+padding) != 0) { + return -1; } - mhod->padding = pad; - total_bytes += (len+pad); + memcpy (mhod->string, string, len); + total_bytes += (len+padding); } - mhod->total_len = get_gint32 (total_bytes, buffer->byte_order); dump_mhod_type_3 (mhod); @@ -378,12 +426,13 @@ write_mhod_type_3 (Itdb_Thumb *thumb, iPodBuffer *buffer) } static int -write_mhni (Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) +write_mhni (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) { MhniHeader *mhni; unsigned int total_bytes; int bytes_written; iPodBuffer *sub_buffer; + const Itdb_ArtworkFormat *format; if (thumb == NULL) { return -1; @@ -397,17 +446,28 @@ write_mhni (Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) total_bytes = get_gint32 (mhni->header_len, buffer->byte_order); mhni->total_len = get_gint32 (total_bytes, buffer->byte_order); - mhni->correlation_id = get_gint32 (correlation_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->correlation_id = get_gint32 (correlation_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); + + /* Work out the image padding */ + format = itdb_device_get_artwork_formats (db->db.photodb->device); + while( format->type != thumb->type && format->type != -1 ) + format++; + mhni->vertical_padding = get_gint16 ( + (format->height - thumb->height) + , buffer->byte_order); + mhni->horizontal_padding = get_gint16 ( + (format->width - thumb->width) + , 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, sub_buffer); + bytes_written = write_mhod_type_3 (thumb->filename, sub_buffer); ipod_buffer_destroy (sub_buffer); if (bytes_written == -1) { return -1; @@ -425,7 +485,7 @@ write_mhni (Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) } static int -write_mhod (Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) +write_mhod (Itdb_DB *db, Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) { ArtworkDB_MhodHeader *mhod; unsigned int total_bytes; @@ -449,7 +509,7 @@ write_mhod (Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) if (sub_buffer == NULL) { return -1; } - bytes_written = write_mhni (thumb, correlation_id, sub_buffer); + bytes_written = write_mhni (db, thumb, correlation_id, sub_buffer); ipod_buffer_destroy (sub_buffer); if (bytes_written == -1) { return -1; @@ -463,25 +523,44 @@ write_mhod (Itdb_Thumb *thumb, int correlation_id, iPodBuffer *buffer) } static int -write_mhii (Itdb_Track *song, iPodBuffer *buffer) +write_mhii (Itdb_DB *db, void *data, iPodBuffer *buffer) { MhiiHeader *mhii; unsigned int total_bytes; int bytes_written; int num_children; - GList *it; + GList *it = NULL; + Itdb_Track *song; + Itdb_Artwork *artwork; mhii = (MhiiHeader *)init_header (buffer, "mhii", sizeof (MhiiHeader)); if (mhii == NULL) { return -1; } total_bytes = get_gint32 (mhii->header_len, buffer->byte_order); - mhii->song_id = get_gint64 (song->dbid, buffer->byte_order); - mhii->image_id = get_guint32 (song->artwork->id, buffer->byte_order); - mhii->orig_img_size = get_gint32 (song->artwork->artwork_size, - buffer->byte_order); + + switch( buffer->db_type) { + case DB_TYPE_ITUNES: + song = (Itdb_Track *)data; + mhii->song_id = get_gint64 (song->dbid, buffer->byte_order); + mhii->image_id = get_guint32 (song->artwork->id, buffer->byte_order); + mhii->orig_img_size = get_gint32 (song->artwork->artwork_size, + buffer->byte_order); + it = song->artwork->thumbnails; + break; + case DB_TYPE_PHOTO: + artwork = (Itdb_Artwork *)data; + mhii->song_id = get_gint64 (artwork->id + 2, buffer->byte_order); + mhii->image_id = get_guint32 (artwork->id, buffer->byte_order); + mhii->orig_date = get_guint32 (itdb_time_host_to_mac( artwork->creation_date ) + , buffer->byte_order); + mhii->digitised_date = get_guint32 (itdb_time_host_to_mac( artwork->creation_date ) + , buffer->byte_order); + it = artwork->thumbnails; + break; + } num_children = 0; - for (it = song->artwork->thumbnails; it != NULL; it = it->next) { + while (it != NULL) { iPodBuffer *sub_buffer; Itdb_Thumb *thumb; const Itdb_ArtworkFormat *img_info; @@ -495,14 +574,11 @@ write_mhii (Itdb_Track *song, iPodBuffer *buffer) } thumb = (Itdb_Thumb *)it->data; img_info = itdb_get_artwork_info_from_type ( - song->itdb->device, thumb->type); + db_get_device(db), thumb->type); if (img_info == NULL) { return -1; } -/* printf("correlation id: %d, type: %d\n", */ -/* img_info->correlation_id, thumb->type); */ -/* printf("title: %s\n", song->title); */ - bytes_written = write_mhod (thumb, img_info->correlation_id, + bytes_written = write_mhod (db, thumb, img_info->correlation_id, sub_buffer); ipod_buffer_destroy (sub_buffer); if (bytes_written == -1) { @@ -510,6 +586,7 @@ write_mhii (Itdb_Track *song, iPodBuffer *buffer) } total_bytes += bytes_written; num_children++; + it = it->next; } mhii->num_children = get_gint32 (num_children, buffer->byte_order); @@ -521,9 +598,9 @@ write_mhii (Itdb_Track *song, iPodBuffer *buffer) } static int -write_mhli (Itdb_iTunesDB *db, iPodBuffer *buffer) +write_mhli (Itdb_DB *db, iPodBuffer *buffer ) { - GList *it; + GList *it = NULL; MhliHeader *mhli; unsigned int total_bytes; int num_thumbs; @@ -535,53 +612,155 @@ write_mhli (Itdb_iTunesDB *db, iPodBuffer *buffer) num_thumbs = 0; total_bytes = get_gint32 (mhli->header_len, buffer->byte_order); - for (it = db->tracks; it != NULL; it = it->next) { + switch (buffer->db_type) { + case DB_TYPE_PHOTO: + it = db->db.photodb->photos; + break; + case DB_TYPE_ITUNES: + it = db->db.itdb->tracks; + break; + } + while (it != NULL) { Itdb_Track *song; int bytes_written; iPodBuffer *sub_buffer; - song = (Itdb_Track*)it->data; - if (song->artwork->id == 0) { - continue; + if (buffer->db_type == DB_TYPE_ITUNES) { + song = (Itdb_Track*)it->data; + if (song->artwork->id == 0) { + it = it->next; + continue; + } } sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes); if (sub_buffer == NULL) { - continue; + break; } - bytes_written = write_mhii (song, sub_buffer); + bytes_written = write_mhii (db, it->data, sub_buffer); ipod_buffer_destroy (sub_buffer); if (bytes_written != -1) { num_thumbs++; total_bytes += bytes_written; - } + } + it = it->next; } - mhli->num_children = get_gint32 (num_thumbs, buffer->byte_order); - dump_mhl ((MhlHeader *)mhli, "mhli"); return total_bytes; } static int -write_mhla (Itdb_iTunesDB *db, iPodBuffer *buffer) +write_mhia (gint image_id, iPodBuffer *buffer) { + MhiaHeader *mhia; + unsigned int total_bytes; + + + mhia = (MhiaHeader *)init_header (buffer, "mhia", 40); + if (mhia == NULL) { + return -1; + } + + mhia->total_len = mhia->header_len; + mhia->image_id = get_gint32 (image_id, buffer->byte_order); + total_bytes = get_gint32 (mhia->header_len, buffer->byte_order); + dump_mhia( mhia ); + return total_bytes; +} + +static int +write_mhba (Itdb_PhotoAlbum *photo_album, iPodBuffer *buffer) +{ + GList *it; + MhbaHeader *mhba; + iPodBuffer *sub_buffer; + unsigned int total_bytes; + unsigned int bytes_written; + + mhba = (MhbaHeader *)init_header (buffer, "mhba", sizeof (MhbaHeader)); + if (mhba == NULL) { + return -1; + } + mhba->num_mhods = get_gint32(1, buffer->byte_order); + mhba->playlist_id = get_gint32(photo_album->album_id, buffer->byte_order); + mhba->master = get_gint32(photo_album->master, buffer->byte_order); + mhba->prev_playlist_id = get_gint32(photo_album->prev_album_id, buffer->byte_order); + mhba->num_mhias = get_gint32(photo_album->num_images, buffer->byte_order); + total_bytes = get_gint32 (mhba->header_len, buffer->byte_order); + + /* FIXME: Write other mhods */ + /* Write album title */ + sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes); + if (sub_buffer == NULL) { + return -1; + } + bytes_written = write_mhod_type_1 (photo_album->name, sub_buffer); + ipod_buffer_destroy (sub_buffer); + if (bytes_written == -1) { + return -1; + } + total_bytes += bytes_written; + + for (it = photo_album->members; it != NULL; it = it->next) { + gint image_id = GPOINTER_TO_INT(it->data); + + sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes); + if (sub_buffer == NULL) { + return -1; + } + bytes_written = write_mhia (image_id, sub_buffer); + ipod_buffer_destroy (sub_buffer); + if (bytes_written == -1) { + return -1; + } + total_bytes += bytes_written; + } + mhba->total_len = get_gint32( total_bytes, buffer->byte_order ); + dump_mhba ( mhba ); + return total_bytes; +} + +static int +write_mhla (Itdb_DB *db, iPodBuffer *buffer) +{ + GList *it; MhlaHeader *mhla; + iPodBuffer *sub_buffer; + unsigned int total_bytes; mhla = (MhlaHeader *)init_header (buffer, "mhla", sizeof (MhlaHeader)); if (mhla == NULL) { return -1; } - - dump_mhl ((MhlHeader *)mhla, "mhla"); + total_bytes = get_gint32 (mhla->header_len, buffer->byte_order); + if (buffer->db_type == DB_TYPE_PHOTO) { + unsigned int bytes_written; - return get_gint32 (mhla->header_len, buffer->byte_order); -} + for (it = db->db.photodb->photoalbums; it != NULL; it = it->next) { + Itdb_PhotoAlbum *photo_album = (Itdb_PhotoAlbum *)it->data; + sub_buffer = ipod_buffer_get_sub_buffer (buffer, total_bytes); + if (sub_buffer == NULL) { + return -1; + } + bytes_written = write_mhba (photo_album, sub_buffer); + ipod_buffer_destroy (sub_buffer); + if (bytes_written == -1) { + return -1; + } + total_bytes += bytes_written; + mhla->num_children++; + } + } + dump_mhl ((MhlHeader *)mhla, "mhla"); + + return total_bytes; +} static int -write_mhif (Itdb_iTunesDB *db, iPodBuffer *buffer, enum iPodThumbnailType type) +write_mhif (Itdb_DB *db, iPodBuffer *buffer, enum iPodThumbnailType type) { MhifHeader *mhif; const Itdb_ArtworkFormat *img_info; @@ -592,11 +771,10 @@ write_mhif (Itdb_iTunesDB *db, iPodBuffer *buffer, enum iPodThumbnailType type) } mhif->total_len = mhif->header_len; - img_info = itdb_get_artwork_info_from_type (db->device, type); + img_info = itdb_get_artwork_info_from_type (db_get_device(db), type); if (img_info == NULL) { return -1; } - mhif->correlation_id = get_gint32 (img_info->correlation_id, buffer->byte_order); mhif->image_size = get_gint32 (img_info->height * img_info->width * 2, @@ -607,14 +785,14 @@ write_mhif (Itdb_iTunesDB *db, iPodBuffer *buffer, enum iPodThumbnailType type) return get_gint32 (mhif->header_len, buffer->byte_order); } - static int -write_mhlf (Itdb_iTunesDB *db, iPodBuffer *buffer) +write_mhlf (Itdb_DB *db, iPodBuffer *buffer) { MhlfHeader *mhlf; unsigned int total_bytes; int bytes_written; iPodBuffer *sub_buffer; + enum iPodThumbnailType thumb_type = IPOD_THUMBNAIL_FULL_SIZE; mhlf = (MhlfHeader *)init_header (buffer, "mhlf", sizeof (MhlfHeader)); if (mhlf == NULL) { @@ -627,7 +805,18 @@ write_mhlf (Itdb_iTunesDB *db, iPodBuffer *buffer) if (sub_buffer == NULL) { return -1; } - bytes_written = write_mhif (db, sub_buffer, IPOD_THUMBNAIL_FULL_SIZE); + + switch (buffer->db_type) { + case DB_TYPE_ITUNES: + thumb_type = IPOD_THUMBNAIL_FULL_SIZE; + break; + case DB_TYPE_PHOTO: + thumb_type = IPOD_PHOTO_FULL_SIZE; + break; + } + bytes_written = write_mhif (db + , sub_buffer + , thumb_type); ipod_buffer_destroy (sub_buffer); if (bytes_written == -1) { return -1; @@ -647,7 +836,18 @@ write_mhlf (Itdb_iTunesDB *db, iPodBuffer *buffer) if (sub_buffer == NULL) { return -1; } - bytes_written = write_mhif (db, sub_buffer, IPOD_THUMBNAIL_NOW_PLAYING); + + switch (buffer->db_type) { + case DB_TYPE_ITUNES: + thumb_type = IPOD_THUMBNAIL_NOW_PLAYING; + break; + case DB_TYPE_PHOTO: + thumb_type = IPOD_PHOTO_LITTLE; + break; + } + bytes_written = write_mhif (db + , sub_buffer + , thumb_type); ipod_buffer_destroy (sub_buffer); if (bytes_written == -1) { return -1; @@ -670,7 +870,7 @@ write_mhlf (Itdb_iTunesDB *db, iPodBuffer *buffer) static int -write_mhsd (Itdb_iTunesDB *db, iPodBuffer *buffer, enum MhsdType type) +write_mhsd (Itdb_DB *db, iPodBuffer *buffer, enum MhsdType type) { ArtworkDB_MhsdHeader *mhsd; unsigned int total_bytes; @@ -717,7 +917,7 @@ write_mhsd (Itdb_iTunesDB *db, iPodBuffer *buffer, enum MhsdType type) } static int -write_mhfd (Itdb_iTunesDB *db, iPodBuffer *buffer, int id_max) +write_mhfd (Itdb_DB *db, iPodBuffer *buffer, int id_max) { MhfdHeader *mhfd; unsigned int total_bytes; @@ -730,8 +930,15 @@ write_mhfd (Itdb_iTunesDB *db, iPodBuffer *buffer, int id_max) } total_bytes = get_gint32 (mhfd->header_len, buffer->byte_order); mhfd->total_len = get_gint32 (total_bytes, buffer->byte_order); - mhfd->unknown2 = get_gint32 (1, buffer->byte_order); - mhfd->unknown4 = get_gint32 (id_max, buffer->byte_order); + switch (buffer->db_type) { + case DB_TYPE_PHOTO: + mhfd->unknown2 = get_gint32 (2, buffer->byte_order); + break; + case DB_TYPE_ITUNES: + mhfd->unknown2 = get_gint32 (1, buffer->byte_order); + break; + } + mhfd->next_id = get_gint32 (id_max, buffer->byte_order); mhfd->unknown_flag1 = 2; for (i = 1 ; i <= 3; i++) { iPodBuffer *sub_buffer; @@ -776,22 +983,26 @@ ipod_artwork_db_set_ids (Itdb_iTunesDB *db) } int -ipod_write_artwork_db (Itdb_iTunesDB *db) +ipod_write_artwork_db (Itdb_iTunesDB *itdb) { iPodBuffer *buf; int bytes_written; int result; char *filename; int id_max; + Itdb_DB db; + + db.db_type = DB_TYPE_ITUNES; + db.db.itdb = itdb; /* First, let's write the .ithmb files, this will create the * various thumbnails as well */ - itdb_write_ithumb_files (db); + itdb_write_ithumb_files (&db); /* Now we can update the ArtworkDB file */ - id_max = ipod_artwork_db_set_ids (db); + id_max = ipod_artwork_db_set_ids (itdb); - filename = ipod_db_get_artwork_db_path (itdb_get_mountpoint (db)); + filename = ipod_db_get_artwork_db_path (itdb_get_mountpoint (itdb)); if (filename == NULL) { /* FIXME: the iTunesDB will be inconsistent wrt artwork_count * it might be better to 0 out this field in all tracks @@ -799,13 +1010,67 @@ ipod_write_artwork_db (Itdb_iTunesDB *db) */ return -1; } - buf = ipod_buffer_new (filename, db->device->byte_order); + buf = ipod_buffer_new (filename, itdb->device->byte_order, DB_TYPE_ITUNES); + if (buf == NULL) { + g_print ("Couldn't create %s\n", filename); + g_free (filename); + return -1; + } + bytes_written = write_mhfd (&db, buf, id_max); + + /* Refcount of the mmap buffer should drop to 0 and this should + * sync buffered data to disk + * FIXME: it's probably less error-prone to add a ipod_buffer_mmap_sync + * call... + */ + ipod_buffer_destroy (buf); + + if (bytes_written == -1) { + g_print ("Failed to save %s\n", filename); + g_free (filename); + /* FIXME: maybe should unlink the file we may have created */ + return -1; + } + + result = truncate (filename, bytes_written); + if (result != 0) { + g_print ("Failed to truncate %s: %s\n", + filename, strerror (errno)); + g_free (filename); + return -1; + } + g_free (filename); + return 0; +} + +int +ipod_write_photo_db (Itdb_PhotoDB *photodb) +{ + iPodBuffer *buf; + int bytes_written; + int result; + char *filename; + int id_max; + Itdb_DB db; + + db.db_type = DB_TYPE_PHOTO; + db.db.photodb = photodb; + + filename = ipod_db_get_photos_db_path (db_get_mountpoint (&db)); + + itdb_write_ithumb_files (&db); + + if (filename == NULL) { + return -1; + } + buf = ipod_buffer_new (filename, photodb->device->byte_order, DB_TYPE_PHOTO); if (buf == NULL) { g_print ("Couldn't create %s\n", filename); g_free (filename); return -1; } - bytes_written = write_mhfd (db, buf, id_max); + id_max = itdb_get_free_photo_id( photodb ); + bytes_written = write_mhfd (&db, buf, id_max); /* Refcount of the mmap buffer should drop to 0 and this should * sync buffered data to disk @@ -833,7 +1098,13 @@ ipod_write_artwork_db (Itdb_iTunesDB *db) } #else int -ipod_write_artwork_db (Itdb_iTunesDB *db) +ipod_write_artwork_db (Itdb_iTunesDB *itdb) +{ + return -1; +} + +int +ipod_write_photo_db (Itdb_PhotoDB *db) { return -1; } diff --git a/src/db-image-parser.c b/src/db-image-parser.c index 0ae79ae..06f8f1e 100644 --- a/src/db-image-parser.c +++ b/src/db-image-parser.c @@ -87,10 +87,11 @@ itdb_get_artwork_info_from_type (Itdb_Device *device, int image_type) } G_GNUC_INTERNAL Itdb_Thumb * -ipod_image_new_from_mhni (MhniHeader *mhni, Itdb_iTunesDB *db) +ipod_image_new_from_mhni (MhniHeader *mhni, Itdb_DB *db) { Itdb_Thumb *img; gint16 corr_id; + Itdb_Device *device = NULL; img = g_new0 (Itdb_Thumb, 1); if (img == NULL) { @@ -101,9 +102,25 @@ ipod_image_new_from_mhni (MhniHeader *mhni, Itdb_iTunesDB *db) img->width = get_gint16_db (db, mhni->image_width); img->height = get_gint16_db (db, mhni->image_height); + switch (db->db_type) { + case DB_TYPE_ITUNES: + device = db->db.itdb->device; + break; + case DB_TYPE_PHOTO: + device = db->db.photodb->device; + break; + } + corr_id = get_gint32_db (db, mhni->correlation_id); - img->type = image_type_from_corr_id (db->device, corr_id); - if ((img->type != IPOD_COVER_SMALL) && (img->type != IPOD_COVER_LARGE)) { + img->type = image_type_from_corr_id (device, corr_id); + + if ( img->type != IPOD_COVER_SMALL + && img->type != IPOD_COVER_LARGE + && img->type != IPOD_PHOTO_SMALL + && img->type != IPOD_PHOTO_LARGE + && img->type != IPOD_PHOTO_FULL_SCREEN + && img->type != IPOD_PHOTO_TV_SCREEN) + { g_warning ("Unexpected cover type in mhni: type %d, size: %ux%u (%d), offset: %d\n", img->type, img->width, img->height, corr_id, img->offset); diff --git a/src/db-image-parser.h b/src/db-image-parser.h index a8e2fe5..39f5fd4 100644 --- a/src/db-image-parser.h +++ b/src/db-image-parser.h @@ -42,9 +42,9 @@ #define BLUE_MASK (((1 << BLUE_BITS)-1) << BLUE_SHIFT) G_GNUC_INTERNAL Itdb_Thumb *ipod_image_new_from_mhni (MhniHeader *mhni, - Itdb_iTunesDB *db); + Itdb_DB *db); -G_GNUC_INTERNAL int itdb_write_ithumb_files (Itdb_iTunesDB *db); +G_GNUC_INTERNAL int itdb_write_ithumb_files (Itdb_DB *db); G_GNUC_INTERNAL const Itdb_ArtworkFormat *itdb_get_artwork_info_from_type ( Itdb_Device *ipod, int image_type); diff --git a/src/db-itunes-parser.h b/src/db-itunes-parser.h index a126f87..344efa4 100644 --- a/src/db-itunes-parser.h +++ b/src/db-itunes-parser.h @@ -325,13 +325,13 @@ struct _ArtworkDB_MhodHeader { unsigned char header_id[4]; gint32 header_len; gint32 total_len; - /* Strangely, the following field is only 16 bits long in the + /* Strangely, the following field is only 16 bits long in the * ArtworkDB (it's definitely 32 bits in the iTunesDB). This * could well be an error with the first generation of mobile * phones with iPod support). */ gint16 type; - gint16 unknown014; + gint16 unknown014; gint32 unknown1; gint32 unknown2; }; @@ -361,13 +361,13 @@ enum MhodArtworkType { MHOD_ARTWORK_TYPE_IMAGE = 5 /* container: full resolution image (in the Photo Database) */ }; -struct __MhodHeaderArtworkType1 { +struct _MhodHeaderArtworkType1 { unsigned char header_id[4]; gint32 header_len; gint32 total_len; -/* FIXME: mobile phone ArtworkDB are known to have a 2 byte type. The - high byte again seems to indicate the padding */ - gint32 type; /* low 3 bytes are type (always 1); high byte is padding length (0-3) */ + gint16 type; + gint8 unknown; + gint8 padding; gint32 unknown1; gint32 unknown2; gint32 string_len; @@ -380,7 +380,8 @@ struct _MhodHeaderArtworkType3 { unsigned char header_id[4]; gint32 header_len; gint32 total_len; - gint32 type; /* 3 */ + gint16 type; /* 3 */ + gint16 padding; /* high byte is padding length (0-3) */ gint32 unknown1; gint32 unknown2; gint32 string_len; @@ -543,13 +544,13 @@ struct _MhfdHeader { gint32 unknown2; gint32 num_children; gint32 unknown3; - gint32 unknown4; + gint32 next_id; gint64 unknown5; gint64 unknown6; - gint8 unknown_flag1; - gint8 unknown_flag2; - gint8 unknown_flag3; - gint8 unknown_flag4; + gint8 unknown_flag1; + gint8 unknown_flag2; + gint8 unknown_flag3; + gint8 unknown_flag4; gint32 unknown8; gint32 unknown9; gint32 unknown10; @@ -574,8 +575,8 @@ struct _MhiiHeader { gint32 unknown4; gint32 unknown5; gint32 unknown6; - gint32 unknown7; - gint32 unknown8; + gint32 orig_date; + gint32 digitised_date; gint32 orig_img_size; unsigned char padding[]; } __attribute__((__packed__)); @@ -593,7 +594,8 @@ struct _MhniHeader { gint32 correlation_id; gint32 ithmb_offset; gint32 image_size; - gint32 unknown3; + gint16 vertical_padding; + gint16 horizontal_padding; gint16 image_height; gint16 image_width; unsigned char padding[]; @@ -614,9 +616,19 @@ struct _MhbaHeader { gint32 num_mhias; /* number of pictures in the album */ gint32 playlist_id; /* starts out at $64 and increments by 1 */ gint32 unknown2; /* unknown, seems to be always 0 */ - gint32 unknown3; /* unknown, but is 0x10000 for the Photo Library and 0x60000 for normal albums - * (maybe not a 4 byte field?) */ - gint32 unknown[7]; /* more zeroes */ + gint16 unknown3; /* unknown, seems to be always 0 */ + gchar master; + /* FIXME: not sure if I have these right; iPod doesn't seem to listen to them */ + guint8 playmusic; + guint8 repeat; + guint8 random; + guint8 show_titles; + guint8 transition_direction; + gint32 slide_duration; + gint32 transition_duration; + gint32 unknown4; + gint32 unknown5; + gint64 song_id; gint32 prev_playlist_id; /* the id of the previous playlist */ unsigned char padding[]; }; diff --git a/src/db-parse-context.c b/src/db-parse-context.c index 6268d21..0adbe30 100644 --- a/src/db-parse-context.c +++ b/src/db-parse-context.c @@ -104,12 +104,16 @@ db_parse_context_get_remaining_length (DBParseContext *ctx) DBParseContext * db_parse_context_get_sub_context (DBParseContext *ctx, off_t offset) { + DBParseContext *sub_ctx; + if (offset >= ctx->total_len) { return NULL; } - return db_parse_context_new (&ctx->buffer[offset], + sub_ctx = db_parse_context_new (&ctx->buffer[offset], ctx->total_len - offset, ctx->byte_order); + sub_ctx->db = ctx->db; + return sub_ctx; } @@ -163,17 +167,30 @@ db_parse_context_get_m_header_internal (DBParseContext *ctx, const char *id, off } DBParseContext * -db_parse_context_new_from_file (const char *filename, guint byte_order) +db_parse_context_new_from_file (const char *filename, Itdb_DB *db) { int fd; struct stat stat_buf; int result; unsigned char *buffer; DBParseContext *ctx; + Itdb_Device *device; buffer = NULL; ctx = NULL; + switch (db->db_type) { + case DB_TYPE_ITUNES: + device = db->db.itdb->device; + break; + case DB_TYPE_PHOTO: + device = db->db.photodb->device; + break; + default: + g_return_val_if_reached (NULL); + } + g_return_val_if_fail (device, NULL); + fd = open (filename, O_RDONLY); if (fd == -1) { g_print ("Failed to open %s: %s\n", @@ -206,10 +223,17 @@ db_parse_context_new_from_file (const char *filename, guint byte_order) goto error; } - ctx = db_parse_context_new (buffer, stat_buf.st_size, byte_order); + if (device->byte_order == 0) + itdb_device_autodetect_endianess (device); + + ctx = db_parse_context_new (buffer, + stat_buf.st_size, device->byte_order); + if (ctx == NULL) { munmap (buffer, stat_buf.st_size); } + ctx->db = db; + error: close (fd); return ctx; diff --git a/src/db-parse-context.h b/src/db-parse-context.h index 8df157e..4e18baa 100644 --- a/src/db-parse-context.h +++ b/src/db-parse-context.h @@ -27,13 +27,14 @@ #define DB_PARSE_CONTEXT #include <sys/types.h> - +#include "itdb.h" struct _DBParseContext { const unsigned char *buffer; const unsigned char *cur_pos; off_t header_len; off_t total_len; guint byte_order; + Itdb_DB *db; }; typedef struct _DBParseContext DBParseContext; @@ -64,7 +65,8 @@ db_parse_context_get_m_header_internal (DBParseContext *ctx, const char *id, off_t size); G_GNUC_INTERNAL DBParseContext * -db_parse_context_new_from_file (const char *filename, guint byte_order); +db_parse_context_new_from_file (const char *filename, Itdb_DB *db); + G_GNUC_INTERNAL void db_parse_context_destroy (DBParseContext *ctx, gboolean unmap); @@ -1,4 +1,4 @@ -/* Time-stamp: <2006-04-04 23:41:58 jcs> +/* Time-stamp: <2006-05-30 21:59:40 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -61,7 +61,10 @@ typedef struct _SPLPref SPLPref; typedef struct _SPLRule SPLRule; typedef struct _SPLRules SPLRules; typedef struct _Itdb_iTunesDB Itdb_iTunesDB; +typedef struct _Itdb_PhotoDB Itdb_PhotoDB; +typedef struct _Itdb_DB Itdb_DB; typedef struct _Itdb_Playlist Itdb_Playlist; +typedef struct _Itdb_PhotoAlbum Itdb_PhotoAlbum; typedef struct _Itdb_Track Itdb_Track; @@ -110,11 +113,25 @@ struct _Itdb_Thumb { gint16 height; }; +typedef enum { + ITDB_COVERART, + ITDB_PHOTO +} ItdbArtworkType; + struct _Itdb_Artwork { GList *thumbnails; /* list of Itdb_Thumbs */ guint32 artwork_size; /* Size in bytes of the original source image */ - guint id; /* some kind of ID, starting with + ItdbArtworkType type; /* Cover art or photo */ + guint32 id; /* Artwork id used by photoalbums, starts at * 0x40... libgpod will set this on sync. */ + gint32 creation_date; /* Date the image was created */ + /* below is for use by application */ + guint64 usertype; + gpointer userdata; + /* function called to duplicate userdata */ + ItdbUserDataDuplicateFunc userdata_duplicate; + /* function called to free userdata */ + ItdbUserDataDestroyFunc userdata_destroy; }; @@ -388,6 +405,35 @@ struct _SPLRules /* one star is how much (track->rating) */ #define ITDB_RATING_STEP 20 +enum _DbType { + DB_TYPE_ITUNES, + DB_TYPE_PHOTO +}; + +typedef enum _DbType DbType; + +struct _Itdb_DB{ + DbType db_type; + union { + Itdb_PhotoDB *photodb; + Itdb_iTunesDB *itdb; + } db; +}; + +struct _Itdb_PhotoDB +{ + GList *photos; + GList *photoalbums; + Itdb_Device *device;/* iPod device info */ + /* below is for use by application */ + guint64 usertype; + gpointer userdata; + /* function called to duplicate userdata */ + ItdbUserDataDuplicateFunc userdata_duplicate; + /* function called to free userdata */ + ItdbUserDataDestroyFunc userdata_destroy; +}; + struct _Itdb_iTunesDB { GList *tracks; @@ -405,6 +451,22 @@ struct _Itdb_iTunesDB ItdbUserDataDestroyFunc userdata_destroy; }; +struct _Itdb_PhotoAlbum +{ + gchar *name; /* name of photoalbum in UTF8 */ + GList *members; /* photos in album (Track *) */ + gint num_images; /* number of photos in album */ + gint master; /* 0x01 for master, 0x00 otherwise */ + gint album_id; + gint prev_album_id; + /* below is for use by application */ + guint64 usertype; + gpointer userdata; + /* function called to duplicate userdata */ + ItdbUserDataDuplicateFunc userdata_duplicate; + /* function called to free userdata */ + ItdbUserDataDestroyFunc userdata_destroy; +}; struct _Itdb_Playlist { @@ -634,13 +696,14 @@ struct _Itdb_Track guint8 has_artwork; /* 0x01: artwork is present. 0x02: no artwork is present for this track (used by the iPod to decide whether to display Artwork or not) */ - guint8 flag2; /* "Skip when shuffling" when set to 0x01, set - to 0x00 otherwise. .m4b and .aa files always - seem to be skipped when shuffling, however */ - guint8 flag3; /* "Remember playback position" when set to + guint8 skip_when_shuffling;/* "Skip when shuffling" when set to 0x01, set to 0x00 otherwise. .m4b and .aa - files always seem to remember the playback - position, however. */ + files always seem to be skipped when + shuffling, however */ + guint8 remember_playback_position;/* "Remember playback position" + when set to 0x01, set to 0x00 otherwise. .m4b + and .aa files always seem to remember the + playback position, however. */ guint8 flag4; /* Used for podcasts, 0x00 otherwise. If set to 0x01 the "Now Playing" page will show Title/Album, when set to 0x00 it will also @@ -720,7 +783,7 @@ GQuark itdb_file_error_quark (void); /* functions for reading/writing database, general itdb functions */ Itdb_iTunesDB *itdb_parse (const gchar *mp, GError **error); Itdb_iTunesDB *itdb_parse_file (const gchar *filename, GError **error); -gboolean itdb_write (Itdb_iTunesDB *itdb, GError **error); +gboolean itdb_write (Itdb_iTunesDB *db, GError **error); gboolean itdb_write_file (Itdb_iTunesDB *itdb, const gchar *filename, GError **error); gboolean itdb_shuffle_write (Itdb_iTunesDB *itdb, GError **error); @@ -751,9 +814,12 @@ gchar *itdb_get_control_dir (const gchar *mountpoint); gchar *itdb_get_itunes_dir (const gchar *mountpoint); gchar *itdb_get_music_dir (const gchar *mountpoint); gchar *itdb_get_artwork_dir (const gchar *mountpoint); +gchar *itdb_get_photos_dir (const gchar *mountpoint); +gchar *itdb_get_photos_thumb_dir (const gchar *mountpoint); gchar *itdb_get_device_dir (const gchar *mountpoint); gchar *itdb_get_itunesdb_path (const gchar *mountpoint); gchar *itdb_get_artworkdb_path (const gchar *mountpoint); +gchar *itdb_get_photodb_path (const gchar *mountpoint); gchar *itdb_get_path (const gchar *dir, const gchar *file); /* itdb_device functions */ @@ -824,6 +890,21 @@ void itdb_spl_update_live (Itdb_iTunesDB *itdb); gboolean itdb_track_set_thumbnails (Itdb_Track *track, const gchar *filename); void itdb_track_remove_thumbnails (Itdb_Track *track); + +/* photoalbum functions */ +Itdb_PhotoDB *itdb_photodb_parse (const gchar *mp, GError **error); +gboolean itdb_photodb_add_photo (Itdb_PhotoDB *db, + const gchar *albumname, + const gchar *filename); +Itdb_PhotoAlbum *itdb_photodb_photoalbum_new (Itdb_PhotoDB *db, + const gchar *album_name); +Itdb_PhotoDB *itdb_photodb_new (void); +void itdb_photodb_free (Itdb_PhotoDB *photodb); +gboolean itdb_photodb_write (Itdb_PhotoDB *db, GError **error); +void itdb_photodb_photoalbum_free (Itdb_PhotoAlbum *pa); +gboolean itdb_photodb_remove_photo (Itdb_PhotoDB *db, + const gint photo_id ); + /* itdb_artwork_... */ Itdb_Artwork *itdb_artwork_new (void); Itdb_Artwork *itdb_artwork_duplicate (Itdb_Artwork *artwork); @@ -846,12 +927,17 @@ void itdb_thumb_free (Itdb_Thumb *thumb); Itdb_Thumb *itdb_thumb_new (void); gchar *itdb_thumb_get_filename (Itdb_Device *device, Itdb_Thumb *thumb); - /* time functions */ guint64 itdb_time_get_mac_time (void); time_t itdb_time_mac_to_host (guint64 mactime); guint64 itdb_time_host_to_mac (time_t time); +/* Initialise a blank ipod */ +gboolean itdb_init_ipod (const gchar *mountpoint, + const gchar *model_number, + const gchar *ipod_name, + GError **error); + G_END_DECLS #endif diff --git a/src/itdb_artwork.c b/src/itdb_artwork.c index 3c7d9d9..7645e35 100644 --- a/src/itdb_artwork.c +++ b/src/itdb_artwork.c @@ -1,4 +1,4 @@ -/* Time-stamp: <2006-03-18 01:23:13 jcs> +/* Time-stamp: <2006-05-26 20:49:27 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -64,6 +64,8 @@ void itdb_artwork_free (Itdb_Artwork *artwork) { g_return_if_fail (artwork); itdb_artwork_remove_thumbnails (artwork); + if (artwork->userdata && artwork->userdata_destroy) + (*artwork->userdata_destroy) (artwork->userdata); g_free (artwork); } @@ -184,7 +186,8 @@ itdb_artwork_add_thumbnail (Itdb_Artwork *artwork, return FALSE; } - artwork->artwork_size = statbuf.st_size; + artwork->artwork_size = statbuf.st_size; + artwork->creation_date = statbuf.st_mtime; thumb = itdb_thumb_new (); thumb->filename = g_strdup (filename); @@ -259,14 +262,23 @@ gchar *itdb_thumb_get_filename (Itdb_Device *device, Itdb_Thumb *thumb) 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) + { + filename = itdb_get_path (artwork_dir, strchr( thumb->filename+1, ':') + 1); + g_free (artwork_dir); + } + + } return filename; } diff --git a/src/itdb_device.c b/src/itdb_device.c index f475be3..dd2e2ad 100644 --- a/src/itdb_device.c +++ b/src/itdb_device.c @@ -1,4 +1,4 @@ -/* Time-stamp: <2006-04-05 22:53:35 jcs> +/* Time-stamp: <2006-05-29 23:55:05 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -31,112 +31,116 @@ | $Id$ */ +#include "itdb_device.h" +#include <ctype.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> -#include <ctype.h> -#include "itdb_device.h" +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> #define GB 1024 static const Itdb_IpodModel ipod_model_table [] = { - /* Handle idiots who hose their iPod file system, or - lucky people with iPods we don't yet know about*/ - {"Invalid", 0, MODEL_TYPE_INVALID, UNKNOWN_GENERATION}, - {"Unknown", 0, MODEL_TYPE_UNKNOWN, UNKNOWN_GENERATION}, - - /* First Generation */ - /* Mechanical buttons arranged around rotating "scroll wheel". - 8513, 8541 and 8709 are Mac types, 8697 is PC */ - {"8513", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, - {"8541", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, - {"8697", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, - {"8709", 10 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, - - /* Second Generation */ - /* Same buttons as First Generation but around touch-sensitive - * "touch wheel". 8737 and 8738 are Mac types, 8740 and 8741 - are PC */ - {"8737", 10 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, - {"8740", 10 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, - {"8738", 20 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, - {"8741", 20 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, - - /* Third Generation */ - /* Touch sensitive buttons and arranged in a line above "touch - wheel". Docking connector was introduced here, same models - for Mac and PC from now on. */ - {"8976", 10 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, - {"8946", 15 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, - {"9460", 15 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, - {"9244", 20 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, - {"8948", 30 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, - {"9245", 40 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, - - /* Fourth Generation */ - /* Buttons are now integrated into the "touch wheel". */ - {"9282", 20 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION}, - {"9787", 25 * GB, MODEL_TYPE_REGULAR_U2, FOURTH_GENERATION}, - {"9268", 40 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION}, - {"A079", 20 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - {"A127", 20 * GB, MODEL_TYPE_COLOR_U2, FOURTH_GENERATION}, - {"9830", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - - /* First Generation Mini */ - {"9160", 4 * GB, MODEL_TYPE_MINI, FIRST_GENERATION}, - {"9436", 4 * GB, MODEL_TYPE_MINI_BLUE, FIRST_GENERATION}, - {"9435", 4 * GB, MODEL_TYPE_MINI_PINK, FIRST_GENERATION}, - {"9434", 4 * GB, MODEL_TYPE_MINI_GREEN, FIRST_GENERATION}, - {"9437", 4 * GB, MODEL_TYPE_MINI_GOLD, FIRST_GENERATION}, - - /* Second Generation Mini */ - {"9800", 4 * GB, MODEL_TYPE_MINI, SECOND_GENERATION}, - {"9802", 4 * GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION}, - {"9804", 4 * GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION}, - {"9806", 4 * GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION}, - {"9801", 6 * GB, MODEL_TYPE_MINI, SECOND_GENERATION}, - {"9803", 6 * GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION}, - {"9805", 6 * GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION}, - {"9807", 6 * GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION}, - - /* Photo / Fourth Generation */ - /* Buttons are integrated into the "touch wheel". */ - {"9829", 30 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - {"9585", 40 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - {"9586", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - {"9830", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - - /* Shuffle / Fourth Generation */ - {"9724", GB / 2, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION}, - {"9725", GB, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION}, - - /* Nano / Fifth Generation */ - /* Buttons are integrated into the "touch wheel". */ - {"A350", GB * 1, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION}, - {"A352", GB * 1, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION}, - {"A004", GB * 2, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION}, - {"A099", GB * 2, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION}, - {"A005", GB * 4, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION}, - {"A107", GB * 4, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION}, - - /* Video / Fifth Generation */ - /* Buttons are integrated into the "touch wheel". */ - {"A002", GB * 30, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION}, - {"A146", GB * 30, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION}, - {"A003", GB * 60, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION}, - {"A147", GB * 60, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION}, - - /* HP iPods, need contributions for this table */ - /* Buttons are integrated into the "touch wheel". */ - {"E436", 40 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION}, - {"S492", 30 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, - - /* No known model number -- create a Device/SysInfo file with - * one entry, e.g.: - ModelNumStr: Mmobile1 - */ - {"mobile1", -1, MODEL_TYPE_MOBILE_1, MOBILE_GENERATION}, - - {NULL, 0, 0, 0} + /* Handle idiots who hose their iPod file system, or lucky people + with iPods we don't yet know about*/ + {"Invalid", 0, MODEL_TYPE_INVALID, UNKNOWN_GENERATION, 0}, + {"Unknown", 0, MODEL_TYPE_UNKNOWN, UNKNOWN_GENERATION, 0}, + + /* First Generation */ + /* Mechanical buttons arranged around rotating "scroll wheel". + 8513, 8541 and 8709 are Mac types, 8697 is PC */ + {"8513", 5*GB, MODEL_TYPE_REGULAR, FIRST_GENERATION, 20}, + {"8541", 5*GB, MODEL_TYPE_REGULAR, FIRST_GENERATION, 20}, + {"8697", 5*GB, MODEL_TYPE_REGULAR, FIRST_GENERATION, 20}, + {"8709", 10*GB, MODEL_TYPE_REGULAR, FIRST_GENERATION, 20}, + + /* Second Generation */ + /* Same buttons as First Generation but around touch-sensitive + "touch wheel". 8737 and 8738 are Mac types, 8740 and 8741 * are + PC */ + {"8737", 10*GB, MODEL_TYPE_REGULAR, SECOND_GENERATION, 20}, + {"8740", 10*GB, MODEL_TYPE_REGULAR, SECOND_GENERATION, 20}, + {"8738", 20*GB, MODEL_TYPE_REGULAR, SECOND_GENERATION, 50}, + {"8741", 20*GB, MODEL_TYPE_REGULAR, SECOND_GENERATION, 50}, + + /* Third Generation */ + /* Touch sensitive buttons and arranged in a line above "touch + wheel". Docking connector was introduced here, same models for + Mac and PC from now on. */ + {"8976", 10*GB, MODEL_TYPE_REGULAR, THIRD_GENERATION, 20}, + {"8946", 15*GB, MODEL_TYPE_REGULAR, THIRD_GENERATION, 50}, + {"9460", 15*GB, MODEL_TYPE_REGULAR, THIRD_GENERATION, 50}, + {"9244", 20*GB, MODEL_TYPE_REGULAR, THIRD_GENERATION, 50}, + {"8948", 30*GB, MODEL_TYPE_REGULAR, THIRD_GENERATION, 50}, + {"9245", 40*GB, MODEL_TYPE_REGULAR, THIRD_GENERATION, 50}, + + /* Fourth Generation */ + /* Buttons are now integrated into the "touch wheel". */ + {"9282", 20*GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION, 50}, + {"9787", 25*GB, MODEL_TYPE_REGULAR_U2, FOURTH_GENERATION, 50}, + {"9268", 40*GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION, 50}, + {"A079", 20*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + {"A127", 20*GB, MODEL_TYPE_COLOR_U2, FOURTH_GENERATION, 50}, + {"9830", 60*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + + /* First Generation Mini */ + {"9160", 4*GB, MODEL_TYPE_MINI, FIRST_GENERATION, 6}, + {"9436", 4*GB, MODEL_TYPE_MINI_BLUE, FIRST_GENERATION, 6}, + {"9435", 4*GB, MODEL_TYPE_MINI_PINK, FIRST_GENERATION, 6}, + {"9434", 4*GB, MODEL_TYPE_MINI_GREEN, FIRST_GENERATION, 6}, + {"9437", 4*GB, MODEL_TYPE_MINI_GOLD, FIRST_GENERATION, 6}, + + /* Second Generation Mini */ + {"9800", 4*GB, MODEL_TYPE_MINI, SECOND_GENERATION, 6}, + {"9802", 4*GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION, 6}, + {"9804", 4*GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION, 6}, + {"9806", 4*GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION, 6}, + {"9801", 6*GB, MODEL_TYPE_MINI, SECOND_GENERATION, 20}, + {"9803", 6*GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION, 20}, + {"9805", 6*GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION, 20}, + {"9807", 6*GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION, 20}, + + /* Photo / Fourth Generation */ + /* Buttons are integrated into the "touch wheel". */ + {"9829", 30*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + {"9585", 40*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + {"9586", 60*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + {"9830", 60*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + + /* Shuffle / Fourth Generation */ + {"9724", GB/2, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION, 3}, + {"9725", GB, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION, 3}, + + /* Nano / Fifth Generation */ + /* Buttons are integrated into the "touch wheel". */ + {"A350", 1*GB, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION, 3}, + {"A352", 1*GB, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION, 3}, + {"A004", 2*GB, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION, 3}, + {"A099", 2*GB, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION, 3}, + {"A005", 4*GB, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION, 6}, + {"A107", 4*GB, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION, 6}, + + /* Video / Fifth Generation */ + /* Buttons are integrated into the "touch wheel". */ + {"A002", 30*GB, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION, 50}, + {"A146", 30*GB, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION, 50}, + {"A003", 60*GB, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION, 50}, + {"A147", 60*GB, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION, 50}, + + /* HP iPods, need contributions for this table */ + /* Buttons are integrated into the "touch wheel". */ + {"E436", 40*GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION, 50}, + {"S492", 30*GB, MODEL_TYPE_COLOR, FOURTH_GENERATION, 50}, + + /* No known model number -- create a Device/SysInfo file with + * one entry, e.g.: + ModelNumStr: Mmobile1 + */ + {"mobile1", -1, MODEL_TYPE_MOBILE_1, MOBILE_GENERATION}, + + {NULL, 0, 0, 0, 0} }; #if 0 @@ -450,6 +454,50 @@ itdb_device_musicdirs_number (Itdb_Device *device) return device->musicdirs; } +/** + * endianess_check_path: + * + * Check if endianess can be determined by looking at header of @path. + * + * @path: the file to look at. + * @hdr: the header string (4 bytes) in case of LITTLE_ENDIAN + * + * Return value: + * G_LITTLE_ENDIAN, G_BIG_ENDIAN or 0 if endianess could not be + * determined. + */ +static guint endianess_check_path (const gchar *path, const gchar *hdr) +{ + guint byte_order = 0; + + if (path) + { + int fd = open (path, O_RDONLY); + if (fd != -1) + { + gchar buf[4]; + if (read (fd, buf, 4) == 4) + { + if (strncmp (buf, hdr, 4) == 0) + { + byte_order = G_LITTLE_ENDIAN; + } + else + { + if ((buf[0] == hdr[3]) && + (buf[1] == hdr[2]) && + (buf[2] == hdr[1]) && + (buf[3] == hdr[0])) + { + byte_order = G_LITTLE_ENDIAN; + } + } + } + close (fd); + } + } + return byte_order; +} /* Attempt to guess the endianess used by this iPod. * @@ -460,25 +508,54 @@ itdb_device_musicdirs_number (Itdb_Device *device) G_GNUC_INTERNAL void itdb_device_autodetect_endianess (Itdb_Device *device) { - g_return_if_fail (device); + guint byte_order = 0; - /* default: non-reversed */ - device->byte_order = G_LITTLE_ENDIAN; + g_return_if_fail (device); if (device->mountpoint) { - gchar *control_dir = itdb_get_control_dir (device->mountpoint); - - if (control_dir) + gchar *path; + if (byte_order == 0) { - gchar *cd_l = g_ascii_strdown (control_dir, -1); - if (strstr (cd_l, "itunes/itunes_control") == - (cd_l + strlen (cd_l) - strlen ("itunes/itunes_control"))) + /* First try reading the iTunesDB */ + path = itdb_get_itunesdb_path (device->mountpoint); + byte_order = endianess_check_path (path, "mhbd"); + g_free (path); + } + if (byte_order == 0) + { + /* Try reading the ArtworkDB */ + path = itdb_get_artworkdb_path (device->mountpoint); + byte_order = endianess_check_path (path, "mhfd"); + g_free (path); + } + if (byte_order == 0) + { + /* Try reading the Photos Database */ + path = itdb_get_photodb_path (device->mountpoint); + byte_order = endianess_check_path (path, "mhfd"); + g_free (path); + } + if (byte_order == 0) + { + gchar *control_dir = itdb_get_control_dir (device->mountpoint); + if (control_dir) { - device->byte_order = G_BIG_ENDIAN; + gchar *cd_l = g_ascii_strdown (control_dir, -1); + if (strstr (cd_l, "itunes/itunes_control") == + (cd_l + strlen (cd_l) - strlen ("itunes/itunes_control"))) + { + device->byte_order = G_BIG_ENDIAN; + } + g_free (cd_l); + g_free (control_dir); } - g_free (cd_l); - g_free (control_dir); } } + + /* default: non-reversed */ + if (byte_order == 0) + byte_order = G_LITTLE_ENDIAN; + + device->byte_order = byte_order; } diff --git a/src/itdb_device.h b/src/itdb_device.h index bb02880..115e08e 100644 --- a/src/itdb_device.h +++ b/src/itdb_device.h @@ -1,4 +1,4 @@ -/* Time-stamp: <2006-03-21 17:22:34 jcs> +/* Time-stamp: <2006-05-30 21:53:34 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -74,6 +74,11 @@ struct _Itdb_IpodModel { const guint64 capacity; guint model_type; guint generation; + /* number of music (Fnn) dirs created by iTunes. The exact + number seems to be version dependent. Therefore, the + numbers here represent a mixture of reported values and + common sense. */ + guint musicdirs; }; typedef enum { @@ -120,8 +125,6 @@ G_GNUC_INTERNAL const Itdb_ArtworkFormat *itdb_device_get_artwork_formats (Itdb_ G_GNUC_INTERNAL const Itdb_IpodModel *itdb_device_get_ipod_model (Itdb_Device *device); G_GNUC_INTERNAL gint itdb_device_musicdirs_number (Itdb_Device *device); G_GNUC_INTERNAL void itdb_device_autodetect_endianess (Itdb_Device *device); - - G_END_DECLS #endif diff --git a/src/itdb_endianness.h b/src/itdb_endianness.h index 9cbf692..3eb129c 100644 --- a/src/itdb_endianness.h +++ b/src/itdb_endianness.h @@ -41,7 +41,7 @@ } \ return 0; /* never reached */ \ } - +/* #define DB_TO_CPU_GET_DB(lower_case_type, upper_case_type) \ DB_TO_CPU_GET(lower_case_type, upper_case_type) \ static inline lower_case_type \ @@ -50,7 +50,23 @@ g_assert (db->device != NULL); \ return get_##lower_case_type (val, db->device->byte_order); \ } +*/ +#define DB_TO_CPU_GET_DB(lower_case_type, upper_case_type) \ + DB_TO_CPU_GET(lower_case_type, upper_case_type) \ + static inline lower_case_type \ + get_##lower_case_type##_db (Itdb_DB *db, lower_case_type val) \ + { \ + switch (db->db_type) { \ + case DB_TYPE_ITUNES: \ + g_assert (db->db.itdb->device != NULL); \ + return get_##lower_case_type (val, db->db.itdb->device->byte_order); \ + case DB_TYPE_PHOTO: \ + g_assert (db->db.photodb->device != NULL); \ + return get_##lower_case_type (val, db->db.photodb->device->byte_order); \ + } \ + return 0; \ +} DB_TO_CPU_GET_DB(guint32, GUINT32) DB_TO_CPU_GET_DB(gint32, GINT32) diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c index 821f756..0ca21d3 100644 --- a/src/itdb_itunesdb.c +++ b/src/itdb_itunesdb.c @@ -1,4 +1,4 @@ -/* Time-stamp: <2006-05-05 01:07:19 jcs> +/* Time-stamp: <2006-05-30 21:59:40 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -111,19 +111,20 @@ # include <config.h> #endif -#include <time.h> +#include "db-artwork-parser.h" +#include "itdb_device.h" +#include "itdb_private.h" +#include <errno.h> +#include <fcntl.h> +#include <glib-object.h> +#include <glib/gi18n-lib.h> +#include <stdio.h> #include <string.h> -#include <sys/types.h> #include <sys/stat.h> -#include <fcntl.h> +#include <sys/statvfs.h> +#include <sys/types.h> +#include <time.h> #include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include "itdb_private.h" -#include "itdb_device.h" -#include "db-artwork-parser.h" -#include <glib/gi18n-lib.h> -#include <glib-object.h> #define ITUNESDB_DEBUG 0 #define ITUNESDB_MHIT_DEBUG 0 @@ -191,6 +192,9 @@ struct _MHODData typedef struct _MHODData MHODData; +/* Declarations */ +static gboolean itdb_create_directories (Itdb_Device *device, GError **error); + /* ID for error domain */ GQuark itdb_file_error_quark (void) @@ -1863,9 +1867,9 @@ static glong get_playlist (FImport *fimp, glong mhyp_seek) /* Some Playlists have added 256 to their type -- I don't know what it's for, so we just ignore it for now -> & 0xff */ plitem->type = get8int (cts, mhyp_seek+20); - plitem->flag1 = get8int (cts, mhyp_seek+20); - plitem->flag2 = get8int (cts, mhyp_seek+20); - plitem->flag3 = get8int (cts, mhyp_seek+20); + plitem->flag1 = get8int (cts, mhyp_seek+21); + plitem->flag2 = get8int (cts, mhyp_seek+22); + plitem->flag3 = get8int (cts, mhyp_seek+23); plitem->timestamp = get32lint (cts, mhyp_seek+24); plitem->id = get64lint (cts, mhyp_seek+28); plitem->mhodcount = get32lint (cts, mhyp_seek+36); @@ -2112,8 +2116,8 @@ static glong get_mhit (FImport *fimp, glong mhit_seek) track->unk156 = get32lint (cts, seek+156); track->unk160 = get32lint (cts, seek+160); track->has_artwork = get8int (cts, seek+164); - track->flag2 = get8int (cts, seek+165); - track->flag3 = get8int (cts, seek+166); + track->skip_when_shuffling = get8int (cts, seek+165); + track->remember_playback_position = get8int (cts, seek+166); track->flag4 = get8int (cts, seek+167); track->dbid2 = get64lint (cts, seek+168); track->lyrics_flag = get8int (cts, seek+176); @@ -2740,7 +2744,6 @@ Itdb_iTunesDB *itdb_parse (const gchar *mp, GError **error) return itdb; } - /** * itdb_parse_file: * @filename: path to a file in iTunesDB format @@ -3300,8 +3303,8 @@ static void mk_mhit (WContents *cts, Itdb_Track *track) put32lint (cts, track->unk156); put32lint (cts, track->unk160); put8int (cts, track->has_artwork); - put8int (cts, track->flag2); - put8int (cts, track->flag3); + put8int (cts, track->skip_when_shuffling); + put8int (cts, track->remember_playback_position); put8int (cts, track->flag4); put64lint (cts, track->dbid2); put8int (cts, track->lyrics_flag); @@ -4212,8 +4215,8 @@ gboolean itdb_write_file (Itdb_iTunesDB *itdb, const gchar *filename, FIXME: figure out a way to store the artwork data when storing to local directories. At the moment it's the application's task to handle this. */ - if (itdb->device) - ipod_write_artwork_db (itdb); + if (itdb->device && itdb_device_get_artwork_formats(itdb->device)) + ipod_write_artwork_db (itdb); #endif fexp = g_new0 (FExport, 1); @@ -4788,6 +4791,45 @@ const gchar *itdb_get_mountpoint (Itdb_iTunesDB *itdb) return itdb->device->mountpoint; } +/* Retrieve a reference to the mountpoint */ +const gchar *itdb_photodb_get_mountpoint (Itdb_PhotoDB *photodb) +{ + g_return_val_if_fail (photodb, NULL); + g_return_val_if_fail (photodb->device, NULL); + return photodb->device->mountpoint; +} + +/* Retrieve a reference to the mountpoint */ +gchar *db_get_mountpoint(Itdb_DB *db) +{ + g_return_val_if_fail (db, NULL); + + switch (db->db_type) { + case DB_TYPE_ITUNES: + g_return_val_if_fail (db->db.itdb->device, NULL); + return db->db.itdb->device->mountpoint; + case DB_TYPE_PHOTO: + g_return_val_if_fail (db->db.photodb->device, NULL); + return db->db.photodb->device->mountpoint; + } + return NULL; +} + +Itdb_Device *db_get_device(Itdb_DB *db) +{ + g_return_val_if_fail (db, NULL); + + switch (db->db_type) { + case DB_TYPE_ITUNES: + g_return_val_if_fail (db->db.itdb->device, NULL); + return db->db.itdb->device; + case DB_TYPE_PHOTO: + g_return_val_if_fail (db->db.photodb->device, NULL); + return db->db.photodb->device; + } + return NULL; +} + /** * itdb_musicdirs_number: @@ -5191,8 +5233,8 @@ gchar *itdb_get_control_dir (const gchar *mountpoint) /** * itdb_get_dir: - * mountpoint: the iPod mountpoint - * dir: a directory + * @mountpoint: the iPod mountpoint + * @dir: a directory * * Retrieve the directory @dir by first calling itdb_get_control_dir() * and then adding @dir @@ -5416,3 +5458,380 @@ guint64 itdb_time_host_to_mac (time_t time) { return (guint64)(((gint64)time) + 2082844800); } + + +/** + * itdb_init_ipod: + * @mountpoint: the iPod mountpoint + * @model_number: the iPod model number + * @model_type: the type of iPod, eg. regular, shuffle + * @ipod_name: the name to give to the iPod. Will be displayed in + * gtkpod or itunes + * + * Initialise an iPod device from scratch. The function attempts to + * create a blank database, complete with master playlist and device + * information as well as the directory structure required for the + * type of iPod. + * + * Return value: TRUE when successful, FALSE if a failure has occurred. + * + **/ +gboolean itdb_init_ipod (const gchar *mountpoint, + const gchar *model_number, + const gchar *ipod_name, + GError **error) +{ + gboolean writeok; + Itdb_iTunesDB *itdb = NULL; + Itdb_Playlist *mpl = NULL; + + g_return_val_if_fail (mountpoint, FALSE); + + /* Create new blank itdb database for writing to iPod */ + itdb = itdb_new(); + + /* Assign iPod device reference to new database */ + itdb_set_mountpoint(itdb, mountpoint); + + /* Rather than reread sysinfo file (that may not exist if + * shuffle, use parameter to load into the sysinfo hash. + * The model number can be extracted in a couple of ways: + * - use the read_sysinfo_file function + * - use libipoddevice and hal to get the model + * (as far as I know, libipoddevice will also + * read the sysinfo file, complemented by some + * guessing). + */ + g_hash_table_insert (itdb->device->sysinfo, + g_strdup ("ModelNumStr"), + g_strdup (model_number)); + + /* Create the remaining directories resident on blank ipod */ + writeok = itdb_create_directories(itdb->device, error); + if(! writeok) + { + return FALSE; + } + + /* Create a new playlist with the desired name of the ipod + * and set it as the mpl */ + if (ipod_name == NULL) + { + mpl = itdb_playlist_new(_("iPod"), FALSE); + } + else + { + mpl = itdb_playlist_new(ipod_name, FALSE); + } + itdb_playlist_set_mpl(mpl); + itdb_playlist_add(itdb, mpl, -1); + + /* Write both the iTunesDB and iTunesSD files to the new ipod */ + writeok = itdb_write(itdb, error); + if(! writeok) + { + itdb_free (itdb); + return FALSE; + } + + writeok = itdb_shuffle_write(itdb, error); + if(! writeok) + { + itdb_free (itdb); + return FALSE; + } + + itdb_free (itdb); + return TRUE; +} + +/*------------------------------------------------------------------*\ + * * + * Create iPod directory hierarchy * + * * +\*------------------------------------------------------------------*/ + +/* mkdir_with_parents is copied from GLIB2.8 (gfileutils.c, V1.78), as + * it is new to V2.8. May be replaced with g_mkdir_with_parents() in a + * couple of years. */ + +/** + * mkdir_with_parents: + * @pathname: a pathname in the GLib file name encoding + * @mode: permissions to use for newly created directories + * + * Create a directory if it doesn't already exist. Create intermediate + * parent directories as needed, too. + * + * Returns: 0 if the directory already exists, or was successfully + * created. Returns -1 if an error occurred, with errno set. + * + */ +static int +mkdir_with_parents (const gchar *pathname, + int mode) +{ + gchar *fn, *p; + + if (pathname == NULL || *pathname == '\0') + { + errno = EINVAL; + return -1; + } + + fn = g_strdup (pathname); + + if (g_path_is_absolute (fn)) + p = (gchar *) g_path_skip_root (fn); + else + p = fn; + + do + { + while (*p && !G_IS_DIR_SEPARATOR (*p)) + p++; + + if (!*p) + p = NULL; + else + *p = '\0'; + + if (!g_file_test (fn, G_FILE_TEST_EXISTS)) + { + if (g_mkdir (fn, mode) == -1) + { + int errno_save = errno; + g_free (fn); + errno = errno_save; + return -1; + } + } + else if (!g_file_test (fn, G_FILE_TEST_IS_DIR)) + { + g_free (fn); + errno = ENOTDIR; + return -1; + } + if (p) + { + *p++ = G_DIR_SEPARATOR; + while (*p && G_IS_DIR_SEPARATOR (*p)) + p++; + } + } + while (p); + + g_free (fn); + + return 0; +} + + +static gboolean itdb_create_directories (Itdb_Device *device, GError **error) +{ + const gchar *mp; + gboolean result; + gchar *pbuf; + gint i, dirnum; + FILE *sysinfo = NULL; + Itdb_IpodModel const *model = NULL; + gboolean calconnotes, devicefile; + gchar *podpath; + + g_return_val_if_fail (device, FALSE); + + mp = device->mountpoint; + g_return_val_if_fail (mp, FALSE); + + /* Retrieve the model from the device information */ + model = itdb_device_get_ipod_model(device); + + /* Set up special treatment for shuffle and mobile */ + switch(model->model_type) + { + case MODEL_TYPE_SHUFFLE: + podpath = g_strdup ("iPod_Control"); + calconnotes = FALSE; + devicefile = TRUE; + break; + case MODEL_TYPE_MOBILE_1: + podpath = g_build_filename ("iTunes", "iTunes_Control", NULL); + calconnotes = FALSE; + devicefile = TRUE; + break; + case MODEL_TYPE_UNKNOWN: + podpath = g_strdup ("iPod_Control"); + calconnotes = TRUE; + devicefile = TRUE; + break; + default: + podpath = g_strdup ("iPod_Control"); + calconnotes = TRUE; + devicefile = TRUE; + break; + } + + /* Construct the Control directory */ + pbuf = g_build_filename (mp, podpath, NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if (mkdir_with_parents(pbuf, 0777) != 0) + { + goto error_dir; + } + } + g_free (pbuf); + + /* Construct the Music directory inside the Control directory */ + pbuf = g_build_filename (mp, podpath, "Music", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + + /* Construct the iTunes directory inside the Control directory */ + pbuf = g_build_filename (mp, podpath, "iTunes", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + + /* Build Artwork directory only for devices requiring artwork + * (assume that 'unknown models' are new and will support + * artwork) */ + if (itdb_device_get_artwork_formats(device) || + (model->model_type == MODEL_TYPE_UNKNOWN)) + { + pbuf = g_build_filename (mp, podpath, "Artwork", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) { + goto error_dir; + } + } + g_free (pbuf); + } + + /* Build the directories that hold the music files */ + dirnum = model->musicdirs; + if (dirnum == 0) + { /* do a guess */ + struct statvfs stat; + if (statvfs (mp, &stat) != 0) + { /* why should this fail !? */ + dirnum = 20; + } + else + { + gdouble size = ((gdouble)stat.f_blocks * stat.f_frsize) / 1073741824; + if (size < 20) dirnum = 20; + else dirnum = 50; + } + } + + for(i = 0; i < dirnum; i++) + { + gchar *num = g_strdup_printf ("F%02d", i); + pbuf = g_build_filename (mp, podpath, "Music", num, NULL); + g_free (num); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + } + + /* Build Calendar directory for models requiring it */ + if (calconnotes) + { + pbuf = g_build_filename (mp, "Calendars", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + + /* Build Contacts directory for models requiring it */ + pbuf = g_build_filename (mp, "Contacts", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + + pbuf = g_build_filename (mp, "Notes", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + } + + /* Construct a Device directory file for special models */ + if (devicefile) + { + pbuf = g_build_filename (mp, podpath, "Device", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + if((mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); + + /* Construct a SysInfo file */ + pbuf = g_build_filename (mp, podpath, "Device", "SysInfo", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) + { + sysinfo = fopen(pbuf, "w"); + if(sysinfo != NULL) + { + fprintf(sysinfo, "ModelNumStr:%s", + model->model_number); + fclose(sysinfo); + } + else + { + goto error_dir; + } + } + g_free (pbuf); + } + pbuf = NULL; + + error_dir: + if (pbuf) + { + g_set_error (error, 0, -1, + _("Problem creating iPod directory or file: '%s'."), + pbuf); + result = FALSE; + } else + { + result = TRUE; + } + g_free (pbuf); + g_free (podpath); + return result; +} diff --git a/src/itdb_photoalbum.c b/src/itdb_photoalbum.c new file mode 100644 index 0000000..3351da0 --- /dev/null +++ b/src/itdb_photoalbum.c @@ -0,0 +1,375 @@ +#include <config.h> + +#include "itdb_private.h" +#include "itdb_device.h" +#include "db-artwork-parser.h" +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <glib/gi18n-lib.h> + + +/* Set @error with standard error message */ +static void error_no_photos_dir (const gchar *mp, GError **error) +{ + gchar *str; + + g_return_if_fail (mp); + + if (error) + { + str = g_build_filename (mp, "iPod_Control", "Photos", NULL); + g_set_error (error, + ITDB_FILE_ERROR, + ITDB_FILE_ERROR_NOTFOUND, + _("Photos directory not found: '%s' (or similar)."), + str); + g_free (str); + } +} + + +/** + * itdb_get_photos_dir: + * @mountpoint: mountpoint of iPod + * + * Retrieve the Photo directory by + * first calling itdb_get_control_dir() and then adding 'Photos' + * + * Return value: path to the Artwork directory or NULL of + * non-existent. Must g_free() after use. + */ +gchar *itdb_get_photos_dir (const gchar *mountpoint) +{ + gchar *p_ipod[] = {"Photos", NULL}; + /* Use an array with all possibilities, so further extension will + be easy */ + gchar **paths[] = {p_ipod, NULL}; + gchar ***ptr; + gchar *result = NULL; + + g_return_val_if_fail (mountpoint, NULL); + + for (ptr=paths; *ptr && !result; ++ptr) + { + result = itdb_resolve_path (mountpoint, (const gchar **)*ptr); + } + return result; +} + +/** + * itdb_get_photodb_path: + * @mountpoint: the iPod mountpoint + * + * Retrieve a path to the Photo DB + * + * Return value: path to the PhotoDB or NULL if non-existent. Must + * g_free() after use. + **/ +gchar *itdb_get_photodb_path (const gchar *mountpoint) +{ + gchar *photo_dir, *path=NULL; + + g_return_val_if_fail (mountpoint, NULL); + + photo_dir = itdb_get_photos_dir (mountpoint); + + if (photo_dir) + { + path = itdb_get_path (photo_dir, "Photo Database"); + g_free (photo_dir); + } + + return path; +} + +/** + * itdb_get_photos_thumb_dir: + * @mountpoint: the iPod mountpoint + * + * Retrieve the Photo Thumbnail directory by + * first calling itdb_get_control_dir() and then adding 'Photos/Thumbs' + * + * Return value: path to the Artwork directory or NULL of + * non-existent. Must g_free() after use. + */ +gchar *itdb_get_photos_thumb_dir (const gchar *mountpoint) +{ + gchar *control_dir; + gchar *result = NULL; + gchar *dir = "Thumbs"; + + g_return_val_if_fail (mountpoint, NULL); + g_return_val_if_fail (dir, NULL); + + control_dir = itdb_get_photos_dir (mountpoint); + if (control_dir) + { + const gchar *p_dir[] = {NULL, NULL}; + p_dir[0] = dir; + result = itdb_resolve_path (control_dir, p_dir); + g_free (control_dir); + } + return result; +} + + +/** + * itdb_photodb_parse: + * + * Parses the photo database of an iPod mounted at @mp. + * + * @mp: mountpoint of the iPod + * @error: will contain the error description when an error occured. + * + * Return value: the imported PhotoDB or NULL in case of an error. + **/ +Itdb_PhotoDB *itdb_photodb_parse (const gchar *mp, GError **error) +{ + gchar *photos_dir; + Itdb_PhotoDB *photodb = NULL; + + photos_dir = itdb_get_photos_dir (mp); + + if (!photos_dir) + { + error_no_photos_dir (mp, error); + return NULL; + } + g_free (photos_dir); + + photodb = itdb_photodb_new (); + itdb_device_set_mountpoint (photodb->device, mp); + ipod_parse_photo_db (photodb); + return photodb; +} + + +/** + * itdb_photodb_new: + * + * Creates a new Itdb_PhotoDB + * + * Return value: a newly created Itdb_PhotoDB to be freed with + * itdb_photodb_free() when it's no longer needed + **/ +Itdb_PhotoDB *itdb_photodb_new (void) +{ + Itdb_PhotoDB *photodb; + + photodb = g_new0 (Itdb_PhotoDB, 1); + photodb->device = itdb_device_new (); + + return photodb; +} + + +/** + * itdb_photodb_free: + * @photodb: an #Itdb_PhotoDB + * + * Free the memory taken by @photodb. + **/ +void itdb_photodb_free (Itdb_PhotoDB *photodb) +{ + if (photodb) + { + g_list_foreach (photodb->photoalbums, + (GFunc)(itdb_photodb_photoalbum_free), NULL); + g_list_free (photodb->photoalbums); + g_list_foreach (photodb->photos, + (GFunc)(itdb_artwork_free), NULL); + g_list_free (photodb->photos); + itdb_device_free (photodb->device); + + if (photodb->userdata && photodb->userdata_destroy) + (*photodb->userdata_destroy) (photodb->userdata); + + g_free (photodb); + } +} + + + + +G_GNUC_INTERNAL gint itdb_get_free_photo_id ( Itdb_PhotoDB *db ) +{ + gint photo_id = 0; + GList *it; + + for (it = db->photos; it != NULL; it = it->next) { + Itdb_Artwork *artwork; + + artwork = (Itdb_Artwork *)it->data; + if( artwork->id > photo_id ) + photo_id = artwork->id; + } + return photo_id + 1; +} + +static gint itdb_get_free_photoalbum_id ( Itdb_PhotoDB *db ) +{ + gint album_id = 0; + GList *it; + + for (it = db->photoalbums; it != NULL; it = it->next) { + Itdb_PhotoAlbum *album; + + album = (Itdb_PhotoAlbum *)it->data; + if( album->album_id > album_id ) + album_id = album->album_id; + } + return album_id + 1; +} + +static Itdb_PhotoAlbum *itdb_get_photoalbum ( Itdb_PhotoDB *db, const gchar *albumname ) +{ + GList *it; + + if( strcmp( albumname, "master" ) == 0 ) + return g_list_nth_data (db->photoalbums, 0); + + for (it = db->photoalbums; it != NULL; it = it->next) { + Itdb_PhotoAlbum *album; + + album = (Itdb_PhotoAlbum *)it->data; + if( strcmp(album->name, albumname) == 0 ) + return album; + } + return (Itdb_PhotoAlbum *)NULL; +} + + +void itdb_photodb_photoalbum_free (Itdb_PhotoAlbum *pa) +{ + if (pa) + { + g_free (pa->name); + g_list_free (pa->members); + + if (pa->userdata && pa->userdata_destroy) + (*pa->userdata_destroy) (pa->userdata); + + g_free (pa); + } +} + +gboolean itdb_photodb_add_photo (Itdb_PhotoDB *db, + const gchar *albumname, + const gchar *filename) +{ + gboolean result; + Itdb_Artwork *artwork; + Itdb_PhotoAlbum *photoalbum; + const Itdb_ArtworkFormat *format; + gint photo_id; + + g_return_val_if_fail (db, FALSE); + g_return_val_if_fail (filename, FALSE); + artwork = itdb_artwork_new (); + + photo_id = itdb_get_free_photo_id( db ); + artwork->id = photo_id; + /* Add a thumbnail for every supported format */ + format = itdb_device_get_artwork_formats(db->device); + for( result = TRUE; format->type != -1 && result == TRUE; format++) { + if( format->type == IPOD_COVER_SMALL + || format->type == IPOD_COVER_LARGE ) + continue; + result = itdb_artwork_add_thumbnail (artwork, + format->type, + filename); + } + + if (result != TRUE) + { + itdb_artwork_remove_thumbnails (artwork); + return result; + } + db->photos = g_list_append (db->photos, artwork); + + photoalbum = itdb_get_photoalbum( db, albumname ); + if( photoalbum == NULL ) + photoalbum = itdb_photodb_photoalbum_new( db, albumname ); + photoalbum->num_images++; + photoalbum->members = g_list_append (photoalbum->members, GINT_TO_POINTER(photo_id)); + + return result; +} + +gboolean itdb_photodb_remove_photo (Itdb_PhotoDB *db, + const gint photo_id ) +{ + gboolean result = TRUE; + GList *it; + + g_return_val_if_fail (db, FALSE); + + /* Remove the photo from the image list */ + for (it = db->photos; it != NULL; it = it->next) { + Itdb_Artwork *artwork; + + artwork = (Itdb_Artwork *)it->data; + if( artwork->id == photo_id ) { + db->photos = g_list_remove (db->photos, artwork); + break; + } + } + + /* Remove the photo from any albums containing it */ + for (it = db->photoalbums; it != NULL; it = it->next) { + Itdb_PhotoAlbum *album; + + album = (Itdb_PhotoAlbum *)it->data; + album->members = g_list_remove (album->members, GINT_TO_POINTER(photo_id)); + album->num_images = g_list_length( album->members ); + } + return result; +} + +Itdb_PhotoAlbum *itdb_photodb_photoalbum_new (Itdb_PhotoDB *db, + const gchar *album_name) +{ + Itdb_PhotoAlbum *photoalbum; + + g_return_val_if_fail (db, FALSE); + g_return_val_if_fail (album_name, FALSE); + + photoalbum = g_new0 (Itdb_PhotoAlbum, 1); + photoalbum->album_id = itdb_get_free_photoalbum_id( db ); + photoalbum->prev_album_id = photoalbum->album_id - 1; + photoalbum->name = g_strdup( album_name ); + db->photoalbums = g_list_append (db->photoalbums, photoalbum); + + return photoalbum; +} + +/** + * itdb_photodb_write: + * @photodb: the #Itdb_PhotoDB to write to disk + * @error: return location for a #GError or NULL + * + * Write out a PhotoDB. + * + * FIXME: error is not set yet. + * + * Return value: TRUE on success, FALSE on error, in which case @error is + * set accordingly. + **/ +gboolean itdb_photodb_write (Itdb_PhotoDB *photodb, GError **error) +{ + gboolean result; + + g_return_val_if_fail (photodb, FALSE); + g_return_val_if_fail (photodb->device, FALSE); + + if (photodb->device->byte_order == 0) + itdb_device_autodetect_endianess (photodb->device); + + result = ipod_write_photo_db (photodb); + + if (result == -1) + return FALSE; + else + return TRUE; +} diff --git a/src/itdb_playlist.c b/src/itdb_playlist.c index f9e7be1..fcd099f 100644 --- a/src/itdb_playlist.c +++ b/src/itdb_playlist.c @@ -1,4 +1,4 @@ -/* Time-stamp: <2005-11-19 16:24:56 jcs> +/* Time-stamp: <2006-05-30 00:29:18 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -40,7 +40,7 @@ /** * itdb_spl_action_known: - * action: an #SPLAction + * @action: an #SPLAction * * Checks if @action is a known (to libgpod) smart playlist action. * diff --git a/src/itdb_private.h b/src/itdb_private.h index c67647e..e13e79e 100644 --- a/src/itdb_private.h +++ b/src/itdb_private.h @@ -1,4 +1,4 @@ -/* Time-stamp: <2006-03-15 00:11:00 jcs> +/* Time-stamp: <2006-05-28 01:11:35 jcs> | | Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> | Part of the gtkpod project. @@ -125,5 +125,9 @@ typedef struct G_GNUC_INTERNAL gboolean itdb_spl_action_known (SPLAction action); G_GNUC_INTERNAL void itdb_splr_free (SPLRule *splr); +G_GNUC_INTERNAL const gchar *itdb_photodb_get_mountpoint (Itdb_PhotoDB *photodb); +G_GNUC_INTERNAL gchar *db_get_mountpoint (Itdb_DB *db); +G_GNUC_INTERNAL Itdb_Device *db_get_device(Itdb_DB *db); +G_GNUC_INTERNAL gint itdb_get_free_photo_id ( Itdb_PhotoDB *db ); #endif diff --git a/src/ithumb-writer.c b/src/ithumb-writer.c index 4cf2523..a94c289 100644 --- a/src/ithumb-writer.c +++ b/src/ithumb-writer.c @@ -58,7 +58,7 @@ typedef struct _iThumbWriter iThumbWriter; * square */ static guint16 * -pack_RGB_565 (GdkPixbuf *pixbuf, int dst_width, int dst_height, guint byte_order) +pack_RGB_565 (GdkPixbuf *pixbuf, iThumbWriter *writer ) { guchar *pixels; guint16 *result; @@ -68,18 +68,32 @@ pack_RGB_565 (GdkPixbuf *pixbuf, int dst_width, int dst_height, guint byte_order gint height; gint w; gint h; + gint horizontal_padding; + gint vertical_padding; + gint byte_order; g_object_get (G_OBJECT (pixbuf), "rowstride", &row_stride, "n-channels", &channels, "height", &height, "width", &width, "pixels", &pixels, NULL); - g_return_val_if_fail ((width <= dst_width) && (height <= dst_height), NULL); + g_return_val_if_fail ((width <= writer->img_info->width) && (height <= writer->img_info->height), NULL); /* dst_width and dst_height come from a width/height database * hardcoded in libipoddevice code, so dst_width * dst_height * 2 can't * overflow, even on an iPod containing malicious data */ - result = g_malloc0 (dst_width * dst_height * 2); + result = g_malloc0 ( writer->img_info->width * writer->img_info->height * 2); + + /* Swap the byte order on full screen nano photos */ + byte_order = writer->byte_order; + if ( writer->img_info->correlation_id == 1023) { + if (byte_order == G_LITTLE_ENDIAN) + byte_order = G_BIG_ENDIAN; + else + byte_order = G_LITTLE_ENDIAN; + } + horizontal_padding = (writer->img_info->width - width)/2; + vertical_padding = (writer->img_info->height - height)/2; for (h = 0; h < height; h++) { for (w = 0; w < width; w++) { gint r; @@ -89,49 +103,75 @@ pack_RGB_565 (GdkPixbuf *pixbuf, int dst_width, int dst_height, guint byte_order r = pixels[h*row_stride + w*channels]; g = pixels[h*row_stride + w*channels + 1]; b = pixels[h*row_stride + w*channels + 2]; + r >>= (8 - RED_BITS); g >>= (8 - GREEN_BITS); b >>= (8 - BLUE_BITS); r = (r << RED_SHIFT) & RED_MASK; g = (g << GREEN_SHIFT) & GREEN_MASK; b = (b << BLUE_SHIFT) & BLUE_MASK; - result[h*dst_width + w] = get_gint16 (r | g | b, - byte_order); + result[(h+vertical_padding)*writer->img_info->width + w + horizontal_padding] + = get_gint16 (r | g | b, byte_order); } } return result; } - - static char * -ipod_image_get_ithmb_filename (const char *mount_point, gint correlation_id, gint index) +ipod_image_get_ithmb_filename (const char *mount_point, gint correlation_id, gint index, DbType db_type ) { - gchar *artwork_dir, *filename, *buf; + gchar *artwork_dir = NULL, *filename, *buf; g_return_val_if_fail (mount_point, NULL); + switch( db_type ) { + case DB_TYPE_PHOTO: + artwork_dir = itdb_get_photos_thumb_dir (mount_point); + if (!artwork_dir) + { + /* attempt to create Thumbs dir */ + gchar *photos_dir = itdb_get_photos_dir (mount_point); + gchar *dir; + if (!photos_dir) + { /* give up */ + return NULL; + } + dir = g_build_filename (photos_dir, "Thumbs", NULL); + mkdir (dir, 0777); + g_free (dir); + g_free (photos_dir); + + /* try again */ + artwork_dir = itdb_get_photos_thumb_dir (mount_point); + if (!artwork_dir) + { /* give up */ + return NULL; + } + } + break; + case DB_TYPE_ITUNES: artwork_dir = itdb_get_artwork_dir (mount_point); if (!artwork_dir) { - /* attempt to create Artwork dir */ - gchar *control_dir = itdb_get_control_dir (mount_point); - gchar *dir; - if (!control_dir) - { /* give up */ - return NULL; - } - dir = g_build_filename (control_dir, "Artwork", NULL); - mkdir (dir, 0777); - g_free (dir); - g_free (control_dir); - - /* try again */ - artwork_dir = itdb_get_artwork_dir (mount_point); - if (!artwork_dir) - { /* give up */ - return NULL; - } + /* attempt to create Artwork dir */ + gchar *control_dir = itdb_get_control_dir (mount_point); + gchar *dir; + if (!control_dir) + { /* give up */ + return NULL; + } + dir = g_build_filename (control_dir, "Artwork", NULL); + mkdir (dir, 0777); + g_free (dir); + g_free (control_dir); + + /* try again */ + artwork_dir = itdb_get_artwork_dir (mount_point); + if (!artwork_dir) + { /* give up */ + return NULL; + } + } } buf = g_strdup_printf ("F%04u_%d.ithmb", correlation_id, index); @@ -199,17 +239,24 @@ ithumb_writer_write_thumbnail (iThumbWriter *writer, thumb->height = height; thumb->offset = writer->cur_offset; thumb->size = writer->img_info->width * writer->img_info->height * 2; -/* printf("offset: %d type: %d, size: %d\n", thumb->offset, thumb->type, thumb->size); */ + /* FIXME: under certain conditions (probably related to * writer->offset getting too big), this should be :F%04u_2.ithmb * and so on */ - thumb->filename = g_strdup_printf (":F%04u_1.ithmb", - writer->img_info->correlation_id); - pixels = pack_RGB_565 (pixbuf, writer->img_info->width, - writer->img_info->height, - writer->byte_order); - g_object_unref (G_OBJECT (pixbuf)); + if( thumb->type == ITDB_THUMB_PHOTO_LARGE + || thumb->type == ITDB_THUMB_PHOTO_SMALL + || thumb->type == ITDB_THUMB_PHOTO_FULL_SCREEN ) + { + thumb->filename = g_strdup_printf (":Thumbs:F%04u_1.ithmb", + writer->img_info->correlation_id); + + } else { + thumb->filename = g_strdup_printf (":F%04u_1.ithmb", + writer->img_info->correlation_id); + } + pixels = pack_RGB_565 (pixbuf, writer ); + g_object_unref (G_OBJECT (pixbuf)); if (pixels == NULL) { @@ -250,8 +297,9 @@ write_thumbnail (gpointer _writer, gpointer _artwork) static iThumbWriter * ithumb_writer_new (const char *mount_point, - const Itdb_ArtworkFormat *info, - guint byte_order) + const Itdb_ArtworkFormat *info, + DbType db_type, + guint byte_order) { char *filename; iThumbWriter *writer; @@ -267,7 +315,8 @@ ithumb_writer_new (const char *mount_point, filename = ipod_image_get_ithmb_filename (mount_point, info->correlation_id, - 1); + 1, + db_type); if (filename == NULL) { g_hash_table_destroy (writer->cache); g_free (writer->img_info); @@ -512,7 +561,7 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key, slots are filled, the file is truncated to the new length. */ static gboolean -ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, +ithmb_rearrange_existing_thumbnails (Itdb_DB *db, const Itdb_ArtworkFormat *info) { GList *gl; @@ -523,11 +572,11 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, gchar *filename; const gchar *mountpoint; - g_return_val_if_fail (itdb, FALSE); + g_return_val_if_fail (db, FALSE); g_return_val_if_fail (info, FALSE); - g_return_val_if_fail (itdb->device, FALSE); + g_return_val_if_fail (db_get_device(db), FALSE); - mountpoint = itdb_get_mountpoint (itdb); + mountpoint = db_get_mountpoint (db); g_return_val_if_fail (mountpoint, FALSE); @@ -538,24 +587,47 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, This will usually be a number of "F%04d_%d.ithmb" files. A GList is kept with pointers to all images in a given file which allows to adjust the offset pointers */ - for (gl=itdb->tracks; gl; gl=gl->next) - { - Itdb_Thumb *thumb; - 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->device, + switch (db->db_type) { + case DB_TYPE_ITUNES: + for (gl=db->db.itdb->tracks; gl; gl=gl->next) + { + Itdb_Thumb *thumb; + 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 (db->db.itdb->device, thumb); - if (filename) - { - thumbs = g_hash_table_lookup (filenamehash, filename); - thumbs = g_list_append (thumbs, thumb); - g_hash_table_insert (filenamehash, filename, thumbs); - } + if (filename) + { + thumbs = g_hash_table_lookup (filenamehash, filename); + thumbs = g_list_append (thumbs, thumb); + g_hash_table_insert (filenamehash, filename, thumbs); + } + } + } + case DB_TYPE_PHOTO: + for (gl=db->db.photodb->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->db.photodb->device, + thumb); + if (filename) + { + thumbs = g_hash_table_lookup (filenamehash, filename); + thumbs = g_list_append (thumbs, thumb); + g_hash_table_insert (filenamehash, filename, thumbs); + } + } } } @@ -566,7 +638,8 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, { filename = ipod_image_get_ithmb_filename (mountpoint, info->correlation_id, - i); + i, + db->db_type); if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (g_hash_table_lookup (filenamehash, filename) == NULL) @@ -588,32 +661,29 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb, #endif G_GNUC_INTERNAL int -itdb_write_ithumb_files (Itdb_iTunesDB *db) +itdb_write_ithumb_files (Itdb_DB *db) { #ifdef HAVE_GDKPIXBUF GList *writers; GList *it; - const gchar *mount_point; + Itdb_Device *device; const Itdb_ArtworkFormat *format; + const gchar *mount_point; g_return_val_if_fail (db, -1); - g_return_val_if_fail (db->device, -1); + device = db_get_device(db); + g_return_val_if_fail (device, -1); - mount_point = itdb_get_mountpoint (db); + mount_point = db_get_mountpoint (db); /* FIXME: support writing to directory rather than writing to iPod */ if (mount_point == NULL) return -1; - if (db->device == NULL) { - return -1; - } - - format = itdb_device_get_artwork_formats (db->device); + format = itdb_device_get_artwork_formats (device); if (format == NULL) { return -1; } - writers = NULL; while (format->type != -1) { iThumbWriter *writer; @@ -621,10 +691,15 @@ itdb_write_ithumb_files (Itdb_iTunesDB *db) switch (format->type) { case IPOD_COVER_SMALL: case IPOD_COVER_LARGE: - ithmb_rearrange_existing_thumbnails (db, - format); - writer = ithumb_writer_new (mount_point, format, - db->device->byte_order); + case IPOD_PHOTO_SMALL: + case IPOD_PHOTO_LARGE: + case IPOD_PHOTO_FULL_SCREEN: + ithmb_rearrange_existing_thumbnails (db, + format ); + writer = ithumb_writer_new (mount_point, + format, + db->db_type, + device->byte_order); if (writer != NULL) { writers = g_list_prepend (writers, writer); } @@ -634,20 +709,32 @@ itdb_write_ithumb_files (Itdb_iTunesDB *db) } format++; } - if (writers == NULL) { return -1; } + switch (db->db_type) { + case DB_TYPE_ITUNES: + for (it = db->db.itdb->tracks; it != NULL; it = it->next) { + Itdb_Track *track; - for (it = db->tracks; it != NULL; it = it->next) { - Itdb_Track *track; + track = it->data; + g_return_val_if_fail (track, -1); - track = it->data; - g_return_val_if_fail (track, -1); + g_list_foreach (writers, write_thumbnail, track->artwork); + } + break; + case DB_TYPE_PHOTO: + for (it = db->db.photodb->photos; it != NULL; it = it->next) { + Itdb_Artwork *photo; - g_list_foreach (writers, write_thumbnail, track->artwork); - } + photo = it->data; + g_return_val_if_fail (photo, -1); + g_list_foreach (writers, write_thumbnail, photo); + } + break; + } + g_list_foreach (writers, (GFunc)ithumb_writer_free, NULL); g_list_free (writers); diff --git a/tests/Makefile.am b/tests/Makefile.am index 651f41a..4aa7bc5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,16 +1,18 @@ if HAVE_GDKPIXBUF -TESTTHUMBS=test-thumbnails test-write-thumbnails +TESTTHUMBS=test-thumbnails test-write-thumbnails test-photos else TESTTHUMBS= endif +TESTMISC=test-init-ipod + if HAVE_TAGLIB TESTTAGLIB=test-rebuild-db else TESTTAGLIB= endif -noinst_PROGRAMS=test-itdb test-ls $(TESTTHUMBS) $(TESTTAGLIB) +noinst_PROGRAMS=test-itdb test-ls $(TESTTHUMBS) $(TESTTAGLIB) $(TESTMISC) INCLUDES=$(LIBGPOD_CFLAGS) -I$(top_srcdir)/src -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" LIBS=$(LIBGPOD_LIBS) $(top_builddir)/src/libgpod.la @@ -31,6 +33,11 @@ if HAVE_GDKPIXBUF test_thumbnails_SOURCES = test-covers.c test_thumbnails_CFLAGS = $(AM_CFLAGS) +test_photos_SOURCES = test-photos.c +test_photos_CFLAGS = $(AM_CFLAGS) + +test_init_ipod_SOURCES = test-init-ipod.c + test_write_thumbnails_SOURCES = test-write-covers.c test_write_thumbnails_CFLAGS = $(AM_CFLAGS) endif diff --git a/tests/test-init-ipod.c b/tests/test-init-ipod.c new file mode 100644 index 0000000..809afcd --- /dev/null +++ b/tests/test-init-ipod.c @@ -0,0 +1,102 @@ +/* Copyright (c) 2006, Jorg Schuler + * <jcsjcs at users dot sourceforge dot net> + * + * The code contained in this file is free software; you can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either version + * 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this code; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * iTunes and iPod are trademarks of Apple + * + * This product is not supported/written/published by Apple! + * + * $Id$ + * + */ + +#include "itdb.h" + +#include <locale.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <glib/gi18n-lib.h> + + +static void usage (const char *argv0) +{ + g_print ("Usage: %s mountpoint [modelnumber]\n", argv0); + g_print ("This test program will create the standard directories on your iPod\n"); + g_print ("including empty iTunesDB and ArtworkDB.\n\n"); + g_print ("Valid model numbers are listed in itdb_device.c, e.g. 'MA350' for a\n"); + g_print ("1 GB iPod nano\n\n"); + g_print ("Often the model number can be found in <mountpoint>/iTunes/Device/SysInfo,\n"); + g_print ("which is written automatically by most iPods when you reset it.\n\n"); + g_print ("If you omit the model number, this program will try to detect the model\n"); + g_print ("number and print it.\n"); +} + + +int +main (int argc, char **argv) +{ + if ((argc < 2) || (argc > 3)) + { + usage (argv[0]); + return 1; + } + setlocale (LC_ALL, ""); + g_type_init (); + + if (argc == 3) + { + GError *error = NULL; + + if (!itdb_init_ipod (argv[1], argv[2], "iPod", &error)) + { + if (error) + { + g_print (_("Error initialising iPod: %s\n"), + error->message); + g_error_free (error); + error = NULL; + } + else + { + g_print (_("Error initialising iPod, unknown error\n")); + } + } + } + if (argc == 2) + { + gchar *model_num; + Itdb_Device *device = itdb_device_new (); + itdb_device_set_mountpoint (device, argv[1]); + + model_num = itdb_device_get_sysinfo (device, "ModelNumStr"); + + if (model_num) + { + g_print ("Your iPod model number seems to be '%s'.\n", + model_num); + } + else + { + g_print ("Your iPod model number could not be detected.\n"); + g_print ("Maybe you have an iPod Shuffle? In that case specify 'M9724' (512 MB)\n"); + g_print ("or 'M9725' (1 GB) to setup your iPod.\n"); + g_print ("If you have a mobile phone, specify 'Mmobile1'.\n"); + g_print ("Otherwise look up the model number on the ipod package or in\n"); + g_print ("itdb_device.c (prepend 'M').\n"); + } + itdb_device_free (device); + } + return 0; +} diff --git a/tests/test-photos.c b/tests/test-photos.c new file mode 100644 index 0000000..ae03c21 --- /dev/null +++ b/tests/test-photos.c @@ -0,0 +1,144 @@ +/* Copyright (c) 2006, Michael McLellan <mikey@mclellan.org.nz> + * + * The code contained in this file is free software; you can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either version + * 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this code; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * iTunes and iPod are trademarks of Apple + * + * This product is not supported/written/published by Apple! + * + * $Id$ + * + */ + +#include "itdb.h" + +#include <locale.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <glib/gi18n-lib.h> + +static void +save_itdb_thumb (Itdb_PhotoDB *itdb, Itdb_Thumb *thumb, const char *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, char *album_name ) +{ + GList *it; + gint i = 0; + + for (it = artwork->thumbnails; it != NULL; it = it->next, i++) { + Itdb_Thumb *thumb; + gchar *filename; + + thumb = (Itdb_Thumb *)it->data; + g_return_if_fail (thumb); + + filename = g_strdup_printf ("%s-%d-%d.png", + album_name, artwork->id, i ); + save_itdb_thumb (db, thumb, filename); + g_free (filename); + } +} + +static void +dump_artwork (Itdb_PhotoDB *db, gint photo_id, char *album_name) +{ + GList *it; + + for (it = db->photos; it != NULL; it = it->next) { + Itdb_Artwork *artwork; + + artwork = (Itdb_Artwork *)it->data; + g_return_if_fail (artwork); + if( artwork->id == photo_id ) { + dump_thumbs( db, artwork, album_name ); + break; + } + } +} + +static void +dump_albums (Itdb_PhotoDB *db) +{ + GList *it; + + for (it = db->photoalbums; it != NULL; it = it->next) { + Itdb_PhotoAlbum *album; + GList *it2; + + album = (Itdb_PhotoAlbum *)it->data; + g_return_if_fail (album); + + for (it2 = album->members; it2 != NULL; it2 = it2->next) { + gint *photo_id; + + photo_id = it2->data; + g_return_if_fail (photo_id); + dump_artwork (db, *photo_id, album->name); + } + } +} + +int +main (int argc, char **argv) +{ + GError *error = NULL; + Itdb_PhotoDB *db; + gint i; + + if (argc < 4) { + g_print ("Usage: %s mountpoint albumname filename(s)\n", argv[0]); + g_print ("albumname should be set to 'master' to add photos to the master photo album\n"); + return 1; + } + setlocale (LC_ALL, ""); + g_type_init (); + db = itdb_photodb_parse (argv[1], &error); + + if (db == NULL) { + if (error) + { + g_print (_("Error reading iPod photo database (%s).\nWill attempt to create a new database.\n"), error->message); + g_error_free (error); + error = NULL; + } + else + { + g_print (_("Error reading iPod photo database, will attempt to create a new database\n")); + } + db = itdb_photodb_new (); + itdb_device_set_mountpoint (db->device, argv[1]); + } + + if( 0 ) + dump_albums (db); + + for (i=3; i<argc; ++i) { + itdb_photodb_add_photo (db, argv[2], argv[i]); + } + itdb_photodb_write (db, NULL); + itdb_photodb_free (db); + return 0; +} + |