File indexing completed on 2024-12-22 04:15:19
0001 /* 0002 * This file is part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2019 Miguel Lopez <reptillia39@live.com> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "gaussianhighpass_filter.h" 0010 #include <QBitArray> 0011 0012 #include <KoColorSpace.h> 0013 #include <KoChannelInfo.h> 0014 #include <KoColor.h> 0015 #include <kis_painter.h> 0016 #include <kis_paint_device.h> 0017 #include <kis_paint_layer.h> 0018 #include <kis_group_layer.h> 0019 0020 #include <kis_mask_generator.h> 0021 #include <kis_gaussian_kernel.h> 0022 #include <filter/kis_filter_category_ids.h> 0023 #include <filter/kis_filter_configuration.h> 0024 #include <kis_processing_information.h> 0025 #include <KoProgressUpdater.h> 0026 #include <KoUpdater.h> 0027 #include <KoMixColorsOp.h> 0028 #include "kis_lod_transform.h" 0029 #include <KoCompositeOpRegistry.h> 0030 0031 #include "wdg_gaussianhighpass.h" 0032 #include "ui_wdggaussianhighpass.h" 0033 #include "KoColorSpaceTraits.h" 0034 #include <KisSequentialIteratorProgress.h> 0035 0036 0037 KisGaussianHighPassFilter::KisGaussianHighPassFilter() : KisFilter(id(), FiltersCategoryEdgeDetectionId, i18n("&Gaussian High Pass...")) 0038 { 0039 setSupportsPainting(true); 0040 setSupportsAdjustmentLayers(true); 0041 setSupportsThreading(true); 0042 setSupportsLevelOfDetail(true); 0043 setColorSpaceIndependence(FULLY_INDEPENDENT); 0044 } 0045 0046 KisConfigWidget * KisGaussianHighPassFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, bool /* useForMasks */) const 0047 { 0048 return new KisWdgGaussianHighPass(parent); 0049 } 0050 0051 KisFilterConfigurationSP KisGaussianHighPassFilter::defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const 0052 { 0053 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface); 0054 config->setProperty("blurAmount", 1); 0055 return config; 0056 } 0057 0058 void KisGaussianHighPassFilter::processImpl(KisPaintDeviceSP device, 0059 const QRect& applyRect, 0060 const KisFilterConfigurationSP config, 0061 KoUpdater * 0062 ) const 0063 { 0064 QPointer<KoUpdater> convolutionUpdater = 0; 0065 KIS_SAFE_ASSERT_RECOVER_RETURN(config); 0066 0067 QVariant value; 0068 KisLodTransformScalar t(device); 0069 const qreal blurAmount = t.scale(config->getProperty("blurAmount", value) ? value.toDouble() : 1.0); 0070 QBitArray channelFlags = config->channelFlags(); 0071 0072 const QRect gaussNeedRect = this->neededRect(applyRect, config, device->defaultBounds()->currentLevelOfDetail()); 0073 0074 KisCachedPaintDevice::Guard d1(device, m_cachedPaintDevice); 0075 KisPaintDeviceSP blur = d1.device(); 0076 KisPainter::copyAreaOptimizedOldData(gaussNeedRect.topLeft(), device, blur, gaussNeedRect); 0077 KisGaussianKernel::applyGaussian(blur, applyRect, 0078 blurAmount, blurAmount, 0079 channelFlags, 0080 convolutionUpdater, 0081 true); // make sure we create an internal transaction on temp device 0082 0083 KisPainter painter(device); 0084 painter.setCompositeOpId(COMPOSITE_GRAIN_EXTRACT); 0085 painter.bitBlt(applyRect.topLeft(), blur, applyRect); 0086 painter.end(); 0087 } 0088 0089 0090 QRect KisGaussianHighPassFilter::neededRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const 0091 { 0092 KisLodTransformScalar t(lod); 0093 0094 QVariant value; 0095 0096 const int halfSize = config->getProperty("blurAmount", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; 0097 0098 return rect.adjusted( -halfSize * 2, -halfSize * 2, halfSize * 2, halfSize * 2); 0099 } 0100 0101 QRect KisGaussianHighPassFilter::changedRect(const QRect & rect, const KisFilterConfigurationSP config, int lod) const 0102 { 0103 KisLodTransformScalar t(lod); 0104 0105 QVariant value; 0106 0107 const int halfSize = config->getProperty("blurAmount", value) ? KisGaussianKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; 0108 0109 return rect.adjusted( -halfSize, -halfSize, halfSize, halfSize); 0110 }