File indexing completed on 2024-06-09 04:27:12

0001 /*
0002  * SPDX-FileCopyrightText: 2017 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_asccdl_filter.h"
0008 #include "kis_wdg_asccdl.h"
0009 #include <kpluginfactory.h>
0010 #include <klocalizedstring.h>
0011 #include <filter/kis_filter_category_ids.h>
0012 #include <filter/kis_filter_registry.h>
0013 #include <filter/kis_color_transformation_configuration.h>
0014 #include <qmath.h>
0015 
0016 K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory,
0017                            "kritaasccdl.json",
0018                            registerPlugin<KritaASCCDL>();)
0019 
0020 
0021 KritaASCCDL::KritaASCCDL(QObject *parent, const QVariantList &) : QObject(parent)
0022 {
0023     KisFilterRegistry::instance()->add(KisFilterSP(new KisFilterASCCDL()));
0024 }
0025 
0026 KritaASCCDL::~KritaASCCDL()
0027 {
0028 
0029 }
0030 
0031 KisFilterASCCDL::KisFilterASCCDL(): KisColorTransformationFilter(id(), FiltersCategoryAdjustId, i18n("&Slope, Offset, Power..."))
0032 {
0033     setSupportsPainting(true);
0034     setSupportsAdjustmentLayers(true);
0035     setSupportsLevelOfDetail(true);
0036     setSupportsThreading(true);
0037     setColorSpaceIndependence(FULLY_INDEPENDENT);
0038     setShowConfigurationWidget(true);
0039 }
0040 
0041 KoColorTransformation *KisFilterASCCDL::createTransformation(const KoColorSpace *cs,
0042                                                              const KisFilterConfigurationSP config) const
0043 {
0044     KoColor black(Qt::black, cs);
0045     KoColor white(Qt::white, cs);
0046     return new KisASCCDLTransformation(cs,
0047                                        config->getColor("slope", black),
0048                                        config->getColor("offset", white),
0049                                        config->getColor("power", black));
0050 }
0051 
0052 KisConfigWidget *KisFilterASCCDL::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const
0053 {
0054     return new KisASCCDLConfigWidget(parent, dev->colorSpace());
0055 }
0056 
0057 bool KisFilterASCCDL::needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const
0058 {
0059     KoColor black(Qt::black, cs);
0060     KoColor offset = config->getColor("offset", black);
0061     offset.convertTo(cs);
0062     if (cs->difference(black.data(), offset.data())>0) {
0063         return true;
0064     }
0065     return false;
0066 }
0067 
0068 KisFilterConfigurationSP KisFilterASCCDL::defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const
0069 {
0070     KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
0071     QVariant colorVariant("KoColor");
0072     KoColor black;
0073     black.fromQColor(QColor(Qt::black));
0074     KoColor white;
0075     white.fromQColor(QColor(Qt::white));
0076     colorVariant.setValue(white);
0077     config->setProperty( "slope", colorVariant);
0078     config->setProperty( "power", colorVariant);
0079     colorVariant.setValue(black);
0080     config->setProperty("offset", colorVariant);
0081     return config;
0082 }
0083 
0084 KisASCCDLTransformation::KisASCCDLTransformation(const KoColorSpace *cs, KoColor slope, KoColor offset, KoColor power)
0085 {
0086     QVector<float> slopeN(cs->channelCount());
0087     slope.convertTo(cs);
0088     slope.colorSpace()->normalisedChannelsValue(slope.data(), slopeN);
0089     m_slope = slopeN;
0090     offset.convertTo(cs);
0091     QVector<float> offsetN(cs->channelCount());
0092     offset.colorSpace()->normalisedChannelsValue(offset.data(), offsetN);
0093     m_offset = offsetN;
0094     power.convertTo(cs);
0095     QVector<float> powerN(cs->channelCount());
0096     power.colorSpace()->normalisedChannelsValue(power.data(), powerN);
0097     m_power = powerN;
0098     m_cs = cs;
0099 }
0100 
0101 void KisASCCDLTransformation::transform(const quint8 *src, quint8 *dst, qint32 nPixels) const
0102 {
0103     QVector<float> normalised(m_cs->channelCount());
0104     const int pixelSize = m_cs->pixelSize();
0105     const int alphaPos = m_cs->alphaPos();
0106     const int channelCount = m_cs->channelCount();
0107 
0108     while (nPixels--) {
0109         m_cs->normalisedChannelsValue(src, normalised);
0110 
0111         for (uint c = 0; c < channelCount; c++){
0112             if (c != alphaPos) {
0113                 normalised[c] = qPow( (normalised.at(c)*m_slope.at(c))+m_offset.at(c), m_power.at(c));
0114             }
0115         }
0116         m_cs->fromNormalisedChannelsValue(dst, normalised);
0117         src += pixelSize;
0118         dst += pixelSize;
0119     }
0120 }
0121 
0122 #include "kis_asccdl_filter.moc"