gaussianhighpass_filter.cpp 4.65 KB
Newer Older
Miguel Lopez's avatar
Miguel Lopez committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * This file is part of Krita
 *
 * Copyright (c) 2019 Miguel Lopez <reptillia39@live.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <compositeops/KoVcMultiArchBuildSupport.h> //MSVC requires that Vc come first
22
#include "gaussianhighpass_filter.h"
Miguel Lopez's avatar
Miguel Lopez committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#include <QBitArray>

#include <KoColorSpace.h>
#include <KoChannelInfo.h>
#include <KoColor.h>
#include <kis_painter.h>
#include <kis_paint_device.h>
#include <kis_paint_layer.h>
#include <kis_group_layer.h>

#include <kis_mask_generator.h>
#include <kis_gaussian_kernel.h>
#include <filter/kis_filter_category_ids.h>
#include <filter/kis_filter_configuration.h>
#include <kis_processing_information.h>
#include <KoProgressUpdater.h>
#include <KoUpdater.h>
#include <KoMixColorsOp.h>
#include <kis_paint_device.h>
#include "kis_lod_transform.h"
43
#include <KoCompositeOpRegistry.h>
Miguel Lopez's avatar
Miguel Lopez committed
44

45 46
#include "wdg_gaussianhighpass.h"
#include "ui_wdggaussianhighpass.h"
Miguel Lopez's avatar
Miguel Lopez committed
47 48 49 50
#include "KoColorSpaceTraits.h"
#include <KisSequentialIteratorProgress.h>


51
KisGaussianHighPassFilter::KisGaussianHighPassFilter() : KisFilter(id(), FiltersCategoryEdgeDetectionId, i18n("&Gaussian High Pass..."))
Miguel Lopez's avatar
Miguel Lopez committed
52 53
{
    setSupportsPainting(true);
54 55 56
    setSupportsAdjustmentLayers(true);
    setSupportsThreading(true);
    setSupportsLevelOfDetail(true);
Miguel Lopez's avatar
Miguel Lopez committed
57 58 59
    setColorSpaceIndependence(FULLY_INDEPENDENT);
}

60
KisConfigWidget * KisGaussianHighPassFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool /* useForMasks */) const
Miguel Lopez's avatar
Miguel Lopez committed
61
{
62
    return new KisWdgGaussianHighPass(parent);
Miguel Lopez's avatar
Miguel Lopez committed
63 64
}

65
KisFilterConfigurationSP KisGaussianHighPassFilter::factoryConfiguration() const
Miguel Lopez's avatar
Miguel Lopez committed
66 67 68 69 70 71
{
    KisFilterConfigurationSP config = new KisFilterConfiguration(id().id(), 1);
    config->setProperty("blurAmount", 1);
    return config;
}

72
void KisGaussianHighPassFilter::processImpl(KisPaintDeviceSP device,
Miguel Lopez's avatar
Miguel Lopez committed
73 74 75 76 77 78 79 80 81 82 83 84 85
                                   const QRect& applyRect,
                                   const KisFilterConfigurationSP _config,
                                   KoUpdater *
                                   ) const
{
    QPointer<KoUpdater> convolutionUpdater = 0;

    KisFilterConfigurationSP config = _config ? _config : new KisFilterConfiguration(id().id(), 1);
    
    QVariant value;
    KisLodTransformScalar t(device);
    const qreal blurAmount = t.scale(config->getProperty("blurAmount", value) ? value.toDouble() : 1.0);
    QBitArray channelFlags = config->channelFlags();
86 87 88 89 90

    const QRect gaussNeedRect = this->neededRect(applyRect, config, device->defaultBounds()->currentLevelOfDetail());

    KisPaintDeviceSP blur = m_cachedPaintDevice.getDevice(device);
    KisPainter::copyAreaOptimizedOldData(gaussNeedRect.topLeft(), device, blur, gaussNeedRect);
Miguel Lopez's avatar
Miguel Lopez committed
91 92 93
    KisGaussianKernel::applyGaussian(blur, applyRect,
                                     blurAmount, blurAmount,
                                     channelFlags,
94 95
                                     convolutionUpdater,
                                     true); // make sure we cerate an internal transaction on temp device
Miguel Lopez's avatar
Miguel Lopez committed
96 97 98
    
    KisPainter painter(device);
    painter.setCompositeOp(blur->colorSpace()->compositeOp(COMPOSITE_GRAIN_EXTRACT));
99
    painter.bitBlt(applyRect.topLeft(), blur, applyRect);
Miguel Lopez's avatar
Miguel Lopez committed
100
    painter.end();
101 102

    m_cachedPaintDevice.putDevice(blur);
Miguel Lopez's avatar
Miguel Lopez committed
103 104 105
}


106
QRect KisGaussianHighPassFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const
Miguel Lopez's avatar
Miguel Lopez committed
107 108 109 110 111
{
    KisLodTransformScalar t(lod);

    QVariant value;

112 113 114
    const int halfSize = config->getProperty("blurAmount", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5;

    return rect.adjusted( -halfSize * 2, -halfSize * 2, halfSize * 2, halfSize * 2);
Miguel Lopez's avatar
Miguel Lopez committed
115 116
}

117
QRect KisGaussianHighPassFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const
Miguel Lopez's avatar
Miguel Lopez committed
118 119 120 121 122
{
    KisLodTransformScalar t(lod);

    QVariant value;

123 124 125
    const int halfSize = config->getProperty("blurAmount", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5;

    return rect.adjusted( -halfSize, -halfSize, halfSize, halfSize);
Miguel Lopez's avatar
Miguel Lopez committed
126
}