Git Product home page Git Product logo

taglib's Introduction

TagLib

Build Status

TagLib Audio Metadata Library

https://taglib.org/

TagLib is a library for reading and editing the metadata of several popular audio formats. Currently, it supports both ID3v1 and ID3v2 for MP3 files, Ogg Vorbis comments and ID3 tags in FLAC, MPC, Speex, WavPack, TrueAudio, WAV, AIFF, MP4, APE, ASF, DSF, DFF and AAC files.

TagLib is distributed under the GNU Lesser General Public License (LGPL) and Mozilla Public License (MPL). Essentially that means that it may be used in proprietary applications, but if changes are made to TagLib they must be contributed back to the project. Please review the licenses if you are considering using TagLib in your project.

taglib's People

Contributors

a17r avatar adriaandegroot avatar albertofustinoni avatar bobsayshilol avatar carewolf avatar chehrlic avatar chouquette avatar complexlogic avatar dbry avatar dfaure avatar evpobr avatar festushagen avatar franklai avatar g-coder avatar gogglesguy avatar gonemad avatar jefferai avatar lalinsky avatar montel avatar neheb avatar panzi avatar poiru avatar purinchu avatar ryanlucchese avatar sbooth avatar scotchi avatar supermihi avatar tsudakageyu avatar ufleisch avatar vinniefalco avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

taglib's Issues

Duplicate NOMINMAX

Hi all,
With the re-inclusion of RefCounterOld we have duplicate NOMINMAX defines in trefcounter.h and trefcounter.cpp causing many warnings on MinGW.

Wasn't sure which way to go so I'll leave it to those that know more then I.

I would pull it from the .cpp.

-Enjoy
fh : )_~

ID3 tags are always created in TagLib::MPEG::File initialization

During initialization the read function is called:

if(isOpen())
   read(readProperties, propertiesStyle);

In the end of read function both id3v1 and id2v2 are created

...
ID3v2Tag(true);
ID3v1Tag(true);
}

This makes impossible to inspect whether the file really has these id3 tags or not. As an implication, non-mpeg files can be damaged during id3 tags check and save.
Seems like the bug was introduced 5 years ago from now in this commit.

Please follow this question of StackOverflow.

ByteVector memory leaks

I'm seeing a lot of memory leaks from ByteVector. The problem seems to occur when a ByteVector is created from an existing ByteVector. The reference count of the backing data gets incremented twice: once in ByteVector::ByteVector(const ByteVector &v, uint offset, uint length) and then again in ByteVectorPrivate(ByteVectorPrivate *d, uint o, uint l).

Removing the ref() in the ByteVector constructor (line 511 in tbytevector.cpp) seems to fix the leaks for me. I'm not a c++ programmer though so I'd appreciate it if somebody more knowledgeable could take a look at this issue.

Thanks.

Trouble compiling taglib2 branch with libc++

I've recently checked out the taglib2 branch and I'm not able to compile it on Mac OS X using clang and libc++ (not the default C++ standard library) . It seems that CMAKE_CXX_FLAGS is ignored by check_cxx_source_compiles and so cmake wants to use tr1::shared_ptr which is available in the system's default C++ standard library but not in the one I'm specifying in the flags (-std=gnu++11 -stdlib=libc++). The end result is that taglib_config.h directs taglib to use the tr1 version of shared_ptr which doesn't exist in libc++:

In file included from /Volumes/Home/sbooth/Development/taglib/taglib/mpeg/mpegfile.cpp:26:
In file included from /Volumes/Home/sbooth/Development/taglib/taglib/tagunion.h:29:
In file included from /Volumes/Home/sbooth/Development/taglib/taglib/tag.h:30:
In file included from /Volumes/Home/sbooth/Development/taglib/taglib/toolkit/tstring.h:29:
In file included from /Volumes/Home/sbooth/Development/taglib/taglib/toolkit/tbytevector.h:31:
/Volumes/Home/sbooth/Development/taglib/taglib/toolkit/tsmartptr.h:34:11: fatal error: 'tr1/memory' file not found
# include <tr1/memory>
          ^
1 error generated.

Mageia's vlc crashes with some mp3s with taglib-1.9 (taglib-1.8 is fine)

Hi all,

Mageia Linux Cauldron x86-64's /usr/bin/vlc crashes/segfaults upon playing the following two .mp3s when taglib-1.9 is installed (it was upgraded today). After I downgraded to taglib-1.8 it can play them fine. I cannot reproduce the problem with a VLC compiled from source under ~/apps/vlc/bin .

offending mp3 1

offending mp3 2

Here is the stack trace:

shlomif@telaviv1:~$ gdb --command=cmds.gdb /usr/bin/vlc
GNU gdb (GDB) 7.6-5.mga4 (Mageia release 4)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-mageia-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/bin/vlc...Reading symbols from /usr/lib/debug/usr/bin/vlc.debug...done.
done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
VLC media player 2.1.0 Rincewind (revision 2.1.0-0-gedd8835)
[New Thread 0x7fffe63aa700 (LWP 32339)]
[0x61f9e8] pulse audio output error: PulseAudio server connection failure: Connection refused
[Thread 0x7fffe63aa700 (LWP 32339) exited]
[New Thread 0x7ffff7fc3700 (LWP 32340)]
[New Thread 0x7fffe5ba9700 (LWP 32341)]
[New Thread 0x7fffe1617700 (LWP 32342)]
[New Thread 0x7fffe04db700 (LWP 32343)]
[0x606058] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
[New Thread 0x7fffe01d7700 (LWP 32344)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe5ba9700 (LWP 32341)]
std::_Rb_tree_insert_and_rebalance (__insert_left=__insert_left@entry=false, 
    __x=__x@entry=0x7fffdcc11fe0, __p=__p@entry=0x7fffdcc119e0, __header=...)
    at ../../../../../libstdc++-v3/src/c++98/tree.cc:282
282         __root->_M_color = _S_black;
(gdb) bt
#0  std::_Rb_tree_insert_and_rebalance (
    __insert_left=__insert_left@entry=false, __x=__x@entry=0x7fffdcc11fe0, 
    __p=__p@entry=0x7fffdcc119e0, __header=...)
    at ../../../../../libstdc++-v3/src/c++98/tree.cc:282
#1  0x00007fffe44bedf5 in std::_Rb_tree<TagLib::ByteVector, std::pair<TagLib::ByteVector const, TagLib::List<TagLib::ID3v2::Frame*> >, std::_Select1st<std::pair<TagLib::ByteVector const, TagLib::List<TagLib::ID3v2::Frame*> > >, std::less<TagLib::ByteVector>, std::allocator<std::pair<TagLib::ByteVector const, TagLib::List<TagLib::ID3v2::Frame*> > > >::_M_insert_ (this=this@entry=0x7fffdcc11038, 
    __x=<optimized out>, __p=0x7fffdcc119e0, __v=...)
    at /usr/include/c++/4.8.2/bits/stl_tree.h:1025
#2  0x00007fffe44b9d24 in _M_insert_unique_ (__v=..., __position=..., 
    this=0x7fffdcc11038) at /usr/include/c++/4.8.2/bits/stl_tree.h:1482
#3  insert (__x=..., __position=..., this=0x7fffdcc11038)
    at /usr/include/c++/4.8.2/bits/stl_map.h:648
#4  operator[] (__k=..., this=0x7fffdcc11038)
    at /usr/include/c++/4.8.2/bits/stl_map.h:469
#5  operator[] (this=<optimized out>, key=...)
    at /usr/include/taglib/tmap.tcc:160
#6  ReadMetaFromId3v2 (tag=0x7fffdcc10ee0, 
    p_demux_meta=p_demux_meta@entry=0x7fffdcc04d48, 
    p_meta=p_meta@entry=0x7fffdcc113f0) at taglib.cpp:249
#7  0x00007fffe44bdd43 in ReadMeta (p_this=0x7fffdcc04d48) at taglib.cpp:657
#8  0x00007ffff71808a8 in module_load (obj=obj@entry=0x7fffdcc04d48, 
    m=m@entry=0x6e8090, init=init@entry=0x7ffff7180800 <generic_start>, 
    args=args@entry=0x7fffe5ba8cf0) at modules/modules.c:185
#9  0x00007ffff7180e5e in vlc_module_load (obj=obj@entry=0x7fffdcc04d48, 
    capability=capability@entry=0x7ffff71b8ce2 "meta reader", 
    name=0x7ffff71b7adb "", name@entry=0x0, strict=strict@entry=false, 
    probe=probe@entry=0x7ffff7180800 <generic_start>) at modules/modules.c:277
#10 0x00007ffff7181334 in module_need (obj=obj@entry=0x7fffdcc04d48, 
    cap=cap@entry=0x7ffff71b8ce2 "meta reader", name=name@entry=0x0, 
    strict=strict@entry=false) at modules/modules.c:366
#11 0x00007ffff714b821 in InputSourceMeta (p_meta=p_meta@entry=0x7fffdcc04c00, 
    p_source=<optimized out>, p_source=<optimized out>, p_input=0x7fffdc0009c8)
    at input/input.c:2699
#12 0x00007ffff714e31c in Init (p_input=p_input@entry=0x7fffdc0009c8)
    at input/input.c:1281
#13 0x00007ffff714f8e0 in input_Preparse (p_parent=p_parent@entry=0x82de08, 
    p_item=p_item@entry=0x63e000) at input/input.c:199
#14 0x00007ffff71307a0 in Preparse (p_item=0x63e000, obj=<optimized out>)
    at playlist/preparser.c:137
#15 Thread (data=0x82f320) at playlist/preparser.c:217
#16 0x00007ffff79adfab in start_thread (arg=0x7fffe5ba9700)
    at pthread_create.c:309
#17 0x00007ffff74db60d in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) 

I would appreciate any light that you can shed upon the problem.

Regards,

-- Shlomi Fish

'tfile.h' file not found - Xcode 4.5.2

I am using Xcode 4.5.2 on OSX 10.8.2

I downloaded the latest TagLib.framework and added the framework to my project.

If I am doing a simple (here I left out the brackets in the imports):

import TagLib/TagLib.h

import taglib/tag.h

import taglib/fileref.h

....
TagLib::FileRef f("test..mp3");

I get a compiler error:
.../taglib.framework/Headers/fileref.h:29:10: 'tfile.h' file not found

The framework files are sitting in .../Documents/XCode/Frameworks. I included the folder in the Header Search Path

Crash acessing tag->framListMap()["TPE2"]

As far as I can tell, the MP3 file in question has a perfectly valid id3v2 tag with a TPE2 frame in it (checked it out in a hex editor).

This is the exact line I'm crashing on:

TagLib::ID3v2::FrameList l = tag->frameListMap()["TPE2"];

Which is entered by the last line of this (the tag above is the first parameter):

if(fpath.endsWith("mp3"))
    {               
        TagLib::MPEG::File fr(fname, true, TagLib::AudioProperties::Fast);              
        if(fr.ID3v2Tag())
            extractID3v2Tag(fr.ID3v2Tag(), stmap);

I uploaded the problem-causing song for you:
https://www.wuala.com/Sushisource/pub/01-beach_fossils-clash_the_truth.mp3/?key=ZCXYHWmfwjtA

Literally while writing this bug I found the PropertyMap and the properties method which changes my life, looks like it was added since I last updated taglib. It works for me, but nonetheless I'm filing this because it seems like this should still work?

Anyways, thanks for the great library guys

TagLib::ulong is not always 32-bit wide

TagLib::ulong can be either 32-bit or 64-bit wide. However, some existing code seems to expect it is 32-bit.
In my opinion, we should ensure that TagLib::ulong is 32-bit wide, or abolish it and replace it with TagLib::uint.

MP3 chapter support

It would be really great, if you could support the ID3 chapter frame:
http://id3.org/id3v2-chapters-1.0
This makes it possible to use chapter marks in all mp3 files!

In the german podcasting scene this format is already used by many people and displayed by podcatchers on Androind (the open-source AntennaPod, https://github.com/danieloeh/AntennaPod) and iOS (e.g. the popular instacast http://vemedio.com/products/instacast).

It really makes sense for podcasts, audiobooks etc. - most of the time you have to provide an MP3 format (because all old cheap players support it) and with the ID3 chapter extension it's possible to add chapters too, which is especially useful for long podcasts.

We (http://auphonic.com) support these chapters too - if you need some code or audio examples, just let me know, I would be happy to send them to you!
We will maybe also build a simple tool, but I think these chapters should go into a major library, so that as many people as possible can use it!

Have a nice day,
LG
Georg

Request for discussion: unified picture interface

Hi,
I am thinking about implementing something similar to properties() / setProperties() for embedded cover art or other related pictures. Before starting to code I'd like to collect some opinions about the optimal interface for that.

The main problem seems to be that pictures are handled differently by different formats.

  • Apparently in both ID3v2 and FLAC each picture has a TYPE from a fixed enum AND an arbitrary string description.
  • For APE there are items of type "BINARY". Can they have both a key and a Stringlist of values as well? The class is not documented. Is there any convention of how to put cover art in APE? Binary items could be everything not only images ...
  • Similar problems in MP4: MP4::Item has "toCoverArtList()" but this probably does not work for all items!?

As for the interface, I imagine something like pictures() / setPictures() in analogy to the properties. What should the class returned from pictures() look like?

  • a "PictureList" of "Picture" objects, where a "Picture" is something with a type, (optional?) description, and actual picture (plus perhaps mime type, ...)
  • a "PictureMap", mapping picture type to (a list of?) picture(s) of that type. This might be overkill.

Then the question is of course how to deal with e.g. APE which does not know picture types. How should they be inferred?

Also some more implementation in the backends is needed which I'm afraid I cannot provide. For example, Ogg::Vorbis::File does not support pictures but according to http://wiki.xiph.org/VorbisComment#Cover_art pictures are actually supported in OGG.

mp4 tag not completely parsed

I have a m4a file whose 'covr' atom is not parsed by TagLib 1.8. This file is correctly processed by the Mac OS 10.8 Finder and the latest version of iTunes (no other OS / iTunes versions tested).

I can provide the file, I see no possibility to attach it here.

Corrupt wav chunk size (not subchunk size) causes crash

I have been having trouble reading tags on a wav file. I have since discovered that the file is corrupt, and the chunksize is bigger than the whole file size. I saw that you have made a fix in 1.8 for what I thought was this issue:-

https://bugs.kde.org/show_bug.cgi?id=283412

This is very close to my issue, but is not quite it. I think your fix is based on the subchunk1size being too large. My file has the chunk size from the RIFF chunk descriptor being too large.

I have tried to get VLC player to read the file and it crashes and my software crashes too.

Is there any way this file can just be marked as invalid and we move on...?

Suspicious code in id3v2frame.cpp

I found suspicious code at:
https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2frame.cpp#L395

static const TagLib::uint txxxFrameTranslationSize = 7;
static const char *txxxFrameTranslation[][2] = {
  { "MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
  { "MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
  { "MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
  { "MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
  { "MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
  { "Acoustid Id", "ACOUSTID_ID" },
  { "Acoustid Fingerprint", "ACOUSTID_FINGERPRINT" },
  { "MusicIP PUID", "MUSICIP_PUID" },
};

txxxFrameTranslationSize is smaller than the actual size of the array and "MusicIP PUID" is ignored. Is it an error or something intentional?

setProperties does not affect all MPEG-tags

If an MPEG file contains more than one tag (say ID3v2 and ID3v1), setProperties will only change one of them (the first of ID3v2, ID3v1, APE that is present).

This bug is in particular annoying together with the tag-duplicating in MPEG::File::save (see http://mail.kde.org/pipermail/taglib-devel/2012-July/002298.html): If a frame is deleted via setProperties, it will be restored from the unchanged ID3v1-tag.

But even without tag duplicating setProperties should change all available tags. The following patch will fix this. However, I'm not sure whether the return value is reasonable in all situations.

--- mpegfile.cpp    2012-12-06 00:02:32.639657076 +0100
+++ mpegfile_new.cpp    2012-12-06 00:02:26.120655903 +0100
@@ -156,16 +156,19 @@
   else if(d->hasID3v1)
     d->tag.access<ID3v1::Tag>(ID3v1Index, false)->removeUnsupportedProperties(properties);
 }
+
 PropertyMap MPEG::File::setProperties(const PropertyMap &properties)
 {
-  if(d->hasID3v2)
-    return d->tag.access<ID3v2::Tag>(ID3v2Index, false)->setProperties(properties);
-  else if(d->hasAPE)
-    return d->tag.access<APE::Tag>(APEIndex, false)->setProperties(properties);
-  else if(d->hasID3v1)
-    return d->tag.access<ID3v1::Tag>(ID3v1Index, false)->setProperties(properties);
-  else
-    return d->tag.access<ID3v2::Tag>(ID3v2Index, true)->setProperties(properties);
+  // Set properties in all available tags
+  PropertyMap result;
+  if (d->hasAPE)
+    result = d->tag.access<APE::Tag>(APEIndex, false)->setProperties(properties);
+  if (d->hasID3v1)
+    result = d->tag.access<ID3v1::Tag>(ID3v1Index, false)->setProperties(properties);
+  // If no tag is present at all, set properties in ID3v2 tag
+  if (d->hasID3v2 or (!d->hasAPE && !d->hasID3v1))
+    result = d->tag.access<ID3v2::Tag>(ID3v2Index, true)->setProperties(properties);
+  return result;
 }

 MPEG::Properties *MPEG::File::audioProperties() const

Newly acquired FreeBSD8.2 Errors

Heya all,

FreeBSD-8.2
taglib current master

Could someone please look into these recently acquired errors.
Still learning and I haven't got to templates yet so I'm lost.

The errors:
taglib/taglib/toolkit/tbytevector.cpp: In function 'T TagLib::toNumber(const TagLib::ByteVector&, size_t, bool) [with T = unsigned int]':
taglib/taglib/toolkit/tbytevector.cpp:805: instantiated from here
taglib/taglib/toolkit/tbytevector.cpp:303: error: no matching function for call to 'toNumber(const TagLib::ByteVector&, size_t&, unsigned int, bool&)'

taglib/taglib/toolkit/tbytevector.cpp: In function 'T TagLib::toNumber(const TagLib::ByteVector&, size_t, bool) [with T = short unsigned int]':
taglib/taglib/toolkit/tbytevector.cpp:820: instantiated from here
taglib/taglib/toolkit/tbytevector.cpp:303: error: no matching function for call to 'toNumber(const TagLib::ByteVector&, size_t&, unsigned int, bool&)'

taglib/taglib/toolkit/tbytevector.cpp: In function 'T TagLib::toNumber(const TagLib::ByteVector&, size_t, bool) [with T = long long unsigned int]':
taglib/taglib/toolkit/tbytevector.cpp:840: instantiated from here
taglib/taglib/toolkit/tbytevector.cpp:303: error: no matching function for call to 'toNumber(const TagLib::ByteVector&, size_t&, unsigned int, bool&)'

Thank you
Joe

ByteVector::replace() crash

The following causes a crash in ByteVector::replace()

int s = 16;
ByteVector frameData(s, char(0));
for (int i = 0; i < s; i+=2)
{
    frameData[i] = '\x00';
    frameData[i+1] = '\xFF';
}
ByteVector pattern(2, char(0));
pattern[0] = '\xFF';
pattern[1] = '\x00';

frameData.replace(pattern, '\xFF');

This seems to be the cause of real world crashes I'm seeing in TagLib::ID3v2::SynchData::decode() but I've not got my hands on a real file that causes it yet.

After poking about a bit it looks like the problem is due to ByteVector::replace() calling find() with an offset equal to (size() - 1) which results in findVector() reading past the end of the vector. I'm not sure if this should be fixed in findVector() or replace().

Note that I've turned on GuardMalloc on OS X to help track this down, without that it doesn't always crash but I presume valgrind or similar will also show it up.

MP4::Tag, can the frameListMap() function be made const?

Exactly as the title says. Syntactically, yes it can. But is there a reason that it isn't already? It seems to me it should follow suite of ID3v2::Tag's frameListMap() function.

The function in question is:

MP4::ItemListMap &
MP4::Tag::itemListMap()
{
  return d->items;
}

APEv2 tag 'Cover Art (Front)' reading result in segfault

Taglib crashes when reading any Musepack with cover art in the tag.

I discovered this one by using Amarok which in turns crashes because of this issue.

Tried with taglib 1.8 and latest master (2013-07-13)

test@test-VirtualBox:~/taglib/taglib/examples$ ./framelist /media/sf_VboxShared/test.mpc
* "/media/sf_VboxShared/test.mpc"*
ID3v2.4.0, 0 bytes in tag

ID3v1
title - ""
artist - ""
album - ""
year - "0"
comment - ""
track - "0"
genre - ""

APE
ALBUM - "Headlines and Deadlines: The Hits of a-ha"
ALBUM ARTIST - "a-ha"
ALBUMARTISTSORT - "a-ha"
ARTIST - "a-ha"
ARTISTSORT - "a-ha"
ASIN - "B000006SA5"
BARCODE - "075992677325"
CATALOGNUMBER - "7599-26773-2"
COMMENT - "1980s (Songs-DB_Custom1)"
Segmentation fault (core dumped)

TagLib occasionally corrupts M4A files?

http://forums.mp3tag.de/index.php?showtopic=17809

I was running some test code on Android. Resulting tag can still be read by TagLib, foobar2000, iTunes, and Windows Explorer, but the end of the audio stream is lost!

I am pretty sure all I did was add a short comment ("NEW Comm"), where there did not yet exist a comment:
jstring value = (jstring) env->GetObjectArrayElement(valueArray, i);
std::wstring wValue = Java_To_WStr(env, value);
audioFile.tag()->setComment(wValue);

I am sure this code did not run, but I use this for custom tags:
audioFile->tag()->itemListMap()[keyStr] = TagLib::StringList(wValue);

I have been trying to reproduce this bug but am having difficulty doing so. I repeated my steps and produced a correct file instead of a broken one. And strangely, when I compared the two files in HxD, I got "the chosen files are identical. the file sizes are different, though!"

I'm not sure where the problem may lie, and I guess I don't know enough about files - why would my hex editor tell me 2 files are identical when the filesizes are different? In Windows, the "size on disk" is identical (6,660,096 bytes) but the "size" differs (6,658,750 vs 6,659,042). Could this be a problem with TagLib, or is it more likely a problem with the storage system (Android device) I was running on?

I can provide the before and 2 after files to anyone who wants to investigate (I suppose I shouldn't post the links publicly).

mpcproperties.cpp: ambiguous call to log10

I cannot build 1.8Beta with MS Visual Studio 10. The compiler finds an error in mpcproperties.cpp in lines 282 and 285: The call to log10 is ambiguous.

The IDE finds two definitions of log10 in math.h:

  • long double log10(long double _X)
  • float log10(float _X)

It compiled after I added an implicit cast: d->trackPeak = (int)(log10((long double)d->trackPeak) * 20 * 256 + .5);
But then the linking failed due to 17 unresolved external symbols:

7> tagreader_c.c
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_file_free" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_free_strings" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_audioproperties_channels" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_audioproperties_samplerate" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_audioproperties_bitrate" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_audioproperties_length" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_genre" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_track" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_comment" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_year" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_album" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_artist" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_tag_title" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_file_audioproperties" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_file_tag" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_file_new" in Funktion "_main".
7>tagreader_c.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__taglib_set_strings_unicode" in Funktion "_main".
7>C:\Daten\Projekte\2011\dev\phatPlaylist\lib\taglib-1.8beta\examples\Release\tagreader_c.exe : fatal error LNK1120: 17 nicht aufgelöste externe Verweise.

Large image in an APE tag causes large memory allocations

Hi,

I am reporting an issue with parsing of APE tags. I am adding some pieces of code that I followed to find the problem.

Problem:
I have an MP3 file with ID3 and APE tags in it. The cover art is about 4MB. This is in APE and ID3 tag. When trying to play the file with VLC I get the following errors:

TagLib: String::prepare() - Unicode conversion error.

I also monitored the memory usage of VLC when playing this file and it went up to 500MB! Normally it is around 30MB when another MP3 file is being played with only ID3 tag (version not depended).

For normal PC, this is not a big issue as there is plenty of memory, but when playing the same file on embedded device, the player will eat app a lot of memory, which is very limited.

Possible issue:
I looked around the source code of TagLib and the problem occurred when doing the following:

TagLib::FileRef val(filename) (filename is the mp3 file)

This one will create a file with

FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle))

The create method will call

MPEG::File(fileName, readAudioProperties, audioPropertiesStyle);

The constructor will call

void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)

Inside this method findAPE() will be called and then a new APE tag will be created

d->tag.set(APEIndex, new APE::Tag(this, d->APEFooterLocation));

The constructor of the APE tag will call read method and this one will call parse(...)

parse(d->file->readBlock(d->footer.tagSize() - Footer::size()));

The parse method will loop until the condition is true

for(uint i = 0; i < d->footer.itemCount() && pos <= data.size() - 11; i++) {
APE::Item item;
item.parse(data.mid(pos));
d->itemListMap.insert(item.key().upper(), item);
pos += item.size();
}

The item.parse(...) will create strings with large sizes (same as the footer).

By looping multiple times, the d->itemListMap.insert(item.key().upper(), item); will grow a lot until the end of loop.

From the documentation I saw that APE tag should not be bigger that 8K. JPEG's are suggested to be put as links i.s.o in the tag.

As we know, users will not follow such rules. (ID3 tag could have 256MB of header).

Is it feasible to add a check on the size of the APE tag to not load APE tags bigger that 8K?

If the file is needed for debugging, please let me know. Or you can use MP3Tag program to attach a 5MB image to your MP3s and you will have the same problem.

Only the first instance of an MP4 Atom should be parsed

I previously wrote to the devel mailing list (MP4 atoms incorrectly showing as non-null empty strings (e.g., "aART" and "\251wrt" atoms).

It seems that some applications, when updating MP4 tags, will have a valid instance of "Atom A" early on in moov/udta/meta/ilst, but towards the end of the atom list, will include orphaned atoms including "Atom A" which have a data block of size 0. Many applications, including iTunes, foobar2000, and Mp3tag, do not acknowledge the existence of these nth atoms containing no data. But TagLib's parsing will overwrite the first atom with the last atom (empty).

Here's the patch I put into my 1.8 code mp4tag.cpp.

void
MP4::Tag::parseText(MP4::Atom *atom, TagLib::File *file, int expectedFlags)
{
...
if (d->items.contains(atom->name)) {
       // don't overwrite
    } else {
        d->items.insert(atom->name, value);
    }
...
}

I have only experienced this with Text atoms - I am unsure if the same patch needs to go into the other ParseX functions.

I have not made a pull request after all because I am using the 1.8 code, not the latest revision, which has changed mp4tag.cpp quite a bit.

Removing album art doesn't reduce filesize for most file formats

I tested MP3, MP4, and FLAC with a 4 MB jpeg. Removing art will cause TagLib and other programs to no longer see the embedded art, but the filesize remains at 4+ MB.

Only Ogg's filesize was reduced when art was removed:

TagLib::Ogg::Vorbis::File audioFile
TagLib::Ogg::XiphComment *tag = audioFile.tag();
tag->removeField("METADATA_BLOCK_PICTURE", TagLib::String::null);

(where the field was a base64 string)

It's possible I'm doing it wrong for MP3, MP4, and FLAC. Just to verify, this is the essentially what code I'm running to remove:

MP4:

tag->itemListMap().erase("covr");
audioFile.save();

MP3:

tag->removeFrames("APIC");
audioFile.save();

FLAC:

audioFile.removePictures();
audioFile.save();

Design flaw of ID3v2::Tag and ID3v2::FrameFactory

I found a flaw in design of ID3v2::Tag and ID3v2::FrameFactory.

The corresponding new and delete operations should be done in the same binary. Otherwise, a program might result in a crash. For example, in the case that we use a DLL compiled with MinGW and a EXE complied with MSVC.

Currently, ID3v2::FrameFactory and ID3v2::Tag creates ID3V2 frames and ID3v2::Tag deletes them. It's OK as long as we are using the default FrameFactory which is defined inside TagLib. However, if we implement our own frame factory, some new and delete operations will be done in different binaries.

I have no idea of how to straighten it out for now.

OGG and picture support (strange behavior)

Maybe I missed something...but I have successfully implemented mp3 and flac thanks to TagLib.

I created a OGG file with 2 covers (front and back) with the application mp3tag for testing. The problem is in XiphComment.cpp with the map which holds the fields. The covers are to METADATA_BLOCK_PICTURE fields...so while parsing, the first cover will be replaced with the next METADATA_BLOCK_PICTURE. If I collect the data from the fields I will only get the last and only cover (but there are 2 covers stored in the ogg). But this is a result of the map.

Is there a way like in FLAC to collect the pictures separately? Because of this situation I can't use the information...the ogg will possibly be corrupted if I save the ogg with new values (fields)?

I hope I could provide all information and sorry for my englisch ;)

Test fails without ZLIB but...

I found that the test TestID3v2::testCompressedFrameWithBrokenLength fails if ZLIB is not installed.
I think it's easy to fix this bug, but I have doubts whether HAVE_ZLIB switch is really needed. Is it really necessary?

TagLib latest does not build or work on Android for a while

I attempted to replace TagLib 1.8 with a newer revision and failed terribly. I'm using android-ndk-r8e-windows-x86_64

First of all, these are compile errors:
https://github.com/taglib/taglib/blob/master/taglib/toolkit/tbytevector.cpp#L216
https://github.com/taglib/taglib/blob/master/taglib/toolkit/tbytevector.cpp#L232

After replacing those "!=" with "=!", Unicode support (reading ID3v2.3) is broken and MP4 tags apparently can't be found at all. The example code (tagreader.cpp) for getting length which worked for 1.8, doesn't work with mp3, m4a, or ogg files on the latest revision either.

I didn't change any of my code which worked on TagLib 1.8.

A delete may go across binary boundaries

There is a delete operation in ID3v1::Tag::setStringHandler() function.
This operation is dangerous because it may go across binary boundaries and it may delete automatic variables.
I think that callers should delete handler if necessary, not this function.

Option to disable duplication between ID3v1 and ID3v2 tags

When an MP3 file is saved, nonexistent values are duplicated between ID3v1 and ID3v2 tags. This may be fine for some applications, however in the case of my project (Kid3), I have received reports of users (e.g. "I cannot delete the ID3v1 comment field") because they have a value set in the ID3v2 tag but want to delete it in the ID3v1 tag (and vice versa). I then try to explain them that this is a feature of TagLib and that I cannot do something about it. So could you please provide the possibility to disable this tag duplication?
Here is a patch which adds another overload to MPEG::File::save() with control over the tag duplication feature:

diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp
index c73da41..51cb578 100644
--- a/taglib/mpeg/mpegfile.cpp
+++ b/taglib/mpeg/mpegfile.cpp
@@ -187,6 +187,11 @@ bool MPEG::File::save(int tags, bool stripOthers)

 bool MPEG::File::save(int tags, bool stripOthers, int id3v2Version)
 {
+  return save(tags, stripOthers, id3v2Version, true);
+}
+
+bool MPEG::File::save(int tags, bool stripOthers, int id3v2Version, bool duplicateTags)
+{
   if(tags == NoTags && stripOthers)
     return strip(AllTags);

@@ -203,14 +208,19 @@ bool MPEG::File::save(int tags, bool stripOthers, int id3v2Version)
     return false;
   }

-  // Create the tags if we've been asked to.  Copy the values from the tag that
-  // does exist into the new tag, except if the existing tag is to be stripped.
+  // Create the tags if we've been asked to.

-  if((tags & ID3v2) && ID3v1Tag() && !(stripOthers && !(tags & ID3v1)))
-    Tag::duplicate(ID3v1Tag(), ID3v2Tag(true), false);
+  if (duplicateTags) {

-  if((tags & ID3v1) && d->tag[ID3v2Index] && !(stripOthers && !(tags & ID3v2)))
-    Tag::duplicate(ID3v2Tag(), ID3v1Tag(true), false);
+    // Copy the values from the tag that does exist into the new tag,
+    // except if the existing tag is to be stripped.
+
+    if((tags & ID3v2) && ID3v1Tag() && !(stripOthers && !(tags & ID3v1)))
+      Tag::duplicate(ID3v1Tag(), ID3v2Tag(true), false);
+
+    if((tags & ID3v1) && d->tag[ID3v2Index] && !(stripOthers && !(tags & ID3v2)))
+      Tag::duplicate(ID3v2Tag(), ID3v1Tag(true), false);
+  }

   bool success = true;

diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h
index 1d99898..0c81788 100644
--- a/taglib/mpeg/mpegfile.h
+++ b/taglib/mpeg/mpegfile.h
@@ -214,6 +214,24 @@ namespace TagLib {
       bool save(int tags, bool stripOthers, int id3v2Version);

       /*!
+       * Save the file.  This will attempt to save all of the tag types that are
+       * specified by OR-ing together TagTypes values.  The save() method above
+       * uses AllTags.  This returns true if saving was successful.
+       *
+       * If \a stripOthers is true this strips all tags not included in the mask,
+       * but does not modify them in memory, so later calls to save() which make
+       * use of these tags will remain valid.  This also strips empty tags.
+       *
+       * The \a id3v2Version parameter specifies the version of the saved
+       * ID3v2 tag. It can be either 4 or 3.
+       *
+       * If \a duplicateTags is true and at least one tag -- ID3v1 or ID3v2 --
+       * exists this will duplicate its content into the other tag.
+       */
+      // BIC: combine with the above method
+      bool save(int tags, bool stripOthers, int id3v2Version, bool duplicateTags);
+
+      /*!
        * Returns a pointer to the ID3v2 tag of the file.
        *
        * A tag will always be returned, regardless of whether there is a

Doubt about MPEG::File::setID3v2FrameFactory() method

Currently, MPEG::File (and some other classes) has setID3v2FrameFactory() method, but it looks meaningless.
The method modifies the ID3v2FrameFactory field, but it is only referred in read() method which is only called from the constructor.

I think that ID3v2FrameFactory takes effect only when reading a tag, so we can remove setID3v2FrameFactory() method.

TYER->TDRC conversion loses the TDAT frame (month and date) for ID3v2.3 files

TagLib::MPEG::File audioFile(szFilepath);

     TagLib::ID3v2::Tag *id3v2 = audioFile.ID3v2Tag(false);
     if (id3v2 && !id3v2->isEmpty())
     { 
        if ( !id3v2->frameListMap()["TYER"].isEmpty()
                && !id3v2->frameListMap()["TDAT"].isEmpty())
        {
            // never true
        }
        else if ( !id3v2->frameListMap()["TYER"].isEmpty() )
        {
            // never true
        }
        else if ( !id3v2->frameListMap()["TDRC"].isEmpty() )
        {
            // ignores TDAT, losing the month and date
        }
        else {
            // no TYER present in mp3 file
        }
     }

There is no way to get the month and date from MP3 tags unless the information has been stored in a different frame such as TDRL.

As stated by Lukas in the 1st comment, TDAT should not be ignored.

[1.8] TagLib::Tag generic returns are inconsistent in handling multi-value tags

I have created a set of test files containing the same metadata (tagged by Mp3tag). I put 3 Artist tags and 2 Composer tags. The composer tags must be retrieved by format-specific code and this seems to work. The artist tags, when retrieved by the generic code, is inconsistent.

 TagLib::FileRef f(szFilepath);
    if(!f.isNull() && f.tag())
    {
      TagLib::Tag *tag = f.tag();
            print(tag->artist()));
    }

ID3v2.4 returns all 3 values joined by spaces.
Ogg/Flac XiphComments only returns the 1st value.

A related but different issue is that ID3v2's namespace makes it harder to quickly handle multivalue tags (relative to XiphComments) because its map entry uses a "FrameList" (List< Frame * >) instead of StringList, so there is no StringList.toString("join all values using this string as a delimiting marker") function to grab all values in one line of code.

taglib leads to corrupted characters in mp3 files when using special characters (e.g. äÄöÖüÜß)

There seems to be a bug when reading and/or writing Id3 tags in mp3-files
with taglib based applications, like e.g. Kid3, Amarok,... This is when dealing
with special characters like the German Umlauts (äÄöÖüÜß) in the tag fields.
I don't know if this is distribution specific. I also put in a bug report for openSuse 12.3, my favorite distribution. Take a look:
https://bugzilla.novell.com/show_bug.cgi?id=814814#c0

I made a little screencast about the steps to reproduce (please
adjust quality level to see details):
http://youtu.be/XoAW1zmgSKA

Tested on openSuse 12.3 (x86-64), Kernel 3.7.10-1.1-Desktop, KDE 4.10.2.
taglib and libtag* v1.8-3.2.1 (OSS Repo)
Also tested with:
taglib and libtag* v1.8.55-7 (multimedia:lib Repo)

This setup leads into corrupted tag-fields when dealing with special
characters. I only tested with mp3-files. Don't know if other files formats are affected.
When using id3lib (ID3v2.3) applications, everything is fine, even with German special characters.

Can someone confirm or help?

FLAC metadata blocks with 0 length invalidate the file

Commit ad9ffc6 added the behavior where FLAC metadata blocks with a length of 0 cause the file to be marked as invalid. I've received numerous reports from users with FLACs purchased/downloaded from third party websites that their tags are no longer showing up. Specifically, it seems WaveLab is creating seektables with a length of 0 causing tag parsing to fail. A 0 length seektable does not conform to the FLAC spec, however metaflac handles the files correctly and I believe the behavior might be a bit too strict.

Line breaks in MP4 Tags are not handled in ByteVector to String conversion

When MP4 tags are parsed to Strings, line breaks are not included. This is because line breaks are marked by 0x0d, but for String conversion to include a line break, this character should be replaced by 0x0a. (This is relevant to the "\251lyr" atom written by iTunes.)

I have patched it in my local code by throwing this into the parseData2 function in mp4tag.cpp:

if(expectedFlags == -1 || flags == expectedFlags) {
          ByteVector tempdata = (data.mid(pos + 16, length - 16)).replace(ByteVector((char)0x0d),ByteVector((char)0x0a));
          result.append(AtomData(AtomDataType(flags), tempdata));
          tempdata.clear();
}

However, I am not sure if this causes a memory leak down the line. I hope someone (Lukas?) with more knowledge of the relevant code can write a better fix.

Crash when saving xm files

When I change the tags of an XM module and save the file, TagLib crashes. The bug is in xmfile.cpp:

    if(i > lines.size())
      writeString(String::null, len);
    else
      writeString(lines[i], len);

The index i to the StringList lines must be between 0 and lines.size() - 1. Here, lines[i] will be executed event if i == lines.size(), which is out of bounds. The code must be fixed to "i >= lines.size()". Here is a patch:

diff -ru taglib-1.8.orig/taglib/xm/xmfile.cpp taglib-1.8/taglib/xm/xmfile.cpp
--- taglib-1.8.orig/taglib/xm/xmfile.cpp    2012-09-06 20:03:15.000000000 +0200
+++ taglib-1.8/taglib/xm/xmfile.cpp 2012-09-22 08:55:07.052052207 +0200
@@ -443,7 +443,7 @@
       return false;

     uint len = std::min(22UL, instrumentHeaderSize - 4U);
-    if(i > lines.size())
+    if(i >= lines.size())
       writeString(String::null, len);
     else
       writeString(lines[i], len);

Invalid returns from firstFrameOffset() and lastFrameOffset() on MPEG files

Hello,

I am trying to get only the MPEG frames from a file (so only the audio stream, without tags) with TagLib but I had some issues with the values returned by firstFrameOffset() and lastFrameOffset().

So I built a test which basically print these values for a bunch of files containing each case of tag for the same audio stream (I only used Mp3tag for deleting specific tag types).
"ape-id3v2.mp3" means that the file has APE tag and ID3v2 but not ID3v1

The output order is :
fileName;
firstFrameOffset
lastFrameOffset
fileSize

And here is the result :

"ape-id3v1-id3v2.mp3"
2190
39806
40519

"ape-id3v1.mp3"
62
37616
38329

"ape-id3v2.mp3"
2190
-1
40391

"ape.mp3"
62
-1
38201

"id3v1-id3v2.mp3"
2190
39806
40352

"id3v1.mp3"
62
37616
38162

"id3v2.mp3"
2190
-1
40224

"none.mp3"
62
-1
38034

As you can see, there is some issues :

  • With no ID3v1 tag -> lastFrameOffset() always returns -1
  • With no ID3v2 tag -> firstFrameOffset() don't point to the beginning of the file but to the second frame

You can find my mp3s test files here : http://serv.v445.net/files/taglib-testfiles.zip

Adding Images Permanently Increases File Size Even After Removing The Frame

I discovered a song corrupting related issue when you add pictures to the ID3 tag. I added a 10 MB picture to a song and saved it. I noticed 10 MB size increase to the song (as expected). I then deleted the picture by setting the Taglib.File.Tag.Pictures to nothing. The file size stayed at 10 MB bigger than it originally was even though it could not find a picture when the program loaded. I thought the picture was still there, but could not be read. So I tried multiple different ID3 readers (even ones that show raw data) and I could not find the picture in this song.

This means any program that uses this library to add pictures will become permanently bigger. Please help me on this one! I am not sure if it is because of padding or if it is a glitch with your library

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.