diff --git a/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp b/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp index 212a36d742..584705242e 100644 --- a/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp +++ b/core/dplugins/dimg/imagemagick/dimgimagemagickplugin.cpp @@ -1,310 +1,314 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2019-09-21 * Description : ImageMagick DImg plugin. * * Copyright (C) 2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "dimgimagemagickplugin.h" // Image Magick includes #include #if MagickLibVersion < 0x700 # include #endif using namespace Magick; using namespace MagickCore; // Qt includes #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "digikam_globals.h" #include "dimgimagemagickloader.h" namespace DigikamImageMagickDImgPlugin { DImgImageMagickPlugin::DImgImageMagickPlugin(QObject* const parent) : DPluginDImg(parent) { MagickCoreGenesis((char*)NULL ,MagickFalse); } DImgImageMagickPlugin::~DImgImageMagickPlugin() { MagickCoreTerminus(); } QString DImgImageMagickPlugin::name() const { return i18n("ImageMagick loader"); } QString DImgImageMagickPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } QIcon DImgImageMagickPlugin::icon() const { return QIcon::fromTheme(QLatin1String("image-x-generic")); } QString DImgImageMagickPlugin::description() const { return i18n("An image loader based on ImageMagick coders"); } QString DImgImageMagickPlugin::details() const { return i18n("

This plugin permit to load and save image using ImageMagick coders.

" "

ImageMagick is a free and open-source software suite for converting raster image and vector image files. " "It can read and write over 200 image file formats.

" "

See ImageMagick documentation for details.

" ); } QList DImgImageMagickPlugin::authors() const { return QList() << DPluginAuthor(QString::fromUtf8("Maik Qualmann"), QString::fromUtf8("metzpinguin at gmail dot com"), QString::fromUtf8("(C) 2019")) << DPluginAuthor(QString::fromUtf8("Gilles Caulier"), QString::fromUtf8("caulier dot gilles at gmail dot com"), QString::fromUtf8("(C) 2006-2019")) ; } void DImgImageMagickPlugin::setup(QObject* const /*parent*/) { // Nothing to do } QMap DImgImageMagickPlugin::extraAboutData() const { QString mimes = typeMimes(); QMap map; ExceptionInfo ex; size_t n = 0; const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex); if (!inflst) { qWarning() << "ImageMagick coders list is null!"; return QMap(); } for (uint i = 0 ; i < n ; ++i) { const MagickInfo* inf = inflst[i]; if (inf) { QString mod = #if (MagickLibVersion >= 0x69A && defined(magick_module)) QString::fromLatin1(inf->magick_module).toUpper(); #else QString::fromLatin1(inf->module).toUpper(); #endif if (mimes.contains(mod)) { map.insert(mod, QLatin1String(inf->description)); } } } return map; } QString DImgImageMagickPlugin::loaderName() const { return QLatin1String("IMAGEMAGICK"); } QString DImgImageMagickPlugin::typeMimes() const { QStringList formats; ExceptionInfo ex; size_t n = 0; const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex); if (!inflst) { qWarning() << "ImageMagick coders list is null!"; return QString(); } for (uint i = 0 ; i < n ; ++i) { const MagickInfo* inf = inflst[i]; if (inf && inf->decoder) { #if (MagickLibVersion >= 0x69A && defined(magick_module)) formats.append(QString::fromLatin1(inf->magick_module).toUpper()); #else formats.append(QString::fromLatin1(inf->module).toUpper()); #endif } } - qDebug() << "ImageMagick support this formats:" << formats; - QString ret; foreach (const QString& str, formats) { if (!ret.contains(str)) { ret += QString::fromUtf8("%1 ").arg(str.toUpper()); } } return ret; } int DImgImageMagickPlugin::canRead(const QString& filePath, bool magic) const { QFileInfo fileInfo(filePath); if (!fileInfo.exists()) { qCDebug(DIGIKAM_DIMG_LOG) << "File " << filePath << " does not exist"; return 0; } if (!magic) { QString mimeType(QMimeDatabase().mimeTypeForFile(filePath).name()); // Ignore non image format. if ( mimeType.startsWith(QLatin1String("video/")) || mimeType.startsWith(QLatin1String("audio/")) ) { return 0; } QStringList formats; ExceptionInfo ex; size_t n = 0; const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex); if (!inflst) { qWarning() << "ImageMagick coders list is null!"; return 0; } for (uint i = 0 ; i < n ; ++i) { const MagickInfo* inf = inflst[i]; if (inf && inf->decoder) { #if (MagickLibVersion >= 0x69A && defined(magick_module)) formats.append(QString::fromLatin1(inf->magick_module).toUpper()); #else formats.append(QString::fromLatin1(inf->module).toUpper()); #endif } } QString format = fileInfo.suffix().toUpper(); + if (formats.contains(QLatin1String("JPEG"))) + { + formats.append(QLatin1String("JPG")); + formats.append(QLatin1String("JPE")); + } + if (formats.contains(format)) { if (format == QLatin1String("WEBP")) { return 40; } else { return 60; } } } return 0; } int DImgImageMagickPlugin::canWrite(const QString& format) const { QStringList formats; ExceptionInfo ex; size_t n = 0; const MagickInfo** inflst = GetMagickInfoList("*", &n, &ex); if (!inflst) { qWarning() << "ImageMagick coders list is null!"; return 0; } for (uint i = 0 ; i < n ; ++i) { const MagickInfo* inf = inflst[i]; if (inf && inf->encoder) { #if (MagickLibVersion >= 0x69A && defined(magick_module)) formats.append(QString::fromLatin1(inf->magick_module).toUpper()); #else formats.append(QString::fromLatin1(inf->module).toUpper()); #endif } } if (formats.contains(format)) { if (format == QLatin1String("WEBP")) { return 40; } else { return 60; } } return 0; } DImgLoader* DImgImageMagickPlugin::loader(DImg* const image, const DRawDecoding&) const { return new DImgImageMagickLoader(image); } } // namespace DigikamImageMagickDImgPlugin diff --git a/core/dplugins/dimg/qimage/dimgqimageplugin.cpp b/core/dplugins/dimg/qimage/dimgqimageplugin.cpp index 7b0a77766b..bc01b66d67 100644 --- a/core/dplugins/dimg/qimage/dimgqimageplugin.cpp +++ b/core/dplugins/dimg/qimage/dimgqimageplugin.cpp @@ -1,169 +1,171 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2019-09-20 * Description : QImage DImg plugin. * * Copyright (C) 2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "dimgqimageplugin.h" // Qt includes #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "digikam_globals.h" #include "dimgqimageloader.h" namespace DigikamQImageDImgPlugin { DImgQImagePlugin::DImgQImagePlugin(QObject* const parent) : DPluginDImg(parent) { } DImgQImagePlugin::~DImgQImagePlugin() { } QString DImgQImagePlugin::name() const { return i18n("QImage loader"); } QString DImgQImagePlugin::iid() const { return QLatin1String(DPLUGIN_IID); } QIcon DImgQImagePlugin::icon() const { return QIcon::fromTheme(QLatin1String("image-x-generic")); } QString DImgQImagePlugin::description() const { return i18n("An image loader based on QImage plugins"); } QString DImgQImagePlugin::details() const { return i18n("

This plugin permit to load and save image using QImage plugins from Qt Framework.

" "

See Qt Framework documentation for details.

" ); } QList DImgQImagePlugin::authors() const { return QList() << DPluginAuthor(QString::fromUtf8("Renchi Raju"), QString::fromUtf8("renchi dot raju at gmail dot com"), QString::fromUtf8("(C) 2005")) << DPluginAuthor(QString::fromUtf8("Gilles Caulier"), QString::fromUtf8("caulier dot gilles at gmail dot com"), QString::fromUtf8("(C) 2006-2019")) ; } void DImgQImagePlugin::setup(QObject* const /*parent*/) { // Nothing to do } QString DImgQImagePlugin::loaderName() const { return QLatin1String("QIMAGE"); } QString DImgQImagePlugin::typeMimes() const { - QList formats = QImageReader::supportedImageFormats(); - - qDebug(DIGIKAM_DIMG_LOG_QIMAGE) << "QImage support this formats:" << formats; - QString ret; - foreach (const QByteArray& ba, formats) + foreach (const QByteArray& ba, QImageReader::supportedImageFormats()) { ret += QString::fromUtf8("%1 ").arg(QString::fromUtf8(ba).toUpper()); } return ret; } int DImgQImagePlugin::canRead(const QString& filePath, bool magic) const { QFileInfo fileInfo(filePath); if (!fileInfo.exists()) { qCDebug(DIGIKAM_DIMG_LOG) << "File " << filePath << " does not exist"; return 0; } if (!magic) { QString mimeType(QMimeDatabase().mimeTypeForFile(filePath).name()); // Ignore non image format. if ( mimeType.startsWith(QLatin1String("video/")) || mimeType.startsWith(QLatin1String("audio/")) ) { return 0; } - return 50; + QString format = fileInfo.suffix(); + + foreach (const QByteArray& ba, QImageReader::supportedImageFormats()) + { + if (QString::fromUtf8(ba).toUpper() == format.toUpper()) + { + return 50; + } + } } return 0; } int DImgQImagePlugin::canWrite(const QString& format) const { - QList formats = QImageWriter::supportedImageFormats(); - - foreach (const QByteArray& ba, formats) + foreach (const QByteArray& ba, QImageWriter::supportedImageFormats()) { - if (QString::fromUtf8(ba).toUpper().contains(format.toUpper())) + if (QString::fromUtf8(ba).toUpper() == format.toUpper()) { return 50; } } return 0; } DImgLoader* DImgQImagePlugin::loader(DImg* const image, const DRawDecoding&) const { return new DImgQImageLoader(image); } } // namespace DigikamQImageDImgPlugin diff --git a/core/libs/dimg/dimg_p.h b/core/libs/dimg/dimg_p.h index b598d2ee00..e882258c76 100644 --- a/core/libs/dimg/dimg_p.h +++ b/core/libs/dimg/dimg_p.h @@ -1,286 +1,286 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2005-06-15 * Description : digiKam 8/16 bits image management API. * Private data container. * * Copyright (C) 2005 by Renchi Raju * Copyright (C) 2005-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_DIMG_PRIVATE_H #define DIGIKAM_DIMG_PRIVATE_H #include "digikam_config.h" // C ANSI includes #ifndef Q_OS_WIN extern "C" { #endif #include #ifndef Q_OS_WIN #include } #endif // C++ includes #include // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include // Local includes #include "dimg.h" #include "dplugindimg.h" #include "digikam_export.h" #include "digikam_debug.h" #include "dmetadata.h" #include "dshareddata.h" #include "dimagehistory.h" #include "iccprofile.h" #include "metaengine_rotation.h" #include "drawdecoder.h" #include "filereadwritelock.h" #include "iccmanager.h" #include "icctransform.h" #include "exposurecontainer.h" #include "dimgloaderobserver.h" #include "randomnumbergenerator.h" /** Lanczos kernel is precomputed in a table with this resolution The value below seems to be enough for HQ upscaling up to eight times */ #define LANCZOS_TABLE_RES 256 /** A support of 3 gives an overall sharper looking image, but it is a) slower b) gives more sharpening artifacts */ #define LANCZOS_SUPPORT 2 /** Define this to use a floating-point implementation of Lanczos interpolation. The integer implementation is a little bit less accurate, but MUCH faster (even on machines with FPU - ~2.5 times faster on Core2); besides, it will run a hell lot faster on computers without a FPU (e.g. PDAs). */ //#define LANCZOS_DATA_FLOAT #ifdef LANCZOS_DATA_FLOAT # define LANCZOS_DATA_TYPE float # define LANCZOS_DATA_ONE 1.0 #else # define LANCZOS_DATA_TYPE int # define LANCZOS_DATA_ONE 4096 #endif typedef uint64_t ullong; // krazy:exclude=typedefs typedef int64_t llong; // krazy:exclude=typedefs namespace Digikam { class DIGIKAM_EXPORT DImg::Private : public DSharedData { public: explicit Private() { null = true; width = 0; height = 0; data = nullptr; lanczos_func = nullptr; alpha = false; sixteenBit = false; } ~Private() { delete [] data; delete [] lanczos_func; } static QList pluginsForFile(const QString& filePath, bool magic) { QMap pluginMap; if (!filePath.isNull()) { foreach (DPlugin* const p, DPluginLoader::instance()->allPlugins()) { int prio; DPluginDImg* const plug = dynamic_cast(p); if (plug && ((prio = plug->canRead(filePath, magic)) > 0)) { - ///* + /* qCDebug(DIGIKAM_DIMG_LOG) << "File path:" << filePath << "Priority:" << prio << "Loader:" << plug->loaderName(); - //*/ + */ pluginMap.insertMulti(prio, plug); } } } return pluginMap.values(); } static DPluginDImg* pluginForFormat(const QString& format) { QMap pluginMap; if (!format.isNull()) { foreach (DPlugin* const p, DPluginLoader::instance()->allPlugins()) { int prio; DPluginDImg* const plug = dynamic_cast(p); if (plug && ((prio = plug->canWrite(format)) > 0)) { pluginMap.insertMulti(prio, plug); } } } if (!pluginMap.isEmpty()) { return pluginMap.first(); } return nullptr; } static DImg::FORMAT loaderNameToFormat(const QString& name) { if (name.isNull()) { return DImg::NONE; } else if (name == QLatin1String("JPEG")) { return DImg::JPEG; } else if (name == QLatin1String("PNG")) { return DImg::PNG; } else if (name == QLatin1String("TIFF")) { return DImg::TIFF; } else if (name == QLatin1String("RAW")) { return DImg::RAW; } else if (name == QLatin1String("JPEG2000")) { return DImg::JP2K; } else if (name == QLatin1String("PGF")) { return DImg::PGF; } else if (name == QLatin1String("HEIF")) { return DImg::HEIF; } // In others cases, ImageMagick or QImage will be used to try to open file. return DImg::QIMAGE; } static QStringList fileOriginAttributes() { QStringList list; list << QLatin1String("format") << QLatin1String("isReadOnly") << QLatin1String("originalFilePath") << QLatin1String("originalSize") << QLatin1String("originalImageHistory") << QLatin1String("rawDecodingSettings") << QLatin1String("rawDecodingFilterAction") << QLatin1String("uniqueHash") << QLatin1String("uniqueHashV2"); return list; } /** * x,y, w x h is a section of the image. The image size is width x height. * Clips the section to the bounds of the image. * Returns if the (clipped) section is a valid rectangle. */ static bool clipped(int& x, int& y, int& w, int& h, uint width, uint height) { QRect inner(x, y, w, h); QRect outer(0, 0, width, height); if (!outer.contains(inner)) { QRect clipped = inner.intersected(outer); x = clipped.x(); y = clipped.y(); w = clipped.width(); h = clipped.height(); return clipped.isValid(); } return inner.isValid(); } public: bool null; bool alpha; bool sixteenBit; unsigned int width; unsigned int height; unsigned char* data; LANCZOS_DATA_TYPE* lanczos_func; MetaEngineData metaData; QMap attributes; QMap embeddedText; IccProfile iccProfile; DImageHistory imageHistory; }; } // namespace Digikam #endif // DIGIKAM_DIMG_PRIVATE_H