diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -108,6 +108,10 @@ TEST_NAME "taglibextractortest" LINK_LIBRARIES Qt5::Test KF5::FileMetaData ${TAGLIB_LIBRARIES} ) + ecm_add_test(embeddedimagedatatest.cpp ../src/embeddedimagedata.cpp + TEST_NAME "embeddedimagedatatest" + LINK_LIBRARIES Qt5::Test KF5::FileMetaData ${TAGLIB_LIBRARIES} + ) endif() diff --git a/autotests/embeddedimagedatatest.h b/autotests/embeddedimagedatatest.h new file mode 100644 --- /dev/null +++ b/autotests/embeddedimagedatatest.h @@ -0,0 +1,38 @@ +/* + * EmbeddedImageData tests. + * + * Copyright (C) 2018 Alexander Stippich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef EMBEDDEDIMAGEDATATEST_H +#define EMBEDDEDIMAGEDATATEST_H + +#include +#include "properties.h" + +class EmbeddedImageDataTest : public QObject +{ + Q_OBJECT +private: + QString testFilePath(const QString& fileName) const; + +private Q_SLOTS: + void test(); +}; + +#endif // EMBEDDEDIMAGEDATATEST_H diff --git a/autotests/embeddedimagedatatest.cpp b/autotests/embeddedimagedatatest.cpp new file mode 100644 --- /dev/null +++ b/autotests/embeddedimagedatatest.cpp @@ -0,0 +1,63 @@ +/* + * EmbeddedImageData tests. + * + * Copyright (C) 2018 Alexander Stippich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "embeddedimagedatatest.h" +#include "embeddedimagedata.h" +#include "indexerextractortestsconfig.h" + +#include + +using namespace KFileMetaData; + +QString EmbeddedImageDataTest::testFilePath(const QString& fileName) const +{ + return QLatin1String(INDEXER_TESTS_SAMPLE_FILES_PATH) + QDir::separator() + fileName; +} + +void EmbeddedImageDataTest::test() +{ + QMap images; + QByteArray originalFrontCoverImage; + QFile testFile(testFilePath("test.jpg")); + testFile.open(QIODevice::ReadOnly); + originalFrontCoverImage = testFile.readAll(); + + EmbeddedImageData imageData; + images = imageData.imageData(testFilePath("test.opus")); + QCOMPARE(images.value(EmbeddedImageData::FrontCover), originalFrontCoverImage); + + images = imageData.imageData(testFilePath("test.ogg")); + QCOMPARE(images.value(EmbeddedImageData::FrontCover), originalFrontCoverImage); + + images = imageData.imageData(testFilePath("test.flac")); + QCOMPARE(images.value(EmbeddedImageData::FrontCover), originalFrontCoverImage); + + images = imageData.imageData(testFilePath("test.mp3")); + QCOMPARE(images.value(EmbeddedImageData::FrontCover), originalFrontCoverImage); + + images = imageData.imageData(testFilePath("test.m4a")); + QCOMPARE(images.value(EmbeddedImageData::FrontCover), originalFrontCoverImage); + + images = imageData.imageData(testFilePath("test.mpc")); + QCOMPARE(images.value(EmbeddedImageData::FrontCover), originalFrontCoverImage); +} + +QTEST_GUILESS_MAIN(EmbeddedImageDataTest) diff --git a/autotests/samplefiles/test.mpc b/autotests/samplefiles/test.mpc index 46966621333b3825900e6a2871fc0ab8c6997567..e9195cf5001e6e6528196b0710e8082db9d53a2d GIT binary patch literal 5227 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 TyE+EaPrus#@p2HgeK`IFKJK)A literal 3739 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 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef KFILEMETADATA_EMBEDDEDIMAGEDATA_H +#define KFILEMETADATA_EMBEDDEDIMAGEDATA_H + +#include "kfilemetadata_export.h" +#include +#include +#include + +namespace KFileMetaData { + +/** + * \class EmbeddedImageData embeddedimagedata.h + * + * \brief The EmbeddedImageData is a class which extracts the images stored + * in the metadata tags of files as byte arrays. For example, the front cover + * art of music albums may be extracted with this class. The byte array will + * mostly contain jpeg or png files, which can be loaded into e.g. QImage. + * + * \author Alexander Stippich + */ +class KFILEMETADATA_EXPORT EmbeddedImageData { +public: + EmbeddedImageData(); + virtual ~EmbeddedImageData(); + enum ImageType { + FrontCover = 0x01, + AllImages = FrontCover + }; + Q_DECLARE_FLAGS(ImageTypes, ImageType) + + /** + * Extracts the images stored in the metadata tags from a file. + * By default, the front cover is extracted. + */ + QMap imageData(const QString &fileUrl, const EmbeddedImageData::ImageTypes types = FrontCover) const; + +private: + class Private; + std::unique_ptr d; + EmbeddedImageData& operator=(const EmbeddedImageData&); +}; + +} + +#endif // KFILEMETADATA_EMBEDDEDIMAGEDATA_H diff --git a/src/embeddedimagedata.cpp b/src/embeddedimagedata.cpp new file mode 100644 --- /dev/null +++ b/src/embeddedimagedata.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2018 Alexander Stippich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "embeddedimagedata.h" +// Taglib includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace KFileMetaData; + +class Q_DECL_HIDDEN EmbeddedImageData::Private +{ +public: + QMimeDatabase mMimeDatabase; + QByteArray getFrontCover(const QString &fileUrl, const QString &mimeType) const; + +}; + +EmbeddedImageData::EmbeddedImageData() + : d(std::unique_ptr(new Private())) +{ +} + +EmbeddedImageData::~EmbeddedImageData() += default; + +QMap +EmbeddedImageData::imageData(const QString &fileUrl, + const EmbeddedImageData::ImageTypes types) const +{ + QMap imageData; + + const auto &fileMimeType = d->mMimeDatabase.mimeTypeForFile(fileUrl); + if (fileMimeType.name().startsWith(QStringLiteral("audio/"))) { + if (types & EmbeddedImageData::FrontCover) { + imageData.insert(EmbeddedImageData::FrontCover, d->getFrontCover(fileUrl, fileMimeType.name())); + } + } + + return imageData; +} + +QByteArray +EmbeddedImageData::Private::getFrontCover(const QString &fileUrl, + const QString &mimeType) const +{ + TagLib::FileStream stream(fileUrl.toUtf8().constData(), true); + if (!stream.isOpen()) { + qWarning() << "Unable to open file readonly: " << fileUrl; + return QByteArray(); + } + if ((mimeType == QStringLiteral("audio/mpeg")) + || (mimeType == QStringLiteral("audio/mpeg3")) + || (mimeType == QStringLiteral("audio/x-mpeg"))) { + + // Handling multiple tags in mpeg files. + TagLib::MPEG::File mpegFile(&stream, TagLib::ID3v2::FrameFactory::instance(), true); + if (!mpegFile.ID3v2Tag() || mpegFile.ID3v2Tag()->isEmpty()) { + return QByteArray(); + } + + TagLib::ID3v2::FrameList lstID3v2; + // Attached Front Picture. + lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()["APIC"]; + if (!lstID3v2.isEmpty()) { + for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) { + auto *frontCoverFrame = static_cast(*it); + if (frontCoverFrame->type() == frontCoverFrame->FrontCover) { + return QByteArray(frontCoverFrame->picture().data(), frontCoverFrame->picture().size()); + } + } + } + + } else if (mimeType == QStringLiteral("audio/mp4")) { + + TagLib::MP4::File mp4File(&stream, true); + if (!mp4File.tag() || mp4File.tag()->isEmpty()) { + return QByteArray(); + } + TagLib::MP4::Item coverArtItem = mp4File.tag()->item("covr"); + if (coverArtItem.isValid()) + { + TagLib::MP4::CoverArtList coverArtList = coverArtItem.toCoverArtList(); + TagLib::MP4::CoverArt& frontCover = coverArtList.front(); + return QByteArray(frontCover.data().data(), frontCover.data().size()); + } + + } else if (mimeType == QStringLiteral("audio/x-musepack")) { + + TagLib::MPC::File mpcFile(&stream, true); + if (!mpcFile.tag() || mpcFile.tag()->isEmpty()) { + return QByteArray(); + } + + TagLib::APE::ItemListMap lstMusepack = mpcFile.APETag()->itemListMap(); + TagLib::APE::ItemListMap::ConstIterator itMPC; + + /* The cover art tag for APEv2 tags starts with the filename as string + * with zero termination followed by the actual picture data */ + itMPC = lstMusepack.find("COVER ART (FRONT)"); + if (itMPC != lstMusepack.end()) { + TagLib::ByteVector pictureData = (*itMPC).second.binaryData(); + int dataPosition = pictureData.find('\0') + 1; + return QByteArray(pictureData.data() + dataPosition, pictureData.size() - dataPosition); + } + + } else if (mimeType == QStringLiteral("audio/flac")) { + + TagLib::FLAC::File flacFile(&stream, TagLib::ID3v2::FrameFactory::instance(), true); + TagLib::List lstPic = flacFile.pictureList(); + + if (!lstPic.isEmpty()) { + for (TagLib::List::Iterator it = lstPic.begin(); it != lstPic.end(); ++it) { + TagLib::FLAC::Picture *picture = *it; + if (picture->type() == picture->FrontCover) { + return QByteArray(picture->data().data(), picture->data().size()); + } + } + } + + } else { + + TagLib::List lstPic; + if (mimeType == QStringLiteral("audio/ogg") || mimeType == QStringLiteral("audio/x-vorbis+ogg")) { + TagLib::Ogg::Vorbis::File oggFile(&stream, true); + if (oggFile.tag() && !oggFile.tag()->isEmpty()) { + lstPic = oggFile.tag()->pictureList(); + } + } + if (mimeType == QStringLiteral("audio/opus") || mimeType == QStringLiteral("audio/x-opus+ogg")) { + TagLib::Ogg::Opus::File opusFile(&stream, true); + if (opusFile.tag() && !opusFile.tag()->isEmpty()) { + lstPic = opusFile.tag()->pictureList(); + } + } + if (!lstPic.isEmpty()) { + for (TagLib::List::Iterator it = lstPic.begin(); it != lstPic.end(); ++it) { + TagLib::FLAC::Picture *picture = *it; + if (picture->type() == picture->FrontCover) { + return QByteArray(picture->data().data(), picture->data().size()); + } + } + } + } + return QByteArray(); +}