ID3_Frame* id3::v2::setLyrics(ID3_TagImpl& tag, String text, String desc,
                              String lang)
{
  ID3_Frame* frame = NULL;
  // See if there is already a comment with this description
  for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
  {
    frame = *iter;
    if (frame == NULL)
    {
      continue;
    }
    if (frame->GetID() == ID3FID_COMMENT)
    {
      String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
      if (tmpDesc == desc)
      {
        break;
      }
    }
    frame = NULL;
  }
  if (frame == NULL)
  {
    frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS);
    if(!tag.AttachFrame(frame)) return NULL;
  }
  frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
  frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
  frame->GetField(ID3FN_TEXT)->Set(text.c_str());

  return frame;
}
Esempio n. 2
0
ID3_Frame *ID3_GetSyncLyrics(const ID3_Tag* tag, const char* lang,
                             const char* desc, const uchar* &pData, size_t& size)
{
    // check if a SYLT frame of this language or descriptor exists
    ID3_Frame* frmExist = NULL;
    if (NULL != lang)
    {
        // search through language
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang);
    }
    else if (NULL != desc)
    {
        // search through descriptor
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc);
    }
    else
    {
        // both language and description not specified, search the first SYLT frame
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS);
    }

    if (NULL == frmExist)
    {
        return NULL;
    }

    // get the lyrics size
    size = dami::min(size, frmExist->GetField(ID3FN_DATA)->Size());

    // get the lyrics data
    pData = frmExist->GetField (ID3FN_DATA)->GetRawBinary();

    // return the frame pointer for further uses
    return frmExist;
}
Esempio n. 3
0
//following routine courtesy of John George
size_t ID3_GetPictureDataOfPicType(ID3_Tag* tag, const char* TempPicPath, ID3_PictureType pictype)
{
    if (NULL == tag)
        return 0;
    else
    {
        ID3_Frame* frame = NULL;
        ID3_Tag::Iterator* iter = tag->CreateIterator();

        while (NULL != (frame = iter->GetNext() ))
        {
            if(frame->GetID() == ID3FID_PICTURE)
            {
                if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
                    break;
            }
        }
        delete iter;

        if (frame != NULL)
        {
            ID3_Field* myField = frame->GetField(ID3FN_DATA);
            if (myField != NULL)
            {
                myField->ToFile(TempPicPath);
                return (size_t)myField->Size();
            }
            else return 0;
        }
        else return 0;
    }
}
int main( int argc, char *argv[])
{
  ID3D_INIT_DOUT();
  ID3D_INIT_WARNING();
  ID3D_INIT_NOTICE();

  ID3_Tag tag;
  ID3_Frame frame;
  
  tag.Link("test-230-compressed.tag");
  tag.Strip(ID3TT_ALL);
  tag.Clear();
  
  frame.SetID(ID3FID_USERTEXT);
  frame.GetField(ID3FN_DESCRIPTION)->Set("compression example");
  frame.GetField(ID3FN_TEXT)->Set("This sample user text frame came from an ID3v2-3.0 tag.  The frame has the 'compression' bit set in it's frame header.  This is the new method for compressing frames, which supercedes the 2.01 Compressed Data Metaframe.");
  frame.SetCompression(true);
  tag.AddFrame(frame);
  
  tag.SetPadding(false);
  tag.SetUnsync(false);
  tag.Update(ID3TT_ID3V2);

  return 0;
}
Esempio n. 5
0
ID3_Frame* ID3_AddLyrics(ID3_Tag *tag, const char *text, const char* desc,
                         const char* lang, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag && strlen(text) > 0)
    {
        if (replace)
        {
            ID3_RemoveLyrics(tag);
        }
        if (replace || tag->Find(ID3FID_UNSYNCEDLYRICS) == NULL)
        {
            frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS);
            if (NULL != frame)
            {
                frame->GetField(ID3FN_LANGUAGE)->Set(lang);
                frame->GetField(ID3FN_DESCRIPTION)->Set(desc);
                frame->GetField(ID3FN_TEXT)->Set(text);
                tag->AttachFrame(frame);
            }
        }
    }

    return frame;
}
Esempio n. 6
0
ID3_Frame* ID3_AddComment(ID3_Tag *tag, const char *text,
                          const char *desc, const char* lang, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag  &&
            NULL != text &&
            NULL != desc &&
            strlen(text) > 0)
    {
        bool bAdd = true;
        if (replace)
        {
            ID3_RemoveComments(tag, desc);
        }
        else
        {
            // See if there is already a comment with this description
            ID3_Tag::Iterator* iter = tag->CreateIterator();
            ID3_Frame* frame = NULL;
            while ((frame = iter->GetNext()) != NULL)
            {
                if (frame->GetID() == ID3FID_COMMENT)
                {
                    char *tmp_desc = ID3_GetString(frame, ID3FN_DESCRIPTION);
                    if (strcmp(tmp_desc, desc) == 0)
                    {
                        bAdd = false;
                    }
                    delete [] tmp_desc;
                    if (!bAdd)
                    {
                        break;
                    }
                }
            }
            delete iter;
        }
        if (bAdd)
        {
            frame = new ID3_Frame(ID3FID_COMMENT);
            if (NULL != frame)
            {
                frame->GetField(ID3FN_LANGUAGE)->Set(lang);
                frame->GetField(ID3FN_DESCRIPTION)->Set(desc);
                frame->GetField(ID3FN_TEXT)->Set(text);
                tag->AttachFrame(frame);
            }
        }
    }
    return frame;
}
Esempio n. 7
0
//following routine courtesy of John George
size_t ID3_RemovePictureType(ID3_Tag* tag, ID3_PictureType pictype)
{
    size_t bremoved = 0;
    ID3_Frame* frame = NULL;

    if (NULL == tag)
        return bremoved;

    ID3_Tag::Iterator* iter = tag->CreateIterator();

    while (NULL != (frame = iter->GetNext()))
    {
        if (frame->GetID() == ID3FID_PICTURE)
        {
            if (frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
                break;
        }
    }
    delete iter;

    if (NULL != frame)
    {
        frame = tag->RemoveFrame(frame);
        delete frame;
        bremoved = 1;
    }
    return bremoved;
}
Esempio n. 8
0
//following routine courtesy of John George
char* ID3_GetDescriptionOfPicType(ID3_Tag* tag, ID3_PictureType pictype)
{
    char* sPicDescription = NULL;
    if (NULL == tag)
        return sPicDescription;

    ID3_Frame* frame = NULL;
    ID3_Tag::Iterator* iter = tag->CreateIterator();

    while (NULL != (frame = iter->GetNext()))
    {
        if(frame->GetID() == ID3FID_PICTURE)
        {
            if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
                break;
        }
    }
    delete iter;

    if (frame != NULL)
    {
        sPicDescription = ID3_GetString(frame, ID3FN_DESCRIPTION);
    }
    return sPicDescription;
}
Esempio n. 9
0
ID3_Frame* ID3_AddArtist(ID3_Tag *tag, const char *text, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag && NULL != text && strlen(text) > 0)
    {
        if (replace)
        {
            ID3_RemoveArtists(tag);
        }
        if (replace ||
                (tag->Find(ID3FID_LEADARTIST) == NULL &&
                 tag->Find(ID3FID_BAND)       == NULL &&
                 tag->Find(ID3FID_CONDUCTOR)  == NULL &&
                 tag->Find(ID3FID_COMPOSER)   == NULL))
        {
            frame = new ID3_Frame(ID3FID_LEADARTIST);
            if (frame)
            {
                frame->GetField(ID3FN_TEXT)->Set(text);
                tag->AttachFrame(frame);
            }
        }
    }
    return frame;
}
void
Genre_addGenre(ID3_Tag & id3, const char * genre) {

  ID3_Frame* frame = NULL;
  if (genre)
  {
    ID3_RemoveGenres(&id3);

    if (NULL == id3.Find(ID3FID_CONTENTTYPE))
    {
      frame = new ID3_Frame(ID3FID_CONTENTTYPE);
      if (NULL != frame)
      {
//        int g = Genre_getInt(genre);
//        char sGenre[100];
//        if (g > 0) {
//            sprintf(sGenre, "(%d)", g);
//        } else {
//            sprintf(sGenre, "%s", genre);
//        }
        frame->GetField(ID3FN_TEXT)->Set(genre);
        id3.AttachFrame(frame);
      }
    }
  }
  
  return;
}
Esempio n. 11
0
ID3_Frame* ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize,
                             ID3_TimeStampFormat format, const char *desc,
                             const char *lang, ID3_ContentType type,
                             bool replace)
{
    ID3_Frame* frame = NULL;
    // language and descriptor should be mandatory
    if ((NULL == lang) || (NULL == desc))
    {
        return NULL;
    }

    // check if a SYLT frame of this language or descriptor already exists
    ID3_Frame* frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang);
    if (!frmExist)
    {
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc);
    }

    if (NULL != tag && NULL != data)
    {
        if (replace && frmExist)
        {
            frmExist = tag->RemoveFrame (frmExist);
            delete frmExist;
            frmExist = NULL;
        }

        // if the frame still exist, cannot continue
        if (frmExist)
        {
            return NULL;
        }

        ID3_Frame* frame = new ID3_Frame(ID3FID_SYNCEDLYRICS);

        frame->GetField(ID3FN_LANGUAGE)->Set(lang);
        frame->GetField(ID3FN_DESCRIPTION)->Set(desc);
        frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format);
        frame->GetField(ID3FN_CONTENTTYPE)->Set(type);
        frame->GetField(ID3FN_DATA)->Set(data, datasize);
        tag->AttachFrame(frame);
    }

    return frame;
}
ID3_Frame* id3::v2::setComment(ID3_TagImpl& tag, String text, String desc,
                               String lang)
{
  ID3D_NOTICE( "id3::v2::setComment: trying to find frame with description = " << desc );
  ID3_Frame* frame = NULL;
  // See if there is already a comment with this description
  for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
  {
    frame = *iter;
    if (frame == NULL)
    {
      continue;
    }
    if (frame->GetID() == ID3FID_COMMENT)
    {
      String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
      if (tmpDesc == desc)
      {
        ID3D_NOTICE( "id3::v2::setComment: found frame with description = " << desc );
        break;
      }
    }
    frame = NULL;
  }
  if (frame == NULL)
  {
    ID3D_NOTICE( "id3::v2::setComment: creating new comment frame" );
    frame = new ID3_Frame(ID3FID_COMMENT);
    if(!tag.AttachFrame(frame)) return NULL;
  }
  if (!frame)
  {
    ID3D_WARNING( "id3::v2::setComment: ack! no frame" );
  }
  else
  {
    frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
    frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
    frame->GetField(ID3FN_TEXT)->Set(text.c_str());
  }

  return frame;
}
Esempio n. 13
0
//following routine courtesy of John George
ID3_Frame* ID3_AddPicture(ID3_Tag* tag, const char* TempPicPath, const char* MimeType, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag )
    {
        if (replace)
            ID3_RemovePictures(tag);
        if (replace || NULL == tag->Find(ID3FID_PICTURE))
        {
            frame = new ID3_Frame(ID3FID_PICTURE);
            if (NULL != frame)
            {
                frame->GetField(ID3FN_DATA)->FromFile(TempPicPath);
                frame->GetField(ID3FN_MIMETYPE)->Set(MimeType);
                tag->AttachFrame(frame);
            }
        }
    }
    return frame;
}
Esempio n. 14
0
int main( int argc, char *argv[])
{
  ID3_Tag tag;
  ID3_Frame frame;
  
  tag.Link("test-230-unicode.tag");
  tag.Strip(ID3TT_ALL);
  tag.Clear();
  
  frame.SetID(ID3FID_USERTEXT);
  frame.GetField(ID3FN_DESCRIPTION)->Set("example text frame");
  frame.GetField(ID3FN_TEXT)->Set("This text and the description should be in Unicode.");
  frame.GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE);
  tag.AddFrame(frame);
  
  tag.SetPadding(false);
  tag.SetUnsync(false);
  tag.Update(ID3TT_ID3V2);

  return 0;
}
ID3_Frame* id3::v2::setFrameText(ID3_TagImpl& tag, ID3_FrameID id, String text)
{
  ID3_Frame* frame = tag.Find(id);
  if (!frame)
  {
    frame = new ID3_Frame(id);
    if(!tag.AttachFrame(frame)) return NULL;
  }
  frame->GetField(ID3FN_TEXT)->Set(text.c_str());

  return frame;
}
BString id3::v2::getSyncLyrics(const ID3_TagImpl& tag, String lang, String desc)
{
  // check if a SYLT frame of this language or descriptor exists
  ID3_Frame* frame = NULL;
  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang.c_str())) ||
  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc.c_str())) ||
  (frame = tag.Find(ID3FID_SYNCEDLYRICS));

  // get the lyrics size
  ID3_Field* fld = frame->GetField(ID3FN_DATA);
  return BString(reinterpret_cast<const BString::value_type *>(fld->GetRawBinary()), fld->Size());
}
Esempio n. 17
0
ID3_Frame *ID3_GetSyncLyricsInfo(const ID3_Tag *tag, const char *desc,
                                 const char *lang,
                                 ID3_TimeStampFormat& format,
                                 ID3_ContentType& type, size_t& size)
{
    // check if a SYLT frame of this language or descriptor exists
    ID3_Frame* frmExist = NULL;
    if (NULL != lang)
    {
        // search through language
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang);
    }
    else if (NULL != desc)
    {
        // search through descriptor
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc);
    }
    else
    {
        // both language and description not specified, search the first SYLT frame
        frmExist = tag->Find(ID3FID_SYNCEDLYRICS);
    }

    if (!frmExist)
    {
        return NULL;
    }

    // get the lyrics time stamp format
    format = static_cast<ID3_TimeStampFormat>(frmExist->GetField(ID3FN_TIMESTAMPFORMAT)->Get ());

    // get the lyrics content type
    type = static_cast<ID3_ContentType>(frmExist->GetField(ID3FN_CONTENTTYPE)->Get ());

    // get the lyrics size
    size = frmExist->GetField (ID3FN_DATA)->Size ();

    // return the frame pointer for further uses
    return frmExist;
}
Esempio n. 18
0
//following routine courtesy of John George
ID3_Frame* ID3_AddPicture(ID3_Tag *tag, const char *TempPicPath, const char *MimeType, ID3_PictureType pictype, const char* Description, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag )
    {
        if (replace)
            ID3_RemovePictureType(tag, pictype);
        if (replace || NULL == tag->Find(ID3FID_PICTURE))
        {
            frame = new ID3_Frame(ID3FID_PICTURE);
            if (NULL != frame)
            {
                frame->GetField(ID3FN_DATA)->FromFile(TempPicPath);
                frame->GetField(ID3FN_MIMETYPE)->Set(MimeType);
                frame->GetField(ID3FN_PICTURETYPE)->Set((uint32)pictype);
                frame->GetField(ID3FN_DESCRIPTION)->Set(Description);
                tag->AttachFrame(frame);
            }
        }
    }
    return frame;
}
Esempio n. 19
0
void CID3LibWrapper::getFrameText( enum ID3_FrameID eFrameId, std::string& sVal ) const{

	ID3_Frame* pframe = myTag.Find(eFrameId);

	if(NULL != pframe){

		ID3_Field* pField = pframe->GetField(ID3FN_TEXT);
		
		if(NULL != pField){
			const_cast<CID3LibWrapper*>(this)->getFieldText(pField, sVal);
			//testFrame(pframe, pField);
		}
	}
}
ID3_Frame* id3::v2::setSyncLyrics(ID3_TagImpl& tag, BString data,
                                  ID3_TimeStampFormat format, String desc,
                                  String lang, ID3_ContentType type)
{
  ID3_Frame* frame = NULL;

  // check if a SYLT frame of this language or descriptor already exists
  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang.c_str())) ||
  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc.c_str()));

  if (!frame)
  {
    frame = new ID3_Frame(ID3FID_SYNCEDLYRICS);
    if(!tag.AttachFrame(frame)) return NULL;
  }
  frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
  frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
  frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format);
  frame->GetField(ID3FN_CONTENTTYPE)->Set(type);
  frame->GetField(ID3FN_DATA)->Set(data.data(), data.size());

  return frame;
}
Esempio n. 21
0
QString PlaybackControls::getComment(QString file)
{
	QString field;
	ID3_Tag mTag(file.toStdString().c_str());
	ID3_Frame* myFrame = mTag.Find(ID3FID_COMMENT);
	if (myFrame)
	{
		ID3_Field* myField = myFrame->GetField(ID3FN_TEXT);
		if (myField)
		{
			field = myField->GetRawText();
		}
	}
	return field;
}
Esempio n. 22
0
QPixmap PlaybackControls::getPicture(QString file)
{
	QPixmap field;
	ID3_Tag mTag(file.toStdString().c_str());
	ID3_Frame* myFrame = mTag.Find(ID3FID_PICTURE);
	if (myFrame)
	{
		ID3_Field* myField = myFrame->GetField(ID3FN_DATA);
		if (myField)
		{
			const uchar *test = myField->GetRawBinary();
			field.loadFromData(test, myField->Size());
		}
	}
	return field;
}
Esempio n. 23
0
//following routine courtesy of John George
bool ID3_HasPicture(const ID3_Tag* tag)
{
    if (NULL == tag)
        return false;
    else
    {
        ID3_Frame* frame = tag->Find(ID3FID_PICTURE);
        if (frame != NULL)
        {
            ID3_Field* myField = frame->GetField(ID3FN_DATA);
            if (myField != NULL)
                return true;
            else
                return false;
        }
        else return false;
    }
}
Esempio n. 24
0
//following routine courtesy of John George
int ID3_GetPictureData(const ID3_Tag *tag, const char *TempPicPath)
{
    if (NULL == tag)
        return 0;
    else
    {
        ID3_Frame* frame = NULL;
        frame = tag->Find(ID3FID_PICTURE);
        if (frame != NULL)
        {
            ID3_Field* myField = frame->GetField(ID3FN_DATA);
            if (myField != NULL)
            {
                myField->ToFile(TempPicPath);
                return (int)myField->Size();
            }
            else return 0;
        }
        else return 0;
    }
}
Esempio n. 25
0
ID3_Frame* ID3_AddLyricist(ID3_Tag *tag, const char *text, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag && NULL != text && strlen(text) > 0)
    {
        if (replace)
        {
            ID3_RemoveLyricist(tag);
        }
        if (replace || (tag->Find(ID3FID_LYRICIST) == NULL))
        {
            frame = new ID3_Frame(ID3FID_LYRICIST);
            if (frame)
            {
                frame->GetField(ID3FN_TEXT)->Set(text);
                tag->AttachFrame(frame);
            }
        }
    }

    return frame;
}
Esempio n. 26
0
ID3_Frame* ID3_AddYear(ID3_Tag *tag, const char *text, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag && NULL != text && strlen(text) > 0)
    {
        if (replace)
        {
            ID3_RemoveYears(tag);
        }
        if (replace || tag->Find(ID3FID_YEAR) == NULL)
        {
            frame = new ID3_Frame(ID3FID_YEAR);
            if (NULL != frame)
            {
                frame->GetField(ID3FN_TEXT)->Set(text);
                tag->AttachFrame(frame);
            }
        }
    }

    return frame;
}
Esempio n. 27
0
//following routine courtesy of John George
ID3_Frame* ID3_AddGenre(ID3_Tag* tag, const char* genre, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag && NULL != genre && strlen(genre) > 0)
    {
        if (replace)
        {
            ID3_RemoveGenres(tag);
        }
        if (replace || NULL == tag->Find(ID3FID_CONTENTTYPE))
        {
            frame = new ID3_Frame(ID3FID_CONTENTTYPE);
            if (NULL != frame)
            {
                frame->GetField(ID3FN_TEXT)->Set(genre);
                tag->AttachFrame(frame);
            }
        }
    }

    return frame;
}
Esempio n. 28
0
ID3_Frame* ID3_AddTrack(ID3_Tag *tag, uchar trk, uchar ttl, bool replace)
{
    ID3_Frame* frame = NULL;
    if (NULL != tag && trk > 0)
    {
        if (replace)
        {
            ID3_RemoveTracks(tag);
        }
        if (replace || NULL == tag->Find(ID3FID_TRACKNUM))
        {
            frame = new ID3_Frame(ID3FID_TRACKNUM);
            if (frame)
            {
                char *sTrack = NULL;
                if (0 == ttl)
                {
                    sTrack = new char[4];
                    sprintf(sTrack, "%lu", (luint) trk);
                }
                else
                {
                    sTrack = new char[8];
                    sprintf(sTrack, "%lu/%lu", (luint) trk, (luint) ttl);
                }

                frame->GetField(ID3FN_TEXT)->Set(sTrack);
                tag->AttachFrame(frame);

                delete [] sTrack;
            }
        }
    }

    return frame;
}
Esempio n. 29
0
bool mm::parse(ID3_TagImpl& tag, ID3_Reader& rdr)
{
  io::ExitTrigger et(rdr);
  ID3_Reader::pos_type end = rdr.getCur();
  if (end < rdr.getBeg() + 48)
  {
    ID3D_NOTICE( "mm::parse: bailing, not enough bytes to parse, pos = " << end );
    return false;
  }
  
  rdr.setCur(end - 48);
  String version;
  
  {
    if (io::readText(rdr, 32) != "Brava Software Inc.             ")
    {
      ID3D_NOTICE( "mm::parse: bailing, couldn't find footer" );
      return false;
    }
    
    version = io::readText(rdr, 4);
    if (version.size() != 4 || 
        !isdigit(version[0]) || version[1] != '.' ||
        !isdigit(version[2]) || 
        !isdigit(version[3]))
    {
      ID3D_WARNING( "mm::parse: bailing, nonstandard version = " << version );
      return false;
    }
  }
    
  ID3_Reader::pos_type beg = rdr.setCur(end - 48);
  et.setExitPos(beg);
  if (end < 68)
  {
    ID3D_NOTICE( "mm::parse: bailing, not enough bytes to parse offsets, pos = " << end );
    return false;
  }
  rdr.setCur(end - 68);
    
  io::WindowedReader dataWindow(rdr);
  dataWindow.setEnd(rdr.getCur());

  uint32 offsets[5];
    
  io::WindowedReader offsetWindow(rdr, 20);
  for (size_t i = 0; i < 5; ++i)
  {
    offsets[i] = io::readLENumber(rdr, sizeof(uint32));
  }

  size_t metadataSize = 0;
  if (version <= "3.00")
  {
    // All MusicMatch tags up to and including version 3.0 had metadata 
    // sections exactly 7868 bytes in length.
    metadataSize = 7868;
  }
  else
  {
    // MusicMatch tags after version 3.0 had three possible lengths for their
    // metadata sections.  We can determine which it was by searching for
    // the version section signature that should precede the metadata section
    // by exactly 256 bytes.
    size_t possibleSizes[] = { 8132, 8004, 7936 };
      
    for (size_t i = 0; i < sizeof(possibleSizes)/sizeof(size_t); ++i)
    {
      dataWindow.setCur(dataWindow.getEnd());
        
      // Our offset will be exactly 256 bytes prior to our potential metadata
      // section
      size_t offset = possibleSizes[i] + 256;
      if (dataWindow.getCur() < offset)
      {
        // if our filesize is less than the offset, then it can't possibly
        // be the correct offset, so try again.
        continue;
      }
      dataWindow.setCur(dataWindow.getCur() - offset);
        
      // now read in the signature to see if it's a match
      if (io::readText(dataWindow, 8) == "18273645")
      {
        metadataSize = possibleSizes[i];
        break;
      }
    }
  }
  if (0 == metadataSize)
  {
    // if we didn't establish a size for the metadata, then something is
    // wrong.  probably should log this.
    ID3D_WARNING( "mm::parse: bailing, couldn't find meta data signature, end = " << end );
    return false;
  }
    
  // parse the offset pointers to determine the actual sizes of all the 
  // sections
  size_t sectionSizes[5];
  size_t tagSize = metadataSize;
    
  // we already know the size of the last section
  sectionSizes[4] = metadataSize;
    
  size_t lastOffset = 0;
  for (int i = 0; i < 5; i++)
  {
    size_t thisOffset = offsets[i];
    //ASSERT(thisOffset > lastOffset);
    if (i > 0)
    {
      size_t sectionSize = thisOffset - lastOffset;
      sectionSizes[i-1] = sectionSize;
      tagSize += sectionSize;
    }
    lastOffset = thisOffset;
  }
    
  // now check to see that our tag size is reasonable
  if (dataWindow.getEnd() < tagSize)
  {
    // Ack!  The tag size doesn't jive with the tag's ending position in
    // the file.  Bail!
    ID3D_WARNING( "mm::parse: bailing, tag size is too big, tag size = " << tagSize << ", end = " << end );
    return false;
  }

  dataWindow.setBeg(dataWindow.getEnd() - tagSize);
  dataWindow.setCur(dataWindow.getBeg());
    
  // Now calculate the adjusted offsets
  offsets[0] = dataWindow.getBeg();
  for (size_t i = 0; i < 4; ++i)
  {
    offsets[i+1] = offsets[i] + sectionSizes[i];
  }
    
  // now check for a tag header and adjust the tag_beg pointer appropriately
  if (dataWindow.getBeg() >= 256)
  {
    rdr.setCur(dataWindow.getBeg() - 256);
    if (io::readText(rdr, 8) == "18273645")
    {
      et.setExitPos(rdr.getCur() - 8);
    }
    else
    {
      et.setExitPos(dataWindow.getBeg());
    }
    dataWindow.setCur(dataWindow.getBeg());
  }
    
  // Now parse the various sections...
    
  // Parse the image extension at offset 0
  dataWindow.setCur(offsets[0]);
  String imgExt = io::readTrailingSpaces(dataWindow, 4);
    
  // Parse the image binary at offset 1
  dataWindow.setCur(offsets[1]);
  uint32 imgSize = io::readLENumber(dataWindow, 4);
  if (imgSize == 0)
  {
    // no image binary.  don't do anything.
  }
  else
  {
    io::WindowedReader imgWindow(dataWindow, imgSize);
    if (imgWindow.getEnd() < imgWindow.getBeg() + imgSize)
    {
      // Ack!  The image size given extends beyond the next offset!  This is 
      // not good...  log?
    }
    else
    {
      BString imgData = io::readAllBinary(imgWindow);
      ID3_Frame* frame = new ID3_Frame(ID3FID_PICTURE);
      if (frame)
      {
        String mimetype("image/");
        mimetype += imgExt;
        frame->GetField(ID3FN_MIMETYPE)->Set(mimetype.c_str());
        frame->GetField(ID3FN_IMAGEFORMAT)->Set("");
        frame->GetField(ID3FN_PICTURETYPE)->Set(static_cast<unsigned int>(0));
        frame->GetField(ID3FN_DESCRIPTION)->Set("");
        frame->GetField(ID3FN_DATA)->Set(reinterpret_cast<const uchar*>(imgData.data()), imgData.size());
        tag.AttachFrame(frame);
      }
    }
  }
    
  //file.seekg(offsets[2]);
  //file.seekg(offsets[3]);
  dataWindow.setCur(offsets[4]);
    
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_TITLE));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_ALBUM));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_LEADARTIST));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_CONTENTTYPE));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Tempo"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Mood"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Situation"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Preference"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_SONGLEN));
    
  // The next 12 bytes can be ignored.  The first 8 represent the 
  // creation date as a 64 bit floating point number.  The last 4 are
  // for a play counter.
  dataWindow.skipChars(12);
    
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Path"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Serial"));
    
  // 2 bytes for track
  uint32 trkNum = io::readLENumber(dataWindow, 2);
  if (trkNum > 0)
  {
    String trkStr = toString(trkNum);
    ID3_Frame* frame = new ID3_Frame(ID3FID_TRACKNUM);
    if (frame)
    {
      frame->GetField(ID3FN_TEXT)->Set(trkStr.c_str());
      tag.AttachFrame(frame);
    }
  }
    
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Notes"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Bio"));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_UNSYNCEDLYRICS));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_WWWARTIST));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_WWWCOMMERCIALINFO));
  tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_ArtistEmail"));
    
  // email?

  return true;
}
Esempio n. 30
0
int main( int argc, char *argv[])
{
  ID3D_INIT_DOUT();
  ID3D_INIT_WARNING();
  ID3D_INIT_NOTICE();

  ID3_Tag tag;
  ID3_Frame frame;
  
  tag.Link("test-230-picture.tag");
  tag.Strip(ID3TT_ALL);
  tag.Clear();
  
  frame.SetID(ID3FID_TITLE);
  frame.GetField(ID3FN_TEXT)->Set("Aquarium");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_CONTENTGROUP);
  frame.GetField(ID3FN_TEXT)->Set("Short fraction of 'Carnival of the Animals: A Grand Zoological Fantasy'");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_COMPOSER);
  frame.GetField(ID3FN_TEXT)->Set("Camille Saint-Saëns");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_BAND);
  frame.GetField(ID3FN_TEXT)->Set("Slovakia Radio Symphony Orchestra");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_CONDUCTOR);
  frame.GetField(ID3FN_TEXT)->Set("Ondrej Lenárd");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_COPYRIGHT);
  frame.GetField(ID3FN_TEXT)->Set("1996 HNH international Ltd.");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_CONTENTTYPE);
  frame.GetField(ID3FN_TEXT)->Set("(32)");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_INVOLVEDPEOPLE);
  frame.GetField(ID3FN_TEXT)->Add("Producer");
  frame.GetField(ID3FN_TEXT)->Add("Martin Sauer");
  frame.GetField(ID3FN_TEXT)->Add("Piano");
  frame.GetField(ID3FN_TEXT)->Add("Peter Toperczer");
  tag.AddFrame(frame);
  
  frame.SetID(ID3FID_PICTURE);
  frame.GetField(ID3FN_MIMETYPE)->Set("image/jpeg");
  frame.GetField(ID3FN_PICTURETYPE)->Set(11);
  frame.GetField(ID3FN_DESCRIPTION)->Set("B/W picture of Saint-Saëns");
  frame.GetField(ID3FN_DATA)->FromFile("composer.jpg");
  tag.AddFrame(frame);
  
  tag.SetPadding(false);
  tag.SetUnsync(true);
  tag.Update(ID3TT_ID3V2);

  return 0;
}