Bug 100515

Summary: doesn't keep parsing after discarding deprecated frame
Product: [Frameworks and Libraries] taglib Reporter: Tom Kliethermes <thamus>
Component: generalAssignee: Scott Wheeler <wheeler>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Gentoo Packages   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Tom Kliethermes 2005-03-01 03:16:40 UTC
Version:           1.3.1 (using KDE KDE 3.3.2)
Installed from:    Gentoo Packages
Compiler:          gcc 3.3.5  
OS:                Linux

I have a lot of mp3s which taglib (used by amaroK) can't seem to read the TCON field.

Long story short, the files are from Emusic.com and they originally had the genre information in TIT1, which wasn't read by anything. So I used id3v2 ( http://id3v2.sourceforge.net/ ) to modify the TCON field to be the same as TIT1.

After that, amaroK was able to load the Genre information for some of them, but not the majority of files.  Something might have gone wrong (including operator error), but both id3v2 and id3info are able to read TCON from the files even when my taglib test program can't.

An example file is:
http://www.thamus.org/brokenTCON.gz
It's a gzip mp3 file (the provider doesn't like mp3s).

Let me know if you need other examples.

Here is the output from the various apps:

My test taglib app:
$ ./taglibtest 05-Triste\ Muy\ Triste.mp3
title: 'Triste Muy Triste '
artist: 'Banda De Musica Municipal '
album: 'Brassband From Cuba II '
comment: ''
genre: ''
year: '0'
track: '5'


$ id3info 05-Triste\ Muy\ Triste.mp3

*** Tag information for 05-Triste Muy Triste.mp3
=== TFLT (File type): MPG/3
=== TIT2 (Title/songname/content description): Triste Muy Triste
=== TPE1 (Lead performer(s)/Soloist(s)): Banda De Musica Municipal
=== TALB (Album/Movie/Show title): Brassband From Cuba II
=== TIT1 (Content group description): World: Cuba
=== TSIZ (Size): 1594955
=== TRCK (Track number/Position in set): 5
=== UFID (Unique file identifier): mailto:webmaster@vunetusa.com, 8 bytes
=== USER (Terms of use):  frame
=== TCON (Content type): World: Cuba
*** mp3 info
MPEG1/layer III
Bitrate: 128KBps
Frequency: 44KHz


$ id3v2 -l 05-Triste\ Muy\ Triste.mp3
id3v1 tag info for 05-Triste Muy Triste.mp3:
Title  : Triste Muy Triste               Artist: Banda De Musica Municipal
Album  : Brassband From Cuba II          Year:     , Genre: Unknown (255)
Comment:                                 Track: 5
id3v2 tag info for 05-Triste Muy Triste.mp3:
TFLT (File type): MPG/3
TIT2 (Title/songname/content description): Triste Muy Triste
TPE1 (Lead performer(s)/Soloist(s)): Banda De Musica Municipal
TALB (Album/Movie/Show title): Brassband From Cuba II
TIT1 (Content group description): World: Cuba
TSIZ (Size): 1594955
TRCK (Track number/Position in set): 5
UFID (Unique file identifier): mailto:webmaster@vunetusa.com, 8 bytes
USER (Terms of use):  frame
TCON (Content type): World: Cuba (255)
Comment 1 Scott Wheeler 2005-03-01 03:52:52 UTC
Actually this is happening after it hits the TSIZ frame which isn't supported in ID3v2.4.  The check to handle that case is a little broken.
Comment 2 Tom Kliethermes 2005-03-11 03:31:44 UTC
Sorry for not coming back sooner, I had some account/computer problems.  I removed the TSIZ from some files and taglib was able to read the genre info fine.  So, I went ahead and removed TSIZ from all the files since I don't need it and it look deprecated.
Comment 3 Scott Wheeler 2005-05-18 01:57:55 UTC
SVN commit 415248 by wheeler:

Instead of returning 0 on finding a deprecated frame type, create an
UnknownFrame and set the flag to discard it on write.

As a special bonus this meant implementing the discard-on-tag-alter
flag.

BUG:100515


 M  +5 -0      trunk/kdesupport/taglib/mpeg/id3v2/id3v2frame.cpp  
 M  +20 -1     trunk/kdesupport/taglib/mpeg/id3v2/id3v2frame.h  
 M  +2 -2      trunk/kdesupport/taglib/mpeg/id3v2/id3v2framefactory.cpp  
 M  +4 -2      trunk/kdesupport/taglib/mpeg/id3v2/id3v2tag.cpp  


--- trunk/kdesupport/taglib/mpeg/id3v2/id3v2frame.cpp #415247:415248
@@ -417,6 +417,11 @@
   return d->tagAlterPreservation;
 }
 
+void Frame::Header::setTagAlterPreservation(bool preserve)
+{
+  d->tagAlterPreservation = preserve;
+}
+
 bool Frame::Header::fileAlterPreservation() const
 {
   return d->fileAlterPreservation;
--- trunk/kdesupport/taglib/mpeg/id3v2/id3v2frame.h #415247:415248
@@ -29,6 +29,7 @@
 
   namespace ID3v2 {
 
+    class Tag;
     class FrameFactory;
 
     //! ID3v2 frame implementation
@@ -44,6 +45,7 @@
 
     class Frame
     {
+      friend class Tag;
       friend class FrameFactory;
 
     public:
@@ -295,11 +297,28 @@
       /*!
        * Returns true if the flag for tag alter preservation is set.
        *
-       * \note This flag is currently ignored internally in TagLib.
+       * The semantics are a little backwards from what would seem natural
+       * (setting the preservation flag to throw away the frame), but this
+       * follows the ID3v2 standard.
+       *
+       * \see setTagAlterPreservation()
        */
       bool tagAlterPreservation() const;
 
       /*!
+       * Sets the flag for preservation of this frame if the tag is set.  If
+       * this is set to true the frame will not be written when the tag is
+       * saved.
+       *
+       * The semantics are a little backwards from what would seem natural
+       * (setting the preservation flag to throw away the frame), but this
+       * follows the ID3v2 standard.
+       *
+       * \see tagAlterPreservation()
+       */
+      void setTagAlterPreservation(bool discard);
+
+      /*!
        * Returns true if the flag for file alter preservation is set.
        *
        * \note This flag is currently ignored internally in TagLib.
--- trunk/kdesupport/taglib/mpeg/id3v2/id3v2framefactory.cpp #415247:415248
@@ -99,8 +99,8 @@
   }
 
   if(!updateFrame(header)) {
-    delete header;
-    return 0;
+    header->setTagAlterPreservation(true);
+    return new UnknownFrame(data, header);
   }
 
   // updateFrame() might have updated the frame ID.
--- trunk/kdesupport/taglib/mpeg/id3v2/id3v2tag.cpp #415247:415248
@@ -343,8 +343,10 @@
 
   // Loop through the frames rendering them and adding them to the tagData.
 
-  for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++)
-    tagData.append((*it)->render());
+  for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) {
+    if(!(*it)->header()->tagAlterPreservation())
+      tagData.append((*it)->render());
+  }
 
   // Compute the amount of padding, and append that to tagData.