File indexing completed on 2024-05-12 15:58:15
0001 /* 0002 * SPDX-FileCopyrightText: 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> 0003 * SPDX-FileCopyrightText: 2005 C. Boemann <cbo@boemann.dk> 0004 * SPDX-FileCopyrightText: 2013 Juan Palacios <jpalaciosdev@gmail.com> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KIS_FILTER_STRATEGY_H_ 0010 #define KIS_FILTER_STRATEGY_H_ 0011 0012 #include <klocalizedstring.h> 0013 0014 #include "KoGenericRegistry.h" 0015 #include "KoID.h" 0016 #include "kritaimage_export.h" 0017 #include <QSize> 0018 0019 class KRITAIMAGE_EXPORT KisFilterStrategy 0020 { 0021 public: 0022 KisFilterStrategy(KoID id) : m_id(id) {} 0023 virtual ~KisFilterStrategy() { } 0024 0025 QString id() { 0026 return m_id.id(); 0027 } 0028 QString name() { 0029 return m_id.name(); 0030 } 0031 virtual qreal valueAt(qreal t, qreal weightsPositionScale) const { 0032 Q_UNUSED(t); 0033 Q_UNUSED(weightsPositionScale); 0034 return 0; 0035 } 0036 virtual qint32 intValueAt(qint32 t, qreal weightsPositionScale) const { 0037 return qint32(255*valueAt(t / 256.0, weightsPositionScale)); 0038 } 0039 virtual qreal support(qreal weightsPositionScale) { 0040 Q_UNUSED(weightsPositionScale); 0041 return supportVal; 0042 } 0043 virtual qint32 intSupport(qreal weightsPositionScale) { 0044 Q_UNUSED(weightsPositionScale); 0045 return intSupportVal; 0046 } 0047 virtual QString description() { 0048 return QString(); 0049 } 0050 0051 protected: 0052 qreal supportVal {0.0}; 0053 qint32 intSupportVal {0}; 0054 KoID m_id; 0055 }; 0056 0057 class KRITAIMAGE_EXPORT KisHermiteFilterStrategy : public KisFilterStrategy 0058 { 0059 public: 0060 KisHermiteFilterStrategy() : KisFilterStrategy(KoID("Hermite", i18n("Hermite"))) { 0061 supportVal = 1.0; intSupportVal = 256; 0062 } 0063 ~KisHermiteFilterStrategy() override {} 0064 0065 qint32 intValueAt(qint32 t, qreal weightsPositionScale) const override; 0066 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0067 }; 0068 0069 class KRITAIMAGE_EXPORT KisBicubicFilterStrategy : public KisFilterStrategy 0070 { 0071 public: 0072 KisBicubicFilterStrategy() : KisFilterStrategy(KoID("Bicubic", i18n("Bicubic"))) { 0073 supportVal = 2.0; intSupportVal = 512; 0074 } 0075 ~KisBicubicFilterStrategy() override {} 0076 0077 QString description() override { 0078 return i18n("Adds pixels using the color of surrounding pixels. Produces smoother tonal gradations than Bilinear."); 0079 } 0080 0081 qint32 intValueAt(qint32 t, qreal weightsPositionScale) const override; 0082 }; 0083 class KRITAIMAGE_EXPORT KisBoxFilterStrategy : public KisFilterStrategy 0084 { 0085 public: 0086 KisBoxFilterStrategy() : KisFilterStrategy(KoID("NearestNeighbor", i18n("Nearest Neighbor"))) { 0087 // 0.5 and 128, but with a bit of margin to ensure the correct pixel will be used 0088 // even in case of calculation errors 0089 supportVal = 0.51; intSupportVal = 129; 0090 } 0091 ~KisBoxFilterStrategy() override {} 0092 0093 QString description() override { 0094 return i18n("Replicate pixels in the image. Preserves all the original detail, but can produce jagged effects."); 0095 } 0096 0097 virtual qreal support(qreal weightsPositionScale) override; 0098 virtual qint32 intSupport(qreal weightsPositionScale) override; 0099 0100 0101 qint32 intValueAt(qint32 t, qreal weightsPositionScale) const override; 0102 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0103 }; 0104 0105 class KRITAIMAGE_EXPORT KisBilinearFilterStrategy : public KisFilterStrategy 0106 { 0107 public: 0108 KisBilinearFilterStrategy() : KisFilterStrategy(KoID("Bilinear", i18n("Bilinear"))) { 0109 supportVal = 1.0; intSupportVal = 256; 0110 } 0111 ~KisBilinearFilterStrategy() override {} 0112 0113 QString description() override { 0114 return i18n("Adds pixels averaging the color values of surrounding pixels. Produces medium quality results when the image is scaled from half to two times the original size."); 0115 } 0116 0117 qint32 intValueAt(qint32 t, qreal weightsPositionScale) const override; 0118 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0119 }; 0120 0121 class KRITAIMAGE_EXPORT KisBellFilterStrategy : public KisFilterStrategy 0122 { 0123 public: 0124 KisBellFilterStrategy() : KisFilterStrategy(KoID("Bell", i18n("Bell"))) { 0125 supportVal = 1.5; intSupportVal = 128 + 256; 0126 } 0127 ~KisBellFilterStrategy() override {} 0128 0129 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0130 }; 0131 0132 class KRITAIMAGE_EXPORT KisBSplineFilterStrategy : public KisFilterStrategy 0133 { 0134 public: 0135 KisBSplineFilterStrategy() : KisFilterStrategy(KoID("BSpline", i18n("BSpline"))) { 0136 supportVal = 2.0; intSupportVal = 512; 0137 } 0138 ~KisBSplineFilterStrategy() override {} 0139 0140 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0141 }; 0142 0143 class KRITAIMAGE_EXPORT KisLanczos3FilterStrategy : public KisFilterStrategy 0144 { 0145 public: 0146 KisLanczos3FilterStrategy() : KisFilterStrategy(KoID("Lanczos3", i18n("Lanczos3"))) { 0147 supportVal = 3.0; intSupportVal = 768; 0148 } 0149 ~KisLanczos3FilterStrategy() override {} 0150 0151 QString description() override { 0152 return i18n("Offers similar results than Bicubic, but maybe a little bit sharper. Can produce light and dark halos along strong edges."); 0153 } 0154 0155 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0156 private: 0157 qreal sinc(qreal x) const; 0158 }; 0159 0160 class KRITAIMAGE_EXPORT KisMitchellFilterStrategy : public KisFilterStrategy 0161 { 0162 public: 0163 KisMitchellFilterStrategy() : KisFilterStrategy(KoID("Mitchell", i18n("Mitchell"))) { 0164 supportVal = 2.0; intSupportVal = 256; 0165 } 0166 ~KisMitchellFilterStrategy() override {} 0167 0168 qreal valueAt(qreal t, qreal weightsPositionScale) const override; 0169 }; 0170 0171 class KRITAIMAGE_EXPORT KisFilterStrategyRegistry : public KoGenericRegistry<KisFilterStrategy *> 0172 { 0173 0174 public: 0175 0176 KisFilterStrategyRegistry(); 0177 ~KisFilterStrategyRegistry() override; 0178 static KisFilterStrategyRegistry* instance(); 0179 0180 /** 0181 * This function return a list of all the keys in KoID format by using the name() method 0182 * on the objects stored in the registry. 0183 */ 0184 QList<KoID> listKeys() const; 0185 0186 /** 0187 * This function return a string formatted in HTML that contains the descriptions of all objects 0188 * (with a non empty description) stored in the registry. 0189 */ 0190 QString formattedDescriptions() const; 0191 0192 /** 0193 * Try to select an appropriate image filtering strategy based on original and desired parameters. 0194 */ 0195 KisFilterStrategy* autoFilterStrategy(QSize originalSize, QSize desiredSize) const; 0196 0197 private: 0198 0199 KisFilterStrategyRegistry(const KisFilterStrategyRegistry&); 0200 KisFilterStrategyRegistry operator=(const KisFilterStrategyRegistry&); 0201 0202 }; 0203 0204 #endif // KIS_FILTER_STRATEGY_H_