mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
metadata: mp3: Support unsync embedded jpeg album art
Support parsing alubm art from id3 metadata with "unsynchronisation scheme": https://id3.org/id3v2.3.0#The_unsynchronisation_scheme Change-Id: I1e2ca4ae0aa967f7e80142a04c9a7d99e38e68b2
This commit is contained in:
parent
6649731563
commit
7f4a8891a6
7 changed files with 72 additions and 23 deletions
|
@ -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->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);
|
||||
|
|
|
@ -1922,7 +1922,7 @@ 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_CLEAR_FLAGS_MASK) == AA_TYPE_JPG)
|
||||
{
|
||||
if (is_current_track)
|
||||
clear_last_folder_album_art();
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "embedded_metadata.h"
|
||||
#include "plugin.h"
|
||||
#include "debug.h"
|
||||
#include "jpeg_load.h"
|
||||
|
@ -79,6 +79,9 @@ struct jpeg
|
|||
int fd;
|
||||
int buf_left;
|
||||
int buf_index;
|
||||
|
||||
int (*read_buf)(struct jpeg* p_jpeg, size_t count);
|
||||
void* custom_param;
|
||||
#endif
|
||||
unsigned long len;
|
||||
unsigned long int bitbuf;
|
||||
|
@ -872,11 +875,21 @@ INLINE void jpeg_putc(struct jpeg* p_jpeg)
|
|||
p_jpeg->data--;
|
||||
}
|
||||
#else
|
||||
|
||||
static int read_buf(struct jpeg* p_jpeg, size_t count)
|
||||
{
|
||||
return read(p_jpeg->fd, p_jpeg->buf, count);
|
||||
}
|
||||
|
||||
static int read_buf_id3_unsync(struct jpeg* p_jpeg, size_t count)
|
||||
{
|
||||
count = read(p_jpeg->fd, p_jpeg->buf, count);
|
||||
return id3_unsynchronize(p_jpeg->buf, count, (bool*) &p_jpeg->custom_param);
|
||||
}
|
||||
|
||||
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);
|
||||
p_jpeg->buf_left = p_jpeg->read_buf(p_jpeg, MIN(JPEG_READ_BUF_SIZE, p_jpeg->len));
|
||||
p_jpeg->buf_index = 0;
|
||||
if (p_jpeg->buf_left > 0)
|
||||
p_jpeg->len -= p_jpeg->buf_left;
|
||||
|
@ -1958,7 +1971,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, 0, jpeg_size, bm, maxsize, format, cformat);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2007,7 +2020,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, int flags,
|
||||
#endif
|
||||
unsigned long len,
|
||||
struct bitmap *bm,
|
||||
|
@ -2038,6 +2051,14 @@ int clip_jpeg_fd(int fd,
|
|||
p_jpeg->fd = fd;
|
||||
if (p_jpeg->len == 0)
|
||||
p_jpeg->len = filesize(p_jpeg->fd);
|
||||
|
||||
p_jpeg->read_buf = read_buf;
|
||||
|
||||
if (flags & AA_FLAG_ID3_UNSYNC)
|
||||
{
|
||||
p_jpeg->read_buf = read_buf_id3_unsync;
|
||||
p_jpeg->custom_param = false;
|
||||
}
|
||||
#endif
|
||||
status = process_markers(p_jpeg);
|
||||
#ifndef JPEG_FROM_MEM
|
||||
|
@ -2225,7 +2246,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, 0, 0, bm, maxsize, format, cformat);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ 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, int flags,
|
||||
unsigned long jpeg_size,
|
||||
struct bitmap *bm,
|
||||
int maxsize,
|
||||
|
|
23
lib/rbcodec/metadata/embedded_metadata.h
Normal file
23
lib/rbcodec/metadata/embedded_metadata.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2024 Roman Artiukhin
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdbool.h>
|
||||
|
||||
int id3_unsynchronize(char* tag, int len, bool *ff_found);
|
|
@ -45,6 +45,7 @@
|
|||
#include "mp3data.h"
|
||||
#include "metadata_common.h"
|
||||
#include "metadata_parsers.h"
|
||||
#include "embedded_metadata.h"
|
||||
#include "misc.h"
|
||||
|
||||
static unsigned long unsync(unsigned long b0,
|
||||
|
@ -161,7 +162,8 @@ struct tag_resolver {
|
|||
|
||||
static bool global_ff_found;
|
||||
|
||||
static int unsynchronize(char* tag, int len, bool *ff_found)
|
||||
#define unsynchronize id3_unsynchronize
|
||||
int id3_unsynchronize(char* tag, int len, bool *ff_found)
|
||||
{
|
||||
int i;
|
||||
unsigned char c;
|
||||
|
@ -299,9 +301,7 @@ static int parsealbumart( struct mp3entry* entry, char* tag, int bufferpos )
|
|||
if(entry->has_embedded_albumart)
|
||||
return bufferpos;
|
||||
|
||||
/* we currently don't support unsynchronizing albumart */
|
||||
if (entry->albumart.type == AA_TYPE_UNSYNC)
|
||||
return bufferpos;
|
||||
bool unsync = entry->albumart.type == AA_FLAG_ID3_UNSYNC;
|
||||
|
||||
entry->albumart.type = AA_TYPE_UNKNOWN;
|
||||
|
||||
|
@ -353,6 +353,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_FLAG_ID3_UNSYNC;
|
||||
}
|
||||
/* check for malformed tag with no picture data */
|
||||
entry->has_embedded_albumart = (entry->albumart.size != 0);
|
||||
}
|
||||
|
@ -1141,15 +1145,12 @@ retry_with_limit:
|
|||
if ((!entry->has_embedded_albumart) &&
|
||||
((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.type = (unsynch || (global_unsynch && version <= ID3_VER_2_3))
|
||||
? AA_FLAG_ID3_UNSYNC
|
||||
: AA_TYPE_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
if( tr->ppFunc )
|
||||
|
|
|
@ -196,13 +196,17 @@ enum {
|
|||
ID3_VER_2_4
|
||||
};
|
||||
|
||||
#define AA_FLAGS_SHIFT 4
|
||||
#define AA_CLEAR_FLAGS_MASK ~(-1 << AA_FLAGS_SHIFT)
|
||||
|
||||
#ifdef HAVE_ALBUMART
|
||||
enum mp3_aa_type {
|
||||
AA_TYPE_UNSYNC = -1,
|
||||
AA_TYPE_UNKNOWN,
|
||||
AA_TYPE_BMP,
|
||||
AA_TYPE_PNG,
|
||||
AA_TYPE_JPG,
|
||||
|
||||
AA_FLAG_ID3_UNSYNC = 1 << (AA_FLAGS_SHIFT + 0),
|
||||
};
|
||||
|
||||
struct mp3_albumart {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue