1 /* === S Y N F I G ========================================================= */
2 /*!	\file tool/optionsprocessor.cpp
3 **	\brief Synfig Tool Options Processor Class
4 **
5 **	$Id$
6 **
7 **	\legal
8 **	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **	Copyright (c) 2007, 2008 Chris Moore
10 **	Copyright (c) 2009-2014 Diego Barrios Romero
11 **
12 **	This package is free software; you can redistribute it and/or
13 **	modify it under the terms of the GNU General Public License as
14 **	published by the Free Software Foundation; either version 2 of
15 **	the License, or (at your option) any later version.
16 **
17 **	This package is distributed in the hope that it will be useful,
18 **	but WITHOUT ANY WARRANTY; without even the implied warranty of
19 **	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 **	General Public License for more details.
21 **	\endlegal
22 */
23 /* ========================================================================= */
24 
25 #ifdef USING_PCH
26 #	include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #	include <config.h>
30 #endif
31 
32 #include <iostream>
33 #include <boost/filesystem.hpp>
34 #include <boost/format.hpp>
35 
36 #include <autorevision.h>
37 #include <synfig/general.h>
38 #include <synfig/localization.h>
39 #include <synfig/canvas.h>
40 #include <synfig/canvasfilenaming.h>
41 #include <synfig/context.h>
42 #include <synfig/target.h>
43 #include <synfig/layer.h>
44 #include <synfig/module.h>
45 #include <synfig/main.h>
46 #include <synfig/importer.h>
47 #include <synfig/loadcanvas.h>
48 #include <synfig/guid.h>
49 #include <synfig/valuenode_registry.h>
50 #include <synfig/filesystemgroup.h>
51 #include <synfig/filesystemnative.h>
52 #include <synfig/filecontainerzip.h>
53 
54 #include "definitions.h"
55 #include "job.h"
56 #include "synfigtoolexception.h"
57 #include "printing_functions.h"
58 #include "optionsprocessor.h"
59 
60 #endif
61 
62 using namespace std;
63 using namespace synfig;
64 namespace bfs=boost::filesystem;
65 
OptionsProcessor(boost::program_options::variables_map & vm,const boost::program_options::options_description & po_visible)66 OptionsProcessor::OptionsProcessor(
67 	boost::program_options::variables_map& vm,
68 	const boost::program_options::options_description& po_visible)
69 		: _vm(vm), _po_visible(po_visible)
70 {
71 	_allowed_video_codecs.push_back(VideoCodec("flv", "Flash Video (FLV) / Sorenson Spark / Sorenson H.263."));
72 	_allowed_video_codecs.push_back(VideoCodec("h263p", "H.263+ / H.263-1998 / H.263 version 2."));
73 	_allowed_video_codecs.push_back(VideoCodec("huffyuv", "Huffyuv / HuffYUV."));
74 	_allowed_video_codecs.push_back(VideoCodec("libtheora", "libtheora Theora."));
75 	_allowed_video_codecs.push_back(VideoCodec("libx264", "H.264 / AVC / MPEG-4 AVC."));
76 	_allowed_video_codecs.push_back(VideoCodec("libx264-lossless", "H.264 / AVC / MPEG-4 AVC (LossLess)."));
77 	_allowed_video_codecs.push_back(VideoCodec("mjpeg", "MJPEG (Motion JPEG)."));
78 	_allowed_video_codecs.push_back(VideoCodec("mpeg1video", "Raw MPEG-1 video."));
79 	_allowed_video_codecs.push_back(VideoCodec("mpeg2video", "Raw MPEG-2 video."));
80 	_allowed_video_codecs.push_back(VideoCodec("mpeg4", "MPEG-4 part 2 (XviD/DivX)."));
81 	_allowed_video_codecs.push_back(VideoCodec("msmpeg4", "MPEG-4 part 2 Microsoft variant version 3."));
82 	_allowed_video_codecs.push_back(VideoCodec("msmpeg4v1", "MPEG-4 part 2 Microsoft variant version 1."));
83 	_allowed_video_codecs.push_back(VideoCodec("msmpeg4v2", "MPEG-4 part 2 Microsoft variant version 2."));
84 	_allowed_video_codecs.push_back(VideoCodec("wmv1", "Windows Media Video 7."));
85 	_allowed_video_codecs.push_back(VideoCodec("wmv2", "Windows Media Video 8."));
86 }
87 
extract_canvas_info(Job & job)88 void OptionsProcessor::extract_canvas_info(Job& job)
89 {
90 	job.canvas_info = true;
91 	string value;
92 	string values = _vm["canvas-info"].as<string>();
93 
94 	std::string::size_type pos;
95 	while (!values.empty())
96 	{
97 		pos = values.find_first_of(',');
98 		if (pos == std::string::npos)
99 		{
100 			value = values;
101 			values = "";
102 		}
103 		else
104 		{
105 			value = values.substr(0, pos);
106 			values = values.substr(pos+1);
107 		}
108 		if (value == "all")
109 		{
110 			job.canvas_info_all = true;
111 			return;
112 		}
113 
114 		if (value == "time_start")			job.canvas_info_time_start		= true;
115 		else if (value == "time_end")		job.canvas_info_time_end		= true;
116 		else if (value == "frame_rate")		job.canvas_info_frame_rate		= true;
117 		else if (value == "frame_start")	job.canvas_info_frame_start		= true;
118 		else if (value == "frame_end")		job.canvas_info_frame_end		= true;
119 		else if (value == "w")				job.canvas_info_w				= true;
120 		else if (value == "h")				job.canvas_info_h				= true;
121 		else if (value == "image_aspect")	job.canvas_info_image_aspect	= true;
122 		else if (value == "pw")				job.canvas_info_pw				= true;
123 		else if (value == "ph")				job.canvas_info_ph				= true;
124 		else if (value == "pixel_aspect")	job.canvas_info_pixel_aspect	= true;
125 		else if (value == "tl")				job.canvas_info_tl				= true;
126 		else if (value == "br")				job.canvas_info_br				= true;
127 		else if (value == "physical_w")		job.canvas_info_physical_w		= true;
128 		else if (value == "physical_h")		job.canvas_info_physical_h		= true;
129 		else if (value == "x_res")			job.canvas_info_x_res			= true;
130 		else if (value == "y_res")			job.canvas_info_y_res			= true;
131 		else if (value == "span")			job.canvas_info_span			= true;
132 		else if (value == "interlaced")		job.canvas_info_interlaced		= true;
133 		else if (value == "antialias")		job.canvas_info_antialias		= true;
134 		else if (value == "clamp")			job.canvas_info_clamp			= true;
135 		else if (value == "flags")			job.canvas_info_flags			= true;
136 		else if (value == "focus")			job.canvas_info_focus			= true;
137 		else if (value == "bg_color")		job.canvas_info_bg_color		= true;
138 		else if (value == "metadata")		job.canvas_info_metadata		= true;
139 		else
140 		{
141 			cerr << _("Unrecognised canvas variable: ") << "'" << value.c_str() << "'" << endl;
142 			cerr << _("Recognized variables are:") << endl <<
143 				"  all, time_start, time_end, frame_rate, frame_start, frame_end, w, h," << endl <<
144 				"  image_aspect, pw, ph, pixel_aspect, tl, br, physical_w, physical_h," << endl <<
145 				"  x_res, y_res, span, interlaced, antialias, clamp, flags," << endl <<
146 				"  focus, bg_color, metadata" << endl;
147 		}
148 
149 		if (pos == std::string::npos)
150 			break;
151 	};
152 }
153 
process_settings_options()154 void OptionsProcessor::process_settings_options()
155 {
156 	if (_vm.count("verbose"))
157 	{
158 		SynfigToolGeneralOptions::instance()->set_verbosity(_vm["verbose"].as<int>());
159 		VERBOSE_OUT(1) << _("verbosity set to ")
160 					   << SynfigToolGeneralOptions::instance()->get_verbosity()
161 					   << std::endl;
162 	}
163 
164 	if (_vm.count("benchmarks"))
165 	{
166 		SynfigToolGeneralOptions::instance()->set_should_print_benchmarks(true);
167 	}
168 
169 	if (_vm.count("quiet"))
170 	{
171 		SynfigToolGeneralOptions::instance()->set_should_be_quiet(true);
172 	}
173 
174 	if (_vm.count("threads"))
175 	{
176 		SynfigToolGeneralOptions::instance()->set_threads(_vm["threads"].as<int>());
177 	}
178 
179 	VERBOSE_OUT(1) << _("Threads set to ")
180 				   << SynfigToolGeneralOptions::instance()->get_threads() << std::endl;
181 }
182 
process_info_options()183 void OptionsProcessor::process_info_options()
184 {
185 	if (_vm.count("help"))
186 	{
187 		print_usage();
188 		cout << _po_visible;
189 
190 		throw (SynfigToolException(SYNFIGTOOL_HELP));
191 	}
192 
193 	if (_vm.count("info"))
194 	{
195 		cout << PACKAGE "-" VERSION << endl;
196 #ifdef DEVEL_VERSION
197 			cout << endl << DEVEL_VERSION << endl << endl;
198 #endif
199 		cout << "Compiled on " __DATE__ /* " at "__TIME__ */;
200 #ifdef __GNUC__
201 		cout << " with GCC " << __VERSION__;
202 #endif
203 #ifdef _MSC_VER
204 		cout << " with Microsoft Visual C++ "
205 			 << (_MSC_VER>>8) << '.' << (_MSC_VER&255);
206 #endif
207 #ifdef __TCPLUSPLUS__
208 		cout << " with Borland Turbo C++ "
209 			 << (__TCPLUSPLUS__>>8) << '.'
210 			 << ((__TCPLUSPLUS__&255)>>4) << '.'
211 			 << (__TCPLUSPLUS__&15);
212 #endif
213 		cout << endl << SYNFIG_COPYRIGHT << endl;
214 		cout << endl;
215 
216 		throw (SynfigToolException(SYNFIGTOOL_HELP));
217 	}
218 
219 	if (_vm.count("version"))
220 	{
221 		cerr << PACKAGE << " " << VERSION << endl;
222 
223 		throw (SynfigToolException(SYNFIGTOOL_HELP));
224 	}
225 
226 	if (_vm.count("license"))
227 	{
228 		cerr << PACKAGE << " " << VERSION << endl;
229 		cout << SYNFIG_COPYRIGHT << endl << endl;
230 		cerr << SYNFIG_LICENSE << endl << endl;
231 
232 		throw (SynfigToolException(SYNFIGTOOL_HELP));
233 	}
234 
235 	if (_vm.count("target-video-codecs"))
236 	{
237 		print_target_video_codecs_help();
238 
239 		throw (SynfigToolException(SYNFIGTOOL_HELP));
240 	}
241 
242 	if (_vm.count("layers"))
243 	{
244 		synfig::Layer::Book::iterator iter =
245 			synfig::Layer::book().begin();
246 		for(; iter != synfig::Layer::book().end(); iter++)
247 			if (iter->second.category != CATEGORY_DO_NOT_USE)
248 				cout << (iter->first).c_str() << endl;
249 
250 		throw (SynfigToolException(SYNFIGTOOL_HELP));
251 	}
252 
253 	if (_vm.count("layer-info"))
254 	{
255 		Layer::Handle layer =
256 			synfig::Layer::create(_vm["layer-info"].as<string>());
257 
258 		cout << _("Layer Name: ") << layer->get_name() << endl;
259 		cout << _("Localized Layer Name: ")
260 			 << layer->get_local_name() << endl;
261 		cout << _("Version: ") << layer->get_version() << endl;
262 
263 		Layer::Vocab vocab = layer->get_param_vocab();
264 		for(; !vocab.empty(); vocab.pop_front())
265 		{
266 			cout << _("param - ") << vocab.front().get_name().c_str();
267 			if(!vocab.front().get_critical())
268 				cout << _(" (not critical)");
269 			cout << endl << _("\tLocalized Name: ")
270 				 << vocab.front().get_local_name().c_str() << endl;
271 
272 			if(!vocab.front().get_description().empty())
273 				cout << _("\tDescription: ")
274 					 << vocab.front().get_description().c_str() << endl;
275 
276 			if(!vocab.front().get_hint().empty())
277 				cout << _("\tHint: ")
278 					 << vocab.front().get_hint().c_str() << endl;
279 		}
280 
281 		throw (SynfigToolException(SYNFIGTOOL_HELP));
282 	}
283 
284 	if (_vm.count("modules"))
285 	{
286 		synfig::Module::Book::iterator iter =
287 			synfig::Module::book().begin();
288 		for(; iter != synfig::Module::book().end(); iter++)
289 			cout << (iter->first).c_str() << endl;
290 
291 		throw (SynfigToolException(SYNFIGTOOL_HELP));
292 	}
293 
294 	if (_vm.count("targets"))
295 	{
296 		synfig::Target::Book::iterator iter =
297 			synfig::Target::book().begin();
298 		for(; iter != synfig::Target::book().end(); iter++)
299 			cout << (iter->first).c_str() << endl;
300 
301 		throw (SynfigToolException(SYNFIGTOOL_HELP));
302 	}
303 
304 	if (_vm.count("valuenodes"))
305 	{
306 		synfig::ValueNodeRegistry::Book::iterator iter =
307 			synfig::ValueNodeRegistry::book().begin();
308 		for(; iter != synfig::ValueNodeRegistry::book().end(); iter++)
309 			cout << (iter->first).c_str() << endl;
310 
311 		throw (SynfigToolException(SYNFIGTOOL_HELP));
312 	}
313 
314 	if (_vm.count("importers"))
315 	{
316 		synfig::Importer::Book::iterator iter =
317 			synfig::Importer::book().begin();
318 		for(; iter != synfig::Importer::book().end(); iter++)
319 			cout << (iter->first).c_str() << endl;
320 
321 		throw (SynfigToolException(SYNFIGTOOL_HELP));
322 	}
323 }
324 
extract_renddesc(const RendDesc & renddesc)325 RendDesc OptionsProcessor::extract_renddesc(const RendDesc& renddesc)
326 {
327 	RendDesc desc = renddesc;
328 	int w, h;
329 	float span;
330 	span = w = h = 0;
331 
332 	if (_vm.count("width"))
333 		w = _vm["width"].as<int>();
334 
335 	if (_vm.count("height"))
336 		h = _vm["height"].as<int>();
337 
338 	if (_vm.count("antialias"))
339 	{
340 		int a;
341 		a = _vm["antialias"].as<int>();
342 		desc.set_antialias(a);
343 		VERBOSE_OUT(1) << boost::format(_("Antialiasing set to %d, "
344 										  "(%d samples per pixel)")) % a % (a*a)
345 						<< std::endl;
346 	}
347 	if (_vm.count("span"))
348 	{
349 	    span = _vm["span"].as<int>();
350 		VERBOSE_OUT(1) << boost::format(_("Span set to %d units")) % span
351                        << std::endl;
352 	}
353 	if (_vm.count("fps"))
354 	{
355 		float fps;
356 		fps = _vm["fps"].as<float>();
357 		desc.set_frame_rate(fps);
358 		VERBOSE_OUT(1) << boost::format(_("Frame rate set to %d frames per "
359 										   "second")) % fps << std::endl;
360 	}
361 	if (_vm.count("dpi"))
362 	{
363 		float dpi, dots_per_meter;
364 		dpi = _vm["dpi"].as<float>();
365 		dots_per_meter = dpi * 39.3700787402;
366 		desc.set_x_res(dots_per_meter);
367 		desc.set_y_res(dots_per_meter);
368 		VERBOSE_OUT(1) << boost::format(_("Physical resolution set to %f "
369                                           "dpi")) % dpi << std::endl;
370 	}
371 	if (_vm.count("dpi-x"))
372 	{
373 		float dpi, dots_per_meter;
374 		dpi = _vm["dpi-x"].as<float>();
375 		dots_per_meter = dpi * 39.3700787402;
376 		desc.set_x_res(dots_per_meter);
377 		VERBOSE_OUT(1) << boost::format(_("Physical X resolution set to %f "
378 										  "dpi")) % dpi << std::endl;
379 	}
380 	if (_vm.count("dpi-y"))
381 	{
382 		float dpi, dots_per_meter;
383 		dpi = _vm["dpi-y"].as<float>();
384 		dots_per_meter = dpi * 39.3700787402;
385 		desc.set_y_res(dots_per_meter);
386 		VERBOSE_OUT(1) << boost::format(_("Physical Y resolution set to %f "
387                                           "dpi")) % dpi << std::endl;
388 	}
389 	if (_vm.count("start-time"))
390 	{
391 		std::string seconds = _vm["start-time"].as<std::string>();
392 		desc.set_time_start(Time(seconds.c_str(), desc.get_frame_rate()));
393 	}
394 	if (_vm.count("begin-time"))
395 	{
396 		std::string seconds = _vm["begin-time"].as<std::string>();
397 		desc.set_time_start(Time(seconds.c_str(), desc.get_frame_rate()));
398 	}
399 	if (_vm.count("end-time"))
400 	{
401 		std::string seconds = _vm["end-time"].as<std::string>();
402 		desc.set_time_end(Time(seconds.c_str(), desc.get_frame_rate()));
403 	}
404 	if (_vm.count("time"))
405 	{
406 		std::string seconds = _vm["time"].as<std::string>();
407 		desc.set_time(Time(seconds.c_str(), desc.get_frame_rate()));
408 
409 		VERBOSE_OUT(1) << _("Rendering frame at ")
410 					   << desc.get_time_start().get_string(desc.get_frame_rate())
411 					   << endl;
412 	}
413 	if (_vm.count("gamma"))
414 	{
415 		synfig::warning(_("Gamma argument is currently ignored"));
416 		//int gamma;
417 		//gamma = _vm["gamma"].as<int>();
418 		//desc.set_gamma(Gamma(gamma));
419 	}
420 
421 	if (w || h)
422 	{
423 		// scale properly
424 		if (!w)
425 			w = desc.get_w() * h / desc.get_h();
426 		else if (!h)
427 			h = desc.get_h() * w / desc.get_w();
428 
429 		desc.set_wh(w, h);
430 		VERBOSE_OUT(1) << boost::format(_("Resolution set to %dx%d.")) % w % h
431                        << std::endl;
432 	}
433 
434 	if(span)
435 		desc.set_span(span);
436 
437 	return desc;
438 }
439 
extract_targetparam()440 TargetParam OptionsProcessor::extract_targetparam()
441 {
442 	TargetParam params;
443 
444 	// Both parameters are co-dependent
445 	if (_vm.count("video-codec") ^ _vm.count("video-bitrate"))
446 		throw (SynfigToolException(SYNFIGTOOL_MISSINGARGUMENT,
447 									_("Both video codec and bitrate parameters are necessary.")));
448 
449 	if (_vm.count("video-codec"))
450 	{
451 		params.video_codec = _vm["video-codec"].as<std::string>();
452 
453 		// video_codec string to lowercase
454 		transform (params.video_codec.begin(),
455 				   params.video_codec.end(),
456 				   params.video_codec.begin(),
457 				   ::tolower);
458 
459 		bool found = false;
460 		// Check if the given video codec is allowed.
461 		for (std::vector<VideoCodec>::const_iterator itr = _allowed_video_codecs.begin();
462 		 itr != _allowed_video_codecs.end(); ++itr)
463 		{
464 			if (params.video_codec == itr->name)
465 			{
466 				found = true;
467 			}
468 		}
469 
470 		if (!found)
471 		{
472 		    throw SynfigToolException(SYNFIGTOOL_UNKNOWNARGUMENT,
473                                       (boost::format(_("Video codec \"%s\" is not supported."))
474                                                       % params.video_codec).str());
475 		}
476 
477 		VERBOSE_OUT(1) << _("Target video codec set to: ") << params.video_codec
478                        << std::endl;
479 	}
480 	if(_vm.count("video-bitrate"))
481 	{
482 		params.bitrate = _vm["video-bitrate"].as<int>();
483 		VERBOSE_OUT(1) << _("Target bitrate set to: ") << params.bitrate << "k."
484 					   << std::endl;
485 	}
486 	if(_vm.count("sequence-separator"))
487 	{
488 		params.sequence_separator = _vm["sequence-separator"].as<std::string>();
489 		VERBOSE_OUT(1) << _("Output file sequence separator set to: '")
490                        << params.sequence_separator
491                        << "'."
492 					   << std::endl;
493 	}
494 
495 	return params;
496 }
497 
extract_job()498 Job OptionsProcessor::extract_job()
499 {
500 	Job job;
501 
502 	// Common input file loading
503 	if (_vm.count("input-file"))
504 	{
505 		job.filename = _vm["input-file"].as<string>();
506 
507 		// Open the composition
508 		string errors, warnings;
509 		try
510 		{
511 			if (FileSystem::Handle file_system = CanvasFileNaming::make_filesystem(job.filename))
512 			{
513 				FileSystem::Identifier identifier = file_system->get_identifier(CanvasFileNaming::project_file(job.filename));
514 				job.root = open_canvas_as(identifier, job.filename, errors, warnings);
515 			}
516 			else
517 			{
518 				errors.append("Cannot open container " + job.filename + "\n");
519 			}
520 		}
521 		catch(runtime_error& x)
522 		{
523 			job.root = 0;
524 		}
525 
526 		// By default, the canvas to render is the root canvas
527 		// This can be changed through --canvas option
528 		job.canvas = job.root;
529 
530 		if(!job.canvas)
531 		{
532 		    throw SynfigToolException(SYNFIGTOOL_FILENOTFOUND,
533                                       (boost::format(_("Unable to load file '%s'.")) % job.filename).str());
534 		}
535 
536 		job.root->set_time(0);
537 	}
538 	else
539 	{
540 	    throw SynfigToolException(SYNFIGTOOL_MISSINGARGUMENT,
541                                   _("No input file provided."));
542 	}
543 
544 	if (_vm.count("target"))
545 	{
546 		job.target_name = _vm["target"].as<std::string>();
547 		VERBOSE_OUT(1) << _("Target set to ") << job.target_name << std::endl;
548 	}
549 
550 	// Determine output
551 	if (_vm.count("output-file"))
552 	{
553 		job.outfilename = _vm["output-file"].as<std::string>();
554 	}
555 
556 	if (_vm.count("extract-alpha"))
557 	{
558 		job.extract_alpha = true;
559 	}
560 
561 	if (_vm.count("quality"))
562 		job.quality = _vm["quality"].as<int>();
563 	else
564 		job.quality = DEFAULT_QUALITY;
565 
566 	VERBOSE_OUT(1) << _("Quality set to ") << job.quality << std::endl;
567 
568 	// WARNING: canvas must be before append
569 
570 	if (_vm.count("canvas"))
571 	{
572 		std::string canvasid;
573 		canvasid = _vm["canvas"].as<std::string>();
574 
575 		try
576 		{
577 			std::string warnings;
578 			job.canvas = job.root->find_canvas(canvasid, warnings);
579 			// TODO: This exceptions should not terminate the program if multi-job
580 			// processing is available.
581 		}
582 		catch(Exception::IDNotFound&)
583 		{
584 			throw SynfigToolException(SYNFIGTOOL_INVALIDJOB,
585                     (boost::format(_("Unable to find canvas with ID \"%s\" in %s.\n"
586                                      "Throwing out job..."))
587                                    % canvasid % job.filename).str());
588 		}
589 		catch(Exception::BadLinkName&)
590 		{
591 		    throw SynfigToolException(SYNFIGTOOL_INVALIDJOB,
592                     (boost::format(_("Invalid canvas name \"%s\" in %s.\n"
593                                      "Throwing out job..."))
594                                    % canvasid % job.filename).str());
595 		}
596 
597 		// Later we need to set the other parameters for the jobs
598 	}
599 
600 	// WARNING: append must be before list-canvases
601 
602 	if (_vm.count("append"))
603 	{
604 		// TODO: Enable multi-appending. Disabled in the previous CLI version
605 		std::string composite_file = _vm["append"].as<std::string>();
606 
607 		std::string errors, warnings;
608 		Canvas::Handle composite;
609 		if (FileSystem::Handle file_system = CanvasFileNaming::make_filesystem(composite_file))
610 		{
611 			FileSystem::Identifier identifier = file_system->get_identifier(CanvasFileNaming::project_file(composite_file));
612 			composite = open_canvas_as(identifier, composite_file, errors, warnings);
613 		}
614 		else
615 		{
616 			errors.append("Cannot open container " + composite_file + "\n");
617 		}
618 
619 		if(!composite)
620 		{
621 			VERBOSE_OUT(1) << _("Unable to append '") << composite_file.c_str()
622 							<< "'." << endl;
623 		}
624 		else
625 		{
626 			Canvas::reverse_iterator iter;
627 			for(iter=composite->rbegin(); iter!=composite->rend(); ++iter)
628 			{
629 				Layer::Handle layer(*iter);
630 				//if(layer->active())
631 					job.canvas->push_front(layer->clone(composite));
632 			}
633 		}
634 
635 		VERBOSE_OUT(2) << _("Appended contents of ") << composite_file << endl;
636 	}
637 
638 	if (_vm.count("list-canvases") || _vm.count("canvases"))
639 	{
640 		print_child_canvases(job.filename + "#", job.root);
641 		std::cerr << std::endl;
642 
643 		throw SynfigToolException(SYNFIGTOOL_OK);
644 	}
645 
646 	if (_vm.count("canvas-info"))
647 	{
648 		extract_canvas_info(job);
649 		print_canvas_info(job);
650 
651 		throw SynfigToolException(SYNFIGTOOL_OK);
652 	}
653 
654 	return job;
655 }
656 
print_target_video_codecs_help() const657 void OptionsProcessor::print_target_video_codecs_help() const
658 {
659 	for (std::vector<VideoCodec>::const_iterator itr = _allowed_video_codecs.begin();
660 		 itr != _allowed_video_codecs.end(); ++itr)
661 	{
662 		std::cout << " " << itr->name << ":   \t" << itr->description
663 				  << std::endl;
664 	}
665 }
666 
667 #ifdef _DEBUG
668 
669 // DEBUG auxiliar functions
guid_test()670 void guid_test()
671 {
672 	std::cout << "GUID Test" << std::endl;
673 	for(int i = 20; i; i--)
674 		std::cout << synfig::GUID().get_string() << ' '
675 				  << synfig::GUID().get_string() << std::endl;
676 }
677 
signal_test_func()678 void signal_test_func()
679 {
680 	std::cout << "**SIGNAL CALLED**" << std::endl;
681 }
682 
signal_test()683 void signal_test()
684 {
685 	sigc::signal<void> sig;
686 	sigc::connection conn;
687 	std::cout << "Signal Test" << std::endl;
688 	conn = sig.connect(sigc::ptr_fun(signal_test_func));
689 	std::cout << "Next line should exclaim signal called." << std::endl;
690 	sig();
691 	conn.disconnect();
692 	std::cout << "Next line should NOT exclaim signal called." << std::endl;
693 	sig();
694 	std::cout << "done." << std::endl;
695 }
696 
697 // DEBUG options ----------------------------------------------
process_debug_options()698 void OptionsProcessor::process_debug_options() throw (SynfigToolException&)
699 {
700 	if (_vm.count("signal-test"))
701 	{
702 		signal_test();
703 		throw (SynfigToolException(SYNFIGTOOL_HELP));
704 	}
705 
706 	if (_vm.count("guid-test"))
707 	{
708 		guid_test();
709 		throw (SynfigToolException(SYNFIGTOOL_HELP));
710 	}
711 }
712 
713 #endif
714 
715