File indexing completed on 2024-12-22 04:15:44
0001 /* 0002 * SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_wdg_options_jpegxl.h" 0008 0009 #include <tuple> 0010 0011 #include <KoColorModelStandardIds.h> 0012 0013 KisWdgOptionsJPEGXL::KisWdgOptionsJPEGXL(QWidget *parent) 0014 : KisConfigWidget(parent) 0015 { 0016 setupUi(this); 0017 0018 { 0019 resampling->addItem(i18nc("JPEG-XL encoder options", "Default (only for low quality)"), -1); 0020 resampling->addItem(i18nc("JPEG-XL encoder options", "No downsampling"), 1); 0021 resampling->addItem(i18nc("JPEG-XL encoder options", "2x2 downsampling"), 2); 0022 resampling->addItem(i18nc("JPEG-XL encoder options", "4x4 downsampling"), 4); 0023 resampling->addItem(i18nc("JPEG-XL encoder options", "8x8 downsampling"), 8); 0024 0025 extraChannelResampling->addItem(i18nc("JPEG-XL encoder options", "Default (only for low quality)"), -1); 0026 extraChannelResampling->addItem(i18nc("JPEG-XL encoder options", "No downsampling"), 1); 0027 extraChannelResampling->addItem(i18nc("JPEG-XL encoder options", "2x2 downsampling"), 2); 0028 extraChannelResampling->addItem(i18nc("JPEG-XL encoder options", "4x4 downsampling"), 4); 0029 extraChannelResampling->addItem(i18nc("JPEG-XL encoder options", "8x8 downsampling"), 8); 0030 } 0031 0032 { 0033 dots->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0034 dots->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0035 dots->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0036 } 0037 0038 { 0039 patches->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0040 patches->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0041 patches->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0042 } 0043 0044 { 0045 gaborish->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0046 gaborish->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0047 gaborish->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0048 } 0049 0050 { 0051 modular->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0052 modular->addItem(i18nc("JPEG-XL encoder options", "VarDCT mode (e.g. for photographic images)"), 0); 0053 modular->addItem(i18nc("JPEG-XL encoder options", "Modular mode (e.g. for lossless images)"), -1); 0054 } 0055 0056 { 0057 keepInvisible->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0058 keepInvisible->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0059 keepInvisible->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0060 } 0061 0062 { 0063 groupOrder->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0064 groupOrder->addItem(i18nc("JPEG-XL encoder options", "Scanline order"), 0); 0065 groupOrder->addItem(i18nc("JPEG-XL encoder options", "Center-first order"), -1); 0066 } 0067 0068 { 0069 responsive->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0070 responsive->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0071 responsive->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0072 } 0073 0074 { 0075 progressiveAC->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0076 progressiveAC->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0077 progressiveAC->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0078 } 0079 0080 { 0081 qProgressiveAC->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0082 qProgressiveAC->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0083 qProgressiveAC->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0084 } 0085 0086 { 0087 progressiveDC->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0088 progressiveDC->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0089 progressiveDC->addItem(i18nc("JPEG-XL encoder options", "64x64 lower resolution pass"), 1); 0090 progressiveDC->addItem(i18nc("JPEG-XL encoder options", "512x512 + 64x64 lower resolution passes"), 2); 0091 } 0092 0093 { 0094 lossyPalette->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0095 lossyPalette->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0096 lossyPalette->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0097 } 0098 0099 { 0100 modularGroupSize->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0101 modularGroupSize->addItem(i18nc("JPEG-XL encoder options", "128"), 0); 0102 modularGroupSize->addItem(i18nc("JPEG-XL encoder options", "256"), 1); 0103 modularGroupSize->addItem(i18nc("JPEG-XL encoder options", "512"), 2); 0104 modularGroupSize->addItem(i18nc("JPEG-XL encoder options", "1024"), 3); 0105 } 0106 0107 { 0108 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0109 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Zero"), 0); 0110 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Left"), 1); 0111 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Top"), 2); 0112 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Avg0"), 3); 0113 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Select"), 4); 0114 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Gradient"), 5); 0115 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Weighted"), 6); 0116 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Top right"), 7); 0117 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Top left"), 8); 0118 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Left left"), 9); 0119 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Avg1"), 10); 0120 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Avg2"), 11); 0121 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Avg3"), 12); 0122 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Toptop predictive average"), 13); 0123 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Gradient + Weighted"), 14); 0124 modularPredictor->addItem(i18nc("JPEG-XL encoder options", "Use all predictors"), 15); 0125 } 0126 0127 { 0128 jpegReconCFL->addItem(i18nc("JPEG-XL encoder options", "Default (encoder chooses)"), -1); 0129 jpegReconCFL->addItem(i18nc("JPEG-XL encoder options", "Disabled"), 0); 0130 jpegReconCFL->addItem(i18nc("JPEG-XL encoder options", "Enabled"), 1); 0131 } 0132 0133 metaDataFilters->setModel(&m_filterRegistryModel); 0134 0135 connect(cmbConversionPolicy, 0136 qOverload<int>(&QComboBox::currentIndexChanged), 0137 this, 0138 &KisWdgOptionsJPEGXL::toggleExtraHDROptions); 0139 0140 connect(modular, qOverload<int>(&QComboBox::currentIndexChanged), this, &KisWdgOptionsJPEGXL::toggleModularTabs); 0141 } 0142 0143 void KisWdgOptionsJPEGXL::toggleExtraHDROptions(int index) 0144 { 0145 const QString option = cmbConversionPolicy->itemData(index).value<QString>(); 0146 chkHLGOOTF->setEnabled(option.contains("HLG")); 0147 } 0148 0149 void KisWdgOptionsJPEGXL::toggleModularTabs(int index) 0150 { 0151 const int id = modular->itemData(index, Qt::UserRole).value<int>(); 0152 advancedParameters->setTabEnabled(1, id == -1 || id == 0); // vardct 0153 advancedParameters->setTabEnabled(2, id == -1 || id == 1); // modular 0154 } 0155 0156 void KisWdgOptionsJPEGXL::setConfiguration(const KisPropertiesConfigurationSP cfg) 0157 { 0158 using SpaceList = QList<std::tuple<QString, QString, QString>>; 0159 0160 haveAnimation->setChecked(cfg->getBool("haveAnimation", true)); 0161 flattenLayers->setChecked(cfg->getBool("flattenLayers", true)); 0162 lossyEncoding->setChecked(!cfg->getBool("lossless", true)); 0163 effort->setValue(cfg->getInt("effort", 7)); 0164 decodingSpeed->setValue(cfg->getInt("decodingSpeed", 0)); 0165 lossyQuality->setValue(cfg->getInt("lossyQuality", 100)); 0166 forceModular->setChecked(cfg->getBool("forceModular", false)); 0167 0168 const int CicpPrimaries = cfg->getInt(KisImportExportFilter::CICPPrimariesTag, PRIMARIES_UNSPECIFIED); 0169 tabWidget->setTabEnabled(1, cfg->getBool(KisImportExportFilter::HDRTag, false) 0170 && cfg->getString(KisImportExportFilter::ColorModelIDTag) != GrayAColorModelID.id()); 0171 SpaceList conversionOptionsList = { 0172 {i18nc("Color space option", "Save as is"), 0173 i18nc("@tooltip", 0174 "The image will be stored without conversion, the ICC profile will be converted to CICP or embedded if " 0175 "it was not possible."), 0176 "KeepSame"}, 0177 {i18nc("Color space name", "Rec 2100 PQ"), 0178 i18nc("@tooltip", 0179 "The image will be converted to Rec 2020 linear first, and then encoded with a perceptual quantizer " 0180 "curve" 0181 " (also known as SMPTE 2048 curve). Recommended for HDR images where the absolute brightness is " 0182 "important."), 0183 "Rec2100PQ"}, 0184 {i18nc("Color space name", "Rec 2100 HLG"), 0185 i18nc("@tooltip", 0186 "The image will be converted to Rec 2020 linear first, and then encoded with a Hybrid Log Gamma curve." 0187 " Recommended for HDR images where the display may not understand HDR."), 0188 "Rec2100HLG"}}; 0189 0190 if (cfg->getString(KisImportExportFilter::ColorModelIDTag) == RGBAColorModelID.id()) { 0191 if (CicpPrimaries != PRIMARIES_UNSPECIFIED) { 0192 conversionOptionsList << std::make_tuple<QString, QString, QString>( 0193 i18nc("Color space option plus transfer function name", "Keep colorants, encode PQ"), 0194 i18nc("@tooltip", 0195 "The image will be linearized first, and then encoded with a perceptual quantizer curve" 0196 " (also known as the SMPTE 2048 curve). Recommended for images where the absolute brightness is " 0197 "important."), 0198 "ApplyPQ"); 0199 0200 conversionOptionsList << std::make_tuple<QString, QString, QString>( 0201 i18nc("Color space option plus transfer function name", "Keep colorants, encode HLG"), 0202 i18nc("@tooltip", 0203 "The image will be linearized first, and then encoded with a Hybrid Log Gamma curve." 0204 " Recommended for images intended for screens which cannot understand PQ"), 0205 "ApplyHLG"); 0206 0207 conversionOptionsList << std::make_tuple<QString, QString, QString>( 0208 i18nc("Color space option plus transfer function name", "Keep colorants, encode SMPTE ST 428"), 0209 i18nc("@tooltip", 0210 "The image will be linearized first, and then encoded with SMPTE ST 428." 0211 " Krita always opens images like these as linear floating point, this option is there to reverse " 0212 "that"), 0213 "ApplySMPTE428"); 0214 } 0215 } 0216 for (int i = 0; i < conversionOptionsList.size(); i++) { 0217 const auto &option = conversionOptionsList.at(i); 0218 cmbConversionPolicy->addItem(std::get<0>(option), std::get<2>(option)); 0219 cmbConversionPolicy->setItemData(i, std::get<1>(option), Qt::ToolTipRole); 0220 } 0221 const QString optionName = cfg->getString("floatingPointConversionOption", "Rec2100PQ"); 0222 cmbConversionPolicy->setCurrentIndex(cmbConversionPolicy->findData(optionName, Qt::UserRole)); 0223 spnNits->setValue(cfg->getDouble("HLGnominalPeak", 1000.0)); 0224 spnGamma->setValue(cfg->getDouble("HLGgamma", 1.2)); 0225 chkHLGOOTF->setChecked(cfg->getBool("removeHGLOOTF", true)); 0226 0227 resampling->setCurrentIndex(resampling->findData(cfg->getInt("resampling", -1))); 0228 extraChannelResampling->setCurrentIndex( 0229 extraChannelResampling->findData(cfg->getInt("extraChannelResampling", -1))); 0230 photonNoise->setValue(cfg->getInt("photonNoise", 0)); 0231 dots->setCurrentIndex(dots->findData(cfg->getInt("dots", -1))); 0232 patches->setCurrentIndex(patches->findData(cfg->getInt("patches", -1))); 0233 epf->setValue(cfg->getInt("epf", -1)); 0234 gaborish->setCurrentIndex(gaborish->findData(cfg->getInt("gaborish", -1))); 0235 modular->setCurrentIndex(modular->findData(cfg->getInt("modularSetVal", -1))); 0236 keepInvisible->setCurrentIndex(keepInvisible->findData(cfg->getInt("keepInvisible", -1))); 0237 groupOrder->setCurrentIndex(groupOrder->findData(cfg->getInt("groupOrder", -1))); 0238 responsive->setCurrentIndex(responsive->findData(cfg->getInt("responsive", -1))); 0239 progressiveAC->setCurrentIndex(progressiveAC->findData(cfg->getInt("progressiveAC", -1))); 0240 qProgressiveAC->setCurrentIndex(qProgressiveAC->findData(cfg->getInt("qProgressiveAC", -1))); 0241 progressiveDC->setCurrentIndex(progressiveDC->findData(cfg->getInt("progressiveDC", -1))); 0242 channelColorsGlobalPercent->setValue(cfg->getInt("channelColorsGlobalPercent", -1)); 0243 channelColorsGroupPercent->setValue(cfg->getInt("channelColorsGroupPercent", -1)); 0244 paletteColors->setValue(cfg->getInt("paletteColors", -1)); 0245 lossyPalette->setCurrentIndex(lossyPalette->findData(cfg->getInt("lossyPalette", -1))); 0246 modularGroupSize->setCurrentIndex(modularGroupSize->findData(cfg->getInt("modularGroupSize", -1))); 0247 modularPredictor->setCurrentIndex(modularPredictor->findData(cfg->getInt("modularPredictor", -1))); 0248 modularMATreeLearningPercent->setValue(cfg->getInt("modularMATreeLearningPercent", -1)); 0249 jpegReconCFL->setCurrentIndex(jpegReconCFL->findData(cfg->getInt("jpegReconCFL", -1))); 0250 0251 chkAuthor->setChecked(cfg->getBool("storeAuthor", false)); 0252 exif->setChecked(cfg->getBool("exif", true)); 0253 xmp->setChecked(cfg->getBool("xmp", true)); 0254 iptc->setChecked(cfg->getBool("iptc", true)); 0255 chkMetadata->setChecked(cfg->getBool("storeMetaData", true)); 0256 m_filterRegistryModel.setEnabledFilters(cfg->getString("filters").split(',')); 0257 } 0258 0259 KisPropertiesConfigurationSP KisWdgOptionsJPEGXL::configuration() const 0260 { 0261 KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); 0262 0263 cfg->setProperty("haveAnimation", haveAnimation->isChecked()); 0264 cfg->setProperty("flattenLayers", flattenLayers->isChecked()); 0265 cfg->setProperty("lossless", !lossyEncoding->isChecked()); 0266 cfg->setProperty("effort", effort->value()); 0267 cfg->setProperty("decodingSpeed", decodingSpeed->value()); 0268 cfg->setProperty("lossyQuality", lossyQuality->value()); 0269 cfg->setProperty("forceModular", forceModular->isChecked()); 0270 cfg->setProperty("modularSetVal", modular->currentData()); 0271 0272 cfg->setProperty("floatingPointConversionOption", cmbConversionPolicy->currentData(Qt::UserRole).toString()); 0273 cfg->setProperty("HLGnominalPeak", spnNits->value()); 0274 cfg->setProperty("HLGgamma", spnGamma->value()); 0275 cfg->setProperty("removeHGLOOTF", chkHLGOOTF->isChecked()); 0276 0277 cfg->setProperty("resampling", resampling->currentData()); 0278 cfg->setProperty("extraChannelResampling", extraChannelResampling->currentData()); 0279 cfg->setProperty("photonNoise", photonNoise->value()); 0280 cfg->setProperty("dots", dots->currentData()); 0281 cfg->setProperty("patches", patches->currentData()); 0282 cfg->setProperty("epf", epf->value()); 0283 cfg->setProperty("gaborish", gaborish->currentData()); 0284 // force modular encoding without overriding value in advanced tab 0285 if (forceModular->isChecked() && lossyEncoding->isChecked()) { 0286 cfg->setProperty("modular", 1); 0287 } else { 0288 cfg->setProperty("modular", modular->currentData()); 0289 } 0290 cfg->setProperty("keepInvisible", keepInvisible->currentData()); 0291 cfg->setProperty("groupOrder", groupOrder->currentData()); 0292 cfg->setProperty("responsive", responsive->currentData()); 0293 cfg->setProperty("progressiveAC", progressiveAC->currentData()); 0294 cfg->setProperty("qProgressiveAC", qProgressiveAC->currentData()); 0295 cfg->setProperty("progressiveDC", progressiveDC->currentData()); 0296 cfg->setProperty("channelColorsGlobalPercent", channelColorsGlobalPercent->value()); 0297 cfg->setProperty("channelColorsGroupPercent", channelColorsGroupPercent->value()); 0298 cfg->setProperty("paletteColors", paletteColors->value()); 0299 cfg->setProperty("lossyPalette", lossyPalette->currentData()); 0300 cfg->setProperty("modularGroupSize", modularGroupSize->currentData()); 0301 cfg->setProperty("modularPredictor", modularPredictor->currentData()); 0302 cfg->setProperty("modularMATreeLearningPercent", modularMATreeLearningPercent->value()); 0303 cfg->setProperty("jpegReconCFL", jpegReconCFL->currentData()); 0304 0305 cfg->setProperty("storeAuthor", chkAuthor->isChecked()); 0306 cfg->setProperty("exif", exif->isChecked()); 0307 cfg->setProperty("xmp", xmp->isChecked()); 0308 cfg->setProperty("iptc", iptc->isChecked()); 0309 cfg->setProperty("storeMetaData", chkMetadata->isChecked()); 0310 0311 QString enabledFilters; 0312 for (const auto *filter: m_filterRegistryModel.enabledFilters()) { 0313 enabledFilters += filter->id() + ','; 0314 } 0315 cfg->setProperty("filters", enabledFilters); 0316 0317 return cfg; 0318 }