Skip to content

Commit 07056dd

Browse files
opus: Try to decode invalid image tags manually. Closes: #1387
opus_picture_tag_parse() will return an error on picture metadata with non-zero width/height but 0 for depth. Unfortunately a lot of programs write such tags because they were generally accepted for Ogg container files containing Vorbis audio, and are strictly advisory (they don't affect image decoding). Other programs (e.g. VLC) seem to also decode Opus picture tags manually as well. Co-authored-by: Thomas Lange <[email protected]>
1 parent 3955410 commit 07056dd

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/opus/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
1010
LD = ${CXX}
1111

1212
CFLAGS += ${PLUGIN_CFLAGS}
13-
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${OPUS_CFLAGS} -I../..
14-
LIBS += ${OPUS_LIBS}
13+
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${OPUS_CFLAGS} ${GLIB_CFLAGS} -I../..
14+
LIBS += ${OPUS_LIBS} ${GLIB_LIBS}

src/opus/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ have_opus = opusfile_dep.found()
55
if have_opus
66
shared_module('opus',
77
'opus.cc',
8-
dependencies: [audacious_dep, opusfile_dep],
8+
dependencies: [audacious_dep, glib_dep, opusfile_dep],
99
name_prefix: '',
1010
include_directories: [src_inc],
1111
install: true,

src/opus/opus.cc

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
#include <cstdlib>
2121
#include <cstring>
2222

23+
#include <glib.h>
2324
#include <opus/opusfile.h>
2425

26+
#define AUD_GLIB_INTEGRATION
27+
#define WANT_AUD_BSWAP
2528
#define WANT_VFS_STDIO_COMPAT
2629
#include <libaudcore/audstrings.h>
2730
#include <libaudcore/i18n.h>
@@ -128,6 +131,35 @@ static void read_tags(const OpusTags * tags, Tuple & tuple)
128131
tuple.set_int(Tuple::Year, std::atoi(date));
129132
}
130133

134+
/*
135+
* Adopted from Ogg Vorbis decoder plugin
136+
* Used as less strict fallback if opusfile rejects an image tag
137+
*/
138+
static bool parse_vorbis_image(Index<char> & data, const char * image)
139+
{
140+
unsigned mime_length, desc_length, length;
141+
size_t data_length;
142+
143+
CharPtr img_data((char *)g_base64_decode(image, &data_length));
144+
if (!img_data || data_length < 8)
145+
return false;
146+
147+
mime_length = FROM_BE32(*(uint32_t *)(img_data + 4));
148+
if (data_length < 8 + mime_length + 4)
149+
return false;
150+
151+
desc_length = FROM_BE32(*(uint32_t *)(img_data + 8 + mime_length));
152+
if (data_length < 8 + mime_length + 4 + desc_length + 20)
153+
return false;
154+
155+
length = FROM_BE32(*(uint32_t *)(img_data + 8 + mime_length + 4 + desc_length + 16));
156+
if (data_length < 8 + mime_length + 4 + desc_length + 20 + length)
157+
return false;
158+
159+
data.insert(img_data + 8 + mime_length + 4 + desc_length + 20, 0, length);
160+
return true;
161+
}
162+
131163
static Index<char> read_image_from_tags(const OpusTags * tags,
132164
const char * filename)
133165
{
@@ -140,7 +172,8 @@ static Index<char> read_image_from_tags(const OpusTags * tags,
140172
OpusPictureTag picture_tag;
141173
if (opus_picture_tag_parse(&picture_tag, image) < 0)
142174
{
143-
AUDERR("Error parsing METADATA_BLOCK_PICTURE in %s.\n", filename);
175+
if (!parse_vorbis_image(data, image))
176+
AUDERR("Error parsing METADATA_BLOCK_PICTURE in %s.\n", filename);
144177
return data;
145178
}
146179

0 commit comments

Comments
 (0)