File indexing completed on 2025-04-27 03:58:22
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-08-02 0007 * Description : a stack of widgets to set image file save 0008 * options into image editor. 0009 * 0010 * SPDX-FileCopyrightText: 2007-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 "filesaveoptionsbox.h" 0017 0018 // Qt includes 0019 0020 #include <QCheckBox> 0021 #include <QGridLayout> 0022 #include <QImageReader> 0023 #include <QLabel> 0024 #include <QWidget> 0025 #include <QApplication> 0026 #include <QStyle> 0027 0028 // KDE includes 0029 0030 #include <kconfiggroup.h> 0031 #include <ksharedconfig.h> 0032 #include <klocalizedstring.h> 0033 0034 // Local includes 0035 0036 #include "digikam_debug.h" 0037 #include "dpluginloader.h" 0038 0039 namespace Digikam 0040 { 0041 0042 class Q_DECL_HIDDEN FileSaveOptionsBox::Private 0043 { 0044 0045 public: 0046 0047 explicit Private() 0048 : noneOptions (nullptr), 0049 noneGrid (nullptr), 0050 labelNone (nullptr), 0051 JPEGOptions (nullptr), 0052 PNGOptions (nullptr), 0053 TIFFOptions (nullptr), 0054 0055 #ifdef HAVE_JASPER 0056 0057 JPEG2000Options (nullptr), 0058 0059 #endif // HAVE_JASPER 0060 0061 #ifdef HAVE_X265 0062 0063 HEIFOptions (nullptr), 0064 0065 #endif // HAVE_X265 0066 0067 PGFOptions (nullptr), 0068 JXLOptions (nullptr), 0069 WEBPOptions (nullptr), 0070 AVIFOptions (nullptr) 0071 { 0072 } 0073 0074 QWidget* noneOptions; 0075 0076 QGridLayout* noneGrid; 0077 0078 QLabel* labelNone; 0079 0080 DImgLoaderSettings* JPEGOptions; 0081 DImgLoaderSettings* PNGOptions; 0082 DImgLoaderSettings* TIFFOptions; 0083 0084 #ifdef HAVE_JASPER 0085 0086 DImgLoaderSettings* JPEG2000Options; 0087 0088 #endif // HAVE_JASPER 0089 0090 #ifdef HAVE_X265 0091 0092 DImgLoaderSettings* HEIFOptions; 0093 0094 #endif // HAVE_X265 0095 0096 DImgLoaderSettings* PGFOptions; 0097 DImgLoaderSettings* JXLOptions; 0098 DImgLoaderSettings* WEBPOptions; 0099 DImgLoaderSettings* AVIFOptions; 0100 }; 0101 0102 FileSaveOptionsBox::FileSaveOptionsBox(QWidget* const parent) 0103 : QStackedWidget(parent), 0104 d (new Private) 0105 { 0106 setAttribute(Qt::WA_DeleteOnClose); 0107 0108 //-- NONE Settings ------------------------------------------------------ 0109 0110 d->noneOptions = new QWidget(this); 0111 d->noneGrid = new QGridLayout(d->noneOptions); 0112 d->noneGrid->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0113 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0114 d->noneOptions->setLayout(d->noneGrid); 0115 d->labelNone = new QLabel(i18n("No options available"), d->noneOptions); 0116 d->noneGrid->addWidget(d->labelNone, 0, 0, 0, 1); 0117 DPluginLoader* const ploader = DPluginLoader::instance(); 0118 0119 //-- JPEG Settings ------------------------------------------------------ 0120 0121 d->JPEGOptions = ploader->exportWidget(QLatin1String("JPEG")); 0122 d->JPEGOptions->setParent(this); 0123 0124 //-- PNG Settings ------------------------------------------------------- 0125 0126 d->PNGOptions = ploader->exportWidget(QLatin1String("PNG")); 0127 d->PNGOptions->setParent(this); 0128 0129 //-- TIFF Settings ------------------------------------------------------ 0130 0131 d->TIFFOptions = ploader->exportWidget(QLatin1String("TIFF")); 0132 d->TIFFOptions->setParent(this); 0133 0134 //-- JPEG 2000 Settings ------------------------------------------------- 0135 0136 #ifdef HAVE_JASPER 0137 0138 d->JPEG2000Options = ploader->exportWidget(QLatin1String("JP2")); 0139 d->JPEG2000Options->setParent(this); 0140 0141 #endif // HAVE_JASPER 0142 0143 //-- PGF Settings ------------------------------------------------- 0144 0145 d->PGFOptions = ploader->exportWidget(QLatin1String("PGF")); 0146 d->PGFOptions->setParent(this); 0147 0148 //-- JXL Settings ------------------------------------------------- 0149 0150 // NOTE: JXL support depend of JXL QImage loader plugin availability. 0151 0152 d->JXLOptions = ploader->exportWidget(QLatin1String("JXL")); 0153 0154 if (d->JXLOptions) 0155 { 0156 d->JXLOptions->setParent(this); 0157 } 0158 0159 //-- WEBP Settings ------------------------------------------------- 0160 0161 // NOTE: WEBP support depend of WEBP QImage loader plugin availability. 0162 0163 d->WEBPOptions = ploader->exportWidget(QLatin1String("WEBP")); 0164 0165 if (d->WEBPOptions) 0166 { 0167 d->WEBPOptions->setParent(this); 0168 } 0169 0170 //-- AVIF Settings ------------------------------------------------- 0171 0172 // NOTE: AVIF support depend of JXL QImage loader plugin availability. 0173 0174 d->AVIFOptions = ploader->exportWidget(QLatin1String("AVIF")); 0175 0176 if (d->AVIFOptions) 0177 { 0178 d->AVIFOptions->setParent(this); 0179 } 0180 0181 //-- HEIF Settings ------------------------------------------------- 0182 0183 #ifdef HAVE_X265 0184 0185 d->HEIFOptions = ploader->exportWidget(QLatin1String("HEIF")); 0186 d->HEIFOptions->setParent(this); 0187 0188 #endif // HAVE_X265 0189 0190 //----------------------------------------------------------------------- 0191 0192 insertWidget(NONE, d->noneOptions); 0193 insertWidget(JPEG, d->JPEGOptions); 0194 insertWidget(PNG, d->PNGOptions); 0195 insertWidget(TIFF, d->TIFFOptions); 0196 0197 #ifdef HAVE_JASPER 0198 0199 insertWidget(JP2K, d->JPEG2000Options); 0200 0201 #endif // HAVE_JASPER 0202 0203 insertWidget(PGF, d->PGFOptions); 0204 0205 #ifdef HAVE_X265 0206 0207 insertWidget(HEIF, d->HEIFOptions); 0208 0209 #endif // HAVE_X265 0210 0211 if (d->JXLOptions) 0212 { 0213 insertWidget(JXL, d->JXLOptions); 0214 } 0215 0216 if (d->WEBPOptions) 0217 { 0218 insertWidget(WEBP, d->WEBPOptions); 0219 } 0220 0221 if (d->AVIFOptions) 0222 { 0223 insertWidget(AVIF, d->AVIFOptions); 0224 } 0225 0226 //----------------------------------------------------------------------- 0227 0228 readSettings(); 0229 } 0230 0231 FileSaveOptionsBox::~FileSaveOptionsBox() 0232 { 0233 delete d; 0234 } 0235 0236 void FileSaveOptionsBox::setImageFileFormat(const QString& ext) 0237 { 0238 qCDebug(DIGIKAM_WIDGETS_LOG) << "Format selected: " << ext; 0239 setCurrentIndex(discoverFormat(ext, NONE)); 0240 } 0241 0242 FileSaveOptionsBox::FORMAT FileSaveOptionsBox::discoverFormat(const QString& filename, 0243 FileSaveOptionsBox::FORMAT fallback) 0244 { 0245 qCDebug(DIGIKAM_WIDGETS_LOG) << "Trying to discover format based on filename '" << filename 0246 << "', fallback = " << fallback; 0247 0248 QStringList splitParts = filename.split(QLatin1Char('.')); 0249 QString ext; 0250 0251 if (splitParts.size() < 2) 0252 { 0253 qCDebug(DIGIKAM_WIDGETS_LOG) << "filename '" << filename 0254 << "' does not contain an extension separated by a point."; 0255 ext = filename; 0256 } 0257 else 0258 { 0259 ext = splitParts.at(splitParts.size() - 1); 0260 } 0261 0262 ext = ext.toUpper(); 0263 0264 FORMAT format = fallback; 0265 0266 if (ext.contains(QLatin1String("JPEG")) || ext.contains(QLatin1String("JPG")) || ext.contains(QLatin1String("JPE"))) 0267 { 0268 format = JPEG; 0269 } 0270 else if (ext.contains(QLatin1String("PNG"))) 0271 { 0272 format = PNG; 0273 } 0274 else if (ext.contains(QLatin1String("TIFF")) || ext.contains(QLatin1String("TIF"))) 0275 { 0276 format = TIFF; 0277 } 0278 0279 #ifdef HAVE_JASPER 0280 0281 else if (ext.contains(QLatin1String("JP2")) || ext.contains(QLatin1String("JPX")) || ext.contains(QLatin1String("JPC")) || 0282 ext.contains(QLatin1String("PGX")) || ext.contains(QLatin1String("J2K"))) 0283 { 0284 format = JP2K; 0285 } 0286 0287 #endif // HAVE_JASPER 0288 0289 #ifdef HAVE_X265 0290 0291 else if (ext.contains(QLatin1String("HEIC")) || ext.contains(QLatin1String("HEIF")) || ext.contains(QLatin1String("HIF"))) 0292 { 0293 format = HEIF; 0294 } 0295 0296 #endif // HAVE_X265 0297 0298 else if (ext.contains(QLatin1String("PGF"))) 0299 { 0300 format = PGF; 0301 } 0302 else if (ext.contains(QLatin1String("JXL"))) 0303 { 0304 format = JXL; 0305 } 0306 else if (ext.contains(QLatin1String("WEBP"))) 0307 { 0308 format = WEBP; 0309 } 0310 else if (ext.contains(QLatin1String("AVIF"))) 0311 { 0312 format = AVIF; 0313 } 0314 else 0315 { 0316 qCWarning(DIGIKAM_WIDGETS_LOG) << "Using fallback format " << fallback; 0317 } 0318 0319 qCDebug(DIGIKAM_WIDGETS_LOG) << "Discovered format: " << format; 0320 0321 return format; 0322 } 0323 0324 void FileSaveOptionsBox::applySettings() 0325 { 0326 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0327 KConfigGroup group = config->group(QLatin1String("ImageViewer Settings")); 0328 group.writeEntry(QLatin1String("JPEGCompression"), d->JPEGOptions->settings()[QLatin1String("quality")].toInt()); 0329 group.writeEntry(QLatin1String("JPEGSubSampling"), d->JPEGOptions->settings()[QLatin1String("subsampling")].toInt()); 0330 0331 // --- 0332 0333 group.writeEntry(QLatin1String("PNGCompression"), d->PNGOptions->settings()[QLatin1String("quality")].toInt()); 0334 0335 // --- 0336 0337 group.writeEntry(QLatin1String("TIFFCompression"), d->TIFFOptions->settings()[QLatin1String("compress")].toBool()); 0338 0339 #ifdef HAVE_JASPER 0340 0341 group.writeEntry(QLatin1String("JPEG2000Compression"), d->JPEG2000Options->settings()[QLatin1String("quality")].toInt()); 0342 group.writeEntry(QLatin1String("JPEG2000LossLess"), d->JPEG2000Options->settings()[QLatin1String("lossless")].toBool()); 0343 0344 #endif // HAVE_JASPER 0345 0346 group.writeEntry(QLatin1String("PGFCompression"), d->PGFOptions->settings()[QLatin1String("quality")].toInt()); 0347 group.writeEntry(QLatin1String("PGFLossLess"), d->PGFOptions->settings()[QLatin1String("lossless")].toBool()); 0348 0349 #ifdef HAVE_X265 0350 0351 group.writeEntry(QLatin1String("HEIFCompression"), d->HEIFOptions->settings()[QLatin1String("quality")].toInt()); 0352 group.writeEntry(QLatin1String("HEIFLossLess"), d->HEIFOptions->settings()[QLatin1String("lossless")].toBool()); 0353 0354 #endif // HAVE_X265 0355 0356 if (d->JXLOptions) 0357 { 0358 group.writeEntry(QLatin1String("JXLCompression"), d->JXLOptions->settings()[QLatin1String("quality")].toInt()); 0359 group.writeEntry(QLatin1String("JXLLossLess"), d->JXLOptions->settings()[QLatin1String("lossless")].toBool()); 0360 } 0361 0362 if (d->WEBPOptions) 0363 { 0364 group.writeEntry(QLatin1String("WEBPCompression"), d->WEBPOptions->settings()[QLatin1String("quality")].toInt()); 0365 group.writeEntry(QLatin1String("WEBPLossLess"), d->WEBPOptions->settings()[QLatin1String("lossless")].toBool()); 0366 } 0367 0368 if (d->AVIFOptions) 0369 { 0370 group.writeEntry(QLatin1String("AVIFCompression"), d->AVIFOptions->settings()[QLatin1String("quality")].toInt()); 0371 group.writeEntry(QLatin1String("AVIFLossLess"), d->AVIFOptions->settings()[QLatin1String("lossless")].toBool()); 0372 } 0373 0374 config->sync(); 0375 } 0376 0377 void FileSaveOptionsBox::readSettings() 0378 { 0379 DImgLoaderPrms set; 0380 0381 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0382 KConfigGroup group = config->group(QLatin1String("ImageViewer Settings")); 0383 0384 set.clear(); 0385 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("JPEGCompression"), 75)); 0386 set.insert(QLatin1String("subsampling"), group.readEntry(QLatin1String("JPEGSubSampling"), 1)); ///< Medium subsampling 0387 d->JPEGOptions->setSettings(set); 0388 0389 // --- 0390 0391 set.clear(); 0392 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("PNGCompression"), 9)); 0393 d->PNGOptions->setSettings(set); 0394 0395 // --- 0396 0397 set.clear(); 0398 set.insert(QLatin1String("compress"), group.readEntry(QLatin1String("TIFFCompression"), false)); 0399 d->TIFFOptions->setSettings(set); 0400 0401 #ifdef HAVE_JASPER 0402 0403 set.clear(); 0404 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("JPEG2000Compression"), 75)); 0405 set.insert(QLatin1String("lossless"), group.readEntry(QLatin1String("JPEG2000LossLess"), true)); 0406 d->JPEG2000Options->setSettings(set); 0407 0408 #endif // HAVE_JASPER 0409 0410 set.clear(); 0411 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("PGFCompression"), 3)); 0412 set.insert(QLatin1String("lossless"), group.readEntry(QLatin1String("PGFLossLess"), true)); 0413 d->PGFOptions->setSettings(set); 0414 0415 #ifdef HAVE_X265 0416 0417 set.clear(); 0418 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("HEIFCompression"), 75)); 0419 set.insert(QLatin1String("lossless"), group.readEntry(QLatin1String("HEIFLossLess"), true)); 0420 d->HEIFOptions->setSettings(set); 0421 0422 #endif // HAVE_X265 0423 0424 if (d->JXLOptions) 0425 { 0426 set.clear(); 0427 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("JXLCompression"), 75)); 0428 set.insert(QLatin1String("lossless"), group.readEntry(QLatin1String("JXLLossLess"), true)); 0429 d->JXLOptions->setSettings(set); 0430 } 0431 0432 if (d->WEBPOptions) 0433 { 0434 set.clear(); 0435 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("WEBPCompression"), 75)); 0436 set.insert(QLatin1String("lossless"), group.readEntry(QLatin1String("WEBPLossLess"), true)); 0437 d->WEBPOptions->setSettings(set); 0438 } 0439 0440 if (d->AVIFOptions) 0441 { 0442 set.clear(); 0443 set.insert(QLatin1String("quality"), group.readEntry(QLatin1String("AVIFCompression"), 75)); 0444 set.insert(QLatin1String("lossless"), group.readEntry(QLatin1String("AVIFLossLess"), true)); 0445 d->AVIFOptions->setSettings(set); 0446 } 0447 } 0448 0449 } // namespace Digikam 0450 0451 #include "moc_filesaveoptionsbox.cpp"