1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2005-05-25
7  * Description : filter to add Film Grain to image.
8  *
9  * Copyright (C) 2005-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10  * Copyright (C) 2005-2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
11  * Copyright (C) 2010      by Martin Klapetek <martin dot klapetek at gmail dot com>
12  *
13  * This program is free software; you can redistribute it
14  * and/or modify it under the terms of the GNU General
15  * Public License as published by the Free Software Foundation;
16  * either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * ============================================================ */
25 
26 #ifndef DIGIKAM_FILM_GRAIN_FILTER_H
27 #define DIGIKAM_FILM_GRAIN_FILTER_H
28 
29 // Local includes
30 
31 #include "digikam_export.h"
32 #include "dimgthreadedfilter.h"
33 #include "digikam_globals.h"
34 #include "dcolor.h"
35 
36 namespace Digikam
37 {
38 
39 class DIGIKAM_EXPORT FilmGrainContainer
40 {
41 
42 public:
43 
FilmGrainContainer()44     FilmGrainContainer()
45       : grainSize(1),
46         photoDistribution(false),
47         addLuminanceNoise(true),
48         lumaIntensity(25),
49         lumaShadows(-100),
50         lumaMidtones(0),
51         lumaHighlights(-100),
52         addChrominanceBlueNoise(false),
53         chromaBlueIntensity(25),
54         chromaBlueShadows(-100),
55         chromaBlueMidtones(0),
56         chromaBlueHighlights(-100),
57         addChrominanceRedNoise(false),
58         chromaRedIntensity(25),
59         chromaRedShadows(-100),
60         chromaRedMidtones(0),
61         chromaRedHighlights(-100)
62     {
63     };
64 
~FilmGrainContainer()65     ~FilmGrainContainer()
66     {
67     };
68 
isDirty()69     bool isDirty() const
70     {
71         return (addLuminanceNoise || addChrominanceBlueNoise || addChrominanceRedNoise);
72     };
73 
74 public:
75 
76     int  grainSize;
77     bool photoDistribution;
78 
79     bool addLuminanceNoise;
80     int  lumaIntensity;
81     int  lumaShadows;
82     int  lumaMidtones;
83     int  lumaHighlights;
84 
85     bool addChrominanceBlueNoise;
86     int  chromaBlueIntensity;
87     int  chromaBlueShadows;
88     int  chromaBlueMidtones;
89     int  chromaBlueHighlights;
90 
91     bool addChrominanceRedNoise;
92     int  chromaRedIntensity;
93     int  chromaRedShadows;
94     int  chromaRedMidtones;
95     int  chromaRedHighlights;
96 };
97 
98 // -----------------------------------------------------------------------------------------------
99 
100 class DIGIKAM_EXPORT FilmGrainFilter : public DImgThreadedFilter
101 {
102     Q_OBJECT
103 
104 public:
105 
106     explicit FilmGrainFilter(QObject* const parent = nullptr);
107     explicit FilmGrainFilter(DImg* const orgImage, QObject* const parent = nullptr, const FilmGrainContainer& settings=FilmGrainContainer());
108     // Constructor for slave mode: execute immediately in current thread with specified master filter
109     explicit FilmGrainFilter(DImgThreadedFilter* const parentFilter, const DImg& orgImage, const DImg& destImage,
110                              int progressBegin=0, int progressEnd=100,
111                              const FilmGrainContainer& settings=FilmGrainContainer());
112     ~FilmGrainFilter() override;
113 
114 
FilterIdentifier()115     static QString          FilterIdentifier()
116     {
117         return QLatin1String("digikam:FilmGrainFilter");
118     }
119 
120     static QString          DisplayableName();
121 
SupportedVersions()122     static QList<int>       SupportedVersions()
123     {
124         return QList<int>() << 1;
125     }
126 
CurrentVersion()127     static int              CurrentVersion()
128     {
129         return 1;
130     }
131 
132     void                    readParameters(const FilterAction& action)        override;
133 
filterIdentifier()134     QString         filterIdentifier()                          const override
135     {
136         return FilterIdentifier();
137     }
138 
139     FilterAction    filterAction()                                    override;
140 
141 private:
142 
143     void filterImage()                                                        override;
144 
145     void filmgrainMultithreaded(uint start, uint stop);
146 
147     inline void computeNoiseSettings(const DColor& col,
148                                      double& luRange, double& luNoise,
149                                      double& cbRange, double& cbNoise,
150                                      double& crRange, double& crNoise);
151     inline double interpolate(int shadows, int midtones, int highlights, const DColor& col);
152     inline double randomizeUniform(double range);
153     inline double randomizeGauss(double sigma);
154     inline double randomizePoisson(double lambda);
155     inline void   adjustYCbCr(DColor& col, double range, double nRand, int channel);
156 
157 private:
158 
159     class Private;
160     Private* const d;
161 };
162 
163 } // namespace Digikam
164 
165 #endif // DIGIKAM_FILM_GRAIN_FILTER_H
166