diff --git a/albumart.c b/albumart.c index 650ca69..e7bd5cb 100644 --- a/albumart.c +++ b/albumart.c @@ -38,6 +38,24 @@ static void libjpeg_error_handler(j_common_ptr cinfo) return; } +int +check_res(int width, int height, char * dlna_pn) +{ + if( (width <= 0) || (height <= 0) ) + return 0; + if( width <= 160 && height <= 160 ) + strcpy(dlna_pn, "JPEG_TN"); + else if( width <= 640 && height <= 480 ) + strcpy(dlna_pn, "JPEG_SM"); + else if( width <= 1024 && height <= 768 ) + strcpy(dlna_pn, "JPEG_MED"); + else if( width <= 4096 && height <= 4096 ) + strcpy(dlna_pn, "JPEG_LRG"); + else + return 0; + return 1; +} + #ifdef HAVE_LIBID3TAG #include @@ -101,9 +119,9 @@ jpeg_memory_src(j_decompress_ptr cinfo, unsigned char const *buffer, size_t bufs src->pub.bytes_in_buffer = bufsize; } -/* And our main album art function */ +/* And our main album art functions */ int -check_embedded_art(const char * path) +check_embedded_art(const char * path, char * dlna_pn) { struct id3_file *file; struct id3_tag *pid3tag; @@ -148,21 +166,22 @@ check_embedded_art(const char * path) } id3_file_close(file); - /* It's not a valid DLNA_PN JPEG_TN unless it's JPEG <= 160x160 */ - return( (width > 0 && width <= 160) && (height > 0 && height <= 160) ); + return( check_res(width, height, dlna_pn) ); } #endif // HAVE_LIBID3TAG char * -check_for_album_file(char * dir) +check_for_album_file(char * dir, char * dlna_pn) { char * file = malloc(PATH_MAX); char * album_art_names[] = { - "Cover.jpg", "cover.jpg", - "Album.jpg", "album.jpg", - "Folder.jpg", "folder.jpg", - "Thumb.jpg", "thumb.jpg", + "AlbumArtSmall.jpg", "albumartsmall.jpg", + "Cover.jpg", "cover.jpg", + "AlbumArt.jpg", "albumart.jpg", + "Album.jpg", "album.jpg", + "Folder.jpg", "folder.jpg", + "Thumb.jpg", "thumb.jpg", 0 }; struct jpeg_decompress_struct cinfo; @@ -191,8 +210,10 @@ check_for_album_file(char * dir) jpeg_destroy_decompress(&cinfo); fclose(infile); - if( (width > 0 && width <= 160) && (height > 0 && height <= 160) ) + if( check_res(width, height, dlna_pn) ) return(file); + else + return(NULL); } } free(file); @@ -200,7 +221,7 @@ check_for_album_file(char * dir) } sqlite_int64 -find_album_art(const char * path) +find_album_art(const char * path, char * dlna_pn) { char * album_art = NULL; char * sql; @@ -210,9 +231,9 @@ find_album_art(const char * path) char * mypath = strdup(path); #ifdef HAVE_LIBID3TAG - if( check_embedded_art(path) || (album_art = check_for_album_file(dirname(mypath))) ) + if( check_embedded_art(path, dlna_pn) || (album_art = check_for_album_file(dirname(mypath), dlna_pn)) ) #else - if( (album_art = check_for_album_file(dirname(mypath))) ) + if( (album_art = check_for_album_file(dirname(mypath), dlna_pn)) ) #endif { sql = sqlite3_mprintf("SELECT ID from ALBUM_ART where PATH = '%q'", album_art ? album_art : path); diff --git a/albumart.h b/albumart.h index ca2cb56..6db6176 100644 --- a/albumart.h +++ b/albumart.h @@ -11,6 +11,6 @@ #define __ALBUMART_H__ sqlite_int64 -find_album_art(const char * path); +find_album_art(const char * path, char * dlna_pn); #endif diff --git a/metadata.c b/metadata.c index ece3c42..e8a9406 100644 --- a/metadata.c +++ b/metadata.c @@ -100,17 +100,18 @@ get_fourcc(const char *s) } sqlite_int64 -GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art) +GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art, const char * art_dlna_pn) { char * sql; int ret; sql = sqlite3_mprintf( "INSERT into DETAILS" - " (TITLE, CREATOR, ARTIST, GENRE, ALBUM_ART) " + " (TITLE, CREATOR, ARTIST, GENRE, ALBUM_ART, ART_DLNA_PN) " "VALUES" - " ('%q', %Q, %Q, %Q, %lld);", + " ('%q', %Q, %Q, %Q, %lld, %Q);", name, artist, artist, genre, - album_art ? strtoll(album_art, NULL, 10) : 0); + album_art ? strtoll(album_art, NULL, 10) : 0, + art_dlna_pn); if( sql_exec(db, sql) != SQLITE_OK ) ret = 0; @@ -136,6 +137,8 @@ GetAudioMetadata(const char * path, char * name) char *zErrMsg = NULL; char *title, *artist, *album, *genre, *comment; int free_flags = 0; + sqlite_int64 album_art; + char art_dlna_pn[9]; if ( stat(path, &file) == 0 ) size = file.st_size; @@ -248,11 +251,13 @@ GetAudioMetadata(const char * path, char * name) strcpy(mime, "audio/mp4"); } + album_art = find_album_art(path, art_dlna_pn); + sql = sqlite3_mprintf( "INSERT into DETAILS" " (PATH, SIZE, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE," - " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, TRACK, DLNA_PN, MIME, ALBUM_ART) " + " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, TRACK, DLNA_PN, MIME, ALBUM_ART, ART_DLNA_PN) " "VALUES" - " (%Q, %llu, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, '%s', '%s', %lld);", + " (%Q, %llu, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, '%s', '%s', %lld, %Q);", path, size, duration, taglib_audioproperties_channels(properties), taglib_audioproperties_bitrate(properties)*1024, taglib_audioproperties_samplerate(properties), @@ -264,7 +269,7 @@ GetAudioMetadata(const char * path, char * name) comment, taglib_tag_track(tag), dlna_pn, mime, - find_album_art(path) ); + album_art, album_art?art_dlna_pn:NULL ); taglib_tag_free_strings(); taglib_file_free(audio_file); diff --git a/metadata.h b/metadata.h index d6c0518..3d7bd81 100644 --- a/metadata.h +++ b/metadata.h @@ -44,7 +44,7 @@ char * modifyString(char * string, const char * before, const char * after, short like); sqlite_int64 -GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art); +GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art, const char * art_dlna_pn); sqlite_int64 GetAudioMetadata(const char * path, char * name); diff --git a/scanner.c b/scanner.c index 83e997d..a10f29d 100644 --- a/scanner.c +++ b/scanner.c @@ -79,7 +79,7 @@ get_next_available_id(const char * table, const char * parentID) long long int insert_container(const char * tmpTable, const char * item, const char * rootParent, const char *subParent, - const char *class, const char *artist, const char *genre, const char *album_art) + const char *class, const char *artist, const char *genre, const char *album_art, const char *art_dlna_pn) { char **result; char *sql; @@ -100,7 +100,7 @@ insert_container(const char * tmpTable, const char * item, const char * rootPare else { parentID = get_next_available_id("OBJECTS", rootParent); - detailID = GetFolderMetadata(item, artist, genre, album_art); + detailID = GetFolderMetadata(item, artist, genre, album_art, art_dlna_pn); sql = sqlite3_mprintf( "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, DETAIL_ID, CLASS, NAME) " "VALUES" @@ -147,7 +147,7 @@ insert_containers(const char * name, const char *path, const char * refID, const { strncpy(date_taken, date, 10); } - container = insert_container("DATES", date_taken, "3$12", NULL, "album.photoAlbum", NULL, NULL, NULL); + container = insert_container("DATES", date_taken, "3$12", NULL, "album.photoAlbum", NULL, NULL, NULL, NULL); parentID = container>>32; objectID = container; sql = sqlite3_mprintf( "INSERT into OBJECTS" @@ -160,12 +160,12 @@ insert_containers(const char * name, const char *path, const char * refID, const } if( cam && date ) { - container = insert_container("CAMS", cam, "3$13", NULL, "storageFolder", NULL, NULL, NULL); + container = insert_container("CAMS", cam, "3$13", NULL, "storageFolder", NULL, NULL, NULL, NULL); parentID = container>>32; //objectID = container; char parent[64]; sprintf(parent, "3$13$%X", parentID); - long long int subcontainer = insert_container("CAMDATE", date_taken, parent, cam, "storageFolder", NULL, NULL, NULL); + long long int subcontainer = insert_container("CAMDATE", date_taken, parent, cam, "storageFolder", NULL, NULL, NULL, NULL); int subParentID = subcontainer>>32; int subObjectID = subcontainer; sql = sqlite3_mprintf( "INSERT into OBJECTS" @@ -187,8 +187,8 @@ insert_containers(const char * name, const char *path, const char * refID, const } else if( strstr(class, "audioItem") ) { - char *artist = cols ? result[7+cols]:NULL, *album = cols ? result[8+cols]:NULL; - char *genre = cols ? result[9+cols]:NULL, *album_art = cols ? result[19+cols]:NULL; + char *artist = cols ? result[7+cols]:NULL, *album = cols ? result[8+cols]:NULL, *genre = cols ? result[9+cols]:NULL; + char *album_art = cols ? result[19+cols]:NULL, *art_dlna_pn = cols ? result[20+cols]:NULL; static char last_artist[1024] = "0"; static int last_artist_parentID, last_artist_objectID; static char last_album[1024]; @@ -207,7 +207,7 @@ insert_containers(const char * name, const char *path, const char * refID, const else { strcpy(last_artist, artist); - container = insert_container("ARTISTS", artist, "1$6", NULL, "person.musicArtist", NULL, genre, NULL); + container = insert_container("ARTISTS", artist, "1$6", NULL, "person.musicArtist", NULL, genre, NULL, NULL); parentID = container>>32; objectID = container; last_artist_objectID = objectID; @@ -231,7 +231,7 @@ insert_containers(const char * name, const char *path, const char * refID, const else { strcpy(last_album, album); - container = insert_container("ALBUMS", album, "1$7", NULL, "album.musicAlbum", artist, genre, album_art); + container = insert_container("ALBUMS", album, "1$7", NULL, "album.musicAlbum", artist, genre, album_art, art_dlna_pn); parentID = container>>32; objectID = container; last_album_objectID = objectID; @@ -255,7 +255,7 @@ insert_containers(const char * name, const char *path, const char * refID, const else { strcpy(last_genre, genre); - container = insert_container("GENRES", genre, "1$5", NULL, "genre.musicGenre", NULL, NULL, NULL); + container = insert_container("GENRES", genre, "1$5", NULL, "genre.musicGenre", NULL, NULL, NULL, NULL); parentID = container>>32; objectID = container; last_genre_objectID = objectID; @@ -361,7 +361,7 @@ insert_directory(const char * name, const char * path, const char * base, const return 1; } - detailID = GetFolderMetadata(name, NULL, NULL, NULL); + detailID = GetFolderMetadata(name, NULL, NULL, NULL, NULL); sql = sqlite3_mprintf( "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, REF_ID, DETAIL_ID, CLASS, NAME) " "VALUES" @@ -513,7 +513,8 @@ CreateDatabase(void) "CREATOR TEXT, " "DLNA_PN TEXT, " "MIME TEXT, " - "ALBUM_ART INTEGER DEFAULT 0" + "ALBUM_ART INTEGER DEFAULT 0, " + "ART_DLNA_PN TEXT DEFAULT NULL" ");"); if( ret != SQLITE_OK ) goto sql_failed; @@ -529,7 +530,7 @@ CreateDatabase(void) sprintf(sql_buf, "INSERT into OBJECTS (OBJECT_ID, PARENT_ID, DETAIL_ID, CLASS, NAME)" " values " "('%s', '%s', %lld, 'container.storageFolder', '%s')", - containers[i], containers[i+1], GetFolderMetadata(containers[i+2], NULL, NULL, NULL), containers[i+2]); + containers[i], containers[i+1], GetFolderMetadata(containers[i+2], NULL, NULL, NULL, NULL), containers[i+2]); ret = sql_exec(db, sql_buf); if( ret != SQLITE_OK ) goto sql_failed; diff --git a/upnpsoap.c b/upnpsoap.c index 3ec9556..c6ceb8c 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -209,8 +209,8 @@ static int callback(void *args, int argc, char **argv, char **azColName) struct Response { char *resp; int returned; int requested; int total; char *filter; } *passed_args = (struct Response *)args; char *id = argv[1], *parent = argv[2], *refID = argv[3], *class = argv[4], *detailID = argv[5], *size = argv[9], *title = argv[10], *duration = argv[11], *bitrate = argv[12], *sampleFrequency = argv[13], *artist = argv[14], *album = argv[15], - *genre = argv[16], *comment = argv[17], *nrAudioChannels = argv[18], *track = argv[19], *date = argv[20], - *resolution = argv[21], *tn = argv[22], *creator = argv[23], *dlna_pn = argv[24], *mime = argv[25], *album_art = argv[26]; + *genre = argv[16], *comment = argv[17], *nrAudioChannels = argv[18], *track = argv[19], *date = argv[20], *resolution = argv[21], + *tn = argv[22], *creator = argv[23], *dlna_pn = argv[24], *mime = argv[25], *album_art = argv[26], *art_dlna_pn = argv[27]; char dlna_buf[64]; char str_buf[4096]; char **result; @@ -269,10 +269,12 @@ static int callback(void *args, int argc, char **argv, char **azColName) strcat(passed_args->resp, str_buf); } if( album_art && atoi(album_art) && (!passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI")) ) { - sprintf(str_buf, "<upnp:albumArtURI %s" - ">http://%s:%d/AlbumArt/%s.jpg</upnp:albumArtURI>", - (!passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI@dlna:profileID")) ? - "dlna:profileID=\"JPEG_TN\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"" : "", + strcat(passed_args->resp, "<upnp:albumArtURI "); + if( !passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI@dlna:profileID") ) { + sprintf(str_buf, "dlna:profileID=\"%s\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"", art_dlna_pn); + strcat(passed_args->resp, str_buf); + } + sprintf(str_buf, ">http://%s:%d/AlbumArt/%s.jpg</upnp:albumArtURI>", lan_addr[0].str, runtime_vars.port, album_art); strcat(passed_args->resp, str_buf); } @@ -368,8 +370,13 @@ static int callback(void *args, int argc, char **argv, char **azColName) strcat(passed_args->resp, str_buf); } if( album_art && atoi(album_art) && (!passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI")) ) { - sprintf(str_buf, "<upnp:albumArtURI dlna:profileID=\"JPEG_TN\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"" - ">http://%s:%d/AlbumArt/%s.jpg</upnp:albumArtURI>", lan_addr[0].str, runtime_vars.port, album_art); + strcat(passed_args->resp, "<upnp:albumArtURI "); + if( !passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI@dlna:profileID") ) { + sprintf(str_buf, "dlna:profileID=\"%s\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"", art_dlna_pn); + strcat(passed_args->resp, str_buf); + } + sprintf(str_buf, ">http://%s:%d/AlbumArt/%s.jpg</upnp:albumArtURI>", + lan_addr[0].str, runtime_vars.port, album_art); strcat(passed_args->resp, str_buf); } sprintf(str_buf, "</container>");