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 a7a4d460db6d12391d233e4f414a638416bfab6d..221b1b9fc01eabecd5521275b417b375d17a1850 GIT binary patch literal 5244 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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(); +}