summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/albumart.c285
-rw-r--r--apps/recorder/albumart.h39
2 files changed, 324 insertions, 0 deletions
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c
new file mode 100644
index 0000000000..abae8c1afc
--- /dev/null
+++ b/apps/recorder/albumart.c
@@ -0,0 +1,285 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Nicolas Pennequin
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <string.h>
21#include "sprintf.h"
22#include "system.h"
23#include "albumart.h"
24#include "id3.h"
25#include "gwps.h"
26#include "buffering.h"
27#include "dircache.h"
28#include "debug.h"
29
30
31/* Strip filename from a full path
32 *
33 * buf - buffer to extract directory to.
34 * buf_size - size of buffer.
35 * fullpath - fullpath to extract from.
36 *
37 * Split the directory part of the given fullpath and store it in buf
38 * (including last '/').
39 * The function return parameter is a pointer to the filename
40 * inside the given fullpath.
41 */
42static char* strip_filename(char* buf, int buf_size, const char* fullpath)
43{
44 char* sep;
45 int len;
46
47 if (!buf || buf_size <= 0 || !fullpath)
48 return NULL;
49
50 /* if 'fullpath' is only a filename return immediately */
51 sep = strrchr(fullpath, '/');
52 if (sep == NULL)
53 {
54 buf[0] = 0;
55 return (char*)fullpath;
56 }
57
58 len = MIN(sep - fullpath + 1, buf_size - 1);
59 strncpy(buf, fullpath, len);
60 buf[len] = 0;
61 return (sep + 1);
62}
63
64/* Strip extension from a filename.
65 *
66 * buf - buffer to output the result to.
67 * buf_size - size of the output buffer buffer.
68 * file - filename to strip extension from.
69 *
70 * Return value is a pointer to buf, which contains the result.
71 */
72static char* strip_extension(char* buf, int buf_size, const char* file)
73{
74 char* sep;
75 int len;
76
77 if (!buf || buf_size <= 0 || !file)
78 return NULL;
79
80 buf[0] = 0;
81
82 sep = strrchr(file,'.');
83 if (sep == NULL)
84 return NULL;
85
86 len = MIN(sep - file, buf_size - 1);
87 strncpy(buf, file, len);
88 buf[len] = 0;
89 return buf;
90}
91
92/* Test file existence, using dircache of possible */
93static bool file_exists(const char *file)
94{
95 int fd;
96
97 if (!file || strlen(file) <= 0)
98 return false;
99
100#ifdef HAVE_DIRCACHE
101 if (dircache_is_enabled())
102 return (dircache_get_entry_ptr(file) != NULL);
103#endif
104
105 fd = open(file, O_RDONLY);
106 if (fd < 0)
107 return false;
108 close(fd);
109 return true;
110}
111
112/* Look for the first matching album art bitmap in the following list:
113 * ./<trackname><size>.bmp
114 * ./<albumname><size>.bmp
115 * ./cover<size>.bmp
116 * ../<albumname><size>.bmp
117 * ../cover<size>.bmp
118 * <size> is the value of the size_string parameter, <trackname> and
119 * <albumname> are read from the ID3 metadata.
120 * If a matching bitmap is found, its filename is stored in buf.
121 * Return value is true if a bitmap was found, false otherwise.
122 */
123static bool search_files(const struct mp3entry *id3, const char *size_string,
124 char *buf, int buflen)
125{
126 char path[MAX_PATH + 1];
127 char dir[MAX_PATH + 1];
128 bool found = false;
129 const char *trackname;
130
131 if (!id3 || !buf)
132 return false;
133
134 trackname = id3->path;
135 strip_filename(dir, sizeof(dir), trackname);
136
137 /* the first file we look for is one specific to the track playing */
138 strip_extension(path, sizeof(path) - strlen(size_string) - 4, trackname);
139 strcat(path, size_string);
140 strcat(path, ".bmp");
141 found = file_exists(path);
142 if (!found && id3->album && strlen(id3->album) > 0)
143 {
144 /* if it doesn't exist,
145 * we look for a file specific to the track's album name */
146 snprintf(path, sizeof(path) - 1,
147 "%s%s%s.bmp",
148 (strlen(dir) >= 1) ? dir : "",
149 id3->album, size_string);
150 path[sizeof(path) - 1] = 0;
151 found = file_exists(path);
152 }
153
154 if (!found)
155 {
156 /* if it still doesn't exist, we look for a generic file */
157 snprintf(path, sizeof(path)-1,
158 "%scover%s.bmp",
159 (strlen(dir) >= 1) ? dir : "", size_string);
160 path[sizeof(path)-1] = 0;
161 found = file_exists(path);
162 }
163
164 if (!found)
165 {
166 /* if it still doesn't exist,
167 * we continue to search in the parent directory */
168 char temp[MAX_PATH + 1];
169 strncpy(temp, dir, strlen(dir) - 1);
170 temp[strlen(dir) - 1] = 0;
171
172 strip_filename(dir, sizeof(dir), temp);
173 }
174
175 if (!found && id3->album && strlen(id3->album) > 0)
176 {
177 /* we look in the parent directory
178 * for a file specific to the track's album name */
179 snprintf(path, sizeof(path)-1,
180 "%s%s%s.bmp",
181 (strlen(dir) >= 1) ? dir : "",
182 id3->album, size_string);
183 found = file_exists(path);
184 }
185
186 if (!found)
187 {
188 /* if it still doesn't exist, we look in the parent directory
189 * for a generic file */
190 snprintf(path, sizeof(path)-1,
191 "%scover%s.bmp",
192 (strlen(dir) >= 1) ? dir : "", size_string);
193 path[sizeof(path)-1] = 0;
194 found = file_exists(path);
195 }
196
197 if (!found)
198 return false;
199
200 strncpy(buf, path, buflen);
201 DEBUGF("Album art found: %s\n", path);
202 return true;
203}
204
205/* Look for albumart bitmap in the same dir as the track and in its parent dir.
206 * Stores the found filename in the buf parameter.
207 * Returns true if a bitmap was found, false otherwise */
208bool find_albumart(const struct mp3entry *id3, char *buf, int buflen)
209{
210 if (!id3 || !buf)
211 return false;
212
213 char size_string[9];
214 struct wps_data *data = gui_wps[0].data;
215
216 if (!data)
217 return false;
218
219 DEBUGF("Looking for album art for %s\n", id3->path);
220
221 /* Write the size string, e.g. ".100x100". */
222 snprintf(size_string, sizeof(size_string), ".%dx%d",
223 data->albumart_max_width, data->albumart_max_height);
224
225 /* First we look for a bitmap of the right size */
226 if (search_files(id3, size_string, buf, buflen))
227 return true;
228
229 /* Then we look for generic bitmaps */
230 *size_string = 0;
231 return search_files(id3, size_string, buf, buflen);
232}
233
234/* Draw the album art bitmap from the given handle ID onto the given WPS. */
235void draw_album_art(struct gui_wps *gwps, int handle_id)
236{
237 if (!gwps || !gwps->data || !gwps->display || handle_id < 0)
238 return;
239
240 struct wps_data *data = gwps->data;
241
242#ifdef HAVE_REMOTE_LCD
243 /* No album art on RWPS */
244 if (data->remote_wps)
245 return;
246#endif
247
248 struct bitmap *bmp;
249 bufgetdata(handle_id, 0, (void *)&bmp);
250
251 short x = data->albumart_x;
252 short y = data->albumart_y;
253 short width = bmp->width;
254 short height = bmp->height;
255
256 if (data->albumart_max_width > 0)
257 {
258 /* Crop if the bitmap is too wide */
259 width = MIN(bmp->width, data->albumart_max_width);
260
261 /* Align */
262 if (data->albumart_xalign & WPS_ALBUMART_ALIGN_RIGHT)
263 x += data->albumart_max_width - width;
264 else if (data->albumart_xalign & WPS_ALBUMART_ALIGN_CENTER)
265 x += (data->albumart_max_width - width) / 2;
266 }
267
268 if (data->albumart_max_height > 0)
269 {
270 /* Crop if the bitmap is too high */
271 height = MIN(bmp->height, data->albumart_max_height);
272
273 /* Align */
274 if (data->albumart_yalign & WPS_ALBUMART_ALIGN_BOTTOM)
275 y += data->albumart_max_height - height;
276 else if (data->albumart_yalign & WPS_ALBUMART_ALIGN_CENTER)
277 y += (data->albumart_max_height - height) / 2;
278 }
279
280 /* Draw the bitmap */
281 gwps->display->set_drawmode(DRMODE_FG);
282 gwps->display->bitmap_part((fb_data*)bmp->data, 0, 0, bmp->width,
283 x, y, width, height);
284 gwps->display->set_drawmode(DRMODE_SOLID);
285}
diff --git a/apps/recorder/albumart.h b/apps/recorder/albumart.h
new file mode 100644
index 0000000000..21ae50edb9
--- /dev/null
+++ b/apps/recorder/albumart.h
@@ -0,0 +1,39 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Nicolas Pennequin
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _ALBUMART_H_
21#define _ALBUMART_H_
22
23#ifdef HAVE_ALBUMART
24
25#include <stdbool.h>
26#include "id3.h"
27#include "gwps.h"
28
29/* Look for albumart bitmap in the same dir as the track and in its parent dir.
30 * Stores the found filename in the buf parameter.
31 * Returns true if a bitmap was found, false otherwise */
32bool find_albumart(const struct mp3entry *id3, char *buf, int buflen);
33
34/* Draw the album art bitmap from the given handle ID onto the given WPS. */
35void draw_album_art(struct gui_wps *gwps, int handle_id);
36
37#endif /* HAVE_ALBUMART */
38
39#endif /* _ALBUMART_H_ */