Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
ui_albumart.c
Go to the documentation of this file.
00001 /*
00002  * Audacious: A cross-platform multimedia player
00003  * Copyright (c) 2007 William Pitcock, Tony Vroon, George Averill,
00004  *                    Giacomo Lozito, Derek Pomery and Yoshiki Yazawa.
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; under version 3 of the License.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses>.
00017  *
00018  * The Audacious team does not consider modular code linking to
00019  * Audacious or using our public API to be a derived work.
00020  */
00021 
00022 #include <glib.h>
00023 #include <string.h>
00024 
00025 #include <libaudcore/audstrings.h>
00026 
00027 #include "config.h"
00028 #include "i18n.h"
00029 #include "misc.h"
00030 
00031 static bool_t
00032 has_front_cover_extension(const char *name)
00033 {
00034     char *ext;
00035 
00036     ext = strrchr(name, '.');
00037     if (!ext) {
00038         /* No file extension */
00039         return FALSE;
00040     }
00041 
00042     return g_strcasecmp(ext, ".jpg") == 0 ||
00043            g_strcasecmp(ext, ".jpeg") == 0 ||
00044            g_strcasecmp(ext, ".png") == 0;
00045 }
00046 
00047 static bool_t
00048 cover_name_filter(const char *name, const char *filter, const bool_t ret_on_empty)
00049 {
00050     bool_t result = FALSE;
00051     char **splitted;
00052     char *current;
00053     char *lname;
00054     int i;
00055 
00056     if (!filter || strlen(filter) == 0) {
00057         return ret_on_empty;
00058     }
00059 
00060     splitted = g_strsplit(filter, ",", 0);
00061 
00062     lname = g_strdup(name);
00063     g_strdown(lname);
00064 
00065     for (i = 0; !result && (current = splitted[i]); i++) {
00066         char *stripped = g_strstrip(g_strdup(current));
00067         g_strdown(stripped);
00068 
00069         result = result || strstr(lname, stripped);
00070 
00071         g_free(stripped);
00072     }
00073 
00074     g_free(lname);
00075     g_strfreev(splitted);
00076 
00077     return result;
00078 }
00079 
00080 /* Check wether it's an image we want */
00081 static bool_t is_front_cover_image (const char * file)
00082 {
00083     char * include = get_string (NULL, "cover_name_include");
00084     char * exclude = get_string (NULL, "cover_name_exclude");
00085     bool_t accept = cover_name_filter (file, include, TRUE) &&
00086      ! cover_name_filter (file, exclude, FALSE);
00087     g_free (include);
00088     g_free (exclude);
00089     return accept;
00090 }
00091 
00092 static bool_t
00093 is_file_image(const char *imgfile, const char *file_name)
00094 {
00095     char *imgfile_ext, *file_name_ext;
00096     size_t imgfile_len, file_name_len;
00097 
00098     imgfile_ext = strrchr(imgfile, '.');
00099     if (!imgfile_ext) {
00100         /* No file extension */
00101         return FALSE;
00102     }
00103 
00104     file_name_ext = strrchr(file_name, '.');
00105     if (!file_name_ext) {
00106         /* No file extension */
00107         return FALSE;
00108     }
00109 
00110     imgfile_len = (imgfile_ext - imgfile);
00111     file_name_len = (file_name_ext - file_name);
00112 
00113     if (imgfile_len == file_name_len) {
00114         return (g_ascii_strncasecmp(imgfile, file_name, imgfile_len) == 0);
00115     } else {
00116         return FALSE;
00117     }
00118 }
00119 
00120 static char * fileinfo_recursive_get_image (const char * path, const char *
00121  file_name, int depth)
00122 {
00123     GDir *d;
00124 
00125     if (get_bool (NULL, "recurse_for_cover") && depth > get_int (NULL, "recurse_for_cover_depth"))
00126         return NULL;
00127 
00128     d = g_dir_open(path, 0, NULL);
00129 
00130     if (d) {
00131         const char *f;
00132 
00133         if (get_bool (NULL, "use_file_cover") && file_name)
00134         {
00135             /* Look for images matching file name */
00136             while((f = g_dir_read_name(d))) {
00137                 char *newpath = g_strconcat(path, "/", f, NULL);
00138 
00139                 if (!g_file_test(newpath, G_FILE_TEST_IS_DIR) &&
00140                     has_front_cover_extension(f) &&
00141                     is_file_image(f, file_name)) {
00142                     g_dir_close(d);
00143                     return newpath;
00144                 }
00145 
00146                 g_free(newpath);
00147             }
00148             g_dir_rewind(d);
00149         }
00150 
00151         /* Search for files using filter */
00152         while ((f = g_dir_read_name(d))) {
00153             char *newpath = g_strconcat(path, "/", f, NULL);
00154 
00155             if (!g_file_test(newpath, G_FILE_TEST_IS_DIR) &&
00156                 has_front_cover_extension(f) &&
00157                 is_front_cover_image(f)) {
00158                 g_dir_close(d);
00159                 return newpath;
00160             }
00161 
00162             g_free(newpath);
00163         }
00164         g_dir_rewind(d);
00165 
00166         /* checks whether recursive or not. */
00167         if (! get_bool (NULL, "recurse_for_cover"))
00168         {
00169             g_dir_close(d);
00170             return NULL;
00171         }
00172 
00173         /* Descend into directories recursively. */
00174         while ((f = g_dir_read_name(d))) {
00175             char *newpath = g_strconcat(path, "/", f, NULL);
00176 
00177             if(g_file_test(newpath, G_FILE_TEST_IS_DIR)) {
00178                 char *tmp = fileinfo_recursive_get_image(newpath,
00179                     NULL, depth + 1);
00180                 if(tmp) {
00181                     g_free(newpath);
00182                     g_dir_close(d);
00183                     return tmp;
00184                 }
00185             }
00186 
00187             g_free(newpath);
00188         }
00189 
00190         g_dir_close(d);
00191     }
00192 
00193     return NULL;
00194 }
00195 
00196 char * get_associated_image_file (const char * filename)
00197 {
00198     if (strncmp (filename, "file://", 7))
00199         return NULL;
00200 
00201     char * unesc = uri_to_filename (filename);
00202     if (! unesc)
00203         return NULL;
00204 
00205     char * path = g_path_get_dirname (unesc);
00206     char * base = g_path_get_basename (unesc);
00207     char * image_file = fileinfo_recursive_get_image (path, base, 0);
00208 
00209     g_free (unesc);
00210     g_free (path);
00211     g_free (base);
00212     return image_file;
00213 }