rendered paste bodyIndex: apps/gui/gwps-common.c===================================================================--- apps/gui/gwps-common.c (révision 15556)+++ apps/gui/gwps-common.c (copie de travail)@@ -48,6 +48,7 @@ /* Image stuff */ #include "bmp.h" #include "atoi.h"+#include "albumart.h" #endif #include "dsp.h" #include "action.h"@@ -929,6 +930,19 @@ case WPS_TOKEN_METADATA_COMMENT: return id3->comment; +#ifdef HAVE_LCD_BITMAP+ case WPS_TOKEN_ALBUMART_DISPLAY:+ draw_album_art(gwps, audio_current_aa_hid());+ return NULL;++ case WPS_TOKEN_ALBUMART_FOUND:+ if (audio_current_aa_hid() >= 0) {+ snprintf(buf, buf_size, "C");+ return buf;+ }+ return NULL;+#endif+ case WPS_TOKEN_FILE_BITRATE: if(id3->bitrate) snprintf(buf, buf_size, "%d", id3->bitrate);Index: apps/gui/albumart.c===================================================================--- apps/gui/albumart.c (révision 0)+++ apps/gui/albumart.c (révision 0)@@ -0,0 +1,228 @@+/***************************************************************************+ * __________ __ ___.+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \+ * \/ \/ \/ \/ \/+ * $Id$+ *+ * Copyright (C) 2007 Nicolas Pennequin+ *+ * All files in this archive are subject to the GNU General Public License.+ * See the file COPYING in the source tree root for full license agreement.+ *+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY+ * KIND, either express or implied.+ *+ ****************************************************************************/++#include <string.h>+#include "sprintf.h"+#include "system.h"+#include "albumart.h"+#include "id3.h"+#include "gwps.h"+#include "buffering.h"+#include "dircache.h"+#include "debug.h"+++/* Strip filename from a full path+ *+ * buf - buffer to extract directory to.+ * buf_size - size of buffer.+ * fullpath - fullpath to extract from.+ *+ * Split the directory part of the given fullpath and store it in buf+ * (including last '/').+ * The function return parameter is a pointer to the filename+ * inside the given fullpath.+ */+static char* strip_filename(char* buf, int buf_size, const char* fullpath)+{+ char* sep;+ int len;++ if (!buf || buf_size <= 0 || !fullpath)+ return NULL;++ /* if 'fullpath' is only a filename return immediately */+ sep = strrchr(fullpath, '/');+ if (sep == NULL)+ {+ buf[0] = 0;+ return (char*)fullpath;+ }++ len = MIN(sep - fullpath + 1, buf_size - 1);+ strncpy(buf, fullpath, len);+ buf[len] = 0;+ return (sep + 1);+}++static char* strip_extension(char* buf, int buf_size, const char* file)+{+ char* sep;+ int len;++ if (!buf || buf_size <= 0 || !file)+ return NULL;++ buf[0] = 0;++ sep = strrchr(file,'.');+ if (sep == NULL)+ return NULL;++ len = MIN(sep - file, buf_size - 1);+ strncpy(buf, file, len);+ buf[len] = 0;+ return buf;+}++static bool file_exists(const char *file)+{+ int fd;++ if (!file || strlen(file) <= 0)+ return false;++#ifdef HAVE_DIRCACHE+ if (dircache_is_enabled())+ return (dircache_get_entry_ptr(file) != NULL);+#endif++ fd = open(file, O_RDONLY);+ if (fd < 0)+ return false;+ close(fd);+ return true;+}++/* Look for albumart bitmap in the same dir as the track and in its parent dir;+ * stores the found filename in the track->albumart_path.+ * Returns true if a bitmap was found, false otherwise */+bool find_albumart(const struct mp3entry *id3, char *buf, int buflen)+{+ char path[MAX_PATH + 1];+ char dir[MAX_PATH + 1];+ bool found = false;+ const char *trackname;++ if (!id3 || !buf)+ return false;++ trackname = id3->path;+ strip_filename(dir, sizeof(dir), trackname);++ DEBUGF("Looking for album art for %s\n", trackname);++ /* the first file we look for is one specific to the track playing */+ strip_extension(path, sizeof(path) - 4, trackname);+ strcat(path, ".bmp");+ found = file_exists(path);+ if (!found && id3->album && strlen(id3->album) > 0)+ { /* if it doesn't exist,+ * we look for a file specific to the track's album name */+ snprintf(path, sizeof(path) - 1,+ "%s%s.bmp",+ (strlen(dir) >= 1) ? dir : "",+ id3->album);+ path[sizeof(path) - 1] = 0;+ found = file_exists(path);+ }++ if (!found)+ {+ /* if it still doesn't exist, we look for a generic file */+ snprintf(path, sizeof(path)-1,+ "%scover.bmp",+ (strlen(dir) >= 1) ? dir : "");+ path[sizeof(path)-1] = 0;+ found = file_exists(path);+ }++ if (!found)+ {+ /* if it still doesn't exist,+ * we continue to search in the parent directory */+ char temp[MAX_PATH + 1];+ strncpy(temp, dir, strlen(dir) - 1);+ temp[strlen(dir) - 1] = 0;++ strip_filename(dir, sizeof(dir), temp);+ }++ if (!found && id3->album && strlen(id3->album) > 0)+ {+ /* we look in the parent directory+ ** for a file specific to the track's album name */+ snprintf(path, sizeof(path)-1,+ "%s%s.bmp",+ (strlen(dir) >= 1) ? dir : "",+ id3->album);+ found = file_exists(path);+ }++ if (!found)+ {+ /* if it still doesn't exist, we look in the parent directory+ * for a generic file */+ snprintf(path, sizeof(path)-1,+ "%scover.bmp",+ (strlen(dir) >= 1) ? dir : "");+ path[sizeof(path)-1] = 0;+ found = file_exists(path);+ }++ if (!found)+ return false;++ strncpy(buf, path, buflen);+ DEBUGF("Album art found for %s : %s\n", trackname, path);+ return true;+}++void draw_album_art(struct gui_wps *gwps, int handle_id)+{+ if(!gwps || !gwps->data || !gwps->display || handle_id < 0)+ return;++ struct wps_data *data = gwps->data;+ /* if(data->wps_uses_albumart == WPS_ALBUMART_NONE)+ return; */++ struct bitmap *bmp;+ bufgetdata(handle_id, 0, (void *)&bmp);++ short x = data->albumart_x;+ short y = data->albumart_y;+ short width = bmp->width;+ short height = bmp->height;++ if(data->albumart_max_width > 0)+ {+ width = MIN(bmp->width, data->albumart_max_width);++ if (data->albumart_xalign & WPS_ALBUMART_ALIGN_RIGHT)+ x += data->albumart_max_width - width;+ else if (data->albumart_xalign & WPS_ALBUMART_ALIGN_CENTER)+ x += (data->albumart_max_width - width)/2;+ }++ if(data->albumart_max_height > 0)+ {+ height = MIN(bmp->height, data->albumart_max_height);++ if (data->albumart_yalign & WPS_ALBUMART_ALIGN_BOTTOM)+ y += data->albumart_max_height - height;+ else if (data->albumart_yalign & WPS_ALBUMART_ALIGN_CENTER)+ y += (data->albumart_max_height - height)/2;+ }++ gwps->display->set_drawmode(DRMODE_FG);+ gwps->display->bitmap_part((fb_data*)bmp->data, 0, 0, bmp->width,+ x, y, width, height);+ gwps->display->set_drawmode(DRMODE_SOLID);+}Index: apps/gui/albumart.h===================================================================--- apps/gui/albumart.h (révision 0)+++ apps/gui/albumart.h (révision 0)@@ -0,0 +1,35 @@+/***************************************************************************+ * __________ __ ___.+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \+ * \/ \/ \/ \/ \/+ * $Id$+ *+ * Copyright (C) 2007 Nicolas Pennequin+ *+ * All files in this archive are subject to the GNU General Public License.+ * See the file COPYING in the source tree root for full license agreement.+ *+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY+ * KIND, either express or implied.+ *+ ****************************************************************************/++#ifndef _ALBUMART_H_+#define _ALBUMART_H_++#ifdef HAVE_LCD_BITMAP++#include <stdbool.h>+#include "id3.h"+#include "gwps.h"+++bool find_albumart(const struct mp3entry *id3, char *buf, int buflen);+void draw_album_art(struct gui_wps *gwps, int handle_id);++#endif /* HAVE_LCD_BITMAP */++#endif /* _ALBUMART_H_ */Index: apps/gui/gwps.c===================================================================--- apps/gui/gwps.c (révision 15556)+++ apps/gui/gwps.c (copie de travail)@@ -796,3 +796,18 @@ unload_remote_wps_backdrop(); #endif }++/*+ * returns true if at least one of the gui_wps screens+ * has an albumart tag in its wps structure+ */+bool gui_sync_wps_uses_albumart(void)+{+ int i;+ FOR_NB_SCREENS(i) {+ struct gui_wps *gwps = &gui_wps[i];+ if (gwps->data && (gwps->data->wps_uses_albumart != WPS_ALBUMART_NONE))+ return true;+ }+ return false;+}Index: apps/gui/wps_parser.c===================================================================--- apps/gui/wps_parser.c (révision 15556)+++ apps/gui/wps_parser.c (copie de travail)@@ -124,6 +124,10 @@ struct wps_token *token, struct wps_data *wps_data); static int parse_image_load(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data);+static int parse_albumart_load(const char *wps_bufptr,+ struct wps_token *token, struct wps_data *wps_data);+static int parse_albumart_conditional(const char *wps_bufptr,+ struct wps_token *token, struct wps_data *wps_data); #endif /*HAVE_LCD_BITMAP */ #ifdef CONFIG_RTC@@ -283,6 +287,8 @@ { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special },+ { WPS_NO_TOKEN, "Cl", 0, parse_albumart_load },+ { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_DYNAMIC, parse_albumart_conditional }, #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, #endif@@ -606,6 +612,217 @@ #endif } +#ifdef HAVE_LCD_BITMAP+static int parse_albumart_load(const char *wps_bufptr,+ struct wps_token *token,+ struct wps_data *wps_data)+{+ const char* _pos;+ bool parsing;+ const short xalign_mask = WPS_ALBUMART_ALIGN_LEFT |+ WPS_ALBUMART_ALIGN_CENTER |+ WPS_ALBUMART_ALIGN_RIGHT;+ const short yalign_mask = WPS_ALBUMART_ALIGN_TOP |+ WPS_ALBUMART_ALIGN_CENTER |+ WPS_ALBUMART_ALIGN_BOTTOM;++ (void)(token); /* silence warning */++ /* reset albumart info in wps */+ wps_data->wps_uses_albumart = WPS_ALBUMART_NONE;+ wps_data->albumart_max_width = -1;+ wps_data->albumart_max_height = -1;+ wps_data->albumart_xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */+ wps_data->albumart_yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */++ /* format: %Cl|x|y|[[l|c|r][d|i|s]mwidth]|[[t|c|b][d|i|s]mheight]| */+ /* initial validation and parsing of x and y components */+ if (*wps_bufptr != '|')+ return 0; /* malformed token: e.g. %Cl7 */++ _pos = wps_bufptr+1;+ if (!isdigit(*_pos))+ return 0; /* malformed token: e.g. %Cl|@ */+ wps_data->albumart_x = atoi(_pos);++ _pos = strchr(_pos, '|');+ if (!_pos || !isdigit(*(++_pos)))+ return 0; /* malformed token: e.g. %Cl|7\n or %Cl|7|@ */++ wps_data->albumart_y = atoi(_pos);++ _pos = strchr(_pos, '|');+ if (!_pos)+ return 0; /* malformed token: no | after y coordinate+ e.g. %Cl|7|59\n */++ /* parsing width field */+ parsing = true;+ while (parsing)+ {+ /* apply each modifier in turn */+ ++_pos;+ switch (*_pos)+ {+ case 'l':+ case 'L':+ case '+':+ wps_data->albumart_xalign =+ (wps_data->albumart_xalign & xalign_mask) |+ WPS_ALBUMART_ALIGN_LEFT;+ break;+ case 'c':+ case 'C':+ wps_data->albumart_xalign =+ (wps_data->albumart_xalign & xalign_mask) |+ WPS_ALBUMART_ALIGN_CENTER;+ break;+ case 'r':+ case 'R':+ case '-':+ wps_data->albumart_xalign =+ (wps_data->albumart_xalign & xalign_mask) |+ WPS_ALBUMART_ALIGN_RIGHT;+ break;+ case 'd':+ case 'D':+ wps_data->albumart_xalign |= WPS_ALBUMART_DECREASE;+ break;+ case 'i':+ case 'I':+ wps_data->albumart_xalign |= WPS_ALBUMART_INCREASE;+ break;+ case 's':+ case 'S':+ wps_data->albumart_xalign |=+ (WPS_ALBUMART_DECREASE | WPS_ALBUMART_INCREASE);+ break;+ default:+ parsing = false;+ break;+ }+ }+ /* extract max width data */+ if (*_pos != '|')+ {+ if (!isdigit(*_pos))+ return 0; /* malformed token: e.g. %Cl|7|59|# */+ wps_data->albumart_max_width = atoi(_pos);+ _pos = strchr(_pos, '|');+ if (!_pos)+ return 0; /* malformed token: no | after width field+ e.g. %Cl|7|59|200\n */+ }++ /* parsing height field */+ parsing = true;+ while (parsing)+ {+ /* apply each modifier in turn */+ ++_pos;+ switch (*_pos)+ {+ case 't':+ case 'T':+ case 'r': /* yuck */+ case 'R':+ case '-':+ wps_data->albumart_yalign =+ (wps_data->albumart_yalign & yalign_mask) |+ WPS_ALBUMART_ALIGN_TOP;+ break;+ case 'c':+ case 'C':+ wps_data->albumart_yalign =+ (wps_data->albumart_yalign & yalign_mask) |+ WPS_ALBUMART_ALIGN_CENTER;+ break;+ case 'b':+ case 'B':+ case 'l': /* yuck */+ case 'L':+ case '+':+ wps_data->albumart_yalign =+ (wps_data->albumart_yalign & yalign_mask) |+ WPS_ALBUMART_ALIGN_BOTTOM;+ break;+ case 'd':+ case 'D':+ wps_data->albumart_yalign |= WPS_ALBUMART_DECREASE;+ break;+ case 'i':+ case 'I':+ wps_data->albumart_yalign |= WPS_ALBUMART_INCREASE;+ break;+ case 's':+ case 'S':+ wps_data->albumart_yalign |=+ (WPS_ALBUMART_DECREASE | WPS_ALBUMART_INCREASE);+ break;+ default:+ parsing = false;+ break;+ }+ }+ /* extract max height data */+ if (*_pos != '|')+ {+ if (!isdigit(*_pos))+ return 0; /* malformed token e.g. %Cl|7|59|200|@ */+ wps_data->albumart_max_height = atoi(_pos);+ _pos = strchr(_pos, '|');+ if (!_pos)+ return 0; /* malformed token: no closing |+ e.g. %Cl|7|59|200|200\n */+ }++ /* if we got here, we parsed everything ok .. ! */+ if (wps_data->albumart_max_width < 0)+ wps_data->albumart_max_width = 0;+ else if (wps_data->albumart_max_width > LCD_WIDTH)+ wps_data->albumart_max_width = LCD_WIDTH;++ if (wps_data->albumart_max_height < 0)+ wps_data->albumart_max_height = 0;+ else if (wps_data->albumart_max_height > LCD_HEIGHT)+ wps_data->albumart_max_height = LCD_HEIGHT;++ wps_data->wps_uses_albumart = WPS_ALBUMART_LOAD;++ /* Skip the rest of the line */+ return skip_end_of_line(wps_bufptr);+}++static int parse_albumart_conditional(const char *wps_bufptr,+ struct wps_token *token,+ struct wps_data *wps_data)+{+ struct wps_token *prevtoken = token;+ --prevtoken;+ if (wps_data->num_tokens >= 1 && prevtoken->type == WPS_TOKEN_CONDITIONAL)+ {+ /* This %C is part of a %?C construct.+ It's either %?C<blah> or %?Cn<blah> */+ token->type = WPS_TOKEN_ALBUMART_FOUND;+ if (*wps_bufptr == 'n' && *(wps_bufptr+1) == '<')+ {+ token->next = true;+ return 1;+ }+ else if (*wps_bufptr == '<')+ {+ return 0;+ }+ else+ {+ token->type = WPS_NO_TOKEN;+ return 0;+ }+ }+ else return 0;+};+#endif /* HAVE_LCD_BITMAP */+ /* Parse a generic token from the given string. Return the length read */ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) {@@ -915,6 +1132,9 @@ bool rwps = data->remote_wps; /* remember whether the data is for a RWPS */ #endif memset(data, 0, sizeof(*data));+#ifdef HAVE_LCD_BITMAP+ data->wps_uses_albumart = WPS_ALBUMART_NONE;+#endif wps_data_init(data); #ifdef HAVE_REMOTE_LCD data->remote_wps = rwps;Index: apps/gui/gwps.h===================================================================--- apps/gui/gwps.h (révision 15556)+++ apps/gui/gwps.h (copie de travail)@@ -39,6 +39,19 @@ #define WPS_ALIGN_CENTER 64 #define WPS_ALIGN_LEFT 128 +/* albumart definitions */+#define WPS_ALBUMART_NONE 0 /* WPS does not contain AA tag */+#define WPS_ALBUMART_CHECK 1 /* WPS contains AA conditional tag */+#define WPS_ALBUMART_LOAD 2 /* WPS contains AA tag */++#define WPS_ALBUMART_ALIGN_RIGHT WPS_ALIGN_RIGHT /* x align: right */+#define WPS_ALBUMART_ALIGN_CENTER WPS_ALIGN_CENTER /* x/y align: center */+#define WPS_ALBUMART_ALIGN_LEFT WPS_ALIGN_LEFT /* x align: left */+#define WPS_ALBUMART_ALIGN_TOP WPS_ALIGN_RIGHT /* y align: top */+#define WPS_ALBUMART_ALIGN_BOTTOM WPS_ALIGN_LEFT /* y align: bottom */+#define WPS_ALBUMART_INCREASE 8 /* increase if smaller */+#define WPS_ALBUMART_DECREASE 16 /* decrease if larger */+ /* wps_data*/ #ifdef HAVE_LCD_BITMAP@@ -185,6 +198,10 @@ WPS_TOKEN_IMAGE_PRELOAD, WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, WPS_TOKEN_IMAGE_DISPLAY,++ /* Albumart */+ WPS_TOKEN_ALBUMART_DISPLAY,+ WPS_TOKEN_ALBUMART_FOUND, #endif /* Metadata */@@ -309,6 +326,18 @@ short progress_start; short progress_end; bool peak_meter_enabled;++ /* Album art additions */+ unsigned char wps_uses_albumart; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */+ short albumart_x;+ short albumart_y;+ unsigned short albumart_xalign; /* WPS_ALBUMART_ALIGN_LEFT, _CENTER, _RIGHT,+ + .._INCREASE, + .._DECREASE */+ unsigned short albumart_yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM,+ + .._INCREASE, + .._DECREASE */+ short albumart_max_width;+ short albumart_max_height;+ #else /*HAVE_LCD_CHARCELLS */ unsigned short wps_progress_pat[8]; bool full_line_progressbar;@@ -417,4 +446,7 @@ void gui_sync_wps_init(void); void gui_sync_wps_screen_init(void); +/* gives back if WPS contains an albumart tag */+bool gui_sync_wps_uses_albumart(void);+ #endifIndex: apps/playback.c===================================================================--- apps/playback.c (révision 15556)+++ apps/playback.c (copie de travail)@@ -66,6 +66,7 @@ #include "icons.h" #include "peakmeter.h" #include "action.h"+#include "albumart.h" #endif #include "lang.h" #include "bookmark.h"@@ -217,6 +218,9 @@ int audio_hid; /* The ID for the track's buffer handle */ int id3_hid; /* The ID for the track's metadata handle */ int codec_hid; /* The ID for the track's codec handle */+#ifdef HAVE_LCD_BITMAP+ int aa_hid; /* The ID for the track's album art handle */+#endif size_t filesize; /* File total length */ @@ -391,6 +395,15 @@ return false; } +#ifdef HAVE_LCD_BITMAP+ if (track->aa_hid >= 0) {+ if (bufclose(track->aa_hid))+ track->aa_hid = -1;+ else+ return false;+#endif+ }+ track->filesize = 0; track->taginfo_ready = false; track->event_sent = false;@@ -635,6 +648,13 @@ #endif /* HAVE_RECORDING */ +#ifdef HAVE_LCD_BITMAP+int audio_current_aa_hid(void)+{+ return CUR_TI->aa_hid;+}+#endif+ struct mp3entry* audio_current_track(void) { const char *filename;@@ -2381,6 +2401,16 @@ else track_id3 = bufgetid3(tracks[track_widx].id3_hid); ++#ifdef HAVE_LCD_BITMAP+ if (gui_sync_wps_uses_albumart())+ {+ char aa_path[MAX_PATH];+ if (find_albumart(track_id3, aa_path, sizeof(aa_path)))+ tracks[track_widx].aa_hid = bufopen(aa_path, 0, TYPE_BITMAP);+ }+#endif+ track_id3->elapsed = 0; enum data_type type = TYPE_PACKET_AUDIO;@@ -3285,6 +3315,9 @@ tracks[i].audio_hid = -1; tracks[i].id3_hid = -1; tracks[i].codec_hid = -1;+#ifdef HAVE_LCD_BITMAP+ tracks[i].aa_hid = -1;+#endif } /* Probably safe to say */Index: apps/SOURCES===================================================================--- apps/SOURCES (révision 15556)+++ apps/SOURCES (copie de travail)@@ -50,6 +50,7 @@ gui/gwps-common.c #ifdef HAVE_LCD_BITMAP gui/icon.c+gui/albumart.c #endif gui/list.c gui/option_select.cIndex: apps/buffering.c===================================================================--- apps/buffering.c (révision 15556)+++ apps/buffering.c (copie de travail)@@ -48,6 +48,7 @@ #include "playback.h" #include "pcmbuf.h" #include "buffer.h"+#include "bmp.h" #ifdef SIMULATOR #define ata_disk_is_active() 1@@ -745,7 +746,7 @@ if (h->next && h->filerem == 0 && (h->type == TYPE_ID3 || h->type == TYPE_CUESHEET ||- h->type == TYPE_IMAGE || h->type == TYPE_CODEC ||+ h->type == TYPE_BITMAP || h->type == TYPE_CODEC || h->type == TYPE_ATOMIC_AUDIO)) { /* metadata handle: we can move all of it */@@ -814,7 +815,19 @@ } } +#ifdef HAVE_LCD_BITMAP+static int load_bitmap(const int fd)+{+ int rc;+ struct bitmap *bmp = (struct bitmap *)&buffer[buf_widx];+ bmp->data = &buffer[buf_widx + sizeof(struct bitmap)];+ int free = (int)MIN(buffer_len - BUF_USED, buffer_len - buf_widx);+ rc = read_bmp_fd(fd, bmp, free, FORMAT_ANY|FORMAT_TRANSPARENT);+ return rc + (rc > 0 ? sizeof(struct bitmap) : 0);+}+#endif + /* MAIN BUFFERING API CALLS ========================@@ -858,7 +871,6 @@ } strncpy(h->path, file, MAX_PATH);- h->filesize = size; h->filerem = size - offset; h->offset = offset; h->ridx = buf_widx;@@ -867,7 +879,23 @@ h->available = 0; h->type = type; - if (type == TYPE_CUESHEET || type == TYPE_IMAGE) {+#ifdef HAVE_LCD_BITMAP+ if (type == TYPE_BITMAP) {+ mutex_lock(&llist_mutex);+ size = load_bitmap(fd);+ if (size <= 0)+ return ERR_FILE_ERROR;+ h->filerem = 0;+ h->available = size;+ h->widx = buf_widx + size; /* safe because the data doesn't wrap */+ buf_widx += size; /* safe too */+ mutex_unlock(&llist_mutex);+ }+#endif++ h->filesize = size;++ if (type == TYPE_CUESHEET) { h->fd = fd; /* Immediately start buffering those */ LOGFQUEUE("buffering >| Q_BUFFER_HANDLE");Index: apps/buffering.h===================================================================--- apps/buffering.h (révision 15556)+++ apps/buffering.h (copie de travail)@@ -30,7 +30,7 @@ TYPE_ATOMIC_AUDIO, TYPE_ID3, TYPE_CUESHEET,- TYPE_IMAGE,+ TYPE_BITMAP, TYPE_BUFFER, TYPE_UNKNOWN, };Index: firmware/export/audio.h===================================================================--- firmware/export/audio.h (révision 15556)+++ firmware/export/audio.h (copie de travail)@@ -91,6 +91,9 @@ #endif /* CONFIG_CODEC == SWCODEC */ void audio_ff_rewind(long newtime); void audio_flush_and_reload_tracks(void);+#ifdef HAVE_LCD_BITMAP+int audio_current_aa_hid(void);+#endif struct mp3entry* audio_current_track(void); struct mp3entry* audio_next_track(void); bool audio_has_changed_track(void);