Warning, file /graphics/krita/plugins/extensions/waveletdecompose/waveletdecompose.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * SPDX-FileCopyrightText: 2016 Miroslav Talasek <miroslav.talasek@seznam.cz>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "waveletdecompose.h"
0008 
0009 #include <QMap>
0010 #include <QPointer>
0011 #include <QHash>
0012 
0013 #include <klocalizedstring.h>
0014 #include <kpluginfactory.h>
0015 
0016 #include <KoColorSpace.h>
0017 #include <KoChannelInfo.h>
0018 #include <KoColor.h>
0019 
0020 #include <kis_debug.h>
0021 #include <kis_types.h>
0022 #include <KisViewManager.h>
0023 #include <kis_image.h>
0024 #include <kis_wavelet_kernel.h>
0025 #include <kis_action.h>
0026 #include <KisDocument.h>
0027 #include <kis_node.h>
0028 #include <kis_painter.h>
0029 #include <kis_paint_device.h>
0030 #include <kis_paint_layer.h>
0031 #include <kis_group_layer.h>
0032 #include <kis_random_accessor_ng.h>
0033 #include "dlg_waveletdecompose.h"
0034 #include "kis_node_manager.h"
0035 #include "kis_node_commands_adapter.h"
0036 #include "kis_undo_adapter.h"
0037 
0038 #include <KisCursorOverrideLock.h>
0039 #include <KoUpdater.h>
0040 #include <KoProgressUpdater.h>
0041 
0042 
0043 
0044 K_PLUGIN_FACTORY_WITH_JSON(WaveletDecomposeFactory, "kritawaveletdecompose.json", registerPlugin<WaveletDecompose>();)
0045 
0046 WaveletDecompose::WaveletDecompose(QObject *parent, const QVariantList &)
0047     : KisActionPlugin(parent)
0048 {
0049     KisAction *action  = createAction("waveletdecompose");
0050     connect(action, SIGNAL(triggered()), this, SLOT(slotWaveletDecompose()));
0051 }
0052 
0053 WaveletDecompose::~WaveletDecompose()
0054 {
0055 }
0056 
0057 void WaveletDecompose::slotWaveletDecompose()
0058 {
0059     DlgWaveletDecompose dlg(viewManager()->mainWindowAsQWidget(), "WaveletDecompose");
0060         
0061     if (dlg.exec() == QDialog::Accepted) {
0062 
0063         KisCursorOverrideLock cursorLock(Qt::WaitCursor);
0064 
0065         QPointer<KoUpdater> updater = viewManager()->createUnthreadedUpdater(i18n("Wavelet Decompose"));
0066 
0067         KisImageSP image = viewManager()->image();
0068         if (!image) return;
0069 
0070         if (!viewManager()->blockUntilOperationsFinished(image)) return;
0071 
0072         image->barrierLock();
0073 
0074         KisPaintDeviceSP projection = new KisPaintDevice(*(image->projection()));
0075         if (!projection) return;
0076        
0077         const KoColorSpace *cs = projection->colorSpace();
0078 
0079         const KoCompositeOp* op = cs->compositeOp(COMPOSITE_GRAIN_EXTRACT);
0080         
0081         int scales = dlg.scales();
0082         
0083         QList<KisPaintDeviceSP> results;
0084         const QBitArray flags(0);
0085         
0086         QRect rc = image->bounds();
0087         
0088         KisPaintDeviceSP original = projection;
0089         
0090         //main loop
0091         for(int level = 0; level < scales; ++level){
0092         
0093             //copy original
0094             KisPaintDeviceSP blur = new KisPaintDevice(*original);
0095            
0096             //blur it
0097             KisWaveletKernel::applyWavelet(blur, rc, 1 << level, 1 << level, flags, 0);
0098        
0099             //do grain extract blur from original
0100             KisPainter painter(original);
0101             painter.setCompositeOpId(op);
0102             painter.bitBlt(0, 0, blur, 0, 0, rc.width(), rc.height());
0103             painter.end();
0104         
0105             //original is new scale and blur is new original
0106             results << original;
0107             original = blur;
0108             updater->setProgress((level * 100) / scales);
0109         }
0110         //add new layers
0111         KisUndoAdapter *undo = image->undoAdapter();
0112         undo->beginMacro(kundo2_i18n("Wavelet decompose"));
0113         
0114         KisNodeCommandsAdapter adapter(viewManager());
0115         
0116         KisGroupLayerSP baseGroup = image->rootLayer();
0117 
0118         //add layer goup              
0119         KisGroupLayerSP grp = new KisGroupLayer(image, i18n("Wavelet decompose"), OPACITY_OPAQUE_U8);
0120         adapter.addNode(grp, baseGroup, baseGroup->lastChild());
0121         baseGroup = grp;
0122 
0123         //add scales
0124         int i = 1;
0125         const KoCompositeOp* op2 = cs->compositeOp(COMPOSITE_GRAIN_MERGE);
0126         Q_FOREACH (const KisPaintDeviceSP &l, results) {
0127             KisPaintLayerSP paintLayer = new KisPaintLayer(image, QStringLiteral("Scale %1").arg(i), OPACITY_OPAQUE_U8, l);
0128             adapter.addNode(paintLayer, baseGroup, 0);
0129             adapter.setCompositeOp(paintLayer, op2);
0130             ++i;
0131         }
0132 
0133         //add residual
0134         KisPaintLayerSP paintLayer = new KisPaintLayer(image, "Residual", OPACITY_OPAQUE_U8, original);
0135         adapter.addNode(paintLayer, baseGroup, 0);
0136         
0137         undo->endMacro();
0138         updater->setProgress(100);
0139         image->unlock();
0140     }
0141 }
0142 
0143 #include "waveletdecompose.moc"