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 "metadata.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 Metadata* 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 Metadata *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 Metadata *metadata = new Metadata(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 continue;
00509 }
00510
00511 artlist.append(art);
00512 }
00513 }
00514
00515 return artlist;
00516 }
00517
00518 QString MetaIOID3::getExtFromMimeType(const QString &mimeType)
00519 {
00520 if (mimeType == "image/png")
00521 return QString(".png");
00522 else if (mimeType == "image/jpeg" || mimeType == "image/jpg")
00523 return QString(".jpg");
00524 else if (mimeType == "image/gif")
00525 return QString(".gif");
00526 else if (mimeType == "image/bmp")
00527 return QString(".bmp");
00528
00529 LOG(VB_GENERAL, LOG_ERR,
00530 "Music Scanner - Unknown image mimetype found - " + mimeType);
00531
00532 return QString();
00533 }
00534
00543 AttachedPictureFrame* MetaIOID3::findAPIC(TagLib::ID3v2::Tag *tag,
00544 const AttachedPictureFrame::Type &type,
00545 const String &description)
00546 {
00547 TagLib::ID3v2::FrameList l = tag->frameList("APIC");
00548 for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
00549 {
00550 AttachedPictureFrame *f = static_cast<AttachedPictureFrame *>(*it);
00551 if (f && f->type() == type &&
00552 (description.isNull() || f->description() == description))
00553 return f;
00554 }
00555 return NULL;
00556 }
00557
00567 bool MetaIOID3::writeAlbumArt(const QString &filename,
00568 const AlbumArtImage *albumart)
00569 {
00570 if (filename.isEmpty() || !albumart)
00571 return false;
00572
00573
00574 QImage image(albumart->filename);
00575 QByteArray imageData;
00576 QBuffer buffer(&imageData);
00577 buffer.open(QIODevice::WriteOnly);
00578 image.save(&buffer, "JPEG");
00579
00580 AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
00581 switch (albumart->imageType)
00582 {
00583 case IT_FRONTCOVER:
00584 type = AttachedPictureFrame::FrontCover;
00585 break;
00586 case IT_BACKCOVER:
00587 type = AttachedPictureFrame::BackCover;
00588 break;
00589 case IT_CD:
00590 type = AttachedPictureFrame::Media;
00591 break;
00592 case IT_INLAY:
00593 type = AttachedPictureFrame::LeafletPage;
00594 break;
00595 case IT_ARTIST:
00596 type = AttachedPictureFrame::Artist;
00597 break;
00598 default:
00599 type = AttachedPictureFrame::Other;
00600 break;
00601 }
00602
00603 if (!OpenFile(filename, true))
00604 return false;
00605
00606 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00607
00608 if (!tag)
00609 return false;
00610
00611 AttachedPictureFrame *apic = findAPIC(tag, type,
00612 QStringToTString(albumart->description));
00613
00614 if (!apic)
00615 {
00616 apic = new AttachedPictureFrame();
00617 tag->addFrame(apic);
00618 apic->setType(type);
00619 }
00620
00621 QString mimetype = "image/jpeg";
00622
00623 TagLib::ByteVector bytevector;
00624 bytevector.setData(imageData.data(), imageData.size());
00625
00626 apic->setMimeType(QStringToTString(mimetype));
00627 apic->setPicture(bytevector);
00628 apic->setDescription(QStringToTString(albumart->description));
00629
00630 if (!SaveFile())
00631 return false;
00632
00633 return true;
00634 }
00635
00643 bool MetaIOID3::removeAlbumArt(const QString &filename,
00644 const AlbumArtImage *albumart)
00645 {
00646 if (filename.isEmpty() || !albumart)
00647 return false;
00648
00649 AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
00650 switch (albumart->imageType)
00651 {
00652 case IT_FRONTCOVER:
00653 type = AttachedPictureFrame::FrontCover;
00654 break;
00655 case IT_BACKCOVER:
00656 type = AttachedPictureFrame::BackCover;
00657 break;
00658 case IT_CD:
00659 type = AttachedPictureFrame::Media;
00660 break;
00661 case IT_INLAY:
00662 type = AttachedPictureFrame::LeafletPage;
00663 break;
00664 case IT_ARTIST:
00665 type = AttachedPictureFrame::Artist;
00666 break;
00667 default:
00668 type = AttachedPictureFrame::Other;
00669 break;
00670 }
00671
00672 if (!OpenFile(filename, true))
00673 return false;
00674
00675 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00676
00677 if (!tag)
00678 return false;
00679
00680 AttachedPictureFrame *apic = findAPIC(tag, type,
00681 QStringToTString(albumart->description));
00682 if (!apic)
00683 return false;
00684
00685 tag->removeFrame(apic);
00686
00687 if (!SaveFile())
00688 return false;
00689
00690 return true;
00691 }
00692
00693 bool MetaIOID3::changeImageType(const QString &filename,
00694 const AlbumArtImage* albumart,
00695 ImageType newType)
00696 {
00697 if (!albumart)
00698 return false;
00699
00700 if (albumart->imageType == newType)
00701 return true;
00702
00703 AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
00704 switch (albumart->imageType)
00705 {
00706 case IT_FRONTCOVER:
00707 type = AttachedPictureFrame::FrontCover;
00708 break;
00709 case IT_BACKCOVER:
00710 type = AttachedPictureFrame::BackCover;
00711 break;
00712 case IT_CD:
00713 type = AttachedPictureFrame::Media;
00714 break;
00715 case IT_INLAY:
00716 type = AttachedPictureFrame::LeafletPage;
00717 break;
00718 case IT_ARTIST:
00719 type = AttachedPictureFrame::Artist;
00720 break;
00721 default:
00722 type = AttachedPictureFrame::Other;
00723 break;
00724 }
00725
00726 if (!OpenFile(filename, true))
00727 return false;
00728
00729 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00730
00731 if (!tag)
00732 return false;
00733
00734 AttachedPictureFrame *apic = findAPIC(tag, type,
00735 QStringToTString(albumart->description));
00736 if (!apic)
00737 return false;
00738
00739
00740 switch (newType)
00741 {
00742 case IT_FRONTCOVER:
00743 apic->setType(AttachedPictureFrame::FrontCover);
00744 break;
00745 case IT_BACKCOVER:
00746 apic->setType(AttachedPictureFrame::BackCover);
00747 break;
00748 case IT_CD:
00749 apic->setType(AttachedPictureFrame::Media);
00750 break;
00751 case IT_INLAY:
00752 apic->setType(AttachedPictureFrame::LeafletPage);
00753 break;
00754 case IT_ARTIST:
00755 apic->setType(AttachedPictureFrame::Artist);
00756 break;
00757 default:
00758 apic->setType(AttachedPictureFrame::Other);
00759 break;
00760 }
00761
00762 if (!SaveFile())
00763 return false;
00764
00765 return true;
00766 }
00767
00778 UserTextIdentificationFrame* MetaIOID3::find(TagLib::ID3v2::Tag *tag,
00779 const String &description)
00780 {
00781 TagLib::ID3v2::FrameList l = tag->frameList("TXXX");
00782 for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
00783 {
00784 UserTextIdentificationFrame *f =
00785 static_cast<UserTextIdentificationFrame *>(*it);
00786 if (f && f->description() == description)
00787 return f;
00788 }
00789 return NULL;
00790 }
00791
00799 PopularimeterFrame* MetaIOID3::findPOPM(TagLib::ID3v2::Tag *tag,
00800 const String &email)
00801 {
00802 TagLib::ID3v2::FrameList l = tag->frameList("POPM");
00803 for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
00804 {
00805 PopularimeterFrame *f = static_cast<PopularimeterFrame *>(*it);
00806 if (f && f->email() == email)
00807 return f;
00808 }
00809 return NULL;
00810 }
00811
00812 bool MetaIOID3::writePlayCount(TagLib::ID3v2::Tag *tag, int playcount)
00813 {
00814 if (!tag)
00815 return false;
00816
00817 PopularimeterFrame *popm = findPOPM(tag, email);
00818
00819 if (!popm)
00820 {
00821 popm = new PopularimeterFrame();
00822 tag->addFrame(popm);
00823 popm->setEmail(email);
00824 }
00825
00826 popm->setCounter(playcount);
00827
00828 return true;
00829 }
00830
00831 bool MetaIOID3::writeVolatileMetadata(const Metadata* mdata)
00832 {
00833 QString filename = mdata->Filename();
00834 int rating = mdata->Rating();
00835 int playcount = mdata->PlayCount();
00836
00837 if (!OpenFile(filename, true))
00838 return false;
00839
00840 TagLib::ID3v2::Tag *tag = GetID3v2Tag();
00841
00842 if (!tag)
00843 return false;
00844
00845 bool result = (writeRating(tag, rating) && writePlayCount(tag, playcount));
00846
00847 if (!SaveFile())
00848 return false;
00849
00850 return result;
00851 }
00852
00853 bool MetaIOID3::writeRating(TagLib::ID3v2::Tag *tag, int rating)
00854 {
00855 if (!tag)
00856 return false;
00857
00858 PopularimeterFrame *popm = findPOPM(tag, email);
00859
00860 if (!popm)
00861 {
00862 popm = new PopularimeterFrame();
00863 tag->addFrame(popm);
00864 popm->setEmail(email);
00865 }
00866 int popmrating = static_cast<int>(((static_cast<float>(rating) / 10.0)
00867 * 255.0) + 0.5);
00868 popm->setRating(popmrating);
00869
00870 return true;
00871 }
00872
00873 bool MetaIOID3::TagExists(const QString &filename)
00874 {
00875 if (!OpenFile(filename))
00876 return false;
00877
00878 TagLib::ID3v1::Tag *v1_tag = GetID3v1Tag();
00879 TagLib::ID3v2::Tag *v2_tag = GetID3v2Tag();
00880
00881 bool retval = false;
00882
00883 if ((v2_tag && !v2_tag->isEmpty()) ||
00884 (v1_tag && !v1_tag->isEmpty()))
00885 retval = true;
00886
00887 return retval;
00888 }