Krita Source Code Documentation
Loading...
Searching...
No Matches
waveletdecompose.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Miroslav Talasek <miroslav.talasek@seznam.cz>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "waveletdecompose.h"
8
9#include <QMap>
10#include <QPointer>
11
12#include <klocalizedstring.h>
13#include <kpluginfactory.h>
14
15#include <KoColorSpace.h>
16#include <KoChannelInfo.h>
17#include <KoColor.h>
18
19#include <kis_debug.h>
20#include <kis_types.h>
21#include <KisViewManager.h>
22#include <kis_image.h>
23#include <kis_wavelet_kernel.h>
24#include <kis_action.h>
25#include <KisDocument.h>
26#include <kis_node.h>
27#include <kis_painter.h>
28#include <kis_paint_device.h>
29#include <kis_paint_layer.h>
30#include <kis_group_layer.h>
33#include "kis_node_manager.h"
35#include "kis_undo_adapter.h"
36
38#include <KoUpdater.h>
39#include <KoProgressUpdater.h>
40
41
42
43K_PLUGIN_FACTORY_WITH_JSON(WaveletDecomposeFactory, "kritawaveletdecompose.json", registerPlugin<WaveletDecompose>();)
44
45WaveletDecompose::WaveletDecompose(QObject *parent, const QVariantList &)
46 : KisActionPlugin(parent)
47{
48 KisAction *action = createAction("waveletdecompose");
49 connect(action, SIGNAL(triggered()), this, SLOT(slotWaveletDecompose()));
50}
51
55
57{
58 DlgWaveletDecompose dlg(viewManager()->mainWindowAsQWidget(), "WaveletDecompose");
59
60 if (dlg.exec() == QDialog::Accepted) {
61
62 KisCursorOverrideLock cursorLock(Qt::WaitCursor);
63
64 QPointer<KoUpdater> updater = viewManager()->createUnthreadedUpdater(i18n("Wavelet Decompose"));
65
66 KisImageSP image = viewManager()->image();
67 if (!image) return;
68
69 if (!viewManager()->blockUntilOperationsFinished(image)) return;
70
71 image->barrierLock();
72
73 KisPaintDeviceSP projection = new KisPaintDevice(*(image->projection()));
74 if (!projection) return;
75
76 const KoColorSpace *cs = projection->colorSpace();
77
79
80 int scales = dlg.scales();
81
83 const QBitArray flags(0);
84
85 QRect rc = image->bounds();
86
87 KisPaintDeviceSP original = projection;
88
89 //main loop
90 for(int level = 0; level < scales; ++level){
91
92 //copy original
93 KisPaintDeviceSP blur = new KisPaintDevice(*original);
94
95 //blur it
96 KisWaveletKernel::applyWavelet(blur, rc, 1 << level, 1 << level, flags, 0);
97
98 //do grain extract blur from original
99 KisPainter painter(original);
100 painter.setCompositeOpId(op);
101 painter.bitBlt(0, 0, blur, 0, 0, rc.width(), rc.height());
102 painter.end();
103
104 //original is new scale and blur is new original
105 results << original;
106 original = blur;
107 updater->setProgress((level * 100) / scales);
108 }
109 //add new layers
110 KisUndoAdapter *undo = image->undoAdapter();
111 undo->beginMacro(kundo2_i18n("Wavelet decompose"));
112
114
115 KisGroupLayerSP baseGroup = image->rootLayer();
116
117 //add layer group
118 KisGroupLayerSP grp = new KisGroupLayer(image, i18n("Wavelet decompose"), OPACITY_OPAQUE_U8);
119 adapter.addNode(grp, baseGroup, baseGroup->lastChild());
120 baseGroup = grp;
121
122 //add scales
123 int i = 1;
125 Q_FOREACH (const KisPaintDeviceSP &l, results) {
126 KisPaintLayerSP paintLayer = new KisPaintLayer(image, QStringLiteral("Scale %1").arg(i), OPACITY_OPAQUE_U8, l);
127 adapter.addNode(paintLayer, baseGroup, 0);
128 adapter.setCompositeOp(paintLayer, op2);
129 ++i;
130 }
131
132 //add residual
133 KisPaintLayerSP paintLayer = new KisPaintLayer(image, "Residual", OPACITY_OPAQUE_U8, original);
134 adapter.addNode(paintLayer, baseGroup, 0);
135
136 undo->endMacro();
137 updater->setProgress(100);
138 image->unlock();
139 }
140}
141
142#include "waveletdecompose.moc"
const quint8 OPACITY_OPAQUE_U8
const QString COMPOSITE_GRAIN_MERGE
const QString COMPOSITE_GRAIN_EXTRACT
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
QPointer< KisViewManager > viewManager() const
KisUndoAdapter * undoAdapter() const
KisGroupLayerSP rootLayer() const
void unlock()
Definition kis_image.cc:805
void barrierLock(bool readOnly=false)
Wait until all the queued background jobs are completed and lock the image.
Definition kis_image.cc:756
KisPaintDeviceSP projection() const
QRect bounds() const override
void addNode(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis, KisImageLayerAddCommand::Flags flags=KisImageLayerAddCommand::DoRedoUpdates|KisImageLayerAddCommand::DoUndoUpdates)
void setCompositeOp(KisNodeSP node, const KoCompositeOp *compositeOp)
const KoColorSpace * colorSpace() const
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
void setCompositeOpId(const KoCompositeOp *op)
static void applyWavelet(KisPaintDeviceSP device, const QRect &rect, qreal xRadius, qreal yRadius, const QBitArray &channelFlags, KoUpdater *updater)
const KoCompositeOp * compositeOp(const QString &id, const KoColorSpace *srcSpace=nullptr) const
WaveletDecompose(QObject *parent, const QVariantList &)
~WaveletDecompose() override
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL
KUndo2MagicString kundo2_i18n(const char *text)
KisNodeSP lastChild() const
Definition kis_node.cpp:367