File indexing completed on 2024-05-26 04:32:09

0001 /*
0002  *  SPDX-FileCopyrightText: 2013 Sahil Nagpal <nagpal.sahil01@gmail.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "kis_dodgeshadows_adjustment.h"
0008 #include <KoConfig.h>
0009 
0010 #include <kis_debug.h>
0011 #include <klocalizedstring.h>
0012 #ifdef HAVE_OPENEXR
0013 #include <half.h>
0014 #endif
0015 
0016 #include <KoColorConversions.h>
0017 #include <KoColorModelStandardIds.h>
0018 #include <KoColorSpace.h>
0019 #include <KoColorSpaceTraits.h>
0020 #include <KoColorTransformation.h>
0021 #include <KoID.h>
0022 
0023 template<typename _channel_type_, typename traits>
0024 class KisDodgeShadowsAdjustment : public KoColorTransformation
0025 {
0026     typedef traits RGBTrait;
0027     typedef typename RGBTrait::Pixel RGBPixel;
0028 
0029 public:
0030     KisDodgeShadowsAdjustment(){}
0031 
0032     void transform(const quint8 *srcU8, quint8 *dstU8, qint32 nPixels) const override
0033     {
0034         const RGBPixel* src = reinterpret_cast<const RGBPixel*>(srcU8);
0035         RGBPixel* dst = reinterpret_cast<RGBPixel*>(dstU8);
0036         float value_red, value_green, value_blue, new_value_red, new_value_green, new_value_blue;
0037         const float factor(exposure * 0.333333);
0038         while (nPixels > 0) {
0039 
0040             value_red = KoColorSpaceMaths<_channel_type_, float>::scaleToA(src->red);
0041             value_green = KoColorSpaceMaths<_channel_type_, float>::scaleToA(src->green);
0042             value_blue = KoColorSpaceMaths<_channel_type_, float>::scaleToA(src->blue);
0043 
0044             new_value_red = factor + value_red  - factor * value_red;
0045             new_value_green = factor + value_green  - factor * value_green;
0046             new_value_blue = factor + value_blue  - factor * value_blue;
0047             
0048             dst->red = KoColorSpaceMaths< float, _channel_type_ >::scaleToA(new_value_red);
0049             dst->green = KoColorSpaceMaths< float, _channel_type_ >::scaleToA(new_value_green);
0050             dst->blue = KoColorSpaceMaths< float, _channel_type_ >::scaleToA(new_value_blue);
0051             dst->alpha = src->alpha;
0052             
0053             --nPixels;
0054             ++src;
0055             ++dst;
0056         }
0057     }
0058 
0059     QList<QString> parameters() const override
0060     {
0061         QList<QString> list;
0062         list << "exposure";
0063         return list;
0064     }
0065 
0066     int parameterId(const QString& name) const override
0067     {
0068         if (name == "exposure")
0069         return 0;
0070         return -1;
0071     }
0072 
0073     void setParameter(int id, const QVariant& parameter) override
0074     {
0075         switch(id)
0076         {
0077         case 0:
0078             exposure = parameter.toDouble();
0079             break;
0080         default:
0081             ;
0082         }
0083     }
0084 private:
0085 
0086     float exposure {0.0f};
0087  };
0088 
0089  KisDodgeShadowsAdjustmentFactory::KisDodgeShadowsAdjustmentFactory()
0090     : KoColorTransformationFactory("DodgeShadows")
0091 {
0092 }
0093 
0094 QList< QPair< KoID, KoID > > KisDodgeShadowsAdjustmentFactory::supportedModels() const
0095 {
0096     QList< QPair< KoID, KoID > > l;
0097     l.append(QPair< KoID, KoID >(RGBAColorModelID , Integer8BitsColorDepthID));
0098     l.append(QPair< KoID, KoID >(RGBAColorModelID , Integer16BitsColorDepthID));
0099     l.append(QPair< KoID, KoID >(RGBAColorModelID , Float16BitsColorDepthID));
0100     l.append(QPair< KoID, KoID >(RGBAColorModelID , Float32BitsColorDepthID));
0101     return l;
0102 }
0103 
0104 KoColorTransformation* KisDodgeShadowsAdjustmentFactory::createTransformation(const KoColorSpace* colorSpace, QHash<QString, QVariant> parameters) const
0105 {
0106     KoColorTransformation * adj;
0107     if (colorSpace->colorModelId() != RGBAColorModelID) {
0108         dbgKrita << "Unsupported color space " << colorSpace->id() << " in KisDodgeShadowsAdjustmentFactory::createTransformation";
0109         return 0;
0110     }
0111     if (colorSpace->colorDepthId() == Float32BitsColorDepthID) {
0112         adj = new KisDodgeShadowsAdjustment < float, KoRgbTraits < float > >();
0113     }
0114 #ifdef HAVE_OPENEXR
0115     else if (colorSpace->colorDepthId() == Float16BitsColorDepthID) {
0116         adj = new KisDodgeShadowsAdjustment< half, KoRgbTraits < half > >();
0117     }
0118 #endif
0119     else if (colorSpace->colorDepthId() == Integer16BitsColorDepthID) {
0120         adj = new KisDodgeShadowsAdjustment< quint16, KoBgrTraits < quint16 > >();
0121     } else if (colorSpace->colorDepthId() == Integer8BitsColorDepthID) {
0122         adj = new KisDodgeShadowsAdjustment< quint8, KoBgrTraits < quint8 > >();
0123     } else {
0124         dbgKrita << "Unsupported color space " << colorSpace->id() << " in KisDodgeShadowsAdjustmentFactory::createTransformation";
0125         return 0;
0126     }
0127     adj->setParameters(parameters);
0128     return adj;
0129 
0130 }