Krita Source Code Documentation
Loading...
Searching...
No Matches
KisUnsharpFilter Class Reference

#include <kis_unsharp_filter.h>

+ Inheritance diagram for KisUnsharpFilter:

Public Member Functions

QRect changedRect (const QRect &rect, const KisFilterConfigurationSP _config, int lod) const override
 
KisConfigWidgetcreateConfigurationWidget (QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override
 
KisFilterConfigurationSP defaultConfiguration (KisResourcesInterfaceSP resourcesInterface) const override
 
 KisUnsharpFilter ()
 
QRect neededRect (const QRect &rect, const KisFilterConfigurationSP _config, int lod) const override
 
void processImpl (KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override
 
- Public Member Functions inherited from KisFilter
virtual bool configurationAllowedForMask (KisFilterConfigurationSP config) const
 
virtual void fixLoadedFilterConfigurationForMasks (KisFilterConfigurationSP config) const
 
 KisFilter (const KoID &id, const KoID &category, const QString &entry)
 
virtual bool needsTransparentPixels (const KisFilterConfigurationSP config, const KoColorSpace *cs) const
 
void process (const KisPaintDeviceSP src, KisPaintDeviceSP dst, KisSelectionSP selection, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater=0) const
 
void process (KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater=0) const
 
virtual bool supportsLevelOfDetail (const KisFilterConfigurationSP config, int lod) const
 
 ~KisFilter () override
 
- Public Member Functions inherited from KisBaseProcessor
KisBookmarkedConfigurationManagerbookmarkManager ()
 
const KisBookmarkedConfigurationManagerbookmarkManager () const
 
ColorSpaceIndependence colorSpaceIndependence () const
 
virtual KisFilterConfigurationSP factoryConfiguration (KisResourcesInterfaceSP resourcesInterface) const
 
QString id () const
 
 KisBaseProcessor (const KoID &id, const KoID &category, const QString &entry)
 
KoID menuCategory () const
 
QString menuEntry () const
 
QString name () const
 
 Private ()
 
QKeySequence shortcut () const
 
bool showConfigurationWidget ()
 If true, the filter wants to show a configuration widget.
 
bool supportsAdjustmentLayers () const
 This filter can be used in adjustment layers.
 
bool supportsPainting () const
 
bool supportsThreading () const
 
virtual ~KisBaseProcessor ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Static Public Member Functions

static KoID id ()
 

Private Member Functions

void processLightnessOnly (KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const
 
void processRaw (KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const
 

Additional Inherited Members

- Public Attributes inherited from KisBaseProcessor
KisBookmarkedConfigurationManagerbookmarkManager
 
KoID category
 
ColorSpaceIndependence colorSpaceIndependence
 
QString entry
 
KoID id
 
QKeySequence shortcut
 
bool showConfigurationWidget
 
bool supportsAdjustmentLayers
 
bool supportsPainting
 
bool supportsThreading
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 
- Protected Member Functions inherited from KisFilter
QString configEntryGroup () const
 
void setSupportsLevelOfDetail (bool value)
 
- Protected Member Functions inherited from KisBaseProcessor
void init (const QString &configEntryGroup)
 
void setColorSpaceIndependence (ColorSpaceIndependence v)
 
void setShortcut (const QKeySequence &shortcut)
 
void setShowConfigurationWidget (bool v)
 
void setSupportsAdjustmentLayers (bool v)
 
void setSupportsPainting (bool v)
 
void setSupportsThreading (bool v)
 
- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Detailed Description

Definition at line 14 of file kis_unsharp_filter.h.

Constructor & Destructor Documentation

◆ KisUnsharpFilter()

KisUnsharpFilter::KisUnsharpFilter ( )

Officially Unsharp Mask doesn't support LoD, because it generates subtle artifacts when the unsharp radius is smaller than current zoom level. But LoD devices can still appear when the filter is used in Adjustment Layer. So the actual LoD is still counted on.

Definition at line 31 of file kis_unsharp_filter.cpp.

31 : KisFilter(id(), FiltersCategoryEnhanceId, i18n("&Unsharp Mask..."))
32{
36
46}
@ FULLY_INDEPENDENT
void setSupportsLevelOfDetail(bool value)
KisFilter(const KoID &id, const KoID &category, const QString &entry)
Definition kis_filter.cc:22
const KoID FiltersCategoryEnhanceId("enhance_filters", ki18nc("The category of enhancement filters, like sharpen. Verb.", "Enhance"))
void setSupportsThreading(bool v)
void setSupportsAdjustmentLayers(bool v)
void setSupportsPainting(bool v)
void setColorSpaceIndependence(ColorSpaceIndependence v)

References FULLY_INDEPENDENT, KisBaseProcessor::setColorSpaceIndependence(), KisBaseProcessor::setSupportsAdjustmentLayers(), KisFilter::setSupportsLevelOfDetail(), KisBaseProcessor::setSupportsPainting(), and KisBaseProcessor::setSupportsThreading().

Member Function Documentation

◆ changedRect()

QRect KisUnsharpFilter::changedRect ( const QRect & rect,
const KisFilterConfigurationSP config,
int lod ) const
overridevirtual

Similar to neededRect : some filters will alter a lot of pixels that are near to each other at the same time. So when you changed a single rectangle in a device, the actual rectangle that will feel the influence of this change might be bigger. Use this function to determine that rect.

Reimplemented from KisFilter.

Definition at line 208 of file kis_unsharp_filter.cpp.

209{
211
212 QVariant value;
213 const qreal halfSize = t.scale(config->getProperty("halfSize", value) ? value.toDouble() : 1.0);
214
215 return rect.adjusted( -halfSize, -halfSize, halfSize, halfSize);
216}
float value(const T *src, size_t ch)

References KisLodTransformScalar::scale(), and value().

◆ createConfigurationWidget()

KisConfigWidget * KisUnsharpFilter::createConfigurationWidget ( QWidget * parent,
const KisPaintDeviceSP dev,
bool useForMasks ) const
overridevirtual

Create the configuration widget for this processor.

Parameters
parentthe Qt owner widget of this widget
devthe paintdevice this filter will act on
useForMasksshown if the filer is going to be used in a mask. Some filters may provide limited options when applied as a mask (e.g. Gaussian Blur)

Reimplemented from KisBaseProcessor.

Definition at line 48 of file kis_unsharp_filter.cpp.

49{
50 return new KisWdgUnsharp(parent);
51}

◆ defaultConfiguration()

KisFilterConfigurationSP KisUnsharpFilter::defaultConfiguration ( KisResourcesInterfaceSP resourcesInterface) const
overridevirtual

Return the configuration set as the default by the user or the default configuration from the filter writer as returned by factoryConfiguration.

This configuration is used by default for the configuration widget and given to the process function if there is no configuration widget.

Returns
the default configuration of this widget

Reimplemented from KisBaseProcessor.

Definition at line 53 of file kis_unsharp_filter.cpp.

54{
55 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
56 config->setProperty("halfSize", 1);
57 config->setProperty("amount", 0.5);
58 config->setProperty("threshold", 0);
59 config->setProperty("lightnessOnly", true);
60 return config;
61}
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const

References KisBaseProcessor::factoryConfiguration().

◆ id()

static KoID KisUnsharpFilter::id ( )
inlinestatic

Definition at line 26 of file kis_unsharp_filter.h.

26 {
27 return KoID("unsharp", i18n("Unsharp Mask"));
28 }
Definition KoID.h:30

◆ neededRect()

QRect KisUnsharpFilter::neededRect ( const QRect & rect,
const KisFilterConfigurationSP config,
int lod ) const
overridevirtual

Some filters need pixels outside the current processing rect to compute the new value (for instance, convolution filters)

Reimplemented from KisFilter.

Definition at line 198 of file kis_unsharp_filter.cpp.

199{
201
202 QVariant value;
203 const qreal halfSize = t.scale(config->getProperty("halfSize", value) ? value.toDouble() : 1.0);
204
205 return rect.adjusted(-halfSize * 2, -halfSize * 2, halfSize * 2, halfSize * 2);
206}

References KisLodTransformScalar::scale(), and value().

◆ processImpl()

void KisUnsharpFilter::processImpl ( KisPaintDeviceSP device,
const QRect & applyRect,
const KisFilterConfigurationSP config,
KoUpdater * progressUpdater ) const
overridevirtual

Override this function with the implementation of your filter.

This is a low level function that expects all the conditions for the

Parameters
devicebe met. Use usual process() methods instead.
devicethe paint device to filter
applyRectthe rectangle where the filter is applied
configthe parameters of the filter
progressUpdaterto pass on the progress the filter is making

Implements KisFilter.

Definition at line 63 of file kis_unsharp_filter.cpp.

68{
69
70 QPointer<KoUpdater> filterUpdater = 0;
71 QPointer<KoUpdater> convolutionUpdater = 0;
72 QScopedPointer<KoProgressUpdater> updater;
73
74 if (progressUpdater) {
75 updater.reset(new KoProgressUpdater(progressUpdater));
76 updater->start(100, i18n("Unsharp Mask"));
77 // Two sub-sub tasks that each go from 0 to 100.
78 convolutionUpdater = updater->startSubtask();
79 filterUpdater = updater->startSubtask();
80 }
81
83
84 QVariant value;
85
86 KisLodTransformScalar t(device);
87
88 const qreal halfSize = t.scale(config->getProperty("halfSize", value) ? value.toDouble() : 1.0);
89 const qreal amount = (config->getProperty("amount", value)) ? value.toDouble() : 0.5;
90 const uint threshold = (config->getProperty("threshold", value)) ? value.toUInt() : 0;
91 const uint lightnessOnly = (config->getProperty("lightnessOnly", value)) ? value.toBool() : true;
92
93 QBitArray channelFlags = config->channelFlags();
94 KisGaussianKernel::applyGaussian(device, applyRect,
95 halfSize, halfSize,
96 channelFlags,
97 convolutionUpdater);
98
99 qreal weights[2];
100 qreal factor = 128;
101
102 weights[0] = factor * (1. + amount);
103 weights[1] = -factor * amount;
104
105 if (lightnessOnly) {
106 processLightnessOnly(device, applyRect, threshold, weights, factor, channelFlags, filterUpdater);
107 } else {
108 processRaw(device, applyRect, threshold, weights, factor, channelFlags, filterUpdater);
109 }
110}
unsigned int uint
static void applyGaussian(KisPaintDeviceSP device, const QRect &rect, qreal xRadius, qreal yRadius, const QBitArray &channelFlags, KoUpdater *updater, bool createTransaction=false, KisConvolutionBorderOp borderOp=BORDER_REPEAT)
void processRaw(KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const
void processLightnessOnly(KisPaintDeviceSP device, const QRect &rect, quint8 threshold, qreal weights[2], qreal factor, const QBitArray &channelFlags, KoUpdater *progressUpdater) const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KisGaussianKernel::applyGaussian(), KIS_SAFE_ASSERT_RECOVER_RETURN, processLightnessOnly(), processRaw(), KisLodTransformScalar::scale(), and value().

◆ processLightnessOnly()

void KisUnsharpFilter::processLightnessOnly ( KisPaintDeviceSP device,
const QRect & rect,
quint8 threshold,
qreal weights[2],
qreal factor,
const QBitArray & channelFlags,
KoUpdater * progressUpdater ) const
private

Definition at line 154 of file kis_unsharp_filter.cpp.

161{
162 const KoColorSpace *cs = device->colorSpace();
163 const int pixelSize = cs->pixelSize();
164
165 quint16 labColorSrc[4];
166 quint16 labColorDst[4];
167
168 const int posL = 0;
169 const int posAlpha = 3;
170
171 const qreal factorInv = 1.0 / factor;
172
173 KisSequentialIteratorProgress dstIt(device, rect, progressUpdater);
174
175 while (dstIt.nextPixel()) {
176 quint8 diff = cs->differenceA(dstIt.oldRawData(), dstIt.rawDataConst());
177 if (diff >= threshold) {
178 cs->toLabA16(dstIt.oldRawData(), (quint8*)labColorSrc, 1);
179 cs->toLabA16(dstIt.rawDataConst(), (quint8*)labColorDst, 1);
180
181 qint32 valueL = (labColorSrc[posL] * weights[0] + labColorDst[posL] * weights[1]) * factorInv;
182 labColorSrc[posL] = CLAMP(valueL,
185
186 qint32 valueAlpha = (labColorSrc[posAlpha] * weights[0] + labColorDst[posAlpha] * weights[1]) * factorInv;
187 labColorSrc[posAlpha] = CLAMP(valueAlpha,
190
191 cs->fromLabA16((quint8*)labColorSrc, dstIt.rawData(), 1);
192 } else {
193 memcpy(dstIt.rawData(), dstIt.oldRawData(), pixelSize);
194 }
195 }
196}
const KoColorSpace * colorSpace() const
virtual quint32 pixelSize() const =0
virtual void toLabA16(const quint8 *src, quint8 *dst, quint32 nPixels) const
virtual void fromLabA16(const quint8 *src, quint8 *dst, quint32 nPixels) const
virtual quint8 differenceA(const quint8 *src1, const quint8 *src2) const =0
#define CLAMP(x, l, h)

References CLAMP, KisPaintDevice::colorSpace(), KoColorSpace::differenceA(), KoColorSpace::fromLabA16(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::oldRawData(), KoColorSpace::pixelSize(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst(), and KoColorSpace::toLabA16().

◆ processRaw()

void KisUnsharpFilter::processRaw ( KisPaintDeviceSP device,
const QRect & rect,
quint8 threshold,
qreal weights[2],
qreal factor,
const QBitArray & channelFlags,
KoUpdater * progressUpdater ) const
private

Definition at line 112 of file kis_unsharp_filter.cpp.

119{
120 const KoColorSpace *cs = device->colorSpace();
121 const int pixelSize = cs->pixelSize();
122 KoConvolutionOp * convolutionOp = cs->convolutionOp();
123
124 quint8 *colors[2];
125 colors[0] = new quint8[pixelSize];
126 colors[1] = new quint8[pixelSize];
127
128 KisSequentialIteratorProgress dstIt(device, rect, progressUpdater);
129
130 while (dstIt.nextPixel()) {
131 quint8 diff = 0;
132 if (threshold == 1) {
133 if (memcmp(dstIt.oldRawData(), dstIt.rawDataConst(), cs->pixelSize()) == 0) {
134 diff = 1;
135 }
136 }
137 else {
138 diff = cs->difference(dstIt.oldRawData(), dstIt.rawDataConst());
139 }
140
141 if (diff >= threshold) {
142 memcpy(colors[0], dstIt.oldRawData(), pixelSize);
143 memcpy(colors[1], dstIt.rawDataConst(), pixelSize);
144 convolutionOp->convolveColors(colors, weights, dstIt.rawData(), factor, 0, 2, channelFlags);
145 } else {
146 memcpy(dstIt.rawData(), dstIt.oldRawData(), pixelSize);
147 }
148 }
149
150 delete[] colors[0];
151 delete[] colors[1];
152}
virtual quint8 difference(const quint8 *src1, const quint8 *src2) const =0
KoConvolutionOp * convolutionOp
virtual void convolveColors(const quint8 *const *colors, const qreal *kernelValues, quint8 *dst, qreal factor, qreal offset, qint32 nColors, const QBitArray &channelFlags) const =0

References KisPaintDevice::colorSpace(), KoColorSpace::convolutionOp, KoConvolutionOp::convolveColors(), KoColorSpace::difference(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::oldRawData(), KoColorSpace::pixelSize(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst().


The documentation for this class was generated from the following files: