File indexing completed on 2025-01-19 03:56:02
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2006-09-15 0007 * Description : Exiv2 library interface. 0008 * Embedded preview loading. 0009 * 0010 * SPDX-FileCopyrightText: 2006-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 // Local includes 0018 0019 #include "metaengine_previews.h" 0020 #include "metaengine_p.h" 0021 #include "digikam_debug.h" 0022 #include "digikam_config.h" 0023 0024 #if defined(Q_CC_CLANG) 0025 # pragma clang diagnostic push 0026 # pragma clang diagnostic ignored "-Wdeprecated-declarations" 0027 #endif 0028 0029 namespace Digikam 0030 { 0031 0032 class Q_DECL_HIDDEN MetaEnginePreviews::Private 0033 { 0034 public: 0035 0036 explicit Private() 0037 : manager(nullptr) 0038 { 0039 } 0040 0041 ~Private() 0042 { 0043 delete manager; 0044 } 0045 0046 void load(Exiv2::Image::AutoPtr image_) // clazy:exclude=function-args-by-ref 0047 { 0048 QMutexLocker lock(&s_metaEngineMutex); 0049 0050 try 0051 { 0052 0053 #if EXIV2_TEST_VERSION(0,27,99) 0054 0055 image = std::move(image_); 0056 0057 #else 0058 0059 image = image_; 0060 0061 #endif 0062 image->readMetadata(); 0063 0064 manager = new Exiv2::PreviewManager(*image); 0065 Exiv2::PreviewPropertiesList props = manager->getPreviewProperties(); 0066 0067 // reverse order of list, which is smallest-first 0068 0069 Exiv2::PreviewPropertiesList::reverse_iterator it; 0070 0071 for (it = props.rbegin() ; it != props.rend() ; ++it) 0072 { 0073 properties << *it; 0074 } 0075 } 0076 catch (Exiv2::AnyError& e) 0077 { 0078 MetaEngine::Private::printExiv2ExceptionError(QLatin1String("Cannot load preview data with Exiv2:"), e); 0079 } 0080 catch (...) 0081 { 0082 qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; 0083 } 0084 } 0085 0086 public: 0087 0088 Exiv2::Image::AutoPtr image; 0089 Exiv2::PreviewManager* manager; 0090 QList<Exiv2::PreviewProperties> properties; 0091 }; 0092 0093 MetaEnginePreviews::MetaEnginePreviews(const QString& filePath) 0094 : d(new Private) 0095 { 0096 QMutexLocker lock(&s_metaEngineMutex); 0097 0098 try 0099 { 0100 0101 #if defined Q_OS_WIN && defined EXV_UNICODE_PATH 0102 0103 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open((const wchar_t*)filePath.utf16()); 0104 0105 #elif defined Q_OS_WIN 0106 0107 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(QFile::encodeName(filePath).constData()); 0108 0109 #else 0110 0111 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filePath.toUtf8().constData()); 0112 0113 #endif 0114 0115 #if EXIV2_TEST_VERSION(0,27,99) 0116 0117 d->load(std::move(image)); 0118 0119 #else 0120 0121 d->load(image); 0122 0123 #endif 0124 0125 } 0126 catch (Exiv2::AnyError& e) 0127 { 0128 MetaEngine::Private::printExiv2ExceptionError(QLatin1String("Cannot load metadata with Exiv2:"), e); 0129 } 0130 catch (...) 0131 { 0132 qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; 0133 } 0134 } 0135 0136 MetaEnginePreviews::MetaEnginePreviews(const QByteArray& imgData) 0137 : d(new Private) 0138 { 0139 QMutexLocker lock(&s_metaEngineMutex); 0140 0141 try 0142 { 0143 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open((Exiv2::byte*)imgData.data(), imgData.size()); 0144 0145 #if EXIV2_TEST_VERSION(0,27,99) 0146 0147 d->load(std::move(image)); 0148 0149 #else 0150 0151 d->load(image); 0152 0153 #endif 0154 0155 } 0156 catch (Exiv2::AnyError& e) 0157 { 0158 MetaEngine::Private::printExiv2ExceptionError(QLatin1String("Cannot load metadata with Exiv2:"), e); 0159 } 0160 catch (...) 0161 { 0162 qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; 0163 } 0164 } 0165 0166 MetaEnginePreviews::~MetaEnginePreviews() 0167 { 0168 delete d; 0169 } 0170 0171 bool MetaEnginePreviews::isEmpty() 0172 { 0173 return d->properties.isEmpty(); 0174 } 0175 0176 QSize MetaEnginePreviews::originalSize() const 0177 { 0178 if (d->image.get()) 0179 { 0180 return QSize(d->image->pixelWidth(), d->image->pixelHeight()); 0181 } 0182 0183 return QSize(); 0184 } 0185 0186 QString MetaEnginePreviews::originalMimeType() const 0187 { 0188 if (d->image.get()) 0189 { 0190 return QString::fromStdString(d->image->mimeType()); 0191 } 0192 0193 return QString(); 0194 } 0195 0196 int MetaEnginePreviews::count() const 0197 { 0198 return d->properties.size(); 0199 } 0200 0201 int MetaEnginePreviews::size() const 0202 { 0203 return count(); 0204 } 0205 0206 int MetaEnginePreviews::dataSize(int index) 0207 { 0208 if ((index < 0) || (index >= size())) 0209 { 0210 return 0; 0211 } 0212 0213 return d->properties[index].size_; 0214 } 0215 0216 int MetaEnginePreviews::width(int index) 0217 { 0218 if ((index < 0) || (index >= size())) 0219 { 0220 return 0; 0221 } 0222 0223 return d->properties[index].width_; 0224 } 0225 0226 int MetaEnginePreviews::height(int index) 0227 { 0228 if ((index < 0) || (index >= size())) 0229 { 0230 return 0; 0231 } 0232 0233 return d->properties[index].height_; 0234 } 0235 0236 QString MetaEnginePreviews::mimeType(int index) 0237 { 0238 if ((index < 0) || (index >= size())) 0239 { 0240 return QString(); 0241 } 0242 0243 return QString::fromStdString(d->properties[index].mimeType_); 0244 } 0245 0246 QString MetaEnginePreviews::fileExtension(int index) 0247 { 0248 if ((index < 0) || (index >= size())) 0249 { 0250 return QString(); 0251 } 0252 0253 return QString::fromStdString(d->properties[index].extension_); 0254 } 0255 0256 QByteArray MetaEnginePreviews::data(int index) 0257 { 0258 if ((index < 0) || (index >= size())) 0259 { 0260 return QByteArray(); 0261 } 0262 0263 qCDebug(DIGIKAM_METAENGINE_LOG) << "index : " << index; 0264 qCDebug(DIGIKAM_METAENGINE_LOG) << "properties: " << count(); 0265 0266 QMutexLocker lock(&s_metaEngineMutex); 0267 0268 try 0269 { 0270 Exiv2::PreviewImage image = d->manager->getPreviewImage(d->properties[index]); 0271 0272 return QByteArray((const char*)image.pData(), image.size()); 0273 } 0274 catch (Exiv2::AnyError& e) 0275 { 0276 MetaEngine::Private::printExiv2ExceptionError(QLatin1String("Cannot load metadata with Exiv2:"), e); 0277 0278 return QByteArray(); 0279 } 0280 catch (...) 0281 { 0282 qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; 0283 0284 return QByteArray(); 0285 } 0286 } 0287 0288 QImage MetaEnginePreviews::image(int index) 0289 { 0290 QByteArray previewData = data(index); 0291 QImage image; 0292 0293 if (previewData.isEmpty() || !image.loadFromData(previewData)) 0294 { 0295 return QImage(); 0296 } 0297 0298 return image; 0299 } 0300 0301 } // namespace Digikam 0302 0303 #if defined(Q_CC_CLANG) 0304 # pragma clang diagnostic pop 0305 #endif