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 <arpa/inet.h>
31
32 #include "../../operations/gaussblur.hh"
33 #include "../../operations/hsl_mask.hh"
34
35 #include "hue_saturation.hh"
36
37
38
HueSaturationPar()39 PF::HueSaturationPar::HueSaturationPar():
40 OpParBase(),
41 hue("hue",this,0),
42 hue_eq("hue_eq",this,0),
43 saturation("saturation",this,0),
44 saturation_eq("saturation_eq",this,0),
45 contrast("contrast",this,0),
46 contrast_eq("contrast_eq",this,0),
47 brightness("brightness",this,0),
48 brightness_eq("brightness_eq",this,0),
49 gamma("gamma",this,0),
50 brightness_is_gamma("brightness_is_gamma",this,false),
51 hue_H_equalizer( "hue_H_equalizer", this ),
52 hue_S_equalizer( "hue_S_equalizer", this ),
53 hue_L_equalizer( "hue_L_equalizer", this ),
54 hue_H_equalizer_enabled( "hue_H_equalizer_enabled", this, false ),
55 hue_S_equalizer_enabled( "hue_S_equalizer_enabled", this, false ),
56 hue_L_equalizer_enabled( "hue_L_equalizer_enabled", this, false ),
57 saturation_H_equalizer( "saturation_H_equalizer", this ),
58 saturation_S_equalizer( "saturation_S_equalizer", this ),
59 saturation_L_equalizer( "saturation_L_equalizer", this ),
60 contrast_H_equalizer( "contrast_H_equalizer", this ),
61 contrast_S_equalizer( "contrast_S_equalizer", this ),
62 contrast_L_equalizer( "contrast_L_equalizer", this ),
63 brightness_H_equalizer( "brightness_H_equalizer", this ),
64 brightness_S_equalizer( "brightness_S_equalizer", this ),
65 brightness_L_equalizer( "brightness_L_equalizer", this ),
66 show_mask("show_mask",this,false),
67 invert_mask("invert_mask",this,false),
68 feather_mask("feather_mask",this,false),
69 feather_radius("feather_radius",this,5.0f)
70 {
71 set_type("hue_saturation" );
72
73 set_default_name( _("basic adjustments") );
74
75 mask = new_hsl_mask();
76 blur = new_gaussblur();
77
78 int id = 0;
79 eq_vec[id++] = &hue_H_equalizer;
80 eq_vec[id++] = &hue_S_equalizer;
81 eq_vec[id++] = &hue_L_equalizer;
82 /*
83 eq_vec[id++] = &saturation_H_equalizer;
84 eq_vec[id++] = &saturation_S_equalizer;
85 eq_vec[id++] = &saturation_L_equalizer;
86 eq_vec[id++] = &contrast_H_equalizer;
87 eq_vec[id++] = &contrast_S_equalizer;
88 eq_vec[id++] = &contrast_L_equalizer;
89 eq_vec[id++] = &brightness_H_equalizer;
90 eq_vec[id++] = &brightness_S_equalizer;
91 eq_vec[id++] = &brightness_L_equalizer;
92 */
93
94 hue_H_equalizer.get().set_circular( true );
95
96 float x1 = 0, y1 = 1., x2 = 1, y2 = 1.;
97 for( id = 0; id < 3; id++ ) {
98 eq_vec[id]->get().set_point( 0, x1, y1 );
99 eq_vec[id]->get().set_point( 1, x2, y2 );
100 eq_vec[id]->store_default();
101 }
102 /*
103 for( id = 0; id < 3; id+=3 ) {
104 float x = 40;
105 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
106 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
107 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
108 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
109 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
110 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
111 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
112 eq_vec[id]->get().add_point( x/360, 0. ); x += 40;
113 }
114 */
115 x1 = 0; y1 = 0.5;
116 //eq_vec[0]->get().set_point( 0, x1, y1 );
117 }
118
119
120
update_curve(PF::Property<PF::SplineCurve> * curve,float * vec)121 void PF::HueSaturationPar::update_curve( PF::Property<PF::SplineCurve>* curve, float* vec )
122 {
123 curve->get().lock();
124 //std::cout<<"CurvesPar::update_curve() called. # of points="<<curve.get().get_npoints()<<std::endl;std::cout.flush();
125 for(int i = 0; i <= 65535; i++) {
126 float x = ((float)i)/65535;
127 float y = curve->get().get_value( x );
128 if( y>1 ) y=1;
129 if( y<0 ) y=0;
130 vec[i] = y;
131 //std::cout<<"i="<<i<<" x="<<x<<" y="<<y<<" vec8[i]="<<vec8[i]<<std::endl;
132 }
133 curve->get().unlock();
134 }
135
136
137
build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)138 VipsImage* PF::HueSaturationPar::build(std::vector<VipsImage*>& in, int first,
139 VipsImage* imap, VipsImage* omap,
140 unsigned int& level)
141 {
142 for( int id = 0; id < 3; id++ ) {
143 if( eq_vec[id]->is_modified() )
144 update_curve( eq_vec[id], vec[id] );
145 eq_enabled[id] = false;
146 //std::cout<<"eq_vec["<<id<<"]->get().get_npoints()="<<eq_vec[id]->get().get_npoints()<<std::endl;
147 //for( size_t pi = 0; pi < eq_vec[id]->get().get_npoints(); pi++ ) {
148 //std::cout<<" get_point("<<pi<<").second="<<eq_vec[id]->get().get_point(pi).second<<std::endl;
149 //if( fabs(eq_vec[id]->get().get_point(pi).second) > 0.001 ) {
150 //eq_enabled[id] = true;
151 //break;
152 //}
153 //}
154 }
155 eq_enabled[0] = hue_H_equalizer_enabled.get();
156 eq_enabled[1] = hue_S_equalizer_enabled.get();
157 eq_enabled[2] = hue_L_equalizer_enabled.get();
158
159 exponent = (gamma.get() >= 0.0f) ? 1.0f / (1.0f + gamma.get()*2.f) : (1.0f - gamma.get()*2.);
160
161 std::vector<VipsImage*> in2;
162 if( in.size() < 1 )
163 return NULL;
164
165 in2.push_back( in[0] );
166 PF::HSLMaskPar* mask_par = dynamic_cast<PF::HSLMaskPar*>( mask->get_par() );
167 PF::GaussBlurPar* blur_par = dynamic_cast<PF::GaussBlurPar*>( blur->get_par() );
168 if( mask_par ) {
169 std::vector<VipsImage*> in3; in3.push_back( in[0] );
170 mask_par->get_H_curve() = hue_H_equalizer;
171 mask_par->get_S_curve() = hue_S_equalizer;
172 mask_par->get_L_curve() = hue_L_equalizer;
173 mask_par->set_H_curve_enabled( hue_H_equalizer_enabled.get() );
174 mask_par->set_S_curve_enabled( hue_S_equalizer_enabled.get() );
175 mask_par->set_L_curve_enabled( hue_L_equalizer_enabled.get() );
176 mask_par->set_invert( get_invert_mask() );
177 mask_par->set_image_hints( in[0] );
178 mask_par->set_format( get_format() );
179 VipsImage* imask = mask_par->build( in3, 0, NULL, NULL, level );
180
181 if( feather_mask.get() == true ) {
182 blur_par->set_radius( feather_radius.get() );
183 blur_par->set_image_hints( in[0] );
184 blur_par->set_format( get_format() );
185 in3.clear();
186 in3.push_back( imask );
187 VipsImage* blurred = blur_par->build( in3, 0, NULL, NULL, level );
188 std::cout<<"blurred = "<<blurred<<std::endl;
189 PF_UNREF( imask, "HueSaturationPar::build(): imask unref");
190 imask = blurred;
191 }
192
193 in2.push_back( imask );
194 }
195
196 VipsImage* out = PF::OpParBase::build( in2, 0, imap, omap, level );
197
198 if( in2.size()>1 ) PF_UNREF( in2[1], "HueSaturationPar::build(): in[2] unref");
199
200 return out;
201 }
202