File indexing completed on 2024-05-12 15:58:12
0001 /* 0002 * SPDX-FileCopyrightText: 2005 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef KIS_CONVOLUTION_PAINTER_H_ 0007 #define KIS_CONVOLUTION_PAINTER_H_ 0008 0009 #include "kis_types.h" 0010 #include "kis_painter.h" 0011 #include "kis_image.h" 0012 #include "kritaimage_export.h" 0013 0014 template<class factory> class KisConvolutionWorker; 0015 0016 0017 enum KisConvolutionBorderOp { 0018 BORDER_IGNORE = 0, // read the pixels outside of the application rect 0019 BORDER_REPEAT = 1 // Use the border for the missing pixels 0020 }; 0021 0022 /** 0023 * @brief The KisConvolutionPainter class applies a convolution kernel to a paint device. 0024 * 0025 * 0026 * Note: https://bugs.kde.org/show_bug.cgi?id=220310 shows that there's something here 0027 * that we need to fix... 0028 */ 0029 class KRITAIMAGE_EXPORT KisConvolutionPainter : public KisPainter 0030 { 0031 0032 public: 0033 0034 KisConvolutionPainter(); 0035 KisConvolutionPainter(KisPaintDeviceSP device); 0036 KisConvolutionPainter(KisPaintDeviceSP device, KisSelectionSP selection); 0037 0038 enum EnginePreference { 0039 NONE, 0040 SPATIAL, 0041 FFTW 0042 }; 0043 0044 0045 KisConvolutionPainter(KisPaintDeviceSP device, EnginePreference enginePreference); 0046 0047 void setEnginePreference(EnginePreference value); 0048 0049 /** 0050 * Convolve all channels in src using the specified kernel; there is only one kernel for all 0051 * channels possible. 0052 * 0053 * WARNING: The painter will read **more** pixels than you pass in \p areaSize. 0054 * The actual processing area will be: 0055 * QRect(x - kernel.width() / 2, 0056 * y - kernel.height() / 2, 0057 * w + 2 * (kernel.width() / 2), 0058 * h + 2 * (kernel.height() / 2)) 0059 * 0060 * The border op decides what to do with pixels too close to the edge of the rect as defined above. 0061 * 0062 * The channels flag determines which set out of color channels, alpha channels. 0063 * channels we convolve. 0064 * 0065 * Note that we do not (currently) support different kernels for 0066 * different channels _or_ channel types. 0067 * 0068 * If you want to convolve a subset of the channels in a pixel, 0069 * set those channels with KisPainter::setChannelFlags(); 0070 */ 0071 void applyMatrix(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, 0072 KisConvolutionBorderOp borderOp = BORDER_REPEAT); 0073 0074 /** 0075 * The caller should ask if the painter needs an explicit transaction iff 0076 * the source and destination devices coincide. Otherwise, the transaction is 0077 * just not needed. 0078 */ 0079 bool needsTransaction(const KisConvolutionKernelSP kernel) const; 0080 0081 static bool supportsFFTW(); 0082 0083 protected: 0084 friend class KisConvolutionPainterTest; 0085 0086 0087 0088 private: 0089 template<class factory> 0090 KisConvolutionWorker<factory>* createWorker(const KisConvolutionKernelSP kernel, 0091 KisPainter *painter, 0092 KoUpdater *progress); 0093 0094 bool useFFTImplementation(const KisConvolutionKernelSP kernel) const; 0095 0096 private: 0097 EnginePreference m_enginePreference; 0098 }; 0099 #endif //KIS_CONVOLUTION_PAINTER_H_