Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_wavelet_kernel.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Miroslav Talasek <miroslav.talasek@seznam.cz>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
11#include <QRect>
12
13
14
16{
17 return 2 * ceil(radius) + 1;
18}
19
20Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic>
22{
23 int kernelSize = kernelSizeFromRadius(radius);
24 Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> matrix(1, kernelSize);
25
30 KIS_ASSERT_RECOVER_NOOP(kernelSize & 0x1);
31 const int center = kernelSize / 2;
32
33 for (int x = 0; x < kernelSize; x++) {
34 if (x == 0 || x == kernelSize - 1)
35 matrix(0, x) = 0.25;
36 else if (x == center)
37 matrix(0, x) = 0.5;
38 else
39 matrix(0, x) = 0;
40 }
41
42 return matrix;
43}
44
45Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic>
47{
48 int kernelSize = kernelSizeFromRadius(radius);
49 Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> matrix(kernelSize, 1);
50
51
56 KIS_ASSERT_RECOVER_NOOP(kernelSize & 0x1);
57 const int center = kernelSize / 2;
58
59 for (int y = 0; y < kernelSize; y++) {
60 if (y == 0 || y == kernelSize - 1)
61 matrix(y, 0) = 0.25;
62 else if (y == center)
63 matrix(y, 0) = 0.5;
64 else
65 matrix(y, 0) = 0;
66 }
67
68 return matrix;
69}
70
73{
74 Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> matrix = createHorizontalMatrix(radius);
75 return KisConvolutionKernel::fromMatrix(matrix, 0, matrix.sum());
76}
77
80{
81 Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> matrix = createVerticalMatrix(radius);
82 return KisConvolutionKernel::fromMatrix(matrix, 0, matrix.sum());
83}
84
86 const QRect& rect,
87 qreal xRadius, qreal yRadius,
88 const QBitArray &channelFlags,
89 KoUpdater *progressUpdater)
90{
91 QPoint srcTopLeft = rect.topLeft();
92
93 if (xRadius > 0.0 && yRadius > 0.0) {
94 KisPaintDeviceSP interm = new KisPaintDevice(device->colorSpace());
95 interm->prepareClone(device);
96
99
100 qreal verticalCenter = qreal(kernelVertical->height()) / 2.0;
101
102 KisConvolutionPainter horizPainter(interm);
103 horizPainter.setChannelFlags(channelFlags);
104 horizPainter.setProgress(progressUpdater);
105 horizPainter.applyMatrix(kernelHoriz, device,
106 srcTopLeft - QPoint(0, ceil(verticalCenter)),
107 srcTopLeft - QPoint(0, ceil(verticalCenter)),
108 rect.size() + QSize(0, 2 * ceil(verticalCenter)), BORDER_REPEAT);
109
110 KisConvolutionPainter verticalPainter(device);
111 verticalPainter.setChannelFlags(channelFlags);
112 verticalPainter.setProgress(progressUpdater);
113 verticalPainter.applyMatrix(kernelVertical, interm, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);
114
115 } else if (xRadius > 0.0) {
116 KisConvolutionPainter painter(device);
117 painter.setChannelFlags(channelFlags);
118 painter.setProgress(progressUpdater);
119
121 painter.applyMatrix(kernelHoriz, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);
122
123 } else if (yRadius > 0.0) {
124 KisConvolutionPainter painter(device);
125 painter.setChannelFlags(channelFlags);
126 painter.setProgress(progressUpdater);
127
129 painter.applyMatrix(kernelVertical, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);
130 }
131}
The KisConvolutionPainter class applies a convolution kernel to a paint device.
void applyMatrix(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, KisConvolutionBorderOp borderOp=BORDER_REPEAT)
const KoColorSpace * colorSpace() const
void prepareClone(KisPaintDeviceSP src)
void setProgress(KoUpdater *progressUpdater)
void setChannelFlags(QBitArray channelFlags)
static int kernelSizeFromRadius(qreal radius)
static KisConvolutionKernelSP createHorizontalKernel(qreal radius)
static KisConvolutionKernelSP createVerticalKernel(qreal radius)
static Eigen::Matrix< qreal, Eigen::Dynamic, Eigen::Dynamic > createHorizontalMatrix(qreal radius)
static void applyWavelet(KisPaintDeviceSP device, const QRect &rect, qreal xRadius, qreal yRadius, const QBitArray &channelFlags, KoUpdater *updater)
static Eigen::Matrix< qreal, Eigen::Dynamic, Eigen::Dynamic > createVerticalMatrix(qreal radius)
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
static KisConvolutionKernelSP fromMatrix(Eigen::Matrix< qreal, Eigen::Dynamic, Eigen::Dynamic > matrix, qreal offset, qreal factor)