File indexing completed on 2024-06-02 04:13:41

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2005-06-15
0007  * Description : digiKam 8/16 bits image management API.
0008  *               Private data container.
0009  *
0010  * SPDX-FileCopyrightText: 2005      by Renchi Raju <renchi dot raju at gmail dot com>
0011  * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #ifndef DIGIKAM_DIMG_PRIVATE_H
0018 #define DIGIKAM_DIMG_PRIVATE_H
0019 
0020 #include "digikam_config.h"
0021 
0022 // C ANSI includes
0023 
0024 #ifndef Q_OS_WIN
0025 extern "C"
0026 {
0027 #endif
0028 
0029 #include <stdint.h>
0030 
0031 #ifndef Q_OS_WIN
0032 #include <math.h>
0033 }
0034 #endif
0035 
0036 // C++ includes
0037 
0038 #include <cstdio>
0039 
0040 // Qt includes
0041 
0042 #include <QCryptographicHash>
0043 #include <QSharedData>
0044 #include <QString>
0045 #include <QByteArray>
0046 #include <QVariant>
0047 #include <QMap>
0048 #include <QFile>
0049 #include <QImage>
0050 #include <QImageReader>
0051 #include <QPaintEngine>
0052 #include <QPainter>
0053 #include <QPixmap>
0054 #include <QSysInfo>
0055 #include <QUuid>
0056 #include <QScopedPointer>
0057 
0058 // KDE includes
0059 
0060 #include <klocalizedstring.h>
0061 
0062 // Local includes
0063 
0064 #include "dimg.h"
0065 #include "dplugindimg.h"
0066 #include "digikam_export.h"
0067 #include "digikam_debug.h"
0068 #include "dmetadata.h"
0069 #include "dimagehistory.h"
0070 #include "iccprofile.h"
0071 #include "metaengine_rotation.h"
0072 #include "drawdecoder.h"
0073 #include "loadsavethread.h"
0074 #include "filereadwritelock.h"
0075 #include "iccmanager.h"
0076 #include "icctransform.h"
0077 #include "exposurecontainer.h"
0078 #include "dimgloaderobserver.h"
0079 #include "randomnumbergenerator.h"
0080 
0081 /**
0082  * Lanczos kernel is precomputed in a table with this resolution
0083  * The value below seems to be enough for HQ upscaling up to eight times
0084  */
0085 #define LANCZOS_TABLE_RES  256
0086 
0087 /**
0088  * A support of 3 gives an overall sharper looking image, but
0089  * it is a) slower b) gives more sharpening artifacts
0090  */
0091 #define LANCZOS_SUPPORT    2
0092 
0093 /**
0094  * Define this to use a floating-point implementation of Lanczos interpolation.
0095  * The integer implementation is a little bit less accurate, but MUCH faster
0096  * (even on machines with FPU - ~2.5 times faster on Core2); besides, it will
0097  * run a hell lot faster on computers without a FPU (e.g. PDAs).
0098  */
0099 //#define LANCZOS_DATA_FLOAT
0100 
0101 #ifdef LANCZOS_DATA_FLOAT
0102 #   define LANCZOS_DATA_TYPE float
0103 #   define LANCZOS_DATA_ONE 1.0
0104 #else
0105 #   define LANCZOS_DATA_TYPE int
0106 #   define LANCZOS_DATA_ONE 4096
0107 #endif
0108 
0109 typedef uint64_t ullong;    // krazy:exclude=typedefs
0110 typedef int64_t  llong;     // krazy:exclude=typedefs
0111 
0112 namespace Digikam
0113 {
0114 
0115 class DIGIKAM_EXPORT DImg::Private : public QSharedData
0116 {
0117 public:
0118 
0119     explicit Private()
0120       : null        (true),
0121         alpha       (false),
0122         sixteenBit  (false),
0123         width       (0),
0124         height      (0),
0125         data        (nullptr),
0126         lanczos_func(nullptr)
0127     {
0128     }
0129 
0130     ~Private()
0131     {
0132         delete [] data;
0133         delete [] lanczos_func;
0134     }
0135 
0136 public:
0137 
0138     bool                    null;
0139     bool                    alpha;
0140     bool                    sixteenBit;
0141 
0142     unsigned int            width;
0143     unsigned int            height;
0144 
0145     unsigned char*          data;
0146     LANCZOS_DATA_TYPE*      lanczos_func;
0147 
0148     MetaEngineData          metaData;
0149     QMap<QString, QVariant> attributes;
0150     QMap<QString, QString>  embeddedText;
0151     IccProfile              iccProfile;
0152     DImageHistory           imageHistory;
0153 };
0154 
0155 // ----------------------------------------------------------------------------
0156 
0157 class DIGIKAM_EXPORT DImgStaticPriv
0158 {
0159 public:
0160 
0161     static DPluginDImg* pluginForFile(const QFileInfo& fileInfo, bool magic)
0162     {
0163         QMultiMap<int, DPluginDImg*> pluginMap;
0164 
0165         Q_FOREACH (DPlugin* const p, DPluginLoader::instance()->allPlugins())
0166         {
0167             int prio;
0168             DPluginDImg* const plug = dynamic_cast<DPluginDImg*>(p);
0169 
0170             if (plug && ((prio = plug->canRead(fileInfo, magic)) > 0))
0171             {
0172  /*
0173                 qCDebug(DIGIKAM_DIMG_LOG) << "File path:" << filePath
0174                                           << "Priority:"  << prio
0175                                           << "Loader:"    << plug->loaderName();
0176  */
0177                 pluginMap.insert(prio, plug);
0178             }
0179         }
0180 
0181         if (pluginMap.isEmpty())
0182         {
0183             return nullptr;
0184         }
0185 
0186         return pluginMap.first();
0187     }
0188 
0189     static DPluginDImg* pluginForFormat(const QString& format)
0190     {
0191         QMultiMap<int, DPluginDImg*> pluginMap;
0192 
0193         if (!format.isNull())
0194         {
0195             Q_FOREACH (DPlugin* const p, DPluginLoader::instance()->allPlugins())
0196             {
0197                 int prio;
0198                 DPluginDImg* const plug = dynamic_cast<DPluginDImg*>(p);
0199 
0200                 if (plug && ((prio = plug->canWrite(format)) > 0))
0201                 {
0202                     pluginMap.insert(prio, plug);
0203                 }
0204             }
0205         }
0206 
0207         if (pluginMap.isEmpty())
0208         {
0209             return nullptr;
0210         }
0211 
0212         return pluginMap.first();
0213     }
0214 
0215     static DImg::FORMAT loaderNameToFormat(const QString& name)
0216     {
0217         if      (name.isNull())
0218         {
0219             return DImg::NONE;
0220         }
0221         else if (name == QLatin1String("JPEG"))
0222         {
0223             return DImg::JPEG;
0224         }
0225         else if (name == QLatin1String("PNG"))
0226         {
0227             return DImg::PNG;
0228         }
0229         else if (name == QLatin1String("TIFF"))
0230         {
0231             return DImg::TIFF;
0232         }
0233         else if (name == QLatin1String("RAW"))
0234         {
0235             return DImg::RAW;
0236         }
0237         else if (name == QLatin1String("JPEG2000"))
0238         {
0239             return DImg::JP2K;
0240         }
0241         else if (name == QLatin1String("PGF"))
0242         {
0243             return DImg::PGF;
0244         }
0245         else if (name == QLatin1String("HEIF"))
0246         {
0247             return DImg::HEIF;
0248         }
0249 
0250         // In others cases, ImageMagick or QImage will be used to try to open file.
0251 
0252         return DImg::QIMAGE;
0253     }
0254 
0255     static QStringList fileOriginAttributes()
0256     {
0257         QStringList list;
0258         list << QLatin1String("format")
0259              << QLatin1String("isReadOnly")
0260              << QLatin1String("originalFilePath")
0261              << QLatin1String("originalSize")
0262              << QLatin1String("originalImageHistory")
0263              << QLatin1String("rawDecodingSettings")
0264              << QLatin1String("rawDecodingFilterAction")
0265              << QLatin1String("uniqueHash")
0266              << QLatin1String("uniqueHashV2");
0267 
0268         return list;
0269     }
0270 };
0271 
0272 } // namespace Digikam
0273 
0274 #endif // DIGIKAM_DIMG_PRIVATE_H