mirror of
https://git.FreeBSD.org/ports.git
synced 2024-11-18 00:10:04 +00:00
converters/gbsdconv: Fix build with Taglib 2.x
PR: 276677
This commit is contained in:
parent
332610a716
commit
13b6ffc52c
@ -1,6 +1,6 @@
|
||||
PORTNAME= gbsdconv
|
||||
PORTVERSION= 11.3
|
||||
PORTREVISION= 3
|
||||
PORTREVISION= 4
|
||||
CATEGORIES= converters python
|
||||
|
||||
MAINTAINER= buganini@gmail.com
|
||||
|
30
converters/gbsdconv/files/patch-gbsdconv
Normal file
30
converters/gbsdconv/files/patch-gbsdconv
Normal file
@ -0,0 +1,30 @@
|
||||
--- gbsdconv.orig 2024-06-06 19:33:30 UTC
|
||||
+++ gbsdconv
|
||||
@@ -38,10 +38,10 @@ taglib.taglib_mpeg_file.restype=c_void_p
|
||||
taglib.taglib_mpeg_file.argtypes=[c_void_p]
|
||||
taglib.taglib_mpeg_file.restype=c_void_p
|
||||
|
||||
-taglib.taglib_mpeg_file_save3.argtypes=[c_void_p, c_int, c_bool, c_int]
|
||||
+taglib.taglib_mpeg_file_save3.argtypes=[c_void_p, c_int, c_bool, c_int, c_bool]
|
||||
taglib.taglib_mpeg_file_save3.restype=c_bool
|
||||
|
||||
-taglib.taglib_mpeg_file_strip.argtypes=[c_void_p, c_int]
|
||||
+taglib.taglib_mpeg_file_strip.argtypes=[c_void_p, c_int, c_bool]
|
||||
taglib.taglib_mpeg_file_strip.restype=c_bool
|
||||
|
||||
taglib.taglib_file_tag.argtypes=[c_void_p]
|
||||
@@ -1281,12 +1281,12 @@ class gBsdConv(object):
|
||||
|
||||
mpeg=taglib.taglib_mpeg_file(mfile)
|
||||
if mpeg and builder.get_object('chk_use_id3v2_3').get_active():
|
||||
- taglib.taglib_mpeg_file_save3(mpeg, 0xffff, False, 3)
|
||||
+ taglib.taglib_mpeg_file_save3(mpeg, 0xffff, False, 3, True)
|
||||
else:
|
||||
taglib.taglib_file_save(mfile)
|
||||
|
||||
if mpeg and builder.get_object('chk_remove_id3v1').get_active():
|
||||
- taglib.taglib_mpeg_file_strip(mpeg, 0x0001)
|
||||
+ taglib.taglib_mpeg_file_strip(mpeg, 0x0001, True)
|
||||
|
||||
taglib.taglib_tag_free_strings()
|
||||
taglib.taglib_file_free(mfile)
|
873
converters/gbsdconv/files/patch-taglib_tag__c.cpp
Normal file
873
converters/gbsdconv/files/patch-taglib_tag__c.cpp
Normal file
@ -0,0 +1,873 @@
|
||||
--- taglib/tag_c.cpp.orig 2014-02-15 21:45:54 UTC
|
||||
+++ taglib/tag_c.cpp
|
||||
@@ -19,43 +19,82 @@
|
||||
* USA *
|
||||
***************************************************************************/
|
||||
|
||||
+#include "tag_c.h"
|
||||
+
|
||||
+#include <cstdlib>
|
||||
+#include <cstring>
|
||||
+#include <sstream>
|
||||
+#include <utility>
|
||||
+
|
||||
#ifdef HAVE_CONFIG_H
|
||||
-#include "config.h"
|
||||
+# include "config.h"
|
||||
#endif
|
||||
+#include "tstringlist.h"
|
||||
+#include "tbytevectorstream.h"
|
||||
+#include "tiostream.h"
|
||||
+#include "tfile.h"
|
||||
+#include "tpropertymap.h"
|
||||
+#include "fileref.h"
|
||||
+#include "asffile.h"
|
||||
+#include "vorbisfile.h"
|
||||
+#include "mpegfile.h"
|
||||
+#include "flacfile.h"
|
||||
+#include "oggflacfile.h"
|
||||
+#include "mpcfile.h"
|
||||
+#include "wavpackfile.h"
|
||||
+#include "speexfile.h"
|
||||
+#include "trueaudiofile.h"
|
||||
+#include "mp4file.h"
|
||||
+#include "aifffile.h"
|
||||
+#include "wavfile.h"
|
||||
+#include "apefile.h"
|
||||
+#include "itfile.h"
|
||||
+#include "modfile.h"
|
||||
+#include "s3mfile.h"
|
||||
+#include "xmfile.h"
|
||||
+#include "opusfile.h"
|
||||
+#include "dsffile.h"
|
||||
+#include "dsdifffile.h"
|
||||
+#include "tag.h"
|
||||
+#include "id3v2framefactory.h"
|
||||
|
||||
-#include <stdlib.h>
|
||||
-#include <fileref.h>
|
||||
-#include <tfile.h>
|
||||
-#include <asffile.h>
|
||||
-#include <vorbisfile.h>
|
||||
-#include <mpegfile.h>
|
||||
-#include <flacfile.h>
|
||||
-#include <oggflacfile.h>
|
||||
-#include <mpcfile.h>
|
||||
-#include <wavpackfile.h>
|
||||
-#include <speexfile.h>
|
||||
-#include <trueaudiofile.h>
|
||||
-#include <mp4file.h>
|
||||
-#include <tag.h>
|
||||
-#include <string.h>
|
||||
-#include <id3v2framefactory.h>
|
||||
+using namespace TagLib;
|
||||
|
||||
-#include "tag_c.h"
|
||||
+namespace
|
||||
+{
|
||||
+ List<char *> strings;
|
||||
+ bool unicodeStrings = true;
|
||||
+ bool stringManagementEnabled = true;
|
||||
|
||||
-using namespace TagLib;
|
||||
+ char *stringToCharArray(const String &s)
|
||||
+ {
|
||||
+ const std::string str = s.to8Bit(unicodeStrings);
|
||||
|
||||
-static List<char *> strings;
|
||||
-static bool unicodeStrings = true;
|
||||
-static bool stringManagementEnabled = true;
|
||||
+#ifdef HAVE_ISO_STRDUP
|
||||
|
||||
+ return ::_strdup(str.c_str());
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+ return ::strdup(str.c_str());
|
||||
+
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ String charArrayToString(const char *s)
|
||||
+ {
|
||||
+ return String(s, unicodeStrings ? String::UTF8 : String::Latin1);
|
||||
+ }
|
||||
+} // namespace
|
||||
+
|
||||
void taglib_set_strings_unicode(BOOL unicode)
|
||||
{
|
||||
- unicodeStrings = bool(unicode);
|
||||
+ unicodeStrings = (unicode != 0);
|
||||
}
|
||||
|
||||
void taglib_set_string_management_enabled(BOOL management)
|
||||
{
|
||||
- stringManagementEnabled = bool(management);
|
||||
+ stringManagementEnabled = (management != 0);
|
||||
}
|
||||
|
||||
void taglib_free(void* pointer)
|
||||
@@ -64,69 +103,130 @@ void taglib_free(void* pointer)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
-// TagLib::File wrapper
|
||||
+// TagLib::IOStream wrapper
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+TagLib_IOStream *taglib_memory_iostream_new(const char *data, unsigned int size)
|
||||
+{
|
||||
+ return reinterpret_cast<TagLib_IOStream *>(
|
||||
+ new ByteVectorStream(ByteVector(data, size)));
|
||||
+}
|
||||
+
|
||||
+void taglib_iostream_free(TagLib_IOStream *stream)
|
||||
+{
|
||||
+ delete reinterpret_cast<IOStream *>(stream);
|
||||
+}
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////////////////////
|
||||
+// TagLib::FileRef wrapper
|
||||
+////////////////////////////////////////////////////////////////////////////////
|
||||
+
|
||||
TagLib_File *taglib_file_new(const char *filename)
|
||||
{
|
||||
- return reinterpret_cast<TagLib_File *>(FileRef::create(filename));
|
||||
+ return reinterpret_cast<TagLib_File *>(new FileRef(filename));
|
||||
}
|
||||
|
||||
TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
|
||||
{
|
||||
+ File *file = NULL;
|
||||
switch(type) {
|
||||
case TagLib_File_MPEG:
|
||||
- return reinterpret_cast<TagLib_File *>(new MPEG::File(filename));
|
||||
+ file = new MPEG::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_OggVorbis:
|
||||
- return reinterpret_cast<TagLib_File *>(new Ogg::Vorbis::File(filename));
|
||||
+ file = new Ogg::Vorbis::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_FLAC:
|
||||
- return reinterpret_cast<TagLib_File *>(new FLAC::File(filename));
|
||||
+ file = new FLAC::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_MPC:
|
||||
- return reinterpret_cast<TagLib_File *>(new MPC::File(filename));
|
||||
+ file = new MPC::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_OggFlac:
|
||||
- return reinterpret_cast<TagLib_File *>(new Ogg::FLAC::File(filename));
|
||||
+ file = new Ogg::FLAC::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_WavPack:
|
||||
- return reinterpret_cast<TagLib_File *>(new WavPack::File(filename));
|
||||
+ file = new WavPack::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_Speex:
|
||||
- return reinterpret_cast<TagLib_File *>(new Ogg::Speex::File(filename));
|
||||
+ file = new Ogg::Speex::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_TrueAudio:
|
||||
- return reinterpret_cast<TagLib_File *>(new TrueAudio::File(filename));
|
||||
+ file = new TrueAudio::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_MP4:
|
||||
- return reinterpret_cast<TagLib_File *>(new MP4::File(filename));
|
||||
+ file = new MP4::File(filename);
|
||||
+ break;
|
||||
case TagLib_File_ASF:
|
||||
- return reinterpret_cast<TagLib_File *>(new ASF::File(filename));
|
||||
+ file = new ASF::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_AIFF:
|
||||
+ file = new RIFF::AIFF::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_WAV:
|
||||
+ file = new RIFF::WAV::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_APE:
|
||||
+ file = new APE::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_IT:
|
||||
+ file = new IT::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_Mod:
|
||||
+ file = new Mod::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_S3M:
|
||||
+ file = new S3M::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_XM:
|
||||
+ file = new XM::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_Opus:
|
||||
+ file = new Ogg::Opus::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_DSF:
|
||||
+ file = new DSF::File(filename);
|
||||
+ break;
|
||||
+ case TagLib_File_DSDIFF:
|
||||
+ file = new DSDIFF::File(filename);
|
||||
+ break;
|
||||
default:
|
||||
- return 0;
|
||||
+ break;
|
||||
}
|
||||
+ return file ? reinterpret_cast<TagLib_File *>(new FileRef(file)) : NULL;
|
||||
+}
|
||||
|
||||
- return 0;
|
||||
+TagLib_File *taglib_file_new_iostream(TagLib_IOStream *stream)
|
||||
+{
|
||||
+ return reinterpret_cast<TagLib_File *>(
|
||||
+ new FileRef(reinterpret_cast<IOStream *>(stream)));
|
||||
}
|
||||
|
||||
void taglib_file_free(TagLib_File *file)
|
||||
{
|
||||
- delete reinterpret_cast<File *>(file);
|
||||
+ delete reinterpret_cast<FileRef *>(file);
|
||||
}
|
||||
|
||||
BOOL taglib_file_is_valid(const TagLib_File *file)
|
||||
{
|
||||
- return reinterpret_cast<const File *>(file)->isValid();
|
||||
+ return !reinterpret_cast<const FileRef *>(file)->isNull();
|
||||
}
|
||||
|
||||
TagLib_Tag *taglib_file_tag(const TagLib_File *file)
|
||||
{
|
||||
- const File *f = reinterpret_cast<const File *>(file);
|
||||
+ auto f = reinterpret_cast<const FileRef *>(file);
|
||||
return reinterpret_cast<TagLib_Tag *>(f->tag());
|
||||
}
|
||||
|
||||
const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file)
|
||||
{
|
||||
- const File *f = reinterpret_cast<const File *>(file);
|
||||
+ auto f = reinterpret_cast<const FileRef *>(file);
|
||||
return reinterpret_cast<const TagLib_AudioProperties *>(f->audioProperties());
|
||||
}
|
||||
|
||||
BOOL taglib_file_save(TagLib_File *file)
|
||||
{
|
||||
- return reinterpret_cast<File *>(file)->save();
|
||||
+ return reinterpret_cast<FileRef *>(file)->save();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -135,8 +235,8 @@ char *taglib_tag_title(const TagLib_Tag *tag)
|
||||
|
||||
char *taglib_tag_title(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
- char *s = ::strdup(t->title().toCString(unicodeStrings));
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
+ char *s = stringToCharArray(t->title());
|
||||
if(stringManagementEnabled)
|
||||
strings.append(s);
|
||||
return s;
|
||||
@@ -144,8 +244,8 @@ char *taglib_tag_artist(const TagLib_Tag *tag)
|
||||
|
||||
char *taglib_tag_artist(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
- char *s = ::strdup(t->artist().toCString(unicodeStrings));
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
+ char *s = stringToCharArray(t->artist());
|
||||
if(stringManagementEnabled)
|
||||
strings.append(s);
|
||||
return s;
|
||||
@@ -153,8 +253,8 @@ char *taglib_tag_album(const TagLib_Tag *tag)
|
||||
|
||||
char *taglib_tag_album(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
- char *s = ::strdup(t->album().toCString(unicodeStrings));
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
+ char *s = stringToCharArray(t->album());
|
||||
if(stringManagementEnabled)
|
||||
strings.append(s);
|
||||
return s;
|
||||
@@ -162,8 +262,8 @@ char *taglib_tag_comment(const TagLib_Tag *tag)
|
||||
|
||||
char *taglib_tag_comment(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
- char *s = ::strdup(t->comment().toCString(unicodeStrings));
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
+ char *s = stringToCharArray(t->comment());
|
||||
if(stringManagementEnabled)
|
||||
strings.append(s);
|
||||
return s;
|
||||
@@ -171,8 +271,8 @@ char *taglib_tag_genre(const TagLib_Tag *tag)
|
||||
|
||||
char *taglib_tag_genre(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
- char *s = ::strdup(t->genre().toCString(unicodeStrings));
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
+ char *s = stringToCharArray(t->genre());
|
||||
if(stringManagementEnabled)
|
||||
strings.append(s);
|
||||
return s;
|
||||
@@ -180,55 +280,55 @@ unsigned int taglib_tag_year(const TagLib_Tag *tag)
|
||||
|
||||
unsigned int taglib_tag_year(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
return t->year();
|
||||
}
|
||||
|
||||
unsigned int taglib_tag_track(const TagLib_Tag *tag)
|
||||
{
|
||||
- const Tag *t = reinterpret_cast<const Tag *>(tag);
|
||||
+ auto t = reinterpret_cast<const Tag *>(tag);
|
||||
return t->track();
|
||||
}
|
||||
|
||||
void taglib_tag_set_title(TagLib_Tag *tag, const char *title)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
- t->setTitle(String(title, unicodeStrings ? String::UTF8 : String::Latin1));
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
+ t->setTitle(charArrayToString(title));
|
||||
}
|
||||
|
||||
void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
- t->setArtist(String(artist, unicodeStrings ? String::UTF8 : String::Latin1));
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
+ t->setArtist(charArrayToString(artist));
|
||||
}
|
||||
|
||||
void taglib_tag_set_album(TagLib_Tag *tag, const char *album)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
- t->setAlbum(String(album, unicodeStrings ? String::UTF8 : String::Latin1));
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
+ t->setAlbum(charArrayToString(album));
|
||||
}
|
||||
|
||||
void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
- t->setComment(String(comment, unicodeStrings ? String::UTF8 : String::Latin1));
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
+ t->setComment(charArrayToString(comment));
|
||||
}
|
||||
|
||||
void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
- t->setGenre(String(genre, unicodeStrings ? String::UTF8 : String::Latin1));
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
+ t->setGenre(charArrayToString(genre));
|
||||
}
|
||||
|
||||
void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
t->setYear(year);
|
||||
}
|
||||
|
||||
void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track)
|
||||
{
|
||||
- Tag *t = reinterpret_cast<Tag *>(tag);
|
||||
+ auto t = reinterpret_cast<Tag *>(tag);
|
||||
t->setTrack(track);
|
||||
}
|
||||
|
||||
@@ -237,8 +337,8 @@ void taglib_tag_free_strings()
|
||||
if(!stringManagementEnabled)
|
||||
return;
|
||||
|
||||
- for(List<char *>::Iterator it = strings.begin(); it != strings.end(); ++it)
|
||||
- free(*it);
|
||||
+ for(auto &string : std::as_const(strings))
|
||||
+ free(string);
|
||||
strings.clear();
|
||||
}
|
||||
|
||||
@@ -248,25 +348,25 @@ int taglib_audioproperties_length(const TagLib_AudioPr
|
||||
|
||||
int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties)
|
||||
{
|
||||
- const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
- return p->length();
|
||||
+ auto p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
+ return p->lengthInSeconds();
|
||||
}
|
||||
|
||||
int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties)
|
||||
{
|
||||
- const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
+ auto p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
return p->bitrate();
|
||||
}
|
||||
|
||||
int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties)
|
||||
{
|
||||
- const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
+ auto p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
return p->sampleRate();
|
||||
}
|
||||
|
||||
int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties)
|
||||
{
|
||||
- const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
+ auto p = reinterpret_cast<const AudioProperties *>(audioProperties);
|
||||
return p->channels();
|
||||
}
|
||||
|
||||
@@ -293,6 +393,423 @@ void taglib_id3v2_set_default_text_encoding(TagLib_ID3
|
||||
ID3v2::FrameFactory::instance()->setDefaultTextEncoding(type);
|
||||
}
|
||||
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * Properties API
|
||||
+ ******************************************************************************/
|
||||
+namespace {
|
||||
+
|
||||
+void _taglib_property_set(TagLib_File *file, const char* prop, const char* value, bool append)
|
||||
+{
|
||||
+ if(file == NULL || prop == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ auto tfile = reinterpret_cast<FileRef *>(file);
|
||||
+ PropertyMap map = tfile->tag()->properties();
|
||||
+
|
||||
+ if(value) {
|
||||
+ auto property = map.find(prop);
|
||||
+ if(property == map.end()) {
|
||||
+ map.insert(prop, StringList(charArrayToString(value)));
|
||||
+ }
|
||||
+ else {
|
||||
+ if(append) {
|
||||
+ property->second.append(charArrayToString(value));
|
||||
+ }
|
||||
+ else {
|
||||
+ property->second = StringList(charArrayToString(value));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else {
|
||||
+ map.erase(prop);
|
||||
+ }
|
||||
+
|
||||
+ tfile->setProperties(map);
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+void taglib_property_set(TagLib_File *file, const char *prop, const char *value)
|
||||
+{
|
||||
+ _taglib_property_set(file, prop, value, false);
|
||||
+}
|
||||
+
|
||||
+void taglib_property_set_append(TagLib_File *file, const char *prop, const char *value)
|
||||
+{
|
||||
+ _taglib_property_set(file, prop, value, true);
|
||||
+}
|
||||
+
|
||||
+char** taglib_property_keys(const TagLib_File *file)
|
||||
+{
|
||||
+ if(file == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ const PropertyMap map = reinterpret_cast<const FileRef *>(file)->properties();
|
||||
+ if(map.isEmpty())
|
||||
+ return NULL;
|
||||
+
|
||||
+ auto props = static_cast<char **>(malloc(sizeof(char *) * (map.size() + 1)));
|
||||
+ char **pp = props;
|
||||
+
|
||||
+ for(const auto &i : map) {
|
||||
+ *pp++ = stringToCharArray(i.first);
|
||||
+ }
|
||||
+ *pp = NULL;
|
||||
+
|
||||
+ return props;
|
||||
+}
|
||||
+
|
||||
+char **taglib_property_get(const TagLib_File *file, const char *prop)
|
||||
+{
|
||||
+ if(file == NULL || prop == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ const PropertyMap map = reinterpret_cast<const FileRef *>(file)->properties();
|
||||
+
|
||||
+ auto property = map.find(prop);
|
||||
+ if(property == map.end())
|
||||
+ return NULL;
|
||||
+
|
||||
+ auto props = static_cast<char **>(malloc(sizeof(char *) * (property->second.size() + 1)));
|
||||
+ char **pp = props;
|
||||
+
|
||||
+ for(const auto &i : property->second) {
|
||||
+ *pp++ = stringToCharArray(i);
|
||||
+ }
|
||||
+ *pp = NULL;
|
||||
+
|
||||
+ return props;
|
||||
+}
|
||||
+
|
||||
+void taglib_property_free(char **props)
|
||||
+{
|
||||
+ if(props == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ char **p = props;
|
||||
+ while(*p) {
|
||||
+ free(*p++);
|
||||
+ }
|
||||
+ free(props);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * Complex Properties API
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+bool _taglib_complex_property_set(
|
||||
+ TagLib_File *file, const char *key,
|
||||
+ const TagLib_Complex_Property_Attribute **value, bool append)
|
||||
+{
|
||||
+ if(file == NULL || key == NULL)
|
||||
+ return false;
|
||||
+
|
||||
+ auto tfile = reinterpret_cast<FileRef *>(file);
|
||||
+
|
||||
+ if(value == NULL) {
|
||||
+ return tfile->setComplexProperties(key, {});
|
||||
+ }
|
||||
+
|
||||
+ VariantMap map;
|
||||
+ const TagLib_Complex_Property_Attribute** attrPtr = value;
|
||||
+ while(*attrPtr) {
|
||||
+ const TagLib_Complex_Property_Attribute *attr = *attrPtr;
|
||||
+ String attrKey(attr->key);
|
||||
+ switch(attr->value.type) {
|
||||
+ case TagLib_Variant_Void:
|
||||
+ map.insert(attrKey, Variant());
|
||||
+ break;
|
||||
+ case TagLib_Variant_Bool:
|
||||
+ map.insert(attrKey, attr->value.value.boolValue != 0);
|
||||
+ break;
|
||||
+ case TagLib_Variant_Int:
|
||||
+ map.insert(attrKey, attr->value.value.intValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_UInt:
|
||||
+ map.insert(attrKey, attr->value.value.uIntValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_LongLong:
|
||||
+ map.insert(attrKey, attr->value.value.longLongValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_ULongLong:
|
||||
+ map.insert(attrKey, attr->value.value.uLongLongValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_Double:
|
||||
+ map.insert(attrKey, attr->value.value.doubleValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_String:
|
||||
+ map.insert(attrKey, charArrayToString(attr->value.value.stringValue));
|
||||
+ break;
|
||||
+ case TagLib_Variant_StringList: {
|
||||
+ StringList strs;
|
||||
+ if(attr->value.value.stringListValue) {
|
||||
+ char **s = attr->value.value.stringListValue;;
|
||||
+ while(*s) {
|
||||
+ strs.append(charArrayToString(*s++));
|
||||
+ }
|
||||
+ }
|
||||
+ map.insert(attrKey, strs);
|
||||
+ break;
|
||||
+ }
|
||||
+ case TagLib_Variant_ByteVector:
|
||||
+ map.insert(attrKey, ByteVector(attr->value.value.byteVectorValue,
|
||||
+ attr->value.size));
|
||||
+ break;
|
||||
+ }
|
||||
+ ++attrPtr;
|
||||
+ }
|
||||
+
|
||||
+ return append ? tfile->setComplexProperties(key, tfile->complexProperties(key).append(map))
|
||||
+ : tfile->setComplexProperties(key, {map});
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+BOOL taglib_complex_property_set(
|
||||
+ TagLib_File *file, const char *key,
|
||||
+ const TagLib_Complex_Property_Attribute **value)
|
||||
+{
|
||||
+ return _taglib_complex_property_set(file, key, value, false);
|
||||
+}
|
||||
+
|
||||
+BOOL taglib_complex_property_set_append(
|
||||
+ TagLib_File *file, const char *key,
|
||||
+ const TagLib_Complex_Property_Attribute **value)
|
||||
+{
|
||||
+ return _taglib_complex_property_set(file, key, value, true);
|
||||
+}
|
||||
+
|
||||
+char** taglib_complex_property_keys(const TagLib_File *file)
|
||||
+{
|
||||
+ if(file == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ const StringList strs = reinterpret_cast<const FileRef *>(file)->complexPropertyKeys();
|
||||
+ if(strs.isEmpty()) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ auto keys = static_cast<char **>(malloc(sizeof(char *) * (strs.size() + 1)));
|
||||
+ char **keyPtr = keys;
|
||||
+
|
||||
+ for(const auto &str : strs) {
|
||||
+ *keyPtr++ = stringToCharArray(str);
|
||||
+ }
|
||||
+ *keyPtr = NULL;
|
||||
+
|
||||
+ return keys;
|
||||
+}
|
||||
+
|
||||
+TagLib_Complex_Property_Attribute*** taglib_complex_property_get(
|
||||
+ const TagLib_File *file, const char *key)
|
||||
+{
|
||||
+ if(file == NULL || key == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ const auto variantMaps = reinterpret_cast<const FileRef *>(file)->complexProperties(key);
|
||||
+ if(variantMaps.isEmpty()) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ auto props = static_cast<TagLib_Complex_Property_Attribute ***>(
|
||||
+ malloc(sizeof(TagLib_Complex_Property_Attribute **) * (variantMaps.size() + 1)));
|
||||
+ TagLib_Complex_Property_Attribute ***propPtr = props;
|
||||
+
|
||||
+ for(const auto &variantMap : variantMaps) {
|
||||
+ if(!variantMap.isEmpty()) {
|
||||
+ auto attrs = static_cast<TagLib_Complex_Property_Attribute **>(
|
||||
+ malloc(sizeof(TagLib_Complex_Property_Attribute *) * (variantMap.size() + 1)));
|
||||
+ auto attr = static_cast<TagLib_Complex_Property_Attribute *>(
|
||||
+ malloc(sizeof(TagLib_Complex_Property_Attribute) * variantMap.size()));
|
||||
+ TagLib_Complex_Property_Attribute **attrPtr = attrs;
|
||||
+ // The next assignment is redundant to silence the clang analyzer,
|
||||
+ // it is done at the end of the loop, which must be entered because
|
||||
+ // variantMap is not empty.
|
||||
+ *attrPtr = attr;
|
||||
+ for(const auto &[k, v] : variantMap) {
|
||||
+ attr->key = stringToCharArray(k);
|
||||
+ attr->value.size = 0;
|
||||
+ switch(v.type()) {
|
||||
+ case Variant::Void:
|
||||
+ attr->value.type = TagLib_Variant_Void;
|
||||
+ attr->value.value.stringValue = NULL;
|
||||
+ break;
|
||||
+ case Variant::Bool:
|
||||
+ attr->value.type = TagLib_Variant_Bool;
|
||||
+ attr->value.value.boolValue = v.value<bool>();
|
||||
+ break;
|
||||
+ case Variant::Int:
|
||||
+ attr->value.type = TagLib_Variant_Int;
|
||||
+ attr->value.value.intValue = v.value<int>();
|
||||
+ break;
|
||||
+ case Variant::UInt:
|
||||
+ attr->value.type = TagLib_Variant_UInt;
|
||||
+ attr->value.value.uIntValue = v.value<unsigned int>();
|
||||
+ break;
|
||||
+ case Variant::LongLong:
|
||||
+ attr->value.type = TagLib_Variant_LongLong;
|
||||
+ attr->value.value.longLongValue = v.value<long long>();
|
||||
+ break;
|
||||
+ case Variant::ULongLong:
|
||||
+ attr->value.type = TagLib_Variant_ULongLong;
|
||||
+ attr->value.value.uLongLongValue = v.value<unsigned long long>();
|
||||
+ break;
|
||||
+ case Variant::Double:
|
||||
+ attr->value.type = TagLib_Variant_Double;
|
||||
+ attr->value.value.doubleValue = v.value<double>();
|
||||
+ break;
|
||||
+ case Variant::String: {
|
||||
+ attr->value.type = TagLib_Variant_String;
|
||||
+ auto str = v.value<String>();
|
||||
+ attr->value.value.stringValue = stringToCharArray(str);
|
||||
+ attr->value.size = str.size();
|
||||
+ break;
|
||||
+ }
|
||||
+ case Variant::StringList: {
|
||||
+ attr->value.type = TagLib_Variant_StringList;
|
||||
+ auto strs = v.value<StringList>();
|
||||
+ auto strPtr = static_cast<char **>(malloc(sizeof(char *) * (strs.size() + 1)));
|
||||
+ attr->value.value.stringListValue = strPtr;
|
||||
+ attr->value.size = strs.size();
|
||||
+ for(const auto &str : strs) {
|
||||
+ *strPtr++ = stringToCharArray(str);
|
||||
+ }
|
||||
+ *strPtr = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ case Variant::ByteVector: {
|
||||
+ attr->value.type = TagLib_Variant_ByteVector;
|
||||
+ const ByteVector data = v.value<ByteVector>();
|
||||
+ auto bytePtr = static_cast<char *>(malloc(data.size()));
|
||||
+ attr->value.value.byteVectorValue = bytePtr;
|
||||
+ attr->value.size = data.size();
|
||||
+ ::memcpy(bytePtr, data.data(), data.size());
|
||||
+ break;
|
||||
+ }
|
||||
+ case Variant::ByteVectorList:
|
||||
+ case Variant::VariantList:
|
||||
+ case Variant::VariantMap: {
|
||||
+ attr->value.type = TagLib_Variant_String;
|
||||
+ std::stringstream ss;
|
||||
+ ss << v;
|
||||
+ attr->value.value.stringValue = stringToCharArray(ss.str());
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ *attrPtr++ = attr++;
|
||||
+ }
|
||||
+ *attrPtr = NULL;
|
||||
+ *propPtr++ = attrs;
|
||||
+ }
|
||||
+ }
|
||||
+ *propPtr = NULL;
|
||||
+ return props;
|
||||
+}
|
||||
+
|
||||
+void taglib_picture_from_complex_property(
|
||||
+ TagLib_Complex_Property_Attribute*** properties,
|
||||
+ TagLib_Complex_Property_Picture_Data *picture)
|
||||
+{
|
||||
+ if(!properties || !picture) {
|
||||
+ return;
|
||||
+ }
|
||||
+ std::memset(picture, 0, sizeof(*picture));
|
||||
+ TagLib_Complex_Property_Attribute*** propPtr = properties;
|
||||
+ while(!picture->data && *propPtr) {
|
||||
+ TagLib_Complex_Property_Attribute** attrPtr = *propPtr;
|
||||
+ while(*attrPtr) {
|
||||
+ TagLib_Complex_Property_Attribute *attr = *attrPtr;
|
||||
+ switch(attr->value.type) {
|
||||
+ case TagLib_Variant_String:
|
||||
+ if(strcmp("mimeType", attr->key) == 0) {
|
||||
+ picture->mimeType = attr->value.value.stringValue;
|
||||
+ }
|
||||
+ else if(strcmp("description", attr->key) == 0) {
|
||||
+ picture->description = attr->value.value.stringValue;
|
||||
+ }
|
||||
+ else if(strcmp("pictureType", attr->key) == 0) {
|
||||
+ picture->pictureType = attr->value.value.stringValue;
|
||||
+ }
|
||||
+ break;
|
||||
+ case TagLib_Variant_ByteVector:
|
||||
+ if(strcmp("data", attr->key) == 0) {
|
||||
+ picture->data = attr->value.value.byteVectorValue;
|
||||
+ picture->size = attr->value.size;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ ++attrPtr;
|
||||
+ }
|
||||
+ ++propPtr;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void taglib_complex_property_free_keys(char **keys)
|
||||
+{
|
||||
+ if(keys == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ char **k = keys;
|
||||
+ while(*k) {
|
||||
+ free(*k++);
|
||||
+ }
|
||||
+ free(keys);
|
||||
+}
|
||||
+
|
||||
+void taglib_complex_property_free(
|
||||
+ TagLib_Complex_Property_Attribute ***props)
|
||||
+{
|
||||
+ if(props == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+ TagLib_Complex_Property_Attribute*** propPtr = props;
|
||||
+ while(*propPtr) {
|
||||
+ TagLib_Complex_Property_Attribute** attrPtr = *propPtr;
|
||||
+ while(*attrPtr) {
|
||||
+ TagLib_Complex_Property_Attribute *attr = *attrPtr;
|
||||
+ switch(attr->value.type) {
|
||||
+ case TagLib_Variant_String:
|
||||
+ free(attr->value.value.stringValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_StringList:
|
||||
+ if(attr->value.value.stringListValue) {
|
||||
+ char **s = attr->value.value.stringListValue;
|
||||
+ while(*s) {
|
||||
+ free(*s++);
|
||||
+ }
|
||||
+ free(attr->value.value.stringListValue);
|
||||
+ }
|
||||
+ break;
|
||||
+ case TagLib_Variant_ByteVector:
|
||||
+ free(attr->value.value.byteVectorValue);
|
||||
+ break;
|
||||
+ case TagLib_Variant_Void:
|
||||
+ case TagLib_Variant_Bool:
|
||||
+ case TagLib_Variant_Int:
|
||||
+ case TagLib_Variant_UInt:
|
||||
+ case TagLib_Variant_LongLong:
|
||||
+ case TagLib_Variant_ULongLong:
|
||||
+ case TagLib_Variant_Double:
|
||||
+ break;
|
||||
+ }
|
||||
+ free(attr->key);
|
||||
+ ++attrPtr;
|
||||
+ }
|
||||
+ free(**propPtr);
|
||||
+ free(*propPtr++);
|
||||
+ }
|
||||
+ free(props);
|
||||
+}
|
||||
+
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TagLib::MPEG::File wrapper
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -302,15 +819,18 @@ TagLib_Mpeg_File *taglib_mpeg_file(TagLib_File *file)
|
||||
return reinterpret_cast<TagLib_Mpeg_File *>(dynamic_cast<MPEG::File *>(reinterpret_cast<File *>(file)));
|
||||
}
|
||||
|
||||
-BOOL taglib_mpeg_file_save3(TagLib_Mpeg_File *file, int tags, BOOL stripOthers, int id3v2Version)
|
||||
+BOOL taglib_mpeg_file_save3(TagLib_Mpeg_File *file, int tags, BOOL stripOthers, int id3v2Version, BOOL duplicateTags)
|
||||
{
|
||||
MPEG::File *f=reinterpret_cast<MPEG::File *>(file);
|
||||
- return f->save(tags, (bool)stripOthers, id3v2Version);
|
||||
+ return f->save(tags,
|
||||
+ stripOthers ? File::StripOthers : File::StripNone,
|
||||
+ id3v2Version == 3 ? ID3v2::v3 : ID3v2::v4,
|
||||
+ duplicateTags ? File::Duplicate : File::DoNotDuplicate);
|
||||
}
|
||||
|
||||
-BOOL taglib_mpeg_file_strip(TagLib_Mpeg_File *file, int tags)
|
||||
+BOOL taglib_mpeg_file_strip(TagLib_Mpeg_File *file, int tags, BOOL freeMemory)
|
||||
{
|
||||
MPEG::File *f=reinterpret_cast<MPEG::File *>(file);
|
||||
- return f->strip(tags);
|
||||
+ return f->strip(tags, freeMemory);
|
||||
|
||||
}
|
428
converters/gbsdconv/files/patch-taglib_tag__c.h
Normal file
428
converters/gbsdconv/files/patch-taglib_tag__c.h
Normal file
@ -0,0 +1,428 @@
|
||||
--- taglib/tag_c.h.orig 2014-02-15 21:45:54 UTC
|
||||
+++ taglib/tag_c.h
|
||||
@@ -29,7 +29,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-#if defined(_WIN32) || defined(_WIN64)
|
||||
+#if defined(TAGLIB_STATIC)
|
||||
+#define TAGLIB_C_EXPORT
|
||||
+#elif defined(_WIN32) || defined(_WIN64)
|
||||
#ifdef MAKE_TAGLIB_C_LIB
|
||||
#define TAGLIB_C_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
@@ -41,7 +43,10 @@ extern "C" {
|
||||
#define TAGLIB_C_EXPORT
|
||||
#endif
|
||||
|
||||
-#ifndef BOOL
|
||||
+#ifdef _MSC_VER
|
||||
+/* minwindef.h contains typedef int BOOL */
|
||||
+#include <windows.h>
|
||||
+#elif !defined BOOL
|
||||
#define BOOL int
|
||||
#endif
|
||||
|
||||
@@ -55,14 +60,15 @@ extern "C" {
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
- * These are used for type provide some type safety to the C API (as opposed to
|
||||
- * using void *, but pointers to them are simply cast to the corresponding C++
|
||||
+ * These are used to give the C API some type safety (as opposed to
|
||||
+ * using void * ), but pointers to them are simply cast to the corresponding C++
|
||||
* types in the implementation.
|
||||
*/
|
||||
|
||||
typedef struct { int dummy; } TagLib_File;
|
||||
typedef struct { int dummy; } TagLib_Tag;
|
||||
typedef struct { int dummy; } TagLib_AudioProperties;
|
||||
+typedef struct { int dummy; } TagLib_IOStream;
|
||||
typedef struct { int dummy; } TagLib_Mpeg_File;
|
||||
|
||||
/*!
|
||||
@@ -86,6 +92,22 @@ TAGLIB_C_EXPORT void taglib_free(void* pointer);
|
||||
TAGLIB_C_EXPORT void taglib_free(void* pointer);
|
||||
|
||||
/*******************************************************************************
|
||||
+ * Stream API
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
+/*!
|
||||
+ * Creates a byte vector stream from \a size bytes of \a data.
|
||||
+ * Such a stream can be used with taglib_file_new_iostream() to create a file
|
||||
+ * from memory.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT TagLib_IOStream *taglib_memory_iostream_new(const char *data, unsigned int size);
|
||||
+
|
||||
+/*!
|
||||
+ * Frees and closes the stream.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_iostream_free(TagLib_IOStream *stream);
|
||||
+
|
||||
+/*******************************************************************************
|
||||
* File API
|
||||
******************************************************************************/
|
||||
|
||||
@@ -99,7 +121,17 @@ typedef enum {
|
||||
TagLib_File_Speex,
|
||||
TagLib_File_TrueAudio,
|
||||
TagLib_File_MP4,
|
||||
- TagLib_File_ASF
|
||||
+ TagLib_File_ASF,
|
||||
+ TagLib_File_AIFF,
|
||||
+ TagLib_File_WAV,
|
||||
+ TagLib_File_APE,
|
||||
+ TagLib_File_IT,
|
||||
+ TagLib_File_Mod,
|
||||
+ TagLib_File_S3M,
|
||||
+ TagLib_File_XM,
|
||||
+ TagLib_File_Opus,
|
||||
+ TagLib_File_DSF,
|
||||
+ TagLib_File_DSDIFF
|
||||
} TagLib_File_Type;
|
||||
|
||||
/*!
|
||||
@@ -118,12 +150,22 @@ TAGLIB_C_EXPORT TagLib_File *taglib_file_new_type(cons
|
||||
TAGLIB_C_EXPORT TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type);
|
||||
|
||||
/*!
|
||||
+ * Creates a TagLib file from a \a stream.
|
||||
+ * A byte vector stream can be used to read a file from memory and write to
|
||||
+ * memory, e.g. when fetching network data.
|
||||
+ * The stream has to be created using taglib_memory_iostream_new() and shall be
|
||||
+ * freed using taglib_iostream_free() \e after this file is freed with
|
||||
+ * taglib_file_free().
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT TagLib_File *taglib_file_new_iostream(TagLib_IOStream *stream);
|
||||
+
|
||||
+/*!
|
||||
* Frees and closes the file.
|
||||
*/
|
||||
TAGLIB_C_EXPORT void taglib_file_free(TagLib_File *file);
|
||||
|
||||
/*!
|
||||
- * Returns true if the file is open and readble and valid information for
|
||||
+ * Returns \c true if the file is open and readable and valid information for
|
||||
* the Tag and / or AudioProperties was found.
|
||||
*/
|
||||
|
||||
@@ -136,7 +178,7 @@ TAGLIB_C_EXPORT TagLib_Tag *taglib_file_tag(const TagL
|
||||
TAGLIB_C_EXPORT TagLib_Tag *taglib_file_tag(const TagLib_File *file);
|
||||
|
||||
/*!
|
||||
- * Returns a pointer to the the audio properties associated with this file. This
|
||||
+ * Returns a pointer to the audio properties associated with this file. This
|
||||
* will be freed automatically when the file is freed.
|
||||
*/
|
||||
TAGLIB_C_EXPORT const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file);
|
||||
@@ -191,12 +233,12 @@ TAGLIB_C_EXPORT char *taglib_tag_genre(const TagLib_Ta
|
||||
TAGLIB_C_EXPORT char *taglib_tag_genre(const TagLib_Tag *tag);
|
||||
|
||||
/*!
|
||||
- * Returns the tag's year or 0 if year is not set.
|
||||
+ * Returns the tag's year or 0 if the year is not set.
|
||||
*/
|
||||
TAGLIB_C_EXPORT unsigned int taglib_tag_year(const TagLib_Tag *tag);
|
||||
|
||||
/*!
|
||||
- * Returns the tag's track number or 0 if track number is not set.
|
||||
+ * Returns the tag's track number or 0 if the track number is not set.
|
||||
*/
|
||||
TAGLIB_C_EXPORT unsigned int taglib_tag_track(const TagLib_Tag *tag);
|
||||
|
||||
@@ -284,14 +326,14 @@ TAGLIB_C_EXPORT TagLib_Mpeg_File *taglib_mpeg_file(Tag
|
||||
TAGLIB_C_EXPORT TagLib_Mpeg_File *taglib_mpeg_file(TagLib_File *file);
|
||||
|
||||
/*!
|
||||
- * bool TagLib::MPEG:File::save(int tags, bool stripOthers, int id3v2Version);
|
||||
+ * bool TagLib::MPEG::File::save(int tags, StripTags strip, ID3v2::Version version, DuplicateTags duplicate);
|
||||
*/
|
||||
-TAGLIB_C_EXPORT BOOL taglib_mpeg_file_save3(TagLib_Mpeg_File *file, int tags, BOOL stripOthers, int id3v2Version);
|
||||
+TAGLIB_C_EXPORT BOOL taglib_mpeg_file_save3(TagLib_Mpeg_File *file, int tags, BOOL stripOthers, int id3v2Version, BOOL duplicateTags);
|
||||
|
||||
/*!
|
||||
- * bool TagLib::MPEG:File::strip(int tags);
|
||||
+ * bool TagLib::MPEG::File::strip(int tags, bool freeMemory);
|
||||
*/
|
||||
-TAGLIB_C_EXPORT BOOL taglib_mpeg_file_strip(TagLib_Mpeg_File *file, int tags);
|
||||
+TAGLIB_C_EXPORT BOOL taglib_mpeg_file_strip(TagLib_Mpeg_File *file, int tags, BOOL freeMemory);
|
||||
|
||||
/*******************************************************************************
|
||||
* Special convenience ID3v2 functions
|
||||
@@ -309,6 +351,275 @@ TAGLIB_C_EXPORT void taglib_id3v2_set_default_text_enc
|
||||
*/
|
||||
|
||||
TAGLIB_C_EXPORT void taglib_id3v2_set_default_text_encoding(TagLib_ID3v2_Encoding encoding);
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * Properties API
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
+/*!
|
||||
+ * Sets the property \a prop with \a value. Use \a value = NULL to remove
|
||||
+ * the property, otherwise it will be replaced.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_property_set(TagLib_File *file, const char *prop, const char *value);
|
||||
+
|
||||
+/*!
|
||||
+ * Appends \a value to the property \a prop (sets it if non-existing).
|
||||
+ * Use \a value = NULL to remove all values associated with the property.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_property_set_append(TagLib_File *file, const char *prop, const char *value);
|
||||
+
|
||||
+/*!
|
||||
+ * Get the keys of the property map.
|
||||
+ *
|
||||
+ * \return NULL terminated array of C-strings (char *), only NULL if empty.
|
||||
+ * It must be freed by the client using taglib_property_free().
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT char** taglib_property_keys(const TagLib_File *file);
|
||||
+
|
||||
+/*!
|
||||
+ * Get value(s) of property \a prop.
|
||||
+ *
|
||||
+ * \return NULL terminated array of C-strings (char *), only NULL if empty.
|
||||
+ * It must be freed by the client using taglib_property_free().
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT char** taglib_property_get(const TagLib_File *file, const char *prop);
|
||||
+
|
||||
+/*!
|
||||
+ * Frees the NULL terminated array \a props and the C-strings it contains.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_property_free(char **props);
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * Complex Properties API
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
+/*!
|
||||
+ * Types which can be stored in a TagLib_Variant.
|
||||
+ *
|
||||
+ * \related TagLib::Variant::Type
|
||||
+ * These correspond to TagLib::Variant::Type, but ByteVectorList, VariantList,
|
||||
+ * VariantMap are not supported and will be returned as their string
|
||||
+ * representation.
|
||||
+ */
|
||||
+typedef enum {
|
||||
+ TagLib_Variant_Void,
|
||||
+ TagLib_Variant_Bool,
|
||||
+ TagLib_Variant_Int,
|
||||
+ TagLib_Variant_UInt,
|
||||
+ TagLib_Variant_LongLong,
|
||||
+ TagLib_Variant_ULongLong,
|
||||
+ TagLib_Variant_Double,
|
||||
+ TagLib_Variant_String,
|
||||
+ TagLib_Variant_StringList,
|
||||
+ TagLib_Variant_ByteVector
|
||||
+} TagLib_Variant_Type;
|
||||
+
|
||||
+/*!
|
||||
+ * Discriminated union used in complex property attributes.
|
||||
+ *
|
||||
+ * \e type must be set according to the \e value union used.
|
||||
+ * \e size is only required for TagLib_Variant_ByteVector and must contain
|
||||
+ * the number of bytes.
|
||||
+ *
|
||||
+ * \related TagLib::Variant.
|
||||
+ */
|
||||
+typedef struct {
|
||||
+ TagLib_Variant_Type type;
|
||||
+ unsigned int size;
|
||||
+ union {
|
||||
+ char *stringValue;
|
||||
+ char *byteVectorValue;
|
||||
+ char **stringListValue;
|
||||
+ BOOL boolValue;
|
||||
+ int intValue;
|
||||
+ unsigned int uIntValue;
|
||||
+ long long longLongValue;
|
||||
+ unsigned long long uLongLongValue;
|
||||
+ double doubleValue;
|
||||
+ } value;
|
||||
+} TagLib_Variant;
|
||||
+
|
||||
+/*!
|
||||
+ * Attribute of a complex property.
|
||||
+ * Complex properties consist of a NULL-terminated array of pointers to
|
||||
+ * this structure with \e key and \e value.
|
||||
+ */
|
||||
+typedef struct {
|
||||
+ char *key;
|
||||
+ TagLib_Variant value;
|
||||
+} TagLib_Complex_Property_Attribute;
|
||||
+
|
||||
+/*!
|
||||
+ * Picture data extracted from a complex property by the convenience function
|
||||
+ * taglib_picture_from_complex_property().
|
||||
+ */
|
||||
+typedef struct {
|
||||
+ char *mimeType;
|
||||
+ char *description;
|
||||
+ char *pictureType;
|
||||
+ char *data;
|
||||
+ unsigned int size;
|
||||
+} TagLib_Complex_Property_Picture_Data;
|
||||
+
|
||||
+/*!
|
||||
+ * Declare complex property attributes to set a picture.
|
||||
+ * Can be used to define a variable \a var which can be used with
|
||||
+ * taglib_complex_property_set() and a "PICTURE" key to set an
|
||||
+ * embedded picture with the picture data \a dat of size \a siz
|
||||
+ * and description \a desc, mime type \a mime and picture type
|
||||
+ * \a typ (size is unsigned int, the other input parameters char *).
|
||||
+ */
|
||||
+#define TAGLIB_COMPLEX_PROPERTY_PICTURE(var, dat, siz, desc, mime, typ) \
|
||||
+const TagLib_Complex_Property_Attribute \
|
||||
+var##Attrs[] = { \
|
||||
+ { \
|
||||
+ (char *)"data", \
|
||||
+ { \
|
||||
+ TagLib_Variant_ByteVector, \
|
||||
+ (siz), \
|
||||
+ { \
|
||||
+ (char *)(dat) \
|
||||
+ } \
|
||||
+ } \
|
||||
+ }, \
|
||||
+ { \
|
||||
+ (char *)"mimeType", \
|
||||
+ { \
|
||||
+ TagLib_Variant_String, \
|
||||
+ 0U, \
|
||||
+ { \
|
||||
+ (char *)(mime) \
|
||||
+ } \
|
||||
+ } \
|
||||
+ }, \
|
||||
+ { \
|
||||
+ (char *)"description", \
|
||||
+ { \
|
||||
+ TagLib_Variant_String, \
|
||||
+ 0U, \
|
||||
+ { \
|
||||
+ (char *)(desc) \
|
||||
+ } \
|
||||
+ } \
|
||||
+ }, \
|
||||
+ { \
|
||||
+ (char *)"pictureType", \
|
||||
+ { \
|
||||
+ TagLib_Variant_String, \
|
||||
+ 0U, \
|
||||
+ { \
|
||||
+ (char *)(typ) \
|
||||
+ } \
|
||||
+ } \
|
||||
+ } \
|
||||
+}; \
|
||||
+const TagLib_Complex_Property_Attribute *var[] = { \
|
||||
+ &var##Attrs[0], &var##Attrs[1], &var##Attrs[2], \
|
||||
+ &var##Attrs[3], NULL \
|
||||
+}
|
||||
+
|
||||
+/*!
|
||||
+ * Sets the complex property \a key with \a value. Use \a value = NULL to
|
||||
+ * remove the property, otherwise it will be replaced with the NULL
|
||||
+ * terminated array of attributes in \a value.
|
||||
+ *
|
||||
+ * A picture can be set with the TAGLIB_COMPLEX_PROPERTY_PICTURE macro:
|
||||
+ *
|
||||
+ * \code {.c}
|
||||
+ * TagLib_File *file = taglib_file_new("myfile.mp3");
|
||||
+ * FILE *fh = fopen("mypicture.jpg", "rb");
|
||||
+ * if(fh) {
|
||||
+ * fseek(fh, 0L, SEEK_END);
|
||||
+ * long size = ftell(fh);
|
||||
+ * fseek(fh, 0L, SEEK_SET);
|
||||
+ * char *data = (char *)malloc(size);
|
||||
+ * fread(data, size, 1, fh);
|
||||
+ * TAGLIB_COMPLEX_PROPERTY_PICTURE(props, data, size, "Written by TagLib",
|
||||
+ * "image/jpeg", "Front Cover");
|
||||
+ * taglib_complex_property_set(file, "PICTURE", props);
|
||||
+ * taglib_file_save(file);
|
||||
+ * free(data);
|
||||
+ * fclose(fh);
|
||||
+ * }
|
||||
+ * \endcode
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT BOOL taglib_complex_property_set(
|
||||
+ TagLib_File *file, const char *key,
|
||||
+ const TagLib_Complex_Property_Attribute **value);
|
||||
+
|
||||
+/*!
|
||||
+ * Appends \a value to the complex property \a key (sets it if non-existing).
|
||||
+ * Use \a value = NULL to remove all values associated with the \a key.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT BOOL taglib_complex_property_set_append(
|
||||
+ TagLib_File *file, const char *key,
|
||||
+ const TagLib_Complex_Property_Attribute **value);
|
||||
+
|
||||
+/*!
|
||||
+ * Get the keys of the complex properties.
|
||||
+ *
|
||||
+ * \return NULL terminated array of C-strings (char *), only NULL if empty.
|
||||
+ * It must be freed by the client using taglib_complex_property_free_keys().
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT char** taglib_complex_property_keys(const TagLib_File *file);
|
||||
+
|
||||
+/*!
|
||||
+ * Get value(s) of complex property \a key.
|
||||
+ *
|
||||
+ * \return NULL terminated array of property values, which are themselves an
|
||||
+ * array of property attributes, only NULL if empty.
|
||||
+ * It must be freed by the client using taglib_complex_property_free().
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT TagLib_Complex_Property_Attribute*** taglib_complex_property_get(
|
||||
+ const TagLib_File *file, const char *key);
|
||||
+
|
||||
+/*!
|
||||
+ * Extract the complex property values of a picture.
|
||||
+ *
|
||||
+ * This function can be used to get the data from a "PICTURE" complex property
|
||||
+ * without having to traverse the whole variant map. A picture can be
|
||||
+ * retrieved like this:
|
||||
+ *
|
||||
+ * \code {.c}
|
||||
+ * TagLib_File *file = taglib_file_new("myfile.mp3");
|
||||
+ * TagLib_Complex_Property_Attribute*** properties =
|
||||
+ * taglib_complex_property_get(file, "PICTURE");
|
||||
+ * TagLib_Complex_Property_Picture_Data picture;
|
||||
+ * taglib_picture_from_complex_property(properties, &picture);
|
||||
+ * // Do something with picture.mimeType, picture.description,
|
||||
+ * // picture.pictureType, picture.data, picture.size, e.g. extract it.
|
||||
+ * FILE *fh = fopen("mypicture.jpg", "wb");
|
||||
+ * if(fh) {
|
||||
+ * fwrite(picture.data, picture.size, 1, fh);
|
||||
+ * fclose(fh);
|
||||
+ * }
|
||||
+ * taglib_complex_property_free(properties);
|
||||
+ * \endcode
|
||||
+ *
|
||||
+ * Note that the data in \a picture contains pointers to data in \a properties,
|
||||
+ * i.e. it only lives as long as the properties, until they are freed with
|
||||
+ * taglib_complex_property_free().
|
||||
+ * If you want to access multiple pictures or additional properties of FLAC
|
||||
+ * pictures ("width", "height", "numColors", "colorDepth" int values), you
|
||||
+ * have to traverse the \a properties yourself.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_picture_from_complex_property(
|
||||
+ TagLib_Complex_Property_Attribute*** properties,
|
||||
+ TagLib_Complex_Property_Picture_Data *picture);
|
||||
+
|
||||
+/*!
|
||||
+ * Frees the NULL terminated array \a keys (as returned by
|
||||
+ * taglib_complex_property_keys()) and the C-strings it contains.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_complex_property_free_keys(char **keys);
|
||||
+
|
||||
+/*!
|
||||
+ * Frees the NULL terminated array \a props of property attribute arrays
|
||||
+ * (as returned by taglib_complex_property_get()) and the data such as
|
||||
+ * C-strings and byte vectors contained in these attributes.
|
||||
+ */
|
||||
+TAGLIB_C_EXPORT void taglib_complex_property_free(
|
||||
+ TagLib_Complex_Property_Attribute ***props);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
Loading…
Reference in New Issue
Block a user