File indexing completed on 2025-04-27 03:58:07
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-02-03 0007 * Description : Loading parameters for multithreaded loading 0008 * 0009 * SPDX-FileCopyrightText: 2006-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2012-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 #include "loadingdescription.h" 0017 0018 // Local includes 0019 0020 #include "icctransform.h" 0021 #include "thumbnailinfo.h" 0022 #include "thumbnailsize.h" 0023 0024 namespace Digikam 0025 { 0026 0027 LoadingDescription::PreviewParameters::PreviewParameters() 0028 : type (NoPreview), 0029 size (0), 0030 flags(NoFlags) 0031 { 0032 } 0033 0034 bool LoadingDescription::PreviewParameters::operator==(const PreviewParameters& other) const 0035 { 0036 return ((type == other.type) && 0037 (size == other.size) && 0038 (flags == other.flags) && 0039 (previewSettings == other.previewSettings) && 0040 (extraParameter == other.extraParameter) && 0041 (storageReference == other.storageReference)); 0042 } 0043 0044 bool LoadingDescription::PreviewParameters::onlyPregenerate() const 0045 { 0046 return (flags & OnlyPregenerate); 0047 } 0048 0049 bool LoadingDescription::PreviewParameters::onlyFromStorage() const 0050 { 0051 return (flags & OnlyFromStorage); 0052 } 0053 0054 bool LoadingDescription::PostProcessingParameters::operator==(const PostProcessingParameters& other) const 0055 { 0056 return (colorManagement == other.colorManagement); 0057 } 0058 0059 bool LoadingDescription::PostProcessingParameters::needsProcessing() const 0060 { 0061 return (colorManagement != NoColorConversion); 0062 } 0063 0064 void LoadingDescription::PostProcessingParameters::setTransform(const IccTransform& transform) 0065 { 0066 iccData = QVariant::fromValue<IccTransform>(transform); 0067 } 0068 0069 bool LoadingDescription::PostProcessingParameters::hasTransform() const 0070 { 0071 return (!iccData.isNull() && iccData.canConvert<IccTransform>()); 0072 } 0073 0074 IccTransform LoadingDescription::PostProcessingParameters::transform() const 0075 { 0076 return iccData.value<IccTransform>(); 0077 } 0078 0079 void LoadingDescription::PostProcessingParameters::setProfile(const IccProfile& profile) 0080 { 0081 iccData = QVariant::fromValue<IccProfile>(profile); 0082 } 0083 0084 bool LoadingDescription::PostProcessingParameters::hasProfile() const 0085 { 0086 return (!iccData.isNull() && iccData.canConvert<IccProfile>()); 0087 } 0088 0089 IccProfile LoadingDescription::PostProcessingParameters::profile() const 0090 { 0091 return iccData.value<IccProfile>(); 0092 } 0093 0094 // ---------------------------------------------------------------------------- 0095 0096 LoadingDescription::LoadingDescription() 0097 : filePath (QString()), 0098 rawDecodingSettings (DRawDecoding()), 0099 rawDecodingHint (RawDecodingDefaultSettings), 0100 previewParameters (PreviewParameters()), 0101 postProcessingParameters (PostProcessingParameters()) 0102 { 0103 } 0104 0105 LoadingDescription::LoadingDescription(const QString& filePath, 0106 ColorManagementSettings cm) 0107 : filePath (filePath), 0108 rawDecodingSettings (DRawDecoding()), 0109 rawDecodingHint (RawDecodingDefaultSettings), 0110 previewParameters (PreviewParameters()) 0111 { 0112 postProcessingParameters.colorManagement = cm; 0113 } 0114 0115 LoadingDescription::LoadingDescription(const QString& filePath, 0116 const DRawDecoding& settings, 0117 RawDecodingHint hint, 0118 ColorManagementSettings cm) 0119 : filePath (filePath), 0120 rawDecodingSettings (settings), 0121 rawDecodingHint (hint), 0122 previewParameters (PreviewParameters()) 0123 { 0124 postProcessingParameters.colorManagement = cm; 0125 } 0126 0127 LoadingDescription::LoadingDescription(const QString& filePath, 0128 const PreviewSettings& previewSettings, 0129 int size, 0130 ColorManagementSettings cm, 0131 LoadingDescription::PreviewParameters::PreviewType type) 0132 : filePath(filePath), 0133 rawDecodingSettings(DRawDecoding()), 0134 rawDecodingHint(RawDecodingDefaultSettings) 0135 { 0136 previewParameters.type = type; 0137 previewParameters.size = size; 0138 previewParameters.previewSettings = previewSettings; 0139 postProcessingParameters.colorManagement = cm; 0140 } 0141 0142 QString LoadingDescription::cacheKey() const 0143 { 0144 // Here we have the knowledge which LoadingDescriptions / RawFileDecodingSettings 0145 // must be cached separately. 0146 0147 // Thumbnail loading. This one is easy. 0148 0149 if (previewParameters.type == PreviewParameters::Thumbnail) 0150 { 0151 QString fileRef = filePath.isEmpty() ? (QLatin1String("id:/") + previewParameters.storageReference.toString()) 0152 : filePath; 0153 0154 return (fileRef + QLatin1String("-thumbnail-") + QString::number(previewParameters.size)); 0155 } 0156 else if (previewParameters.type == PreviewParameters::DetailThumbnail) 0157 { 0158 QString fileRef = filePath.isEmpty() ? (QLatin1String("id:/") + previewParameters.storageReference.toString()) 0159 : filePath; 0160 QRect rect = previewParameters.extraParameter.toRect(); 0161 QString rectString = QString::fromLatin1("%1,%2-%3x%4-") 0162 .arg(rect.x()) 0163 .arg(rect.y()) 0164 .arg(rect.width()) 0165 .arg(rect.height()); 0166 0167 return (fileRef + QLatin1String("-thumbnail-") + rectString + QString::number(previewParameters.size)); 0168 } 0169 0170 // DImg loading 0171 0172 if (previewParameters.type == PreviewParameters::NoPreview) 0173 { 0174 // Assumption: Full loading. For Raw images, we need to check all parameters here. 0175 // Non-raw images will always be loaded full-size. 0176 // NOTE: do not identify these by cache key only, check the settings! 0177 0178 if (rawDecodingHint == RawDecodingGlobalSettings) 0179 { 0180 return (filePath + QLatin1String("-globalraw")); 0181 } 0182 else if (rawDecodingHint == RawDecodingCustomSettings) 0183 { 0184 return (filePath + QLatin1String("-customraw")); 0185 } 0186 } 0187 else 0188 { 0189 // Assumption: Size-limited previews are always eight bit and do not care for raw settings. 0190 0191 if (previewParameters.size) 0192 { 0193 return (filePath + QLatin1String("-previewImage-") + QString::number(previewParameters.size)); 0194 } 0195 else 0196 { 0197 return (filePath + QLatin1String("-previewImage")); 0198 } 0199 } 0200 0201 QString suffix; 0202 0203 // Assumption: Time-optimized loading is used for previews and non-previews 0204 0205 if (rawDecodingHint == RawDecodingTimeOptimized) 0206 { 0207 // Assumption: With time-optimized, we can have 8 or 16bit and halfSize or demosaiced. 0208 0209 suffix += QLatin1String("-timeoptimized"); 0210 0211 if (!rawDecodingSettings.rawPrm.sixteenBitsImage) 0212 { 0213 suffix += QLatin1String("-8"); 0214 } 0215 0216 if (rawDecodingSettings.rawPrm.halfSizeColorImage) 0217 { 0218 suffix += QLatin1String("-halfSize"); 0219 } 0220 } 0221 0222 return (filePath + suffix); 0223 } 0224 0225 QStringList LoadingDescription::lookupCacheKeys() const 0226 { 0227 // Build a hierarchy which cache entries may be used for this LoadingDescription. 0228 0229 // Thumbnail loading. No other cache key included! 0230 0231 if ((previewParameters.type == PreviewParameters::Thumbnail) || 0232 (previewParameters.type == PreviewParameters::DetailThumbnail)) 0233 { 0234 return QStringList() << cacheKey(); 0235 } 0236 0237 // DImg loading. 0238 // Typically, the first is the best. An actual loading operation may use a 0239 // lower-quality loading and will effectively only add the last entry of the 0240 // list to the cache, although it can accept the first if already available. 0241 // Hierarchy: 0242 // Raw with GlobalSettings and CustomSettings 0243 // Raw with optimized loading, 8 or 16bit 0244 // full size 0245 // halfSize 0246 // "Normal" image (default raw parameters) 0247 // Preview image 0248 // full size 0249 // reduced size 0250 0251 QStringList cacheKeys; 0252 0253 if (previewParameters.type != PreviewParameters::NoPreview) 0254 { 0255 if (previewParameters.size) 0256 { 0257 cacheKeys << filePath + QLatin1String("-previewImage-") + QString::number(previewParameters.size); 0258 } 0259 0260 // full size preview 0261 0262 cacheKeys << filePath + QLatin1String("-previewImage"); 0263 } 0264 0265 if (rawDecodingHint == RawDecodingDefaultSettings) 0266 { 0267 cacheKeys << filePath; 0268 } 0269 0270 if (rawDecodingHint == RawDecodingTimeOptimized) 0271 { 0272 if (rawDecodingSettings.rawPrm.sixteenBitsImage) 0273 { 0274 cacheKeys << filePath + QLatin1String("-timeoptimized"); 0275 0276 if (rawDecodingSettings.rawPrm.halfSizeColorImage) 0277 { 0278 cacheKeys << filePath + QLatin1String("-timeoptimized-halfSize"); 0279 } 0280 } 0281 else 0282 { 0283 cacheKeys << filePath + QLatin1String("-timeoptimized-8"); 0284 0285 if (rawDecodingSettings.rawPrm.halfSizeColorImage) 0286 { 0287 cacheKeys << filePath + QLatin1String("-timeoptimized-8-halfSize"); 0288 } 0289 } 0290 } 0291 0292 if (rawDecodingHint == RawDecodingGlobalSettings) 0293 { 0294 cacheKeys << filePath + QLatin1String("-globalraw"); 0295 } 0296 else if (rawDecodingHint == RawDecodingCustomSettings) 0297 { 0298 cacheKeys << filePath + QLatin1String("-customraw"); 0299 } 0300 0301 return cacheKeys; 0302 } 0303 0304 bool LoadingDescription::needCheckRawDecoding() const 0305 { 0306 return ((rawDecodingHint == RawDecodingGlobalSettings) || 0307 (rawDecodingHint == RawDecodingCustomSettings)); 0308 } 0309 0310 bool LoadingDescription::isReducedVersion() const 0311 { 0312 // return true if this loads anything but the full version 0313 0314 return (rawDecodingSettings.rawPrm.halfSizeColorImage || 0315 (previewParameters.type != PreviewParameters::NoPreview)); 0316 } 0317 0318 bool LoadingDescription::operator==(const LoadingDescription& other) const 0319 { 0320 return ((filePath == other.filePath) && 0321 (rawDecodingSettings == other.rawDecodingSettings) && 0322 (previewParameters == other.previewParameters) && 0323 (postProcessingParameters == other.postProcessingParameters)); 0324 } 0325 0326 bool LoadingDescription::operator!=(const LoadingDescription& other) const 0327 { 0328 return (!operator==(other)); 0329 } 0330 0331 bool LoadingDescription::equalsIgnoreReducedVersion(const LoadingDescription& other) const 0332 { 0333 return (filePath == other.filePath); 0334 } 0335 0336 bool LoadingDescription::equalsOrBetterThan(const LoadingDescription& other) const 0337 { 0338 // This method is similar to operator==. But it returns true as well if this 0339 // loads a "better" version than <other>. 0340 // Preview parameters must have the same size, or other has no size restriction. 0341 // Comparing raw decoding settings is complicated. We allow to be loaded with optimizeTimeLoading(). 0342 0343 DRawDecoding fast = rawDecodingSettings; 0344 fast.optimizeTimeLoading(); 0345 0346 return ( 0347 (filePath == other.filePath) && 0348 ( 0349 (rawDecodingSettings == other.rawDecodingSettings) || 0350 (fast == other.rawDecodingSettings) 0351 ) && 0352 ( 0353 (previewParameters.size == other.previewParameters.size) || 0354 other.previewParameters.size 0355 ) 0356 ); 0357 } 0358 0359 bool LoadingDescription::isThumbnail() const 0360 { 0361 return ((previewParameters.type == PreviewParameters::Thumbnail) || 0362 (previewParameters.type == PreviewParameters::DetailThumbnail)); 0363 } 0364 0365 bool LoadingDescription::isPreviewImage() const 0366 { 0367 return (previewParameters.type == PreviewParameters::PreviewImage); 0368 } 0369 0370 ThumbnailIdentifier LoadingDescription::thumbnailIdentifier() const 0371 { 0372 ThumbnailIdentifier id; 0373 0374 if (!isThumbnail()) 0375 { 0376 return id; 0377 } 0378 0379 id.filePath = filePath; 0380 id.id = previewParameters.storageReference.toLongLong(); 0381 0382 return id; 0383 } 0384 0385 QStringList LoadingDescription::possibleCacheKeys(const QString& filePath) 0386 { 0387 QStringList keys; 0388 keys << filePath ; 0389 keys << filePath + QLatin1String("-timeoptimized-8-halfSize"); 0390 keys << filePath + QLatin1String("-timeoptimized-8"); 0391 keys << filePath + QLatin1String("-timeoptimized-halfSize"); 0392 keys << filePath + QLatin1String("-timeoptimized"); 0393 keys << filePath + QLatin1String("-customraw"); 0394 keys << filePath + QLatin1String("-globalraw"); 0395 0396 for (int i = 1 ; i <= ThumbnailSize::HD ; ++i) 0397 { 0398 keys << filePath + QLatin1String("-previewImage-") + QString::number(i); 0399 } 0400 0401 return keys; 0402 } 0403 0404 QStringList LoadingDescription::possibleThumbnailCacheKeys(const QString& filePath) 0405 { 0406 // FIXME: With details, there is an endless number of possible cache keys. Need different approach. 0407 0408 QStringList keys; 0409 0410 // there are (ThumbnailSize::HD) possible keys... 0411 0412 QString path = filePath + QLatin1String("-thumbnail-"); 0413 0414 for (int i = 1 ; i <= ThumbnailSize::HD ; ++i) 0415 { 0416 keys << path + QString::number(i); 0417 } 0418 0419 return keys; 0420 } 0421 0422 } // namespace Digikam