diff --git a/apps/buffering.c b/apps/buffering.c index b9f30fc6dfc..d1c2173f70c 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -867,7 +867,7 @@ static int load_image(int fd, const char *path, #ifdef HAVE_JPEG if (aa != NULL) { lseek(fd, aa->pos, SEEK_SET); - rc = clip_jpeg_fd(fd, aa->size, bmp, (int)max_size, format, NULL); + rc = clip_jpeg_fd(fd, aa->type & AA_TYPE_UNSYNC, aa->size, bmp, (int)max_size, format, NULL); } else if (strcmp(path + strlen(path) - 4, ".bmp")) rc = read_jpeg_fd(fd, bmp, (int)max_size, format, NULL); diff --git a/apps/playback.c b/apps/playback.c index 638bb31edb1..c1cecb63526 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -1793,7 +1793,8 @@ static int audio_load_albumart(struct track_info *infop, /* We can only decode jpeg for embedded AA */ if (global_settings.album_art != AA_OFF && hid < 0 && hid != ERR_BUFFER_FULL && - track_id3->has_embedded_albumart && track_id3->albumart.type == AA_TYPE_JPG) + track_id3->has_embedded_albumart && + (track_id3->albumart.type == AA_TYPE_JPG || track_id3->albumart.type == (AA_TYPE_JPG | AA_TYPE_UNSYNC))) { if (is_current_track) clear_last_folder_album_art(); diff --git a/apps/recorder/jpeg_load.c b/apps/recorder/jpeg_load.c index 154a57b98c9..2e1293607c7 100644 --- a/apps/recorder/jpeg_load.c +++ b/apps/recorder/jpeg_load.c @@ -28,7 +28,6 @@ ****************************************************************************/ #include "plugin.h" -#include "debug.h" #include "jpeg_load.h" /*#define JPEG_BS_DEBUG*/ //#define ROCKBOX_DEBUG_JPEG @@ -839,6 +838,7 @@ static const struct idct_entry idct_tbl[] = { #endif }; +int global_ff_found = -1; /* JPEG decoder implementation */ #ifdef JPEG_FROM_MEM @@ -872,11 +872,43 @@ INLINE void jpeg_putc(struct jpeg* p_jpeg) p_jpeg->data--; } #else + +static int unsynchronize(char* tag, int len, int *ff_found) +{ + int i; + unsigned char c; + unsigned char *rp, *wp; + + wp = rp = (unsigned char *)tag; + + rp = (unsigned char *)tag; + for(i = 0;i < len;i++) { + /* Read the next byte and write it back, but don't increment the + write pointer */ + c = *rp++; + *wp = c; + if(*ff_found) { + /* Increment the write pointer if it isn't an unsynch pattern */ + if(c != 0) + wp++; + *ff_found = false; + } else { + if(c == 0xff) + *ff_found = true; + wp++; + } + } + return (intptr_t)wp - (intptr_t)tag; +} + INLINE void fill_buf(struct jpeg* p_jpeg) { - p_jpeg->buf_left = read(p_jpeg->fd, p_jpeg->buf, - (p_jpeg->len >= JPEG_READ_BUF_SIZE)? - JPEG_READ_BUF_SIZE : p_jpeg->len); + int nread = read(p_jpeg->fd, p_jpeg->buf, + (p_jpeg->len >= JPEG_READ_BUF_SIZE)? + JPEG_READ_BUF_SIZE : p_jpeg->len); + p_jpeg->buf_left = global_ff_found < 0 + ? nread + : unsynchronize(p_jpeg->buf, nread, &global_ff_found); p_jpeg->buf_index = 0; if (p_jpeg->buf_left > 0) p_jpeg->len -= p_jpeg->buf_left; @@ -935,6 +967,7 @@ do {\ c; \ }) + /* Preprocess the JPEG JFIF file */ static int process_markers(struct jpeg* p_jpeg) { @@ -1958,7 +1991,7 @@ int clip_jpeg_file(const char* filename, return fd * 10 - 1; } lseek(fd, offset, SEEK_SET); - ret = clip_jpeg_fd(fd, jpeg_size, bm, maxsize, format, cformat); + ret = clip_jpeg_fd(fd, false, jpeg_size, bm, maxsize, format, cformat); close(fd); return ret; } @@ -2007,7 +2040,7 @@ int get_jpeg_dim_mem(unsigned char *data, unsigned long len, int decode_jpeg_mem(unsigned char *data, #else -int clip_jpeg_fd(int fd, +int clip_jpeg_fd(int fd, bool unsync, #endif unsigned long len, struct bitmap *bm, @@ -2023,6 +2056,7 @@ int clip_jpeg_fd(int fd, #ifdef JPEG_FROM_MEM struct jpeg *p_jpeg = &jpeg; #else + global_ff_found = unsync ? 0 : -1; struct jpeg *p_jpeg = (struct jpeg*)bm->data; int tmp_size = maxsize; ALIGN_BUFFER(p_jpeg, tmp_size, sizeof(long)); @@ -2225,7 +2259,7 @@ int read_jpeg_fd(int fd, int format, const struct custom_format *cformat) { - return clip_jpeg_fd(fd, 0, bm, maxsize, format, cformat); + return clip_jpeg_fd(fd, false, 0, bm, maxsize, format, cformat); } #endif diff --git a/apps/recorder/jpeg_load.h b/apps/recorder/jpeg_load.h index 129b0fbf19b..d6d0f376b66 100644 --- a/apps/recorder/jpeg_load.h +++ b/apps/recorder/jpeg_load.h @@ -67,11 +67,10 @@ int clip_jpeg_file(const char* filename, * read embedded jpeg files as above. Needs an open file descripter, and * assumes the caller has lseek()'d to the start of the jpeg blob **/ -int clip_jpeg_fd(int fd, +int clip_jpeg_fd(int fd, bool unsync, unsigned long jpeg_size, struct bitmap *bm, int maxsize, int format, const struct custom_format *cformat); - #endif /* _JPEG_JPEG_DECODER_H */ diff --git a/lib/rbcodec/metadata/id3tags.c b/lib/rbcodec/metadata/id3tags.c index 627ba22e041..58c4d4b6783 100644 --- a/lib/rbcodec/metadata/id3tags.c +++ b/lib/rbcodec/metadata/id3tags.c @@ -300,8 +300,7 @@ static int parsealbumart( struct mp3entry* entry, char* tag, int bufferpos ) return bufferpos; /* we currently don't support unsynchronizing albumart */ - if (entry->albumart.type == AA_TYPE_UNSYNC) - return bufferpos; + bool unsync = entry->albumart.type == AA_TYPE_UNSYNC; entry->albumart.type = AA_TYPE_UNKNOWN; @@ -353,6 +352,10 @@ static int parsealbumart( struct mp3entry* entry, char* tag, int bufferpos ) /* fixup offset&size for image data */ entry->albumart.pos += tag - start; entry->albumart.size -= tag - start; + if (unsync) + { + entry->albumart.type |= AA_TYPE_UNSYNC; + } /* check for malformed tag with no picture data */ entry->has_embedded_albumart = (entry->albumart.size != 0); } @@ -1107,17 +1110,14 @@ void setid3v2title(int fd, struct mp3entry *entry) #ifdef HAVE_ALBUMART /* albumart */ if ((!entry->has_embedded_albumart) && - ((tr->tag_length == 4 && !memcmp( header, "APIC", 4)) || - (tr->tag_length == 3 && !memcmp( header, "PIC" , 3)))) + ((tr->tag_length == 4 && !memcmp(header, "APIC", 4)) || + (tr->tag_length == 3 && !memcmp(header, "PIC", 3)))) { - if (unsynch || (global_unsynch && version <= ID3_VER_2_3)) - entry->albumart.type = AA_TYPE_UNSYNC; - else - { - entry->albumart.pos = lseek(fd, 0, SEEK_CUR) - framelen; - entry->albumart.size = totframelen; - entry->albumart.type = AA_TYPE_UNKNOWN; - } + entry->albumart.pos = lseek(fd, 0, SEEK_CUR) - framelen; + entry->albumart.size = totframelen; + entry->albumart.type = (unsynch || (global_unsynch && version <= ID3_VER_2_3)) + ? AA_TYPE_UNSYNC + : AA_TYPE_UNKNOWN; } #endif if( tr->ppFunc ) diff --git a/lib/rbcodec/metadata/metadata.h b/lib/rbcodec/metadata/metadata.h index 97fe8eade9f..3238530733a 100644 --- a/lib/rbcodec/metadata/metadata.h +++ b/lib/rbcodec/metadata/metadata.h @@ -199,11 +199,12 @@ enum { #ifdef HAVE_ALBUMART enum mp3_aa_type { - AA_TYPE_UNSYNC = -1, AA_TYPE_UNKNOWN, AA_TYPE_BMP, AA_TYPE_PNG, AA_TYPE_JPG, + + AA_TYPE_UNSYNC = 0x100, //it's a flag }; struct mp3_albumart {