Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_convolution_painter.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2005 Cyrille Berger <cberger@cberger.net>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <stdlib.h>
10#include <string.h>
11#include <cfloat>
12
13#include <QBrush>
14#include <QColor>
15#include <QPen>
16#include <QMap>
17#include <QPainter>
18#include <QRect>
19
20#include <kis_debug.h>
21#include <klocalizedstring.h>
22
24#include "kis_global.h"
25#include "kis_image.h"
26#include "kis_layer.h"
27#include "kis_paint_device.h"
28#include "kis_painter.h"
29#include "KoColorSpace.h"
30#include <KoChannelInfo.h>
31#include "kis_types.h"
32#include "kis_default_bounds.h"
33
34#include "kis_selection.h"
35
38
39#include "config_convolution.h"
40
41#ifdef HAVE_FFTW3
43#endif
44
45
47{
48 bool result = false;
49
50#ifdef HAVE_FFTW3
51 #define THRESHOLD_SIZE 5
52
53 result =
56 (kernel->width() > THRESHOLD_SIZE ||
57 kernel->height() > THRESHOLD_SIZE));
58#else
59 Q_UNUSED(kernel);
60#endif
61
62 return result;
63}
64
65template<class factory>
67 KisPainter *painter,
68 KoUpdater *progress)
69{
71
72#ifdef HAVE_FFTW3
73 if (useFFTImplementation(kernel)) {
74 worker = new KisConvolutionWorkerFFT<factory>(painter, progress);
75 } else {
76 worker = new KisConvolutionWorkerSpatial<factory>(painter, progress);
77 }
78#else
79 Q_UNUSED(kernel);
80 worker = new KisConvolutionWorkerSpatial<factory>(painter, progress);
81#endif
82
83 return worker;
84}
85
86
88{
89#ifdef HAVE_FFTW3
90 return true;
91#else
92 return false;
93#endif
94}
95
96
98 : KisPainter(),
99 m_enginePreference(NONE)
100{
101}
102
104 : KisPainter(device),
105 m_enginePreference(NONE)
106{
107}
108
110 : KisPainter(device, selection),
111 m_enginePreference(NONE)
112{
113}
114
116 : KisPainter(device),
117 m_enginePreference(enginePreference)
118{
119}
120
125
126void KisConvolutionPainter::applyMatrix(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, KisConvolutionBorderOp borderOp)
127{
133 if (src->defaultBounds()->wrapAroundMode() && src->supportsWraproundMode()) {
134 borderOp = BORDER_IGNORE;
135 }
136
137 // Determine whether we convolve border pixels, or not.
138 switch (borderOp) {
139 case BORDER_REPEAT: {
147 const QRect boundsRect = src->defaultBounds()->bounds();
148 const QRect requestedRect = QRect(srcPos, areaSize);
149 QRect dataRect = requestedRect | boundsRect;
150
152 dataRect = requestedRect | src->exactBounds();
153 }
154
165 if(dataRect.isValid()) {
167 worker = createWorker<RepeatIteratorFactory>(kernel, this, progressUpdater());
168 worker->execute(kernel, src, srcPos, dstPos, areaSize, dataRect);
169 delete worker;
170 }
171 break;
172 }
173 case BORDER_IGNORE:
174 default: {
176 worker = createWorker<StandardIteratorFactory>(kernel, this, progressUpdater());
177 worker->execute(kernel, src, srcPos, dstPos, areaSize, QRect());
178 delete worker;
179 }
180 }
181}
182
184{
185 return !useFFTImplementation(kernel);
186}
float value(const T *src, size_t ch)
@ NONE
EnginePreference m_enginePreference
void applyMatrix(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, KisConvolutionBorderOp borderOp=BORDER_REPEAT)
void setEnginePreference(EnginePreference value)
bool useFFTImplementation(const KisConvolutionKernelSP kernel) const
KisConvolutionWorker< factory > * createWorker(const KisConvolutionKernelSP kernel, KisPainter *painter, KoUpdater *progress)
bool needsTransaction(const KisConvolutionKernelSP kernel) const
virtual void execute(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, const QRect &dataRect)=0
KoUpdater * progressUpdater
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define bounds(x, a, b)