File indexing completed on 2025-01-19 03:51:01

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2019-04-19
0007  * Description : Magick loader for DImg framework - load method.
0008  *
0009  * SPDX-FileCopyrightText: 2019-2023 by Caulier Gilles <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2019-2023 by Maik Qualmann <metzpinguin at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "dimgimagemagickloader.h"
0017 
0018 // ImageMagick includes
0019 
0020 // Pragma directives to reduce warnings from ImageMagick header files.
0021 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
0022 #   pragma GCC diagnostic push
0023 #   pragma GCC diagnostic ignored "-Wignored-qualifiers"
0024 #   pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
0025 #endif
0026 
0027 #if defined(Q_CC_CLANG)
0028 #   pragma clang diagnostic push
0029 #   pragma clang diagnostic ignored "-Wignored-qualifiers"
0030 #   pragma clang diagnostic ignored "-Wkeyword-macro"
0031 #endif
0032 
0033 #include <Magick++.h>
0034 
0035 // Restore warnings
0036 
0037 #if defined(Q_CC_CLANG)
0038 #   pragma clang diagnostic pop
0039 #endif
0040 
0041 #if defined(Q_CC_GNU)
0042 #   pragma GCC diagnostic pop
0043 #endif
0044 
0045 // Local includes
0046 
0047 #include "digikam_debug.h"
0048 #include "dimgloaderobserver.h"
0049 
0050 using namespace Magick;
0051 
0052 namespace DigikamImageMagickDImgPlugin
0053 {
0054 
0055 bool DImgImageMagickLoader::load(const QString& filePath, DImgLoaderObserver* const observer)
0056 {
0057     readMetadata(filePath);
0058 
0059     // Loading is opaque to us. No support for stopping from observer,
0060     // progress info are only pseudo values
0061 
0062     if (observer)
0063     {
0064         observer->progressInfo(0.5F);
0065     }
0066 
0067     qCDebug(DIGIKAM_DIMG_LOG) << "Try to load image with ImageMagick codecs";
0068 
0069     try
0070     {
0071         Image image;
0072 
0073         if (m_loadFlags & LoadImageData)
0074         {
0075             try
0076             {
0077                 image.read(filePath.toUtf8().constData());
0078             }
0079             catch (Warning& warning)
0080             {
0081                 qCWarning(DIGIKAM_DIMG_LOG) << "ImageMagick warning [" << filePath << "]" << warning.what();
0082             }
0083 
0084             if (observer)
0085             {
0086                 observer->progressInfo(0.8F);
0087             }
0088 
0089             qCDebug(DIGIKAM_DIMG_LOG) << "IM to DImg      :" << image.columns() << image.rows();
0090             qCDebug(DIGIKAM_DIMG_LOG) << "IM QuantumRange :" << QuantumRange;
0091             qCDebug(DIGIKAM_DIMG_LOG) << "IM Depth        :" << image.depth();
0092             qCDebug(DIGIKAM_DIMG_LOG) << "IM Format       :" << image.format().c_str();
0093 
0094             m_sixteenBit     = (image.depth() == 16);
0095             StorageType type = m_sixteenBit ? ShortPixel : CharPixel;
0096             uchar* data      = new_failureTolerant(image.columns(), image.rows(), m_sixteenBit ? 8 : 4);
0097 
0098             if (!data)
0099             {
0100                 qCWarning(DIGIKAM_DIMG_LOG_QIMAGE) << "Failed to allocate memory for loading" << filePath;
0101                 loadingFailed();
0102 
0103                 return false;
0104             }
0105 
0106             image.write(0, 0, image.columns(), image.rows(), "BGRA", type, (void*)data);
0107 
0108             if (observer)
0109             {
0110                 observer->progressInfo(0.9F);
0111             }
0112 
0113             if (m_loadFlags & LoadICCData)
0114             {
0115                 Blob iccBlob(image.iccColorProfile());
0116                 QByteArray iccRawProfile((char*)iccBlob.data(), iccBlob.length());
0117 
0118                 if (!iccRawProfile.isEmpty())
0119                 {
0120                     imageSetIccProfile(IccProfile(iccRawProfile));
0121                 }
0122             }
0123 
0124             if (observer)
0125             {
0126                 observer->progressInfo(1.0F);
0127             }
0128 
0129             imageWidth()  = image.columns();
0130             imageHeight() = image.rows();
0131             imageData()   = data;
0132 
0133 #if MagickLibVersion < 0x700
0134 
0135             m_hasAlpha    = image.matte();
0136 
0137 #else
0138 
0139             m_hasAlpha    = image.alpha();
0140 
0141 #endif
0142 
0143             // We considering that PNG is the most representative format of an image loaded by ImageMagick
0144             imageSetAttribute(QLatin1String("format"),             QLatin1String("PNG"));
0145             imageSetAttribute(QLatin1String("originalColorModel"), DImg::RGB);
0146             imageSetAttribute(QLatin1String("originalBitDepth"),   m_sixteenBit ? 16 : 8);
0147             imageSetAttribute(QLatin1String("originalSize"),       QSize(image.columns(), image.rows()));
0148         }
0149         else
0150         {
0151             try
0152             {
0153                 image.ping(filePath.toUtf8().constData());
0154             }
0155             catch (Warning& warning)
0156             {
0157                 qCWarning(DIGIKAM_DIMG_LOG) << "ImageMagick warning [" << filePath << "]" << warning.what();
0158             }
0159 
0160             imageWidth()  = image.columns();
0161             imageHeight() = image.rows();
0162 
0163 #if MagickLibVersion < 0x700
0164 
0165             m_hasAlpha    = image.matte();
0166 
0167 #else
0168 
0169             m_hasAlpha    = image.alpha();
0170 
0171 #endif
0172 
0173             m_sixteenBit  = (image.depth() == 16);
0174 
0175             imageSetAttribute(QLatin1String("format"),             QLatin1String("PNG"));
0176             imageSetAttribute(QLatin1String("originalColorModel"), DImg::RGB);
0177             imageSetAttribute(QLatin1String("originalBitDepth"),   m_sixteenBit ? 16 : 8);
0178             imageSetAttribute(QLatin1String("originalSize"),       QSize(image.columns(), image.rows()));
0179         }
0180     }
0181     catch (Exception& error)
0182     {
0183         qCWarning(DIGIKAM_DIMG_LOG) << "ImageMagick exception [" << filePath << "]" << error.what();
0184         loadingFailed();
0185         return false;
0186     }
0187 
0188     return true;
0189 }
0190 
0191 } // namespace DigikamImageMagickDImgPlugin