File indexing completed on 2025-01-19 03:54:49
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2005-06-14 0007 * Description : DImg image loader interface 0008 * 0009 * SPDX-FileCopyrightText: 2005 by Renchi Raju <renchi dot raju at gmail dot com> 0010 * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #ifndef DIGIKAM_DIMG_LOADER_H 0017 #define DIGIKAM_DIMG_LOADER_H 0018 0019 // C++ includes 0020 0021 #include <limits> 0022 0023 // Qt includes 0024 0025 #include <QMap> 0026 #include <QString> 0027 #include <QVariant> 0028 0029 // Local includes 0030 0031 #include "digikam_debug.h" 0032 #include "digikam_export.h" 0033 #include "dimg.h" 0034 0035 namespace Digikam 0036 { 0037 0038 class DImgLoaderObserver; 0039 class DMetadata; 0040 0041 class DIGIKAM_EXPORT DImgLoader 0042 { 0043 public: 0044 0045 /** 0046 * This is the list of loading modes usable by DImg image plugins 0047 */ 0048 enum LoadFlag 0049 { 0050 /// Load image information without image data 0051 0052 LoadItemInfo = 1, ///< Image info as width and height 0053 LoadMetadata = 2, ///< Image metadata 0054 LoadICCData = 4, ///< Image color profile 0055 0056 LoadImageData = 8, ///< Full image data 0057 LoadUniqueHash = 16, ///< Image unique hash 0058 LoadImageHistory = 32, ///< Image version history 0059 0060 /// Special mode to load reduced image data 0061 0062 LoadPreview = 64, ///< Load embedded preview image instead full size image 0063 0064 /// Helper to load all information, metadata and full image. 0065 0066 LoadAll = LoadItemInfo | LoadMetadata | LoadICCData | LoadImageData | LoadUniqueHash | LoadImageHistory 0067 }; 0068 Q_DECLARE_FLAGS(LoadFlags, LoadFlag) 0069 0070 public: 0071 0072 void setLoadFlags(LoadFlags flags); 0073 0074 virtual ~DImgLoader(); 0075 0076 virtual bool load(const QString& filePath, DImgLoaderObserver* const observer) = 0; 0077 virtual bool save(const QString& filePath, DImgLoaderObserver* const observer) = 0; 0078 0079 virtual bool hasLoadedData() const; 0080 virtual bool hasAlpha() const = 0; 0081 virtual bool sixteenBit() const = 0; 0082 virtual bool isReadOnly() const = 0; 0083 0084 static unsigned char* new_failureTolerant(size_t unsecureSize); 0085 static unsigned char* new_failureTolerant(quint64 w, quint64 h, uint typesPerPixel); 0086 static unsigned short* new_short_failureTolerant(size_t unsecureSize); 0087 static unsigned short* new_short_failureTolerant(quint64 w, quint64 h, uint typesPerPixel); 0088 0089 static int convertCompressionForLibPng(int value); 0090 static int convertCompressionForLibJpeg(int value); 0091 0092 /** 0093 * Value returned : -1 : unsupported platform 0094 * 0 : parse failure from supported platform 0095 * 1 : parse done with success from supported platform 0096 */ 0097 static qint64 checkAllocation(qint64 fullSize); 0098 0099 template <typename Type> static Type* new_failureTolerant(size_t unsecureSize); 0100 template <typename Type> static Type* new_failureTolerant(quint64 w, quint64 h, uint typesPerPixel); 0101 0102 protected: 0103 0104 explicit DImgLoader(DImg* const image); 0105 0106 unsigned char*& imageData(); 0107 unsigned int& imageWidth(); 0108 unsigned int& imageHeight(); 0109 0110 bool imageHasAlpha() const; 0111 bool imageSixteenBit() const; 0112 0113 quint64 imageNumBytes() const; 0114 int imageBitsDepth() const; 0115 int imageBytesDepth() const; 0116 0117 void imageSetIccProfile(const IccProfile& profile); 0118 QVariant imageGetAttribute(const QString& key) const; 0119 void imageSetAttribute(const QString& key, 0120 const QVariant& value); 0121 0122 QMap<QString, QString>& imageEmbeddedText() const; 0123 QString imageGetEmbbededText(const QString& key) const; 0124 void imageSetEmbbededText(const QString& key, 0125 const QString& text); 0126 0127 void loadingFailed(); 0128 bool checkExifWorkingColorSpace() const; 0129 void purgeExifWorkingColorSpace(); 0130 void storeColorProfileInMetadata(); 0131 0132 virtual bool readMetadata(const QString& filePath); 0133 virtual bool saveMetadata(const QString& filePath); 0134 virtual int granularity(DImgLoaderObserver* const observer, int total, float progressSlice = 1.0F); 0135 0136 protected: 0137 0138 DImg* m_image; 0139 LoadFlags m_loadFlags; 0140 0141 private: 0142 0143 // Disable 0144 DImgLoader() = delete; 0145 0146 private: 0147 0148 Q_DISABLE_COPY(DImgLoader) 0149 }; 0150 0151 // --------------------------------------------------------------------------------------------------- 0152 0153 /** 0154 * Allows safe multiplication of requested pixel number and bytes per pixel, avoiding particularly 0155 * 32 bits overflow and exceeding the size_t type 0156 */ 0157 template <typename Type> 0158 Q_INLINE_TEMPLATE Type* DImgLoader::new_failureTolerant(quint64 w, quint64 h, uint typesPerPixel) 0159 { 0160 quint64 requested = w * h * (quint64)typesPerPixel; 0161 0162 if (requested >= std::numeric_limits<size_t>::max()) 0163 { 0164 qCCritical(DIGIKAM_DIMG_LOG) << "Requested memory of" << requested * quint64(sizeof(Type)) 0165 << "is larger than size_t supported by platform."; 0166 return nullptr; 0167 } 0168 0169 return new_failureTolerant<Type>(requested); 0170 } 0171 0172 template <typename Type> 0173 Q_INLINE_TEMPLATE Type* DImgLoader::new_failureTolerant(size_t size) 0174 { 0175 qint64 res = checkAllocation(size); 0176 0177 switch (res) 0178 { 0179 case 0: // parse failure from supported platform 0180 { 0181 return nullptr; 0182 } 0183 0184 case -1: // unsupported platform 0185 { 0186 // We will try to continue to allocate 0187 break; 0188 } 0189 0190 default: // parse done with success from supported platform 0191 { 0192 break; 0193 } 0194 } 0195 0196 Type* const reserved = new (std::nothrow) Type[size]; 0197 0198 if (!reserved) 0199 { 0200 qCCritical(DIGIKAM_DIMG_LOG) << "Failed to allocate chunk of memory of size" << size; 0201 } 0202 0203 return reserved; 0204 } 0205 0206 Q_DECLARE_OPERATORS_FOR_FLAGS(DImgLoader::LoadFlags) 0207 0208 } // namespace Digikam 0209 0210 #endif // DIGIKAM_DIMG_LOADER_H