1 /*
2  */
3 
4 /*
5 
6     Copyright (C) 2014 Ferrero Andrea
7 
8     This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21 
22  */
23 
24 /*
25 
26     These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/
27 
28  */
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 
34 #include "../base/processor_imp.hh"
35 #include "tone_mapping_v2.hh"
36 #include "relight.hh"
37 #include "operations.hh"
38 
39 
40 
RelightPar()41 PF::RelightPar::RelightPar():
42 OpParBase(),
43 strength("strength",this,pow(10, 0.2)),
44 range("range",this,0.75),
45 contrast("contrast",this,0),
46 LE_compression("LE_compression",this,0.95)
47 {
48   shahl = new_shadows_highlights_v2();
49   if( shahl && shahl->get_par() ) {
50     PF::OpParBase* par = shahl->get_par();
51     par->set_property( "amount", pow(10, 0.5) );
52     par->set_property( "shadows", strength.get() );
53     par->set_property( "shadows_range", 5.0f );
54     par->set_property( "highlights", pow(10, 0.0) );
55     par->set_property( "highlights_range", 0.5 );
56     par->set_property( "constrast", 0.0f );
57     par->set_property( "constrast_threshold", 1 );
58     par->set_property( "anchor", range.get() );
59     par->set_property( "sh_radius", 128 );
60     par->set_property( "sh_threshold", 0.1 );
61   }
62 
63   tm = new_tone_mapping_v2();
64   if( tm && tm->get_par() ) {
65     PF::OpParBase* par = tm->get_par();
66     PF::PropertyBase* p = par->get_property("preset");
67     if( p ) p->set_enum_value(PF::TONE_MAPPING_PRESET_CUSTOM);
68     par->set_property( "hue_protection", false );
69     par->set_property( "LE_gain", 1 );
70     par->set_property( "LE_compression", 0.639112f );
71     par->set_property( "LE_slope", contrast.get()+1.0f );
72     par->set_property( "LE_lin_max", range.get() );
73     par->set_property( "LE_knee_strength", 1.0f );
74     par->set_property( "LE_shoulder_slope", 0.0f );
75     par->set_property( "LE_shoulder_max", 1.0f );
76     par->set_property( "lumi_blend_frac", 0 );
77     par->set_property( "saturation_scaling", 0.0 );
78     par->set_property( "sh_desaturation", 0.5 );
79     par->set_property( "hl_desaturation", 1.0 );
80     par->set_property( "local_contrast_amount", 0.0 );
81     par->set_property( "local_contrast_radius", 0.5 );
82     par->set_property( "local_contrast_threshold", 0.075 );
83   }
84 
85   set_type("relight" );
86 
87   set_default_name( _("relight") );
88 }
89 
90 
needs_caching()91 bool PF::RelightPar::needs_caching()
92 {
93   return true;
94 }
95 
96 
propagate_settings()97 void PF::RelightPar::propagate_settings()
98 {
99   if( shahl && shahl->get_par() ) {
100       PF::OpParBase* par = shahl->get_par();
101       par->set_property( "amount", pow(10, 0.5) );
102       par->set_property( "shadows", strength.get() );
103       par->set_property( "shadows_range", 5.0f );
104       par->set_property( "highlights", pow(10, 0.0) );
105       par->set_property( "highlights_range", 0.5f );
106       par->set_property( "constrast", 0.0f );
107       par->set_property( "constrast_threshold", 1 );
108       par->set_property( "anchor", range.get() );
109       par->set_property( "sh_radius", 128 );
110       par->set_property( "sh_threshold", 0.1 );
111     shahl->get_par()->propagate_settings();
112   }
113   if( tm && tm->get_par() ) {
114     PF::OpParBase* par = tm->get_par();
115     PF::PropertyBase* p = par->get_property("preset");
116     if( p ) p->set_enum_value(PF::TONE_MAPPING_PRESET_CUSTOM);
117     par->set_property( "hue_protection", false );
118     par->set_property( "LE_gain", 1 );
119     par->set_property( "LE_compression", LE_compression.get() );
120     par->set_property( "LE_slope", contrast.get()+1.0f );
121     par->set_property( "LE_lin_max", range.get() );
122     par->set_property( "LE_knee_strength", 1.0f );
123     par->set_property( "LE_shoulder_slope", 0.0f );
124     par->set_property( "LE_shoulder_max", 1.0f );
125     par->set_property( "lumi_blend_frac", 0 );
126     par->set_property( "saturation_scaling", 0.0 );
127     par->set_property( "sh_desaturation", 0.5 );
128     par->set_property( "hl_desaturation", 1.0 );
129     par->set_property( "local_contrast_amount", 0.0 );
130     par->set_property( "local_contrast_radius", 0.5 );
131     par->set_property( "local_contrast_threshold", 0.075 );
132     par->propagate_settings();
133   }
134 }
135 
136 
compute_padding(VipsImage * full_res,unsigned int id,unsigned int level)137 void PF::RelightPar::compute_padding( VipsImage* full_res, unsigned int id, unsigned int level )
138 {
139   int tot_padding = 0;
140   if( shahl && shahl->get_par() ) {
141     PF::OpParBase* par = shahl->get_par();
142     par->set_property( "shadows", strength.get() );
143     par->set_property( "shadows_range", range.get() );
144     par->propagate_settings();
145     par->compute_padding(full_res, id, level);
146     tot_padding += par->get_padding(id);
147   }
148 
149   set_padding( tot_padding, id );
150 }
151 
152 
153 
pre_build(rendermode_t mode)154 void PF::RelightPar::pre_build( rendermode_t mode )
155 {
156   if( tm && tm->get_par() ) {
157     PF::OpParBase* par = tm->get_par();
158     PF::PropertyBase* p = par->get_property("preset");
159     if( p ) p->set_enum_value(PF::TONE_MAPPING_PRESET_CUSTOM);
160     par->set_property( "hue_protection", false );
161     par->set_property( "LE_gain", 1 );
162     par->set_property( "LE_compression", 0.639112f );
163     par->set_property( "LE_slope", contrast.get()+1.0f );
164     par->set_property( "LE_lin_max", range.get() );
165     par->set_property( "LE_knee_strength", 1.0f );
166     par->set_property( "LE_shoulder_slope", 0.0f );
167     par->set_property( "LE_shoulder_max", 1.0f );
168     par->set_property( "lumi_blend_frac", 0 );
169     par->set_property( "saturation_scaling", 0.0 );
170     par->set_property( "sh_desaturation", 0.5 );
171     par->set_property( "hl_desaturation", 1.0 );
172     par->set_property( "local_contrast_amount", 0.0 );
173     par->set_property( "local_contrast_radius", 0.5 );
174     par->set_property( "local_contrast_threshold", 0.075 );
175 
176     tm->get_par()->pre_build( mode );
177 
178     p = par->get_property("LE_compression");
179     if( p ) LE_compression.import(p);
180     par->set_property( "LE_compression", LE_compression.get() );
181 
182   }
183 }
184 
build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)185 VipsImage* PF::RelightPar::build(std::vector<VipsImage*>& in, int first,
186     VipsImage* imap, VipsImage* omap,
187     unsigned int& level)
188 {
189   if( (in.size()<1) || (in[0]==NULL) )
190     return NULL;
191 
192   std::vector<VipsImage*> in2;
193 
194   VipsImage* srcimg = in[0];
195   VipsImage* outimg = NULL;
196   if( true && strength.get() > 1 && shahl && shahl->get_par() ) {
197     PF::OpParBase* par = shahl->get_par();
198     par->set_property( "amount", pow(10, 0.5) );
199     par->set_property( "shadows", strength.get() );
200     par->set_property( "shadows_range", 5.0f );
201     par->set_property( "highlights", pow(10, 0.0) );
202     par->set_property( "highlights_range", 0.5f );
203     par->set_property( "constrast", 0.0f );
204     par->set_property( "constrast_threshold", 1 );
205     par->set_property( "anchor", range.get() );
206     par->set_property( "sh_radius", 128 );
207     par->set_property( "sh_threshold", 0.1 );
208 
209     par->set_image_hints( srcimg );
210     par->set_format( get_format() );
211     par->propagate_settings();
212     par->compute_padding(srcimg, 0, level);
213     in2.clear(); in2.push_back( srcimg );
214     outimg = par->build( in2, 0, NULL, NULL, level );
215   } else {
216     outimg = srcimg;
217     PF_REF(srcimg, "RelightPar::build: srcimg unref after tm");
218   }
219 
220   srcimg = outimg;
221   if( contrast.get() > 0 && tm && tm->get_par() ) {
222     //std::cout<<"RelightPar::build: building the tone mapping module"<<std::endl;
223     PF::OpParBase* par = tm->get_par();
224     PF::PropertyBase* p = par->get_property("preset");
225     if( p ) p->set_enum_value(PF::TONE_MAPPING_PRESET_CUSTOM);
226     par->set_property( "hue_protection", false );
227     par->set_property( "LE_gain", 1 );
228     par->set_property( "LE_compression", LE_compression.get() );
229     par->set_property( "LE_slope", contrast.get()+1.0f );
230     par->set_property( "LE_lin_max", range.get() );
231     par->set_property( "LE_knee_strength", 1.0f );
232     par->set_property( "LE_shoulder_slope", 0.0f );
233     par->set_property( "LE_shoulder_max", 1.0f );
234     par->set_property( "lumi_blend_frac", 0 );
235     par->set_property( "saturation_scaling", 0.0 );
236     par->set_property( "sh_desaturation", 0.5 );
237     par->set_property( "hl_desaturation", 1.0 );
238     par->set_property( "local_contrast_amount", 0.0 );
239     par->set_property( "local_contrast_radius", 0.5 );
240     par->set_property( "local_contrast_threshold", 0.075 );
241 
242     par->set_image_hints( srcimg );
243     par->set_format( get_format() );
244     in2.clear(); in2.push_back( srcimg );
245     outimg = par->build( in2, 0, NULL, NULL, level );
246     PF_UNREF(srcimg, "RelightPar::build: srcimg unref after tm");
247   }
248 
249   //std::cout<<"RelightPar::build(): par->shadows_range: "<<shahl->get_par()->get_property("shadows_range")->get_str()<<std::endl;
250 
251   return outimg;
252 }
253 
254 
255 
new_relight()256 PF::ProcessorBase* PF::new_relight()
257 { return new PF::Processor<PF::RelightPar,PF::RelightProc>(); }
258