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 "file_util.hh"
31 #include "layer.hh"
32 #include "image.hh"
33 
34 
Layer(uint32_t i,bool c)35 PF::Layer::Layer(uint32_t i, bool c):
36   id(i),
37   processor( NULL ),
38   blender( NULL ),
39   cached( c ),
40   image( NULL )
41 {
42   // A layer is always dirty when created, as it is by definition not included in the
43   // VIPS rendering chain yet
44   dirty = true;
45   modified_flag = true;
46 
47   enabled = true;
48   visible = true;
49   hidden = false;
50   sticky = false;
51   expanded = true;
52 
53   normal = true;
54 
55   set_cached( c );
56 }
57 
58 
59 
set_processor(ProcessorBase * p)60 void PF::Layer::set_processor(ProcessorBase* p)
61 {
62   processor = p;
63   processor->get_par()->signal_modified.connect(sigc::mem_fun(this, &PF::Layer::modified) );
64   //processor->get_par()->signal_modified.connect(sigc::mem_fun(image, &PF::Image::set_modified) );
65 }
66 
67 
set_blender(ProcessorBase * p)68 void PF::Layer::set_blender(ProcessorBase* p)
69 {
70   blender = p;
71   blender->get_par()->signal_modified.connect(sigc::mem_fun(this, &PF::Layer::modified) );
72   //blender->get_par()->signal_modified.connect(sigc::mem_fun(image, &PF::Image::set_modified) );
73 }
74 
75 
set_image(Image * img)76 void PF::Layer::set_image( Image* img )
77 {
78   image = img;
79   signal_modified.connect(sigc::mem_fun(image, &PF::Image::modified) );
80 }
81 
82 
set_cached(bool c)83 void PF::Layer::set_cached( bool c )
84 {
85   bool changed = (cached != c);
86   cached = c;
87   if( cached && cache_buffers.empty() ) {
88     //cache_buffers.insert( std::make_pair(PF::PF_RENDER_PREVIEW, new PF::CacheBuffer()) );
89     cache_buffers.insert( std::make_pair(PF::PF_RENDER_NORMAL, new PF::CacheBuffer()) );
90   }
91   if( cached && changed )
92     reset_cache_buffers();
93 }
94 
95 
get_cache_buffer()96 PF::CacheBuffer* PF::Layer::get_cache_buffer()
97 {
98   std::map<rendermode_t,PF::CacheBuffer*>::iterator i = cache_buffers.find( /*mode*/PF_RENDER_NORMAL );
99   if( i != cache_buffers.end() ) return i->second;
100   return NULL;
101 }
102 
103 
reset_cache_buffers()104 void PF::Layer::reset_cache_buffers()
105 {
106   //std::cout<<"Layer::reset_cache_buffers(\""<<get_name()<<"\")called"<<std::endl;
107   std::map<rendermode_t,CacheBuffer*>::iterator i;
108   for(i = cache_buffers.begin(); i != cache_buffers.end(); i++ ) {
109     if( i->second )
110       i->second->reset();
111   }
112 }
113 
114 
115 
insert(std::list<PF::Layer * > & list,PF::Layer * l,int32_t lid)116 bool PF::Layer::insert(std::list<PF::Layer*>& list, PF::Layer* l, int32_t lid)
117 {
118   if( lid < 0 ) {
119     list.push_back( l );
120     return true;
121   }
122 
123   std::list<Layer*>::iterator it;
124   for( it = list.begin(); it != list.end(); ++it )
125     if( (int32_t)(*it)->get_id() == lid ) break;
126 
127   if( it == list.end() ) return false;
128 
129   it++;
130   list.insert( it, l );
131   return true;
132 }
133 
134 
135 
insert_before(std::list<PF::Layer * > & list,PF::Layer * l,int32_t lid)136 bool PF::Layer::insert_before(std::list<PF::Layer*>& list, PF::Layer* l, int32_t lid)
137 {
138   std::list<Layer*>::iterator it;
139   for( it = list.begin(); it != list.end(); ++it )
140     if( (int32_t)(*it)->get_id() == lid ) break;
141 
142   if( it == list.end() ) return false;
143 
144   list.insert( it, l );
145   return true;
146 }
147 
148 
149 
sublayers_insert(PF::Layer * l,int32_t lid)150 bool PF::Layer::sublayers_insert(PF::Layer* l, int32_t lid)
151 {
152   return insert(sublayers,l,lid);
153 }
154 
sublayers_insert_before(PF::Layer * l,int32_t lid)155 bool PF::Layer::sublayers_insert_before(PF::Layer* l, int32_t lid)
156 {
157   return insert_before(sublayers,l,lid);
158 }
159 
160 
imap_insert(PF::Layer * l,int32_t lid)161 bool PF::Layer::imap_insert(PF::Layer* l, int32_t lid)
162 {
163   return insert(imap_layers,l,lid);
164 }
165 
imap_insert_before(PF::Layer * l,int32_t lid)166 bool PF::Layer::imap_insert_before(PF::Layer* l, int32_t lid)
167 {
168   return insert_before(imap_layers,l,lid);
169 }
170 
171 
omap_insert(PF::Layer * l,int32_t lid)172 bool PF::Layer::omap_insert(PF::Layer* l, int32_t lid)
173 {
174   return insert(omap_layers,l,lid);
175 }
176 
omap_insert_before(PF::Layer * l,int32_t lid)177 bool PF::Layer::omap_insert_before(PF::Layer* l, int32_t lid)
178 {
179   return insert_before(omap_layers,l,lid);
180 }
181 
182 
remove_input(int32_t lid)183 void PF::Layer::remove_input(int32_t lid)
184 {
185   bool done = true;
186   do {
187     done = true;
188     for( unsigned int i = 0; i < inputs.size(); i++) {
189       if( inputs[i].first.first == lid ) {
190         inputs.erase( inputs.begin()+i );
191         done = false;
192         break;
193       }
194     }
195   } while( !done );
196 }
197 
198 
199 
save(std::ostream & ostr,int level)200 bool PF::Layer::save( std::ostream& ostr, int level )
201 {
202   if( is_hidden() ) return true;
203 
204   for(int i = 0; i < level; i++) ostr<<"  ";
205   ostr<<"<layer name=\""<<PF::pf_escape_xml(name)<<"\" id=\""<<id<<"\" visible=\""<<enabled<<"\" expanded=\""<<expanded
206       <<"\" normal=\""<<normal<<"\" inputs=\"";
207   int n;
208   for( size_t i=0, n=0; i < inputs.size(); i++ ) {
209     int32_t id = inputs[i].first.first;
210     int32_t imgid = inputs[i].first.second;
211     if( id < 0 ) continue;
212     PF::Layer* l = image->get_layer_manager().get_layer( id );
213     if( !l ) continue;
214     if( n>0 ) ostr<<" ";
215     ostr<<l->get_id()<<" "<<imgid<<" "<<inputs[i].second;
216     n++;
217   }
218   ostr<<"\">"<<std::endl;
219 
220   if( processor && processor->get_par() )
221     processor->get_par()->save( ostr, level+1 );
222 
223   if( blender && blender->get_par() )
224     blender->get_par()->save( ostr, level+1 );
225 
226   for(int i = 0; i < level+1; i++) ostr<<"  ";
227   ostr<<"<sublayers type=\"child\">"<<std::endl;
228   for( std::list<Layer*>::iterator li = sublayers.begin();
229        li != sublayers.end(); li++ ) {
230     (*li)->save( ostr, level+2 );
231   }
232   for(int i = 0; i < level+1; i++) ostr<<"  ";
233   ostr<<"</sublayers>"<<std::endl;
234 
235   for(int i = 0; i < level+1; i++) ostr<<"  ";
236   ostr<<"<sublayers type=\"imap\">"<<std::endl;
237   for( std::list<Layer*>::iterator li = imap_layers.begin();
238        li != imap_layers.end(); li++ ) {
239     (*li)->save( ostr, level+2 );
240   }
241   for(int i = 0; i < level+1; i++) ostr<<"  ";
242   ostr<<"</sublayers>"<<std::endl;
243 
244   for(int i = 0; i < level+1; i++) ostr<<"  ";
245   ostr<<"<sublayers type=\"omap\">"<<std::endl;
246   for( std::list<Layer*>::iterator li = omap_layers.begin();
247        li != omap_layers.end(); li++ ) {
248     (*li)->save( ostr, level+2 );
249   }
250   for(int i = 0; i < level+1; i++) ostr<<"  ";
251   ostr<<"</sublayers>"<<std::endl;
252 
253   for(int i = 0; i < level; i++) ostr<<"  ";
254   ostr<<"</layer>"<<std::endl;
255 
256   return true;
257 }
258