Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
ui_albumart.c
Go to the documentation of this file.
1 /*
2  * ui_albumart.c
3  * Copyright 2006 Michael Hanselmann and Yoshiki Yazawa
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <glib.h>
21 #include <string.h>
22 
23 #include <libaudcore/audstrings.h>
24 
25 #include "i18n.h"
26 #include "misc.h"
27 
28 static bool_t
30 {
31  char *ext;
32 
33  ext = strrchr(name, '.');
34  if (!ext) {
35  /* No file extension */
36  return FALSE;
37  }
38 
39  return g_ascii_strcasecmp(ext, ".jpg") == 0 ||
40  g_ascii_strcasecmp(ext, ".jpeg") == 0 ||
41  g_ascii_strcasecmp(ext, ".png") == 0;
42 }
43 
44 static bool_t
45 cover_name_filter(const char *name, const char *filter, const bool_t ret_on_empty)
46 {
47  bool_t result = FALSE;
48  char **splitted;
49  char *current;
50  char *lname;
51  int i;
52 
53  if (!filter || strlen(filter) == 0) {
54  return ret_on_empty;
55  }
56 
57  splitted = g_strsplit(filter, ",", 0);
58  lname = g_ascii_strdown (name, -1);
59 
60  for (i = 0; ! result && (current = splitted[i]); i ++)
61  {
62  char * stripped = g_strstrip (g_ascii_strdown (current, -1));
63  result = result || strstr(lname, stripped);
64  g_free(stripped);
65  }
66 
67  g_free(lname);
68  g_strfreev(splitted);
69 
70  return result;
71 }
72 
73 /* Check wether it's an image we want */
74 static bool_t is_front_cover_image (const char * file)
75 {
76  char * include = get_string (NULL, "cover_name_include");
77  char * exclude = get_string (NULL, "cover_name_exclude");
78  bool_t accept = cover_name_filter (file, include, TRUE) &&
79  ! cover_name_filter (file, exclude, FALSE);
80  g_free (include);
81  g_free (exclude);
82  return accept;
83 }
84 
85 static bool_t
86 is_file_image(const char *imgfile, const char *file_name)
87 {
88  char *imgfile_ext, *file_name_ext;
89  size_t imgfile_len, file_name_len;
90 
91  imgfile_ext = strrchr(imgfile, '.');
92  if (!imgfile_ext) {
93  /* No file extension */
94  return FALSE;
95  }
96 
97  file_name_ext = strrchr(file_name, '.');
98  if (!file_name_ext) {
99  /* No file extension */
100  return FALSE;
101  }
102 
103  imgfile_len = (imgfile_ext - imgfile);
104  file_name_len = (file_name_ext - file_name);
105 
106  if (imgfile_len == file_name_len) {
107  return (g_ascii_strncasecmp(imgfile, file_name, imgfile_len) == 0);
108  } else {
109  return FALSE;
110  }
111 }
112 
113 static char * fileinfo_recursive_get_image (const char * path, const char *
114  file_name, int depth)
115 {
116  GDir *d;
117 
118  if (get_bool (NULL, "recurse_for_cover") && depth > get_int (NULL, "recurse_for_cover_depth"))
119  return NULL;
120 
121  d = g_dir_open(path, 0, NULL);
122 
123  if (d) {
124  const char *f;
125 
126  if (get_bool (NULL, "use_file_cover") && file_name)
127  {
128  /* Look for images matching file name */
129  while((f = g_dir_read_name(d))) {
130  char *newpath = g_strconcat(path, "/", f, NULL);
131 
132  if (!g_file_test(newpath, G_FILE_TEST_IS_DIR) &&
134  is_file_image(f, file_name)) {
135  g_dir_close(d);
136  return newpath;
137  }
138 
139  g_free(newpath);
140  }
141  g_dir_rewind(d);
142  }
143 
144  /* Search for files using filter */
145  while ((f = g_dir_read_name(d))) {
146  char *newpath = g_strconcat(path, "/", f, NULL);
147 
148  if (!g_file_test(newpath, G_FILE_TEST_IS_DIR) &&
151  g_dir_close(d);
152  return newpath;
153  }
154 
155  g_free(newpath);
156  }
157  g_dir_rewind(d);
158 
159  /* checks whether recursive or not. */
160  if (! get_bool (NULL, "recurse_for_cover"))
161  {
162  g_dir_close(d);
163  return NULL;
164  }
165 
166  /* Descend into directories recursively. */
167  while ((f = g_dir_read_name(d))) {
168  char *newpath = g_strconcat(path, "/", f, NULL);
169 
170  if(g_file_test(newpath, G_FILE_TEST_IS_DIR)) {
171  char *tmp = fileinfo_recursive_get_image(newpath,
172  NULL, depth + 1);
173  if(tmp) {
174  g_free(newpath);
175  g_dir_close(d);
176  return tmp;
177  }
178  }
179 
180  g_free(newpath);
181  }
182 
183  g_dir_close(d);
184  }
185 
186  return NULL;
187 }
188 
189 char * get_associated_image_file (const char * filename)
190 {
191  if (strncmp (filename, "file://", 7))
192  return NULL;
193 
194  char * unesc = uri_to_filename (filename);
195  if (! unesc)
196  return NULL;
197 
198  char * path = g_path_get_dirname (unesc);
199  char * base = g_path_get_basename (unesc);
200  char * image_unesc = fileinfo_recursive_get_image (path, base, 0);
201  char * image_file = image_unesc ? filename_to_uri (image_unesc) : NULL;
202 
203  g_free (unesc);
204  g_free (path);
205  g_free (base);
206  g_free (image_unesc);
207 
208  return image_file;
209 }
const char filename
Definition: misc-api.h:85
EXPORT char * uri_to_filename(const char *uri)
Definition: audstrings.c:172
char * get_string(const char *section, const char *name)
Definition: config.c:276
#define FALSE
Definition: core.h:37
Index Index bool_t
Definition: playlist-api.h:122
const char * name
Definition: plugin-init.c:38
static bool_t is_file_image(const char *imgfile, const char *file_name)
Definition: ui_albumart.c:86
static bool_t cover_name_filter(const char *name, const char *filter, const bool_t ret_on_empty)
Definition: ui_albumart.c:45
static bool_t has_front_cover_extension(const char *name)
Definition: ui_albumart.c:29
#define NULL
Definition: core.h:29
#define TRUE
Definition: core.h:39
bool_t get_bool(const char *section, const char *name)
Definition: config.c:300
static char * fileinfo_recursive_get_image(const char *path, const char *file_name, int depth)
Definition: ui_albumart.c:113
static bool_t is_front_cover_image(const char *file)
Definition: ui_albumart.c:74
int get_int(const char *section, const char *name)
Definition: config.c:316
EXPORT char * filename_to_uri(const char *name)
Definition: audstrings.c:143
char * get_associated_image_file(const char *filename)
Definition: ui_albumart.c:189