Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_emboss_filter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Krita
3 *
4 * SPDX-FileCopyrightText: 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
5 *
6 * ported from digikam, Copyrighted 2004 Gilles Caulier,
7 * Original Emboss algorithm copyrighted 2004 by
8 * Pieter Z. Voloshyn <pieter_voloshyn at ame.com.br>.
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13#include "kis_emboss_filter.h"
14
15
16#include <stdlib.h>
17#include <vector>
18
19#include <QPoint>
20#include <QSpinBox>
21
22#include <klocalizedstring.h>
23#include <kis_debug.h>
24#include <kpluginfactory.h>
25
26#include "KoIntegerMaths.h"
27#include <KoUpdater.h>
28
31#include <kis_global.h>
32#include <kis_selection.h>
33#include <kis_types.h>
36#include <kis_paint_device.h>
38
41
42
50
52{
53 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
54 config->setProperty("depth", 30);
55 return config;
56}
57
58// This method have been ported from Pieter Z. Voloshyn algorithm code.
59
60/* Function to apply the Emboss effect
61 *
62 * data => The image data in RGBA mode.
63 * Width => Width of image.
64 * Height => Height of image.
65 * d => Emboss value
66 *
67 * Theory => This is an amazing effect. And the theory is very simple to
68 * understand. You get the difference between the colors and
69 * increase it. After this, get the gray tone
70 */
72 const QRect& applyRect,
73 const KisFilterConfigurationSP config,
74 KoUpdater* progressUpdater
75 ) const
76{
77 QPoint srcTopLeft = applyRect.topLeft();
78 Q_ASSERT(device);
79
80 //read the filter configuration values from the KisFilterConfiguration object
81 quint32 embossdepth = config ? config->getInt("depth", 30) : 30;
82
83 //the actual filter function from digikam. It needs a pointer to a quint8 array
84 //with the actual pixel data.
85
86 float Depth = embossdepth / 10.0;
87 int R = 0, G = 0, B = 0;
88 uchar Gray = 0;
89 int Width = applyRect.width();
90 int Height = applyRect.height();
91
92 KisSequentialIteratorProgress it(device, applyRect, progressUpdater);
93 QColor color1;
94 QColor color2;
96 while (it.nextPixel()) {
97
98 // XXX: COLORSPACE_INDEPENDENCE or at least work IN RGB16A
99 device->colorSpace()->toQColor(it.oldRawData(), &color1);
100 acc->moveTo(srcTopLeft.x() + it.x() + Lim_Max(it.x(), 1, Width), srcTopLeft.y() + it.y() + Lim_Max(it.y(), 1, Height));
101
102 device->colorSpace()->toQColor(acc->oldRawData(), &color2);
103
104 R = abs((int)((color1.red() - color2.red()) * (int)Depth + (quint8_MAX / 2)));
105 G = abs((int)((color1.green() - color2.green()) * (int)Depth + (quint8_MAX / 2)));
106 B = abs((int)((color1.blue() - color2.blue()) * (int)Depth + (quint8_MAX / 2)));
107
108 Gray = CLAMP((R + G + B) / 3, 0, quint8_MAX);
109
110 device->colorSpace()->fromQColor(QColor(Gray, Gray, Gray, color1.alpha()), it.rawData());
111 }
112}
113
114// This method have been ported from Pieter Z. Voloshyn algorithm code.
115
116/* This function limits the max and min values
117 * defined by the developer
118 *
119 * Now => Original value
120 * Up => Increments
121 * Max => Maximum value
122 *
123 * Theory => This function is used in some functions to limit the
124 * "for step". E.g. I have a picture with 309 pixels (width), and
125 * my "for step" is 5. All the code goes alright until it reaches the
126 * w = 305, because in the next step we will go to 310, but we want
127 * to analyze all the pixels. So, this function will reduce the
128 * "for step", when necessary, until we reach the last possible value
129 */
130
131int KisEmbossFilter::Lim_Max(int Now, int Up, int Max) const
132{
133 --Max;
134 while (Now > Max - Up)
135 --Up;
136 return (Up);
137}
138
140{
141 Q_UNUSED(dev);
142
144 param.push_back(KisIntegerWidgetParam(10, 300, 30, i18nc("Emboss depth", "Depth"), "depth"));
145 KisConfigWidget * w = new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param);
146 Q_CHECK_PTR(w);
147 return w;
148}
Eigen::Matrix< double, 4, 2 > R
@ TO_RGBA8
virtual const quint8 * oldRawData() const =0
KisConfigWidget * createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override
void processImpl(KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override
int Lim_Max(int Now, int Up, int Max) const
KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const override
const KoColorSpace * colorSpace() const
KisRandomAccessorSP createRandomAccessorNG()
virtual void moveTo(qint32 x, qint32 y)=0
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE const quint8 * oldRawData() const
ALWAYS_INLINE int y() const
virtual void toQColor(const quint8 *src, QColor *c) const =0
virtual void fromQColor(const QColor &color, quint8 *dst) const =0
#define CLAMP(x, l, h)
const KoID FiltersCategoryEmbossId("emboss_filters", ki18nc("The category of emboss filters. Verb.", "Emboss"))
const quint8 quint8_MAX
Definition kis_global.h:24
std::vector< KisIntegerWidgetParam > vKisIntegerWidgetParam
void setSupportsThreading(bool v)
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const
void setSupportsAdjustmentLayers(bool v)
void setSupportsPainting(bool v)
void setColorSpaceIndependence(ColorSpaceIndependence v)