[multimedia/kwave/5-codec_mp3-broken-id3-tags-due-to-id3lib-bad-handling-of-utf-16] plugins/codec_mp3: codec_mp3: workaround for broken MBS conversion in ID3LIB
Thomas Eschenbacher <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit a98c47b39a936e844fa250673c7a871b8dfe9207 by Thomas Eschenbacher.
Committed on 15/08/2026 at 08:41.
Pushed by eschenbacher into branch '5-codec_mp3-broken-id3-tags-due-to-id3lib-bad-handling-of-utf-16'.
codec_mp3: workaround for broken MBS conversion in ID3LIB
M +57 -6 plugins/codec_mp3/MP3Decoder.cpp
M +6 -5 plugins/codec_mp3/MP3Encoder.cpp
https://invent.kde.org/multimedia/kwave/-/commit/a98c47b39a936e844fa250673c7a871b8dfe9207
diff --git a/plugins/codec_mp3/MP3Decoder.cpp b/plugins/codec_mp3/MP3Decoder.cpp
index ea56a1b4..74568685 100644
--- a/plugins/codec_mp3/MP3Decoder.cpp
+++ b/plugins/codec_mp3/MP3Decoder.cpp
@@ -32,6 +32,7 @@
#include <QDateTime>
#include <QIODevice>
#include <QLatin1Char>
+#include <QStringView>
#include <QTime>
#include "libkwave/Compression.h"
@@ -416,13 +417,63 @@ bool Kwave::MP3Decoder::parseID3Tags(ID3_Tag &tag)
//***************************************************************************
QString Kwave::MP3Decoder::parseId3Frame2String(const ID3_Frame *frame)
{
- QString s;
- char *text = ID3_GetString(frame, ID3FN_TEXT);
- if (text && strlen(text)) {
- s = _(text);
- ID3_FreeString(text);
+ if (!frame) return QString();
+
+ // retrieve the encoding field from the ID3 frame
+ ID3_TextEnc enc = ID3TE_NONE;
+ const ID3_Field *enc_field = frame->GetField(ID3FN_TEXTENC);
+ if (enc_field != nullptr)
+ enc = static_cast<ID3_TextEnc>(enc_field->Get());
+
+ switch (enc) {
+ case ID3TE_UTF16: /* FALLTHROUGH */
+ case ID3TE_UTF16BE: {
+ // read raw unicode text directly to bypass id3lib's broken
+ // mbs conversion
+ const ID3_Field *field = frame->GetField(ID3FN_TEXT);
+ if (field != nullptr) {
+ const size_t num_chars = field->GetNumTextItems();
+ if (num_chars > 0) {
+ const char16_t *uc16_data =
+ reinterpret_cast<const char16_t *>(
+ field->GetRawText());
+ const size_t size_in_bytes = field->Size();
+ if ((uc16_data != nullptr) && (size_in_bytes > 0)) {
+ const size_t max_chars =
+ size_in_bytes / sizeof(char16_t);
+ const qsizetype pos =
+ QStringView(uc16_data, max_chars).indexOf(u'\0');
+ const qsizetype len = (pos >= 0) ? pos :
+ static_cast<qsizetype>(max_chars);
+ return QString::fromUtf16(uc16_data, len).trimmed();
+ }
+ }
+ }
+ break;
+ }
+ case ID3TE_UTF8: {
+ char *text = ID3_GetString(frame, ID3FN_TEXT);
+ if (text != nullptr) {
+ QString result = QString::fromUtf8(text).trimmed();
+ ID3_FreeString(text);
+ return result;
+ }
+ break;
+ }
+ case ID3TE_ISO8859_1: /* FALLTHROUGH */
+ case ID3TE_NONE: /* FALLTHROUGH */
+ default: {
+ char *text = ID3_GetString(frame, ID3FN_TEXT);
+ if (text != nullptr) {
+ QString result = QString::fromLatin1(text).trimmed();
+ ID3_FreeString(text);
+ return result;
+ }
+ break;
+ }
}
- return s;
+
+ return QString();
}
//***************************************************************************
diff --git a/plugins/codec_mp3/MP3Encoder.cpp b/plugins/codec_mp3/MP3Encoder.cpp
index 942ee845..77a681eb 100644
--- a/plugins/codec_mp3/MP3Encoder.cpp
+++ b/plugins/codec_mp3/MP3Encoder.cpp
@@ -90,7 +90,6 @@ void Kwave::MP3Encoder::encodeID3Tags(const Kwave::MetaDataList &meta_data,
ID3_Tag &tag)
{
const Kwave::FileInfo info(meta_data);
- ID3_FrameInfo frameInfo;
const QMap<Kwave::FileProperty, QVariant> properties(info.properties());
QMap<Kwave::FileProperty, QVariant>::const_iterator it;
@@ -134,7 +133,7 @@ void Kwave::MP3Encoder::encodeID3Tags(const Kwave::MetaDataList &meta_data,
{
field->SetEncoding(ID3TE_UTF16);
- // if "number of CDs is available: append with "/"
+ // if "number of CDs" is available: append with "/"
int cds = info.get(Kwave::INF_CDS).toInt();
if (cds > 0)
str_val += _("/%1").arg(cds);
@@ -144,7 +143,7 @@ void Kwave::MP3Encoder::encodeID3Tags(const Kwave::MetaDataList &meta_data,
}
case ID3_PropertyMap::ENC_TRACK_NUM:
{
- // if "number of tracks is available: append with "/"
+ // if "number of tracks" is available: append with "/"
int tracks = info.get(Kwave::INF_TRACKS).toInt();
if (tracks > 0)
str_val += _("/%1").arg(tracks);
@@ -179,8 +178,10 @@ void Kwave::MP3Encoder::encodeID3Tags(const Kwave::MetaDataList &meta_data,
}
/* frame->GetField(ID3FN_DESCRIPTION)->Set("..."); */
field = frame->GetField(ID3FN_TEXT);
- field->SetEncoding(ID3TE_UTF16);
- field->Set(static_cast<const unicode_t *>(c.utf16()));
+ if (field) {
+ field->SetEncoding(ID3TE_UTF16);
+ field->Set(static_cast<const unicode_t *>(c.utf16()));
+ }
if (tag.AttachFrame(frame)) {
frame = nullptr;