File indexing completed on 2024-04-28 04:18:50

0001 // vim: set tabstop=4 shiftwidth=4 expandtab:
0002 /*
0003 Gwenview: an image viewer
0004 Copyright 2007 Aurélien Gâteau <agateau@kde.org>
0005 
0006 This program is free software; you can redistribute it and/or
0007 modify it under the terms of the GNU General Public License
0008 as published by the Free Software Foundation; either version 2
0009 of the License, or (at your option) any later version.
0010 
0011 This program is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU General Public License for more details.
0015 
0016 You should have received a copy of the GNU General Public License
0017 along with this program; if not, write to the Free Software
0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0019 
0020 */
0021 // Self
0022 #include "exiv2imageloader.h"
0023 
0024 // Qt
0025 #include <QByteArray>
0026 #include <QFile>
0027 #include <QString>
0028 
0029 // KF
0030 
0031 // Exiv2
0032 #include <exiv2/exiv2.hpp>
0033 
0034 // Local
0035 #include "gwenview_exiv2_debug.h"
0036 
0037 namespace Gwenview
0038 {
0039 struct Exiv2ImageLoaderPrivate {
0040     std::unique_ptr<Exiv2::Image> mImage;
0041     QString mErrorMessage;
0042 };
0043 
0044 struct Exiv2LogHandler {
0045     static void handleMessage(int level, const char *message)
0046     {
0047         switch (level) {
0048         case Exiv2::LogMsg::debug:
0049             qCDebug(GWENVIEW_EXIV2_LOG) << message;
0050             break;
0051         case Exiv2::LogMsg::info:
0052             qCInfo(GWENVIEW_EXIV2_LOG) << message;
0053             break;
0054         case Exiv2::LogMsg::warn:
0055         case Exiv2::LogMsg::error:
0056         case Exiv2::LogMsg::mute:
0057             qCWarning(GWENVIEW_EXIV2_LOG) << message;
0058             break;
0059         default:
0060             qCWarning(GWENVIEW_EXIV2_LOG) << "unhandled log level" << level << message;
0061             break;
0062         }
0063     }
0064 
0065     Exiv2LogHandler()
0066     {
0067         Exiv2::LogMsg::setHandler(&Exiv2LogHandler::handleMessage);
0068     }
0069 };
0070 
0071 Exiv2ImageLoader::Exiv2ImageLoader()
0072     : d(new Exiv2ImageLoaderPrivate)
0073 {
0074     // This is a threadsafe way to ensure that we only register it once
0075     static Exiv2LogHandler handler;
0076 }
0077 
0078 Exiv2ImageLoader::~Exiv2ImageLoader()
0079 {
0080     delete d;
0081 }
0082 
0083 bool Exiv2ImageLoader::load(const QString &filePath)
0084 {
0085     QByteArray filePathByteArray = QFile::encodeName(filePath);
0086     try {
0087         d->mImage.reset(Exiv2::ImageFactory::open(filePathByteArray.constData()).release());
0088         d->mImage->readMetadata();
0089     } catch (const Exiv2::Error &error) {
0090         d->mErrorMessage = QString::fromUtf8(error.what());
0091         return false;
0092     }
0093     return true;
0094 }
0095 
0096 bool Exiv2ImageLoader::load(const QByteArray &data)
0097 {
0098     try {
0099         d->mImage.reset(Exiv2::ImageFactory::open((unsigned char *)data.constData(), data.size()).release());
0100         d->mImage->readMetadata();
0101     } catch (const Exiv2::Error &error) {
0102         d->mErrorMessage = QString::fromUtf8(error.what());
0103         return false;
0104     }
0105     return true;
0106 }
0107 
0108 QString Exiv2ImageLoader::errorMessage() const
0109 {
0110     return d->mErrorMessage;
0111 }
0112 
0113 std::unique_ptr<Exiv2::Image> Exiv2ImageLoader::popImage()
0114 {
0115     return std::move(d->mImage);
0116 }
0117 
0118 } // namespace