summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-11-11 12:29:37 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-11-11 12:29:37 +0000
commit9d4bed7ff06818b098926932db824a8d6532bfee (patch)
tree0a1cfa6a98a75a2badc1a8d2a2d7839454522beb /apps/recorder
parentf34720b163aff1d167ae031f23f3250356aa2c1b (diff)
downloadrockbox-9d4bed7ff06818b098926932db824a8d6532bfee.tar.gz
rockbox-9d4bed7ff06818b098926932db824a8d6532bfee.zip
Album art support. Based on FS#3045, but heavily modified to adapt to MoB and for cleanness.
The cover pictures are loaded from external bitmaps. JPEG and embedded art are not supported. The pictures will only be drawn on the main display. There is no resizing but it is possible to specify the WPS bitmap size in the bitmap names (e.g. cover.100x100.bmp). The bitmaps are stored in the main buffer and read directly from there. Currently, duplicate bitmaps will simply be present several times in the buffer, but this will be improved. To enable for a target, #define HAVE_ALBUMART in its config file. For more information, see the wiki page: http://www.rockbox.org/wiki/AlbumArt. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15572 a1c6a512-1295-4272-9138-f99709370657
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_ */