File indexing completed on 2025-01-19 03:54:50
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2005-06-14 0007 * Description : digiKam 8/16 bits image management API 0008 * Files input output 0009 * 0010 * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "dimg_p.h" 0018 0019 namespace Digikam 0020 { 0021 0022 bool DImg::loadItemInfo(const QString& filePath, bool loadMetadata, bool loadICCData, bool loadUniqueHash, bool loadImageHistory) 0023 { 0024 DImgLoader::LoadFlags loadFlags = DImgLoader::LoadItemInfo; 0025 0026 if (loadMetadata) 0027 { 0028 loadFlags |= DImgLoader::LoadMetadata; 0029 } 0030 0031 if (loadICCData) 0032 { 0033 loadFlags |= DImgLoader::LoadICCData; 0034 } 0035 0036 if (loadUniqueHash) 0037 { 0038 loadFlags |= DImgLoader::LoadUniqueHash; 0039 } 0040 0041 if (loadImageHistory) 0042 { 0043 loadFlags |= DImgLoader::LoadImageHistory; 0044 } 0045 0046 return load(filePath, loadFlags, nullptr, DRawDecoding()); 0047 } 0048 0049 bool DImg::load(const QString& filePath, 0050 DImgLoaderObserver* const observer, 0051 const DRawDecoding& rawDecodingSettings) 0052 { 0053 return load(filePath, DImgLoader::LoadAll, observer, rawDecodingSettings); 0054 } 0055 0056 bool DImg::load(const QString& filePath, 0057 bool loadMetadata, 0058 bool loadICCData, 0059 bool loadUniqueHash, 0060 bool loadImageHistory, 0061 DImgLoaderObserver* const observer, 0062 const DRawDecoding& rawDecodingSettings) 0063 { 0064 DImgLoader::LoadFlags loadFlags = DImgLoader::LoadItemInfo | DImgLoader::LoadImageData; 0065 0066 if (loadMetadata) 0067 { 0068 loadFlags |= DImgLoader::LoadMetadata; 0069 } 0070 0071 if (loadICCData) 0072 { 0073 loadFlags |= DImgLoader::LoadICCData; 0074 } 0075 0076 if (loadUniqueHash) 0077 { 0078 loadFlags |= DImgLoader::LoadUniqueHash; 0079 } 0080 0081 if (loadImageHistory) 0082 { 0083 loadFlags |= DImgLoader::LoadImageHistory; 0084 } 0085 0086 return load(filePath, loadFlags, observer, rawDecodingSettings); 0087 } 0088 0089 bool DImg::load(const QString& filePath, 0090 int loadFlagsInt, 0091 DImgLoaderObserver* const observer, 0092 const DRawDecoding& rawDecodingSettings) 0093 { 0094 QFileInfo fileInfo(filePath); 0095 0096 if (!fileInfo.exists() || !fileInfo.isReadable()) 0097 { 0098 qCDebug(DIGIKAM_DIMG_LOG) << "File" << filePath << "does not exist"; 0099 return false; 0100 } 0101 0102 DPluginDImg* plugin = DImgStaticPriv::pluginForFile(fileInfo, false); 0103 DImgLoader::LoadFlags loadFlags = (DImgLoader::LoadFlags)loadFlagsInt; 0104 setAttribute(QLatin1String("originalFilePath"), filePath); 0105 0106 FileReadLocker lock(filePath); 0107 0108 // First step we check the file extension to find the right loader. 0109 0110 if (observer && !observer->continueQuery()) 0111 { 0112 return false; 0113 } 0114 0115 if (plugin && (!(loadFlags & DImgLoader::LoadPreview) || plugin->previewSupported())) 0116 { 0117 qCDebug(DIGIKAM_DIMG_LOG) << filePath << ":" << plugin->loaderName() << "file identified"; 0118 FORMAT format = DImgStaticPriv::loaderNameToFormat(plugin->loaderName()); 0119 DImgLoader* const loader = plugin->loader(this, rawDecodingSettings); 0120 setAttribute(QLatin1String("detectedFileFormat"), format); 0121 loader->setLoadFlags(loadFlags); 0122 0123 if (loader->load(filePath, observer)) 0124 { 0125 m_priv->null = !loader->hasLoadedData(); 0126 m_priv->alpha = loader->hasAlpha(); 0127 m_priv->sixteenBit = loader->sixteenBit(); 0128 setAttribute(QLatin1String("isReadOnly"), loader->isReadOnly()); 0129 delete loader; 0130 0131 return true; 0132 } 0133 0134 delete loader; 0135 } 0136 0137 // In the second step we check the magic bytes to find the right loader. 0138 0139 plugin = DImgStaticPriv::pluginForFile(fileInfo, true); 0140 0141 if (observer && !observer->continueQuery()) 0142 { 0143 return false; 0144 } 0145 0146 if (plugin && (!(loadFlags & DImgLoader::LoadPreview) || plugin->previewSupported())) 0147 { 0148 qCDebug(DIGIKAM_DIMG_LOG) << filePath << ":" << plugin->loaderName() << "file identified (magic)"; 0149 FORMAT format = DImgStaticPriv::loaderNameToFormat(plugin->loaderName()); 0150 DImgLoader* const loader = plugin->loader(this, rawDecodingSettings); 0151 setAttribute(QLatin1String("detectedFileFormat"), format); 0152 loader->setLoadFlags(loadFlags); 0153 0154 if (loader->load(filePath, observer)) 0155 { 0156 m_priv->null = !loader->hasLoadedData(); 0157 m_priv->alpha = loader->hasAlpha(); 0158 m_priv->sixteenBit = loader->sixteenBit(); 0159 setAttribute(QLatin1String("isReadOnly"), loader->isReadOnly()); 0160 delete loader; 0161 0162 return true; 0163 } 0164 0165 delete loader; 0166 } 0167 0168 if (!plugin && !(loadFlags & DImgLoader::LoadPreview)) 0169 { 0170 qCDebug(DIGIKAM_DIMG_LOG) << filePath << ": Unknown image format !!!"; 0171 return false; 0172 } 0173 0174 if (observer && 0175 observer->continueQuery() && 0176 !(loadFlags & DImgLoader::LoadPreview)) 0177 { 0178 qCWarning(DIGIKAM_DIMG_LOG) << filePath << ": Cannot load file !!!"; 0179 } 0180 0181 return false; 0182 } 0183 0184 QString DImg::formatToMimeType(FORMAT frm) 0185 { 0186 QString format; 0187 0188 switch (frm) 0189 { 0190 case (NONE): 0191 { 0192 return format; 0193 } 0194 0195 case (JPEG): 0196 { 0197 format = QLatin1String("JPG"); 0198 break; 0199 } 0200 0201 case (TIFF): 0202 { 0203 format = QLatin1String("TIF"); 0204 break; 0205 } 0206 0207 case (PNG): 0208 { 0209 format = QLatin1String("PNG"); 0210 break; 0211 } 0212 0213 case (JP2K): 0214 { 0215 format = QLatin1String("JP2"); 0216 break; 0217 } 0218 0219 case (PGF): 0220 { 0221 format = QLatin1String("PGF"); 0222 break; 0223 } 0224 0225 default: 0226 { 0227 // For QImage or ImageMagick based. 0228 break; 0229 } 0230 } 0231 0232 return format; 0233 } 0234 0235 bool DImg::save(const QString& filePath, FORMAT frm, DImgLoaderObserver* const observer) 0236 { 0237 if (isNull()) 0238 { 0239 return false; 0240 } 0241 0242 return(save(filePath, formatToMimeType(frm), observer)); 0243 } 0244 0245 bool DImg::save(const QString& filePath, const QString& format, DImgLoaderObserver* const observer) 0246 { 0247 qCDebug(DIGIKAM_DIMG_LOG) << "Saving to " << filePath << " with format: " << format; 0248 0249 if (isNull()) 0250 { 0251 return false; 0252 } 0253 0254 if (format.isEmpty()) 0255 { 0256 return false; 0257 } 0258 0259 QString frm = format.toUpper(); 0260 setAttribute(QLatin1String("savedFilePath"), filePath); 0261 setAttribute(QLatin1String("savedFormat"), frm); 0262 0263 FileWriteLocker lock(filePath); 0264 0265 DPluginDImg* const plug = DImgStaticPriv::pluginForFormat(frm); 0266 DImg copyForSave = copy(); 0267 0268 if ((frm == QLatin1String("JPEG")) || (frm == QLatin1String("JPG")) || (frm == QLatin1String("JPE"))) 0269 { 0270 // JPEG does not support transparency, so we shall provide an image without alpha channel. 0271 // This is only necessary if the image has an alpha channel, and there are actually transparent pixels 0272 0273 if (hasTransparentPixels()) 0274 { 0275 copyForSave.removeAlphaChannel(); 0276 } 0277 } 0278 0279 if (plug) 0280 { 0281 DImgLoader* const loader = plug->loader(©ForSave); 0282 copyForSave.setAttribute(QLatin1String("format"), frm); 0283 copyForSave.setAttribute(QLatin1String("savedFormat-isReadOnly"), loader->isReadOnly()); 0284 bool ret = loader->save(filePath, observer); 0285 delete loader; 0286 0287 return ret; 0288 } 0289 0290 qCWarning(DIGIKAM_DIMG_LOG) << filePath << " : Unknown save format !!!"; 0291 0292 return false; 0293 } 0294 0295 DImg::FORMAT DImg::fileFormat(const QString& filePath) 0296 { 0297 FORMAT format = DImg::NONE; 0298 0299 if (filePath.isEmpty()) 0300 { 0301 return format; 0302 } 0303 0304 QFileInfo fileInfo(filePath); 0305 0306 if (!fileInfo.exists() || !fileInfo.isReadable()) 0307 { 0308 return format; 0309 } 0310 0311 DPluginDImg* const plugin = DImgStaticPriv::pluginForFile(fileInfo, false); 0312 0313 if (plugin) 0314 { 0315 QString name = plugin->loaderName(); 0316 format = DImgStaticPriv::loaderNameToFormat(name); 0317 } 0318 0319 return format; 0320 } 0321 0322 QDateTime DImg::creationDateFromFilesystem(const QFileInfo& fileInfo) const 0323 { 0324 // creation date is not what it seems on Unix 0325 0326 QDateTime ctime = fileInfo.birthTime(); 0327 QDateTime mtime = fileInfo.lastModified(); 0328 0329 if (ctime.isValid()) 0330 { 0331 ctime.setTimeSpec(Qt::UTC); 0332 0333 return ctime; 0334 } 0335 0336 if (mtime.isValid()) 0337 { 0338 mtime.setTimeSpec(Qt::UTC); 0339 0340 return mtime; 0341 } 0342 0343 QDateTime dateTime = QDateTime::currentDateTime(); 0344 dateTime.setTimeSpec(Qt::UTC); 0345 0346 return dateTime; 0347 } 0348 0349 } // namespace Digikam