* Fix some unused result warnings.

* Handle folder art a little differently than file album art.
This commit is contained in:
Justin Maggard 2011-11-19 08:26:10 +00:00
parent d42f8fc193
commit 875f0e2351
5 changed files with 105 additions and 78 deletions

View File

@ -36,22 +36,26 @@
#include "image_utils.h" #include "image_utils.h"
#include "log.h" #include "log.h"
int static int
art_cache_exists(const char * orig_path, char ** cache_file) art_cache_exists(const char *orig_path, char **cache_file)
{ {
asprintf(cache_file, "%s/art_cache%s", db_path, orig_path); if( asprintf(cache_file, "%s/art_cache%s", db_path, orig_path) < 0 )
{
*cache_file = NULL;
return 0;
}
strcpy(strchr(*cache_file, '\0')-4, ".jpg"); strcpy(strchr(*cache_file, '\0')-4, ".jpg");
return (!access(*cache_file, F_OK)); return (!access(*cache_file, F_OK));
} }
char * static char *
save_resized_album_art(image_s * imsrc, const char * path) save_resized_album_art(image_s *imsrc, const char *path)
{ {
int dstw, dsth; int dstw, dsth;
image_s * imdst; image_s *imdst;
char * cache_file; char *cache_file;
char * cache_dir; char cache_dir[MAXPATHLEN];
if( !imsrc ) if( !imsrc )
return NULL; return NULL;
@ -59,9 +63,8 @@ save_resized_album_art(image_s * imsrc, const char * path)
if( art_cache_exists(path, &cache_file) ) if( art_cache_exists(path, &cache_file) )
return cache_file; return cache_file;
cache_dir = strdup(cache_file); strncpyt(cache_dir, cache_file, sizeof(cache_dir));
make_dir(dirname(cache_dir), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); make_dir(dirname(cache_dir), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
free(cache_dir);
if( imsrc->width > imsrc->height ) if( imsrc->width > imsrc->height )
{ {
@ -88,7 +91,8 @@ error:
} }
/* Simple, efficient hash function from Daniel J. Bernstein */ /* Simple, efficient hash function from Daniel J. Bernstein */
unsigned int DJBHash(const char * str, int len) static unsigned int
DJBHash(const char *str, int len)
{ {
unsigned int hash = 5381; unsigned int hash = 5381;
unsigned int i = 0; unsigned int i = 0;
@ -103,19 +107,22 @@ unsigned int DJBHash(const char * str, int len)
/* And our main album art functions */ /* And our main album art functions */
void void
update_if_album_art(const char * path) update_if_album_art(const char *path)
{ {
char * dir; char *dir;
char * match = NULL; char *match;
char * file = NULL; char file[MAXPATHLEN];
char fpath[MAXPATHLEN];
char dpath[MAXPATHLEN];
int ncmp = 0; int ncmp = 0;
int album_art; int album_art;
DIR * dh; DIR *dh;
struct dirent *dp; struct dirent *dp;
enum file_types type = TYPE_UNKNOWN; enum file_types type = TYPE_UNKNOWN;
sqlite_int64 art_id = 0; sqlite_int64 art_id = 0;
match = strdup(basename((char *)path)); strncpyt(fpath, path, sizeof(fpath));
match = basename(fpath);
/* Check if this file name matches a specific audio or video file */ /* Check if this file name matches a specific audio or video file */
if( ends_with(match, ".cover.jpg") ) if( ends_with(match, ".cover.jpg") )
{ {
@ -128,7 +135,8 @@ update_if_album_art(const char * path)
/* Check if this file name matches one of the default album art names */ /* Check if this file name matches one of the default album art names */
album_art = is_album_art(match); album_art = is_album_art(match);
dir = dirname(strdup(path)); strncpyt(dpath, path, sizeof(dpath));
dir = dirname(dpath);
dh = opendir(dir); dh = opendir(dir);
if( !dh ) if( !dh )
return; return;
@ -141,9 +149,8 @@ update_if_album_art(const char * path)
break; break;
case DT_LNK: case DT_LNK:
case DT_UNKNOWN: case DT_UNKNOWN:
asprintf(&file, "%s/%s", dir, dp->d_name); snprintf(file, sizeof(file), "%s/%s", dir, dp->d_name);
type = resolve_unknown_type(file, ALL_MEDIA); type = resolve_unknown_type(file, ALL_MEDIA);
free(file);
break; break;
default: default:
type = TYPE_UNKNOWN; type = TYPE_UNKNOWN;
@ -156,27 +163,25 @@ update_if_album_art(const char * path)
(album_art || strncmp(dp->d_name, match, ncmp) == 0) ) (album_art || strncmp(dp->d_name, match, ncmp) == 0) )
{ {
DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like cover art for %s\n", path, dp->d_name); DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like cover art for %s\n", path, dp->d_name);
asprintf(&file, "%s/%s", dir, dp->d_name); snprintf(file, sizeof(file), "%s/%s", dir, dp->d_name);
art_id = find_album_art(file, NULL, 0); art_id = find_album_art(file, NULL, 0);
if( sql_exec(db, "UPDATE DETAILS set ALBUM_ART = %lld where PATH = '%q'", art_id, file) != SQLITE_OK ) if( sql_exec(db, "UPDATE DETAILS set ALBUM_ART = %lld where PATH = '%q'", art_id, file) != SQLITE_OK )
DPRINTF(E_WARN, L_METADATA, "Error setting %s as cover art for %s\n", match, dp->d_name); DPRINTF(E_WARN, L_METADATA, "Error setting %s as cover art for %s\n", match, dp->d_name);
free(file);
} }
} }
closedir(dh); closedir(dh);
free(dir); free(dir);
free(match);
} }
char * char *
check_embedded_art(const char * path, const char * image_data, int image_size) check_embedded_art(const char *path, const char *image_data, int image_size)
{ {
int width = 0, height = 0; int width = 0, height = 0;
char * art_path = NULL; char *art_path = NULL;
char * cache_dir; char *cache_dir;
FILE * dstfile; FILE *dstfile;
image_s * imsrc; image_s *imsrc;
static char last_path[PATH_MAX]; static char last_path[PATH_MAX];
static unsigned int last_hash = 0; static unsigned int last_hash = 0;
static int last_success = 0; static int last_success = 0;
@ -269,14 +274,28 @@ end_art:
return(art_path); return(art_path);
} }
char * static char *
check_for_album_file(const char * dir, const char * path) check_for_album_file(const char *path)
{ {
char file[MAXPATHLEN]; char file[MAXPATHLEN];
struct album_art_name_s * album_art_name; char mypath[MAXPATHLEN];
image_s * imsrc = NULL; struct album_art_name_s *album_art_name;
image_s *imsrc = NULL;
int width=0, height=0; int width=0, height=0;
char * art_file; char *art_file;
const char *dir;
struct stat st;
if( stat(path, &st) != 0 )
return NULL;
if( S_ISDIR(st.st_mode) )
{
dir = path;
goto check_dir;
}
strncpyt(mypath, path, sizeof(mypath));
dir = dirname(mypath);
/* First look for file-specific cover art */ /* First look for file-specific cover art */
snprintf(file, sizeof(file), "%s.cover.jpg", path); snprintf(file, sizeof(file), "%s.cover.jpg", path);
@ -302,7 +321,7 @@ check_for_album_file(const char * dir, const char * path)
if( imsrc ) if( imsrc )
goto found_file; goto found_file;
} }
check_dir:
/* Then fall back to possible generic cover art file names */ /* Then fall back to possible generic cover art file names */
for( album_art_name = album_art_names; album_art_name; album_art_name = album_art_name->next ) for( album_art_name = album_art_names; album_art_name; album_art_name = album_art_name->next )
{ {
@ -333,30 +352,16 @@ found_file:
} }
sqlite_int64 sqlite_int64
find_album_art(const char * path, const char * image_data, int image_size) find_album_art(const char *path, const char *image_data, int image_size)
{ {
char * album_art = NULL; char *album_art = NULL;
char * sql; char *sql;
char ** result; char **result;
int cols, rows; int cols, rows;
sqlite_int64 ret = 0; sqlite_int64 ret = 0;
char * mypath;
const char * dir;
struct stat st;
if( stat(path, &st) == 0 && S_ISDIR(st.st_mode) )
{
mypath = NULL;
dir = path;
}
else
{
mypath = strdup(path);
dir = dirname(mypath);
}
if( (image_size && (album_art = check_embedded_art(path, image_data, image_size))) || if( (image_size && (album_art = check_embedded_art(path, image_data, image_size))) ||
(album_art = check_for_album_file(dir, path)) ) (album_art = check_for_album_file(path)) )
{ {
sql = sqlite3_mprintf("SELECT ID from ALBUM_ART where PATH = '%q'", album_art ? album_art : path); sql = sqlite3_mprintf("SELECT ID from ALBUM_ART where PATH = '%q'", album_art ? album_art : path);
if( (sql_get_table(db, sql, &result, &rows, &cols) == SQLITE_OK) && rows ) if( (sql_get_table(db, sql, &result, &rows, &cols) == SQLITE_OK) && rows )
@ -372,7 +377,6 @@ find_album_art(const char * path, const char * image_data, int image_size)
sqlite3_free(sql); sqlite3_free(sql);
} }
free(album_art); free(album_art);
free(mypath);
return ret; return ret;
} }

View File

@ -242,38 +242,41 @@ image_get_jpeg_resolution(const char * path, int * width, int * height)
unsigned char buf[8]; unsigned char buf[8];
u_int16_t offset, h, w; u_int16_t offset, h, w;
int ret = 1; int ret = 1;
size_t nread;
long size; long size;
img = fopen(path, "r"); img = fopen(path, "r");
if( !img ) if( !img )
return(-1); return -1;
fseek(img, 0, SEEK_END); fseek(img, 0, SEEK_END);
size = ftell(img); size = ftell(img);
rewind(img); rewind(img);
fread(&buf, 2, 1, img); nread = fread(&buf, 2, 1, img);
if( (buf[0] != 0xFF) || (buf[1] != 0xD8) ) if( (nread < 1) || (buf[0] != 0xFF) || (buf[1] != 0xD8) )
{ {
fclose(img); fclose(img);
return(-1); return -1;
} }
memset(&buf, 0, sizeof(buf)); memset(&buf, 0, sizeof(buf));
while( ftell(img) < size ) while( ftell(img) < size )
{ {
while( buf[0] != 0xFF && !feof(img) ) while( nread > 0 && buf[0] != 0xFF && !feof(img) )
fread(&buf, 1, 1, img); nread = fread(&buf, 1, 1, img);
while( buf[0] == 0xFF && !feof(img) ) while( nread > 0 && buf[0] == 0xFF && !feof(img) )
fread(&buf, 1, 1, img); nread = fread(&buf, 1, 1, img);
if( (buf[0] >= 0xc0) && (buf[0] <= 0xc3) ) if( (buf[0] >= 0xc0) && (buf[0] <= 0xc3) )
{ {
fread(&buf, 7, 1, img); nread = fread(&buf, 7, 1, img);
*width = 0; *width = 0;
*height = 0; *height = 0;
if( nread < 1 )
break;
memcpy(&h, buf+3, 2); memcpy(&h, buf+3, 2);
*height = SWAP16(h); *height = SWAP16(h);
memcpy(&w, buf+5, 2); memcpy(&w, buf+5, 2);
@ -284,7 +287,9 @@ image_get_jpeg_resolution(const char * path, int * width, int * height)
else else
{ {
offset = 0; offset = 0;
fread(&buf, 2, 1, img); nread = fread(&buf, 2, 1, img);
if( nread < 1 )
break;
memcpy(&offset, buf, 2); memcpy(&offset, buf, 2);
offset = SWAP16(offset) - 2; offset = SWAP16(offset) - 2;
if( fseek(img, offset, SEEK_CUR) == -1 ) if( fseek(img, offset, SEEK_CUR) == -1 )
@ -305,13 +310,14 @@ image_get_jpeg_date_xmp(const char * path, char ** date)
struct NameValueParserData xml; struct NameValueParserData xml;
char * exif; char * exif;
int ret = 1; int ret = 1;
size_t nread;
img = fopen(path, "r"); img = fopen(path, "r");
if( !img ) if( !img )
return(-1); return(-1);
fread(&buf, 2, 1, img); nread = fread(&buf, 2, 1, img);
if( (buf[0] != 0xFF) || (buf[1] != 0xD8) ) if( (nread < 1) || (buf[0] != 0xFF) || (buf[1] != 0xD8) )
{ {
fclose(img); fclose(img);
return(-1); return(-1);
@ -320,11 +326,11 @@ image_get_jpeg_date_xmp(const char * path, char ** date)
while( !feof(img) ) while( !feof(img) )
{ {
while( buf[0] != 0xFF && !feof(img) ) while( nread > 0 && buf[0] != 0xFF && !feof(img) )
fread(&buf, 1, 1, img); nread = fread(&buf, 1, 1, img);
while( buf[0] == 0xFF && !feof(img) ) while( nread > 0 && buf[0] == 0xFF && !feof(img) )
fread(&buf, 1, 1, img); nread = fread(&buf, 1, 1, img);
if( feof(img) ) if( feof(img) )
break; break;
@ -332,7 +338,9 @@ image_get_jpeg_date_xmp(const char * path, char ** date)
if( buf[0] == 0xE1 ) // APP1 marker if( buf[0] == 0xE1 ) // APP1 marker
{ {
offset = 0; offset = 0;
fread(&buf, 2, 1, img); nread = fread(&buf, 2, 1, img);
if( nread < 1 )
break;
memcpy(&offset, buf, 2); memcpy(&offset, buf, 2);
offset = SWAP16(offset) - 2; offset = SWAP16(offset) - 2;
@ -347,7 +355,9 @@ image_get_jpeg_date_xmp(const char * path, char ** date)
break; break;
data = newdata; data = newdata;
fread(data, 29, 1, img); nread = fread(data, 29, 1, img);
if( nread < 1 )
break;
offset -= 29; offset -= 29;
if( strcmp(data, "http://ns.adobe.com/xap/1.0/") != 0 ) if( strcmp(data, "http://ns.adobe.com/xap/1.0/") != 0 )
{ {
@ -359,7 +369,9 @@ image_get_jpeg_date_xmp(const char * path, char ** date)
if( !newdata ) if( !newdata )
break; break;
data = newdata; data = newdata;
fread(data, offset, 1, img); nread = fread(data, offset, 1, img);
if( nread < 1 )
break;
ParseNameValue(data, offset, &xml); ParseNameValue(data, offset, &xml);
exif = GetValueFromNameValueList(&xml, "DateTimeOriginal"); exif = GetValueFromNameValueList(&xml, "DateTimeOriginal");
@ -378,7 +390,9 @@ image_get_jpeg_date_xmp(const char * path, char ** date)
else else
{ {
offset = 0; offset = 0;
fread(&buf, 2, 1, img); nread = fread(&buf, 2, 1, img);
if( nread < 1 )
break;
memcpy(&offset, buf, 2); memcpy(&offset, buf, 2);
offset = SWAP16(offset) - 2; offset = SWAP16(offset) - 2;
fseek(img, offset, SEEK_CUR); fseek(img, offset, SEEK_CUR);

View File

@ -402,8 +402,7 @@ GetAudioMetadata(const char * path, char * name)
if( !getenv("LANG") ) if( !getenv("LANG") )
strcpy(lang, "en_US"); strcpy(lang, "en_US");
else else
strncpy(lang, getenv("LANG"), 5); strncpyt(lang, getenv("LANG"), sizeof(lang));
lang[5] = '\0';
} }
if( readtags((char *)path, &song, &file, lang, type) != 0 ) if( readtags((char *)path, &song, &file, lang, type) != 0 )
@ -595,11 +594,11 @@ GetImageMetadata(const char * path, char * name)
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE); e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
if( e ) if( e )
{ {
strncpy(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make)); strncpyt(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL); e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
if( e ) if( e )
{ {
strncpy(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model)); strncpyt(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));
if( !strcasestr(model, make) ) if( !strcasestr(model, make) )
snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b))); snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b)));
m.creator = strdup(model); m.creator = strdup(model);

View File

@ -45,6 +45,13 @@ strcatf(struct string_s *str, const char *fmt, ...)
return ret; return ret;
} }
inline void
strncpyt(char *dst, const char *src, size_t len)
{
strncpy(dst, src, len);
dst[len-1] = '\0';
}
int int
ends_with(const char * haystack, const char * needle) ends_with(const char * haystack, const char * needle)
{ {

View File

@ -27,6 +27,9 @@
int int
strcatf(struct string_s *str, char *fmt, ...); strcatf(struct string_s *str, char *fmt, ...);
void
strncpyt(char *dst, const char *src, size_t len);
int int
ends_with(const char * haystack, const char * needle); ends_with(const char * haystack, const char * needle);