00001 #include <set>
00002
00003
00004 #include <QBuffer>
00005
00006
00007 #include <mythlogging.h>
00008
00009
00010 #include <flacfile.h>
00011 #include <mpegfile.h>
00012
00013
00014 #include "metaioid3.h"
00015 #include "musicmetadata.h"
00016 #include "musicutils.h"
00017
00018 const String email = "music@mythtv.org";
00019
00020 MetaIOID3::MetaIOID3(void)
00021 : MetaIOTagLib(),
00022 m_file(NULL), m_fileType(kMPEG)
00023 {
00024 }
00025
00026 MetaIOID3::~MetaIOID3(void)
00027 {
00028 CloseFile();
00029 }
00030
00037 bool MetaIOID3::OpenFile(const QString &filename, bool forWriting)
00038 {
00039
00040 if (m_file && (m_filename == filename) &&
00041 (!forWriting || !m_file->readOnly()))
00042 return true;
00043
00044 if (m_file)
00045 {
00046 LOG(VB_FILE, LOG_DEBUG,
00047 QString("MetaIO switch file: %1 New File: %2 Type: %3")
00048 .arg(m_filename)
00049 .arg(filename)
00050 .arg(m_fileType));
00051 }
00052
00053
00054 if (m_file)
00055 CloseFile();
00056
00057 m_filename = filename;
00058
00059 QString extension = m_filename.section('.', -1);
00060
00061 if (extension.toLower() == "flac")
00062 m_fileType = kFLAC;
00063 else if (extension.toLower() == "mp3")
00064 m_fileType = kMPEG;
00065 else
00066 return false;
00067
00068 QByteArray fname = m_filename.toLocal8Bit();
00069
00070 switch (m_fileType)
00071 {
00072 case kMPEG :
00073 m_file = new TagLib::MPEG::File(fname.constData());
00074 break;
00075 case kFLAC :
00076 m_file = new TagLib::FLAC::File(fname.constData());
00077 break;
00078 }
00079
00080
00081 if (!m_file->isOpen() || (forWriting && m_file->readOnly()))
00082 {
00083 if (m_file->isOpen())
00084 LOG(VB_FILE, LOG_NOTICE,
00085 QString("Could not open file for writing: %1").arg(m_filename));
00086 else
00087 LOG(VB_FILE, LOG_ERR,
00088 QString("Could not open file: %1").arg(m_filename));
00089
00090 CloseFile();
00091 return false;
00092 }
00093
00094 return true;
00095 }
00096
00097 bool MetaIOID3::SaveFile()
00098 {
00099 if (!m_file)
00100 return false;
00101
00102 bool retval = m_file->save();
00103
00104 return retval;
00105 }
00106
00107 void MetaIOID3::CloseFile()
00108 {
00109 LOG(VB_FILE, LOG_DEBUG, QString("MetaIO Close file: %1") .arg(m_filename));
00110 delete m_file;
00111 m_file = NULL;
00112 m_fileType = kMPEG;
00113 m_filename.clear();
00114 }
00115
00116 TagLib::ID3v2::Tag* MetaIOID3::GetID3v2Tag(bool create)
00117 {
00118 if (!m_file)
00119 return NULL;
00120
00121 TagLib::ID3v2::Tag *tag = NULL;
00122 switch (m_fileType)
00123 {
00124 case kMPEG :
00125 tag = (static_cast<TagLib::MPEG::File*>(m_file))->ID3v2Tag(create);
00126 break;
00127 case kFLAC :
00128 tag = (static_cast<TagLib::FLAC::File*>(m_file))->ID3v2Tag(create);
00129 break;
00130 }
00131
00132 return tag;
00133 }
00134
00135 TagLib::ID3v1::Tag* MetaIOID3::GetID3v1Tag(bool create)
00136 {
00137 if (!m_file)
00138 return NULL;
00139
00140 TagLib::ID3v1::Tag *tag = NULL;
00141 switch (m_fileType)
00142 {
00143 case kMPEG :
00144 tag = (static_cast<TagLib::MPEG::File*>(m_file))->ID3v1Tag(create);
00145 break;
00146 case kFLAC :
00147
00148 break;
00149 }
00150
00151 return tag;
00152 }
00153
00157 bool MetaIOID3::write(const MusicMetadata* mdata)
00158 {
00159 if (!OpenFile(mdata->Filename(), true))
00160 return false;
00161
00162 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00163
00164 if (!tag)
00165 return false;
00166
00167 WriteGenericMetadata(tag, mdata);
00168
00169
00170 writeRating(tag, mdata->Rating());
00171 writePlayCount(tag, mdata->PlayCount());
00172
00173
00174 UserTextIdentificationFrame *musicbrainz = NULL;
00175 musicbrainz = find(tag, "MusicBrainz Album Artist Id");
00176
00177 if (mdata->Compilation())
00178 {
00179
00180 if (!musicbrainz)
00181 {
00182 musicbrainz = new UserTextIdentificationFrame(TagLib::String::UTF8);
00183 tag->addFrame(musicbrainz);
00184 musicbrainz->setDescription("MusicBrainz Album Artist Id");
00185 }
00186
00187 musicbrainz->setText(MYTH_MUSICBRAINZ_ALBUMARTIST_UUID);
00188 }
00189 else if (musicbrainz)
00190 tag->removeFrame(musicbrainz);
00191
00192
00193 if (!mdata->CompilationArtist().isEmpty())
00194 {
00195 TextIdentificationFrame *tpe4frame = NULL;
00196 TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
00197 if (!tpelist.isEmpty())
00198 tpe4frame = (TextIdentificationFrame *)tpelist.front();
00199
00200 if (!tpe4frame)
00201 {
00202 tpe4frame = new TextIdentificationFrame(TagLib::ByteVector("TPE4"),
00203 TagLib::String::UTF8);
00204 tag->addFrame(tpe4frame);
00205 }
00206 tpe4frame->setText(QStringToTString(mdata->CompilationArtist()));
00207
00208
00209 TextIdentificationFrame *tpe2frame = NULL;
00210 tpelist = tag->frameListMap()["TPE2"];
00211 if (!tpelist.isEmpty())
00212 tpe2frame = (TextIdentificationFrame *)tpelist.front();
00213
00214 if (!tpe2frame)
00215 {
00216 tpe2frame = new TextIdentificationFrame(TagLib::ByteVector("TPE2"),
00217 TagLib::String::UTF8);
00218 tag->addFrame(tpe2frame);
00219 }
00220 tpe2frame->setText(QStringToTString(mdata->CompilationArtist()));
00221 }
00222
00223 if (!SaveFile())
00224 return false;
00225
00226 return true;
00227 }
00228
00232 MusicMetadata *MetaIOID3::read(const QString &filename)
00233 {
00234 if (!OpenFile(filename))
00235 return NULL;
00236
00237 TagLib::ID3v2::Tag *tag = GetID3v2Tag(true);
00238
00239
00240
00241 if (tag->isEmpty())
00242 {
00243 TagLib::ID3v1::Tag *tag_v1 = GetID3v1Tag();
00244
00245 if (!tag_v1)
00246 return NULL;
00247
00248 if (!tag_v1->isEmpty())
00249 {
00250 tag->setTitle(tag_v1->title());
00251 tag->setArtist(tag_v1->artist());
00252 tag->setAlbum(tag_v1->album());
00253 tag->setTrack(tag_v1->track());
00254 tag->setYear(tag_v1->year());
00255 tag->setGenre(tag_v1->genre());
00256 }
00257 }
00258
00259 MusicMetadata *metadata = new MusicMetadata(filename);
00260
00261 ReadGenericMetadata(tag, metadata);
00262
00263 bool compilation = false;
00264
00265
00266
00267
00268
00269 TextIdentificationFrame *tpeframe = NULL;
00270 TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
00271 if (tpelist.isEmpty() || tpelist.front()->toString().isEmpty())
00272 tpelist = tag->frameListMap()["TPE2"];
00273 if (!tpelist.isEmpty())
00274 tpeframe = (TextIdentificationFrame *)tpelist.front();
00275
00276 if (tpeframe && !tpeframe->toString().isEmpty())
00277 {
00278 QString compilation_artist = TStringToQString(tpeframe->toString())
00279 .trimmed();
00280 metadata->setCompilationArtist(compilation_artist);
00281 }
00282
00283
00284 PopularimeterFrame *popm = findPOPM(tag, email);
00285
00286 if (!popm)
00287 {
00288 if (!tag->frameListMap()["POPM"].isEmpty())
00289 popm = dynamic_cast<PopularimeterFrame *>
00290 (tag->frameListMap()["POPM"].front());
00291 }
00292
00293 if (popm)
00294 {
00295 int rating = popm->rating();
00296 rating = static_cast<int>(((static_cast<float>(rating)/255.0)
00297 * 10.0) + 0.5);
00298 metadata->setRating(rating);
00299 metadata->setPlaycount(popm->counter());
00300 }
00301
00302
00303 UserTextIdentificationFrame *musicbrainz = find(tag,
00304 "MusicBrainz Album Artist Id");
00305
00306 if (musicbrainz)
00307 {
00308
00309
00310 if (!compilation && !musicbrainz->fieldList().isEmpty())
00311 compilation = (MYTH_MUSICBRAINZ_ALBUMARTIST_UUID
00312 == TStringToQString(musicbrainz->fieldList().front()));
00313 }
00314
00315
00316
00317
00318
00319
00320 if (!tag->frameListMap()["TLEN"].isEmpty())
00321 {
00322 int length = tag->frameListMap()["TLEN"].front()->toString().toInt();
00323 LOG(VB_FILE, LOG_DEBUG,
00324 QString("MetaIOID3::read: Length for '%1' from tag is '%2'\n").arg(filename).arg(length));
00325 }
00326
00327 metadata->setCompilation(compilation);
00328
00329 metadata->setLength(getTrackLength(m_file));
00330
00331
00332 if (!tag->frameListMap()["TRCK"].isEmpty())
00333 {
00334 QString trackFrame = TStringToQString(
00335 tag->frameListMap()["TRCK"].front()->toString())
00336 .trimmed();
00337 int trackCount = trackFrame.section('/', -1).toInt();
00338 if (trackCount > 0)
00339 metadata->setTrackCount(trackCount);
00340 }
00341
00342 LOG(VB_FILE, LOG_DEBUG,
00343 QString("MetaIOID3::read: Length for '%1' from properties is '%2'\n").arg(filename).arg(metadata->Length()));
00344
00345 return metadata;
00346 }
00347
00355 QImage* MetaIOID3::getAlbumArt(const QString &filename, ImageType type)
00356 {
00357 QImage *picture = new QImage();
00358
00359 AttachedPictureFrame::Type apicType
00360 = AttachedPictureFrame::FrontCover;
00361
00362 switch (type)
00363 {
00364 case IT_UNKNOWN :
00365 apicType = AttachedPictureFrame::Other;
00366 break;
00367 case IT_FRONTCOVER :
00368 apicType = AttachedPictureFrame::FrontCover;
00369 break;
00370 case IT_BACKCOVER :
00371 apicType = AttachedPictureFrame::BackCover;
00372 break;
00373 case IT_CD :
00374 apicType = AttachedPictureFrame::Media;
00375 break;
00376 case IT_INLAY :
00377 apicType = AttachedPictureFrame::LeafletPage;
00378 break;
00379 case IT_ARTIST :
00380 apicType = AttachedPictureFrame::Artist;
00381 break;
00382 default:
00383 return picture;
00384 }
00385
00386 if (OpenFile(filename))
00387 {
00388 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00389 if (tag && !tag->frameListMap()["APIC"].isEmpty())
00390 {
00391 TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"];
00392
00393 for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
00394 it != apicframes.end(); ++it)
00395 {
00396 AttachedPictureFrame *frame =
00397 static_cast<AttachedPictureFrame *>(*it);
00398 if (frame && frame->type() == apicType)
00399 {
00400 picture->loadFromData((const uchar *)frame->picture().data(),
00401 frame->picture().size());
00402 return picture;
00403 }
00404 }
00405 }
00406 }
00407
00408 delete picture;
00409
00410 return NULL;
00411 }
00412
00413
00419 AlbumArtList MetaIOID3::getAlbumArtList(const QString &filename)
00420 {
00421 AlbumArtList imageList;
00422 if (OpenFile(filename))
00423 {
00424 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00425
00426 if (!tag)
00427 return imageList;
00428
00429 imageList = readAlbumArt(tag);
00430 }
00431
00432 return imageList;
00433 }
00434
00442 AlbumArtList MetaIOID3::readAlbumArt(TagLib::ID3v2::Tag *tag)
00443 {
00444 AlbumArtList artlist;
00445
00446 if (!tag->frameListMap()["APIC"].isEmpty())
00447 {
00448 TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"];
00449
00450 for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
00451 it != apicframes.end(); ++it)
00452 {
00453
00454 AttachedPictureFrame *frame =
00455 static_cast<AttachedPictureFrame *>(*it);
00456
00457
00458
00459 if (frame->picture().size() < 100)
00460 {
00461 LOG(VB_GENERAL, LOG_NOTICE,
00462 "Music Scanner - Discarding APIC frame "
00463 "with size less than 100 bytes");
00464 continue;
00465 }
00466
00467 AlbumArtImage *art = new AlbumArtImage();
00468
00469 if (frame->description().isEmpty())
00470 art->description.clear();
00471 else
00472 art->description = TStringToQString(frame->description());
00473
00474 art->embedded = true;
00475
00476 QString ext = getExtFromMimeType(
00477 TStringToQString(frame->mimeType()).toLower());
00478
00479 switch (frame->type())
00480 {
00481 case AttachedPictureFrame::FrontCover :
00482 art->imageType = IT_FRONTCOVER;
00483 art->filename = QString("front") + ext;
00484 break;
00485 case AttachedPictureFrame::BackCover :
00486 art->imageType = IT_BACKCOVER;
00487 art->filename = QString("back") + ext;
00488 break;
00489 case AttachedPictureFrame::Media :
00490 art->imageType = IT_CD;
00491 art->filename = QString("cd") + ext;
00492 break;
00493 case AttachedPictureFrame::LeafletPage :
00494 art->imageType = IT_INLAY;
00495 art->filename = QString("inlay") + ext;
00496 break;
00497 case AttachedPictureFrame::Artist :
00498 art->imageType = IT_ARTIST;
00499 art->filename = QString("artist") + ext;
00500 break;
00501 case AttachedPictureFrame::Other :
00502 art->imageType = IT_UNKNOWN;
00503 art->filename = QString("unknown") + ext;
00504 break;
00505 default:
00506 LOG(VB_GENERAL, LOG_ERR, "Music Scanner - APIC tag found "
00507 "with unsupported type");
00508 delete art;
00509 continue;
00510 }
00511
00512 artlist.append(art);
00513 }
00514 }
00515
00516 return artlist;
00517 }
00518
00519 QString MetaIOID3::getExtFromMimeType(const QString &mimeType)
00520 {
00521 if (mimeType == "image/png")
00522 return QString(".png");
00523 else if (mimeType == "image/jpeg" || mimeType == "image/jpg")
00524 return QString(".jpg");
00525 else if (mimeType == "image/gif")
00526 return QString(".gif");
00527 else if (mimeType == "image/bmp")
00528 return QString(".bmp");
00529
00530 LOG(VB_GENERAL, LOG_ERR,
00531 "Music Scanner - Unknown image mimetype found - " + mimeType);
00532
00533 return QString();
00534 }
00535
00544 AttachedPictureFrame* MetaIOID3::findAPIC(TagLib::ID3v2::Tag *tag,
00545 const AttachedPictureFrame::Type &type,
00546 const String &description)
00547 {
00548 TagLib::ID3v2::FrameList l = tag->frameList("APIC");
00549 for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
00550 {
00551 AttachedPictureFrame *f = static_cast<AttachedPictureFrame *>(*it);
00552 if (f && f->type() == type &&
00553 (description.isNull() || f->description() == description))
00554 return f;
00555 }
00556 return NULL;
00557 }
00558
00568 bool MetaIOID3::writeAlbumArt(const QString &filename,
00569 const AlbumArtImage *albumart)
00570 {
00571 if (filename.isEmpty() || !albumart)
00572 return false;
00573
00574
00575 QImage image(albumart->filename);
00576 QByteArray imageData;
00577 QBuffer buffer(&imageData);
00578 buffer.open(QIODevice::WriteOnly);
00579 image.save(&buffer, "JPEG");
00580
00581 AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
00582 switch (albumart->imageType)
00583 {
00584 case IT_FRONTCOVER:
00585 type = AttachedPictureFrame::FrontCover;
00586 break;
00587 case IT_BACKCOVER:
00588 type = AttachedPictureFrame::BackCover;
00589 break;
00590 case IT_CD:
00591 type = AttachedPictureFrame::Media;
00592 break;
00593 case IT_INLAY:
00594 type = AttachedPictureFrame::LeafletPage;
00595 break;
00596 case IT_ARTIST:
00597 type = AttachedPictureFrame::Artist;
00598 break;
00599 default:
00600 type = AttachedPictureFrame::Other;
00601 break;
00602 }
00603
00604 if (!OpenFile(filename, true))
00605 return false;
00606
00607 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00608
00609 if (!tag)
00610 return false;
00611
00612 AttachedPictureFrame *apic = findAPIC(tag, type,
00613 QStringToTString(albumart->description));
00614
00615 if (!apic)
00616 {
00617 apic = new AttachedPictureFrame();
00618 tag->addFrame(apic);
00619 apic->setType(type);
00620 }
00621
00622 QString mimetype = "image/jpeg";
00623
00624 TagLib::ByteVector bytevector;
00625 bytevector.setData(imageData.data(), imageData.size());
00626
00627 apic->setMimeType(QStringToTString(mimetype));
00628 apic->setPicture(bytevector);
00629 apic->setDescription(QStringToTString(albumart->description));
00630
00631 if (!SaveFile())
00632 return false;
00633
00634 return true;
00635 }
00636
00644 bool MetaIOID3::removeAlbumArt(const QString &filename,
00645 const AlbumArtImage *albumart)
00646 {
00647 if (filename.isEmpty() || !albumart)
00648 return false;
00649
00650 AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
00651 switch (albumart->imageType)
00652 {
00653 case IT_FRONTCOVER:
00654 type = AttachedPictureFrame::FrontCover;
00655 break;
00656 case IT_BACKCOVER:
00657 type = AttachedPictureFrame::BackCover;
00658 break;
00659 case IT_CD:
00660 type = AttachedPictureFrame::Media;
00661 break;
00662 case IT_INLAY:
00663 type = AttachedPictureFrame::LeafletPage;
00664 break;
00665 case IT_ARTIST:
00666 type = AttachedPictureFrame::Artist;
00667 break;
00668 default:
00669 type = AttachedPictureFrame::Other;
00670 break;
00671 }
00672
00673 if (!OpenFile(filename, true))
00674 return false;
00675
00676 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00677
00678 if (!tag)
00679 return false;
00680
00681 AttachedPictureFrame *apic = findAPIC(tag, type,
00682 QStringToTString(albumart->description));
00683 if (!apic)
00684 return false;
00685
00686 tag->removeFrame(apic);
00687
00688 if (!SaveFile())
00689 return false;
00690
00691 return true;
00692 }
00693
00694 bool MetaIOID3::changeImageType(const QString &filename,
00695 const AlbumArtImage* albumart,
00696 ImageType newType)
00697 {
00698 if (!albumart)
00699 return false;
00700
00701 if (albumart->imageType == newType)
00702 return true;
00703
00704 AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
00705 switch (albumart->imageType)
00706 {
00707 case IT_FRONTCOVER:
00708 type = AttachedPictureFrame::FrontCover;
00709 break;
00710 case IT_BACKCOVER:
00711 type = AttachedPictureFrame::BackCover;
00712 break;
00713 case IT_CD:
00714 type = AttachedPictureFrame::Media;
00715 break;
00716 case IT_INLAY:
00717 type = AttachedPictureFrame::LeafletPage;
00718 break;
00719 case IT_ARTIST:
00720 type = AttachedPictureFrame::Artist;
00721 break;
00722 default:
00723 type = AttachedPictureFrame::Other;
00724 break;
00725 }
00726
00727 if (!OpenFile(filename, true))
00728 return false;
00729
00730 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00731
00732 if (!tag)
00733 return false;
00734
00735 AttachedPictureFrame *apic = findAPIC(tag, type,
00736 QStringToTString(albumart->description));
00737 if (!apic)
00738 return false;
00739
00740
00741 switch (newType)
00742 {
00743 case IT_FRONTCOVER:
00744 apic->setType(AttachedPictureFrame::FrontCover);
00745 break;
00746 case IT_BACKCOVER:
00747 apic->setType(AttachedPictureFrame::BackCover);
00748 break;
00749 case IT_CD:
00750 apic->setType(AttachedPictureFrame::Media);
00751 break;
00752 case IT_INLAY:
00753 apic->setType(AttachedPictureFrame::LeafletPage);
00754 break;
00755 case IT_ARTIST:
00756 apic->setType(AttachedPictureFrame::Artist);
00757 break;
00758 default:
00759 apic->setType(AttachedPictureFrame::Other);
00760 break;
00761 }
00762
00763 if (!SaveFile())
00764 return false;
00765
00766 return true;
00767 }
00768
00779 UserTextIdentificationFrame* MetaIOID3::find(TagLib::ID3v2::Tag *tag,
00780 const String &description)
00781 {
00782 TagLib::ID3v2::FrameList l = tag->frameList("TXXX");
00783 for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
00784 {
00785 UserTextIdentificationFrame *f =
00786 static_cast<UserTextIdentificationFrame *>(*it);
00787 if (f && f->description() == description)
00788 return f;
00789 }
00790 return NULL;
00791 }
00792
00800 PopularimeterFrame* MetaIOID3::findPOPM(TagLib::ID3v2::Tag *tag,
00801 const String &email)
00802 {
00803 TagLib::ID3v2::FrameList l = tag->frameList("POPM");
00804 for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
00805 {
00806 PopularimeterFrame *f = static_cast<PopularimeterFrame *>(*it);
00807 if (f && f->email() == email)
00808 return f;
00809 }
00810 return NULL;
00811 }
00812
00813 bool MetaIOID3::writePlayCount(TagLib::ID3v2::Tag *tag, int playcount)
00814 {
00815 if (!tag)
00816 return false;
00817
00818 PopularimeterFrame *popm = findPOPM(tag, email);
00819
00820 if (!popm)
00821 {
00822 popm = new PopularimeterFrame();
00823 tag->addFrame(popm);
00824 popm->setEmail(email);
00825 }
00826
00827 popm->setCounter(playcount);
00828
00829 return true;
00830 }
00831
00832 bool MetaIOID3::writeVolatileMetadata(const MusicMetadata* mdata)
00833 {
00834 QString filename = mdata->Filename();
00835 int rating = mdata->Rating();
00836 int playcount = mdata->PlayCount();
00837
00838 if (!OpenFile(filename, true))
00839 return false;
00840
00841 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00842
00843 if (!tag)
00844 return false;
00845
00846 bool result = (writeRating(tag, rating) && writePlayCount(tag, playcount));
00847
00848 if (!SaveFile())
00849 return false;
00850
00851 return result;
00852 }
00853
00854 bool MetaIOID3::writeRating(TagLib::ID3v2::Tag *tag, int rating)
00855 {
00856 if (!tag)
00857 return false;
00858
00859 PopularimeterFrame *popm = findPOPM(tag, email);
00860
00861 if (!popm)
00862 {
00863 popm = new PopularimeterFrame();
00864 tag->addFrame(popm);
00865 popm->setEmail(email);
00866 }
00867 int popmrating = static_cast<int>(((static_cast<float>(rating) / 10.0)
00868 * 255.0) + 0.5);
00869 popm->setRating(popmrating);
00870
00871 return true;
00872 }
00873
00874 bool MetaIOID3::TagExists(const QString &filename)
00875 {
00876 if (!OpenFile(filename))
00877 return false;
00878
00879 TagLib::ID3v1::Tag *v1_tag = GetID3v1Tag();
00880 TagLib::ID3v2::Tag *v2_tag = GetID3v2Tag();
00881
00882 bool retval = false;
00883
00884 if ((v2_tag && !v2_tag->isEmpty()) ||
00885 (v1_tag && !v1_tag->isEmpty()))
00886 retval = true;
00887
00888 return retval;
00889 }