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