1 /* === S Y N F I G ========================================================= */
2 /*! \file tool/main.cpp
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
34 #include <ETL/stringf>
40 #include <synfig/loadcanvas.h>
41 #include <synfig/savecanvas.h>
42 #include <synfig/target_scanline.h>
43 #include <synfig/module.h>
44 #include <synfig/importer.h>
45 #include <synfig/layer.h>
46 #include <synfig/canvas.h>
47 #include <synfig/target.h>
48 #include <synfig/time.h>
49 #include <synfig/string.h>
50 #include <synfig/paramdesc.h>
51 #include <synfig/main.h>
52 #include <synfig/guid.h>
57 using namespace synfig
;
59 /* === M A C R O S ========================================================= */
63 #define _(x) gettext(x)
72 SYNFIGTOOL_FILENOTFOUND
= 1,
75 SYNFIGTOOL_UNKNOWNARGUMENT
= 4,
76 SYNFIGTOOL_UNKNOWNERROR
= 5,
77 SYNFIGTOOL_INVALIDTARGET
= 6,
78 SYNFIGTOOL_RENDERFAILURE
= 7,
80 SYNFIGTOOL_BADVERSION
= 9,
81 SYNFIGTOOL_MISSINGARGUMENT
=10
85 #define VERSION "unknown"
86 #define PACKAGE "synfig-tool"
89 #ifdef DEFAULT_QUALITY
90 #undef DEFAULT_QUALITY
93 #define DEFAULT_QUALITY 2
94 #define VERBOSE_OUT(x) if(verbosity>=(x))std::cerr
96 /* === G L O B A L S ======================================================= */
101 bool print_benchmarks
=false;
103 /* === M E T H O D S ======================================================= */
105 class Progress
: public synfig::ProgressCallback
111 Progress(const char *name
):program(name
) { }
114 task(const String
&task
)
116 VERBOSE_OUT(1)<<program
<<": "<<task
<<std::endl
;
121 error(const String
&task
)
123 std::cerr
<<program
<<": "<<_("error")<<": "<<task
<<std::endl
;
128 warning(const String
&task
)
130 std::cerr
<<program
<<": "<<_("warning")<<": "<<task
<<std::endl
;
135 amount_complete(int /*current*/, int /*total*/)
141 class RenderProgress
: public synfig::ProgressCallback
146 int clk_scanline
; // The scanline at which the clock was reset
152 RenderProgress():clk_scanline(0), last_time(0) { }
155 task(const String
&thetask
)
162 error(const String
&task
)
164 std::cout
<<_("error")<<": "<<task
<<std::endl
;
169 warning(const String
&task
)
171 std::cout
<<_("warning")<<": "<<task
<<std::endl
;
176 amount_complete(int scanline
, int h
)
178 if(be_quiet
)return true;
181 const float time(clk()*(float)(h
-scanline
)/(float)(scanline
-clk_scanline
));
182 const float delta(time
-last_time
);
184 int weeks
=0,days
=0,hours
=0,minutes
=0,seconds
=0;
196 //cerr<<"reset"<<endl;
198 clk_scanline
=scanline
;
204 clk_scanline
=scanline
;
208 minutes
++,seconds
-=60;
216 cerr
<<taskname
<<": "<<_("Line")<<" "<<scanline
<<_(" of ")<<h
<<" -- ";
217 //cerr<<time/(h-clk_scanline)<<" ";
219 if(delta>=-time/(h-clk_scanline) )
222 if(delta
>=0 && clk()>4.0 && scanline
>clk_scanline
+200)
224 //cerr<<"reset"<<endl;
226 clk_scanline
=scanline
;
243 cerr
<<taskname
<<": "<<_("DONE")<<" "<<endl
;;
256 Canvas::Handle canvas
;
257 Target::Handle target
;
263 bool canvas_info
, canvas_info_all
, canvas_info_time_start
, canvas_info_time_end
, canvas_info_frame_rate
,
264 canvas_info_frame_start
, canvas_info_frame_end
, canvas_info_w
, canvas_info_h
, canvas_info_image_aspect
,
265 canvas_info_pw
, canvas_info_ph
, canvas_info_pixel_aspect
, canvas_info_tl
, canvas_info_br
,
266 canvas_info_physical_w
, canvas_info_physical_h
, canvas_info_x_res
, canvas_info_y_res
, canvas_info_span
,
267 canvas_info_interlaced
, canvas_info_antialias
, canvas_info_clamp
, canvas_info_flags
, canvas_info_focus
,
268 canvas_info_bg_color
, canvas_info_metadata
;
272 canvas_info
= canvas_info_all
= canvas_info_time_start
= canvas_info_time_end
= canvas_info_frame_rate
= canvas_info_frame_start
= canvas_info_frame_end
= canvas_info_w
= canvas_info_h
= canvas_info_image_aspect
= canvas_info_pw
= canvas_info_ph
= canvas_info_pixel_aspect
= canvas_info_tl
= canvas_info_br
= canvas_info_physical_w
= canvas_info_physical_h
= canvas_info_x_res
= canvas_info_y_res
= canvas_info_span
= canvas_info_interlaced
= canvas_info_antialias
= canvas_info_clamp
= canvas_info_flags
= canvas_info_focus
= canvas_info_bg_color
= canvas_info_metadata
= false;
276 typedef list
<String
> arg_list_t
;
277 typedef list
<Job
> job_list_t
;
281 cout
<<"GUID Test"<<endl
;
283 cout
<<synfig::GUID().get_string()<<' '<<synfig::GUID().get_string()<<endl
;
286 void signal_test_func()
288 cout
<<"**SIGNAL CALLED**"<<endl
;
293 sigc::signal
<void> sig
;
294 sigc::connection conn
;
295 cout
<<"Signal Test"<<endl
;
296 conn
=sig
.connect(sigc::ptr_fun(signal_test_func
));
297 cout
<<"Next line should exclaim signal called."<<endl
;
300 cout
<<"Next line should NOT exclaim signal called."<<endl
;
305 /* === P R O C E D U R E S ================================================= */
307 void display_help(int amount
)
312 Argument(const char *flag
,const char *arg
, string description
)
314 const char spaces
[]=" ";
316 cerr
<<strprintf(" %s %s %s",flag
, arg
, spaces
+strlen(arg
)+strlen(flag
)+1)+description
<<endl
;
318 cerr
<<strprintf(" %s %s",flag
,spaces
+strlen(flag
))+description
<<endl
;
322 cerr
<< endl
<< _("syntax: ") << progname
<< " [DEFAULT OPTIONS] ([SIF FILE] [SPECIFIC OPTIONS])..." << endl
<< endl
;
325 Argument("--help",NULL
,_("Print out usage and syntax info"));
328 Argument("-t","<output type>",_("Specify output target (Default:unknown)"));
329 Argument("-w","<pixel width>",_("Set the image width (Use zero for file default)"));
330 Argument("-h","<pixel height>",_("Set the image height (Use zero for file default)"));
331 Argument("-s","<image dist>",_("Set the diagonal size of image window (Span)"));
332 Argument("-a","<1...30>",_("Set antialias amount for parametric renderer."));
333 Argument("-Q","<0...10>",strprintf(_("Specify image quality for accelerated renderer (default=%d)"),DEFAULT_QUALITY
).c_str());
334 Argument("-g","<amount>",_("Gamma (default=2.2)"));
335 Argument("-v",NULL
,_("Verbose Output (add more for more verbosity)"));
336 Argument("-q",NULL
,_("Quiet mode (No progress/time-remaining display)"));
337 Argument("-c","<canvas id>",_("Render the canvas with the given id instead of the root."));
338 Argument("-o","<output file>",_("Specify output filename"));
339 Argument("-T","<# of threads>",_("Enable multithreaded renderer using specified # of threads"));
340 Argument("-b",NULL
,_("Print Benchmarks"));
341 Argument("--fps","<framerate>",_("Set the frame rate"));
342 Argument("--time","<time>",_("Render a single frame at <seconds>"));
343 Argument("--begin-time","<time>",_("Set the starting time"));
344 Argument("--start-time","<time>",_("Set the starting time"));
345 Argument("--end-time","<time>",_("Set the ending time"));
346 Argument("--dpi","<res>",_("Set the physical resolution (dots-per-inch)"));
347 Argument("--dpi-x","<res>",_("Set the physical X resolution (dots-per-inch)"));
348 Argument("--dpi-y","<res>",_("Set the physical Y resolution (dots-per-inch)"));
350 Argument("--list-canvases",NULL
,_("List the exported canvases in the composition"));
351 Argument("--canvas-info","<fields>",_("Print out specified details of the root canvas"));
352 Argument("--append","<filename>",_("Append layers in <filename> to composition"));
354 Argument("--layer-info","<layer>",_("Print out layer's description, parameter info, etc."));
355 Argument("--layers",NULL
,_("Print out the list of available layers"));
356 Argument("--targets",NULL
,_("Print out the list of available targets"));
357 Argument("--importers",NULL
,_("Print out the list of available importers"));
358 Argument("--valuenodes",NULL
,_("Print out the list of available ValueNodes"));
359 Argument("--modules",NULL
,_("Print out the list of loaded modules"));
360 Argument("--version",NULL
,_("Print out version information"));
361 Argument("--info",NULL
,_("Print out misc build information"));
362 Argument("--license",NULL
,_("Print out license information"));
365 Argument("--guid-test",NULL
,_("Test GUID generation"));
366 Argument("--signal-test",NULL
,_("Test signal implementation"));
373 int process_global_flags(arg_list_t
&arg_list
)
375 arg_list_t::iterator iter
, next
;
377 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
380 return SYNFIGTOOL_OK
;
382 if(*iter
== "--signal-test")
385 return SYNFIGTOOL_HELP
;
388 if(*iter
== "--guid-test")
391 return SYNFIGTOOL_HELP
;
394 if(*iter
== "--help")
397 return SYNFIGTOOL_HELP
;
400 if(*iter
== "--info")
402 cout
<<PACKAGE
"-"VERSION
<<endl
;
403 cout
<<"Compiled on "__DATE__
/* " at "__TIME__ */;
405 cout
<<" with GCC "<<__VERSION__
;
408 cout
<<" with Microsoft Visual C++ "<<(_MSC_VER
>>8)<<'.'<<(_MSC_VER
&255);
410 #ifdef __TCPLUSPLUS__
411 cout
<<" with Borland Turbo C++ "<<(__TCPLUSPLUS__
>>8)<<'.'<<((__TCPLUSPLUS__
&255)>>4)<<'.'<<(__TCPLUSPLUS__
&15);
414 cout
<<endl
<<SYNFIG_COPYRIGHT
<<endl
;
416 return SYNFIGTOOL_HELP
;
419 if(*iter
== "--layers")
422 synfig::Main
synfig_main(dirname(progname
),&p
);
423 synfig::Layer::Book::iterator iter
=synfig::Layer::book().begin();
424 for(;iter
!=synfig::Layer::book().end();iter
++)
425 if (iter
->second
.category
!= CATEGORY_DO_NOT_USE
)
426 cout
<<iter
->first
<<endl
;
428 return SYNFIGTOOL_HELP
;
431 if(*iter
== "--layer-info")
434 synfig::Main
synfig_main(dirname(progname
),&p
);
436 if (iter
==arg_list
.end())
438 error("The `%s' flag requires a value. Use --help for a list of options.", "--layer-info");
439 return SYNFIGTOOL_MISSINGARGUMENT
;
441 Layer::Handle layer
=synfig::Layer::create(*iter
);
442 cout
<<"Layer Name: "<<layer
->get_name()<<endl
;
443 cout
<<"Localized Layer Name: "<<layer
->get_local_name()<<endl
;
444 cout
<<"Version: "<<layer
->get_version()<<endl
;
445 Layer::Vocab vocab
=layer
->get_param_vocab();
446 for(;!vocab
.empty();vocab
.pop_front())
448 cout
<<"param - "<<vocab
.front().get_name();
449 if(!vocab
.front().get_critical())
450 cout
<<" (not critical)";
451 cout
<<endl
<<"\tLocalized Name: "<<vocab
.front().get_local_name()<<endl
;
452 if(!vocab
.front().get_description().empty())
453 cout
<<"\tDescription: "<<vocab
.front().get_description()<<endl
;
454 if(!vocab
.front().get_hint().empty())
455 cout
<<"\tHint: "<<vocab
.front().get_hint()<<endl
;
458 return SYNFIGTOOL_HELP
;
461 if(*iter
== "--modules")
464 synfig::Main
synfig_main(dirname(progname
),&p
);
465 synfig::Module::Book::iterator iter
=synfig::Module::book().begin();
466 for(;iter
!=synfig::Module::book().end();iter
++)
467 cout
<<iter
->first
<<endl
;
468 return SYNFIGTOOL_HELP
;
471 if(*iter
== "--targets")
474 synfig::Main
synfig_main(dirname(progname
),&p
);
475 synfig::Target::Book::iterator iter
=synfig::Target::book().begin();
476 for(;iter
!=synfig::Target::book().end();iter
++)
477 cout
<<iter
->first
<<endl
;
478 return SYNFIGTOOL_HELP
;
481 if(*iter
== "--valuenodes")
484 synfig::Main
synfig_main(dirname(progname
),&p
);
485 synfig::LinkableValueNode::Book::iterator iter
=synfig::LinkableValueNode::book().begin();
486 for(;iter
!=synfig::LinkableValueNode::book().end();iter
++)
487 cout
<<iter
->first
<<endl
;
488 return SYNFIGTOOL_HELP
;
491 if(*iter
== "--importers")
494 synfig::Main
synfig_main(dirname(progname
),&p
);
495 synfig::Importer::Book::iterator iter
=synfig::Importer::book().begin();
496 for(;iter
!=synfig::Importer::book().end();iter
++)
497 cout
<<iter
->first
<<endl
;
498 return SYNFIGTOOL_HELP
;
501 if(*iter
== "--version")
503 cerr
<<PACKAGE
<<" "<<VERSION
<<endl
;
504 arg_list
.erase(iter
);
505 return SYNFIGTOOL_HELP
;
508 if(*iter
== "--license")
510 cerr
<<PACKAGE
<<" "<<VERSION
<<endl
;
511 cout
<<SYNFIG_COPYRIGHT
<<endl
<<endl
;
513 ** This package is free software; you can redistribute it and/or\n\
514 ** modify it under the terms of the GNU General Public License as\n\
515 ** published by the Free Software Foundation; either version 2 of\n\
516 ** the License, or (at your option) any later version.\n\
518 ** " << endl
<< endl
;
519 arg_list
.erase(iter
);
520 return SYNFIGTOOL_HELP
;
526 arg_list
.erase(iter
);
533 arg_list
.erase(iter
);
538 print_benchmarks
=true;
539 arg_list
.erase(iter
);
544 return SYNFIGTOOL_OK
;
547 /* true if the given flag takes an extra parameter */
548 bool flag_requires_value(String flag
)
550 return (flag
=="-a" || flag
=="-c" || flag
=="-g" || flag
=="-h" || flag
=="-o" ||
551 flag
=="-Q" || flag
=="-s" || flag
=="-t" || flag
=="-T" || flag
=="-w" ||
552 flag
=="--append" || flag
=="--begin-time" || flag
=="--canvas-info"|| flag
=="--dpi" || flag
=="--dpi-x" ||
553 flag
=="--dpi-y" || flag
=="--end-time" || flag
=="--fps" || flag
=="--layer-info" || flag
=="--start-time" ||
557 int extract_arg_cluster(arg_list_t
&arg_list
,arg_list_t
&cluster
)
559 arg_list_t::iterator iter
, next
;
561 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
563 if(*iter
->begin() != '-')
565 //cerr<<*iter->begin()<<"-----------"<<endl;
566 return SYNFIGTOOL_OK
;
569 if (flag_requires_value(*iter
))
571 cluster
.push_back(*iter
);
572 arg_list
.erase(iter
);
574 if (iter
==arg_list
.end())
576 error("The `%s' flag requires a value. Use --help for a list of options.", cluster
.back().c_str());
577 return SYNFIGTOOL_MISSINGARGUMENT
;
581 cluster
.push_back(*iter
);
582 arg_list
.erase(iter
);
585 return SYNFIGTOOL_OK
;
588 int extract_RendDesc(arg_list_t
&arg_list
,RendDesc
&desc
)
590 arg_list_t::iterator iter
, next
;
593 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
597 arg_list
.erase(iter
);
599 w
=atoi(iter
->c_str());
600 arg_list
.erase(iter
);
604 arg_list
.erase(iter
);
606 h
=atoi(iter
->c_str());
607 arg_list
.erase(iter
);
612 arg_list
.erase(iter
);
614 a
=atoi(iter
->c_str());
615 desc
.set_antialias(a
);
616 VERBOSE_OUT(1)<<strprintf(_("Antialiasing set to %d, (%d samples per pixel)"),a
,a
*a
)<<endl
;
617 arg_list
.erase(iter
);
621 arg_list
.erase(iter
);
623 span
=atof(iter
->c_str());
624 VERBOSE_OUT(1)<<strprintf(_("Span set to %d units"),span
)<<endl
;
625 arg_list
.erase(iter
);
627 else if(*iter
=="--fps")
629 arg_list
.erase(iter
);
631 float fps
=atof(iter
->c_str());
632 desc
.set_frame_rate(fps
);
633 arg_list
.erase(iter
);
634 VERBOSE_OUT(1)<<strprintf(_("Frame rate set to %d frames per second"),fps
)<<endl
;
636 else if(*iter
=="--dpi")
638 arg_list
.erase(iter
);
640 float dpi
=atof(iter
->c_str());
641 float dots_per_meter
=dpi
*39.3700787402;
642 desc
.set_x_res(dots_per_meter
).set_y_res(dots_per_meter
);
643 arg_list
.erase(iter
);
644 VERBOSE_OUT(1)<<strprintf(_("Physical resolution set to %f dpi"),dpi
)<<endl
;
646 else if(*iter
=="--dpi-x")
648 arg_list
.erase(iter
);
650 float dpi
=atof(iter
->c_str());
651 float dots_per_meter
=dpi
*39.3700787402;
652 desc
.set_x_res(dots_per_meter
);
653 arg_list
.erase(iter
);
654 VERBOSE_OUT(1)<<strprintf(_("Physical X resolution set to %f dpi"),dpi
)<<endl
;
656 else if(*iter
=="--dpi-y")
658 arg_list
.erase(iter
);
660 float dpi
=atof(iter
->c_str());
661 float dots_per_meter
=dpi
*39.3700787402;
662 desc
.set_y_res(dots_per_meter
);
663 arg_list
.erase(iter
);
664 VERBOSE_OUT(1)<<strprintf(_("Physical Y resolution set to %f dpi"),dpi
)<<endl
;
666 else if(*iter
=="--start-time" || *iter
=="--begin-time")
668 arg_list
.erase(iter
);
670 desc
.set_time_start(Time(*iter
,desc
.get_frame_rate()));
671 arg_list
.erase(iter
);
673 else if(*iter
=="--end-time")
675 arg_list
.erase(iter
);
677 desc
.set_time_end(Time(*iter
,desc
.get_frame_rate()));
678 arg_list
.erase(iter
);
680 else if(*iter
=="--time")
682 arg_list
.erase(iter
);
684 desc
.set_time(Time(*iter
,desc
.get_frame_rate()));
685 VERBOSE_OUT(1)<<_("Rendering frame at ")<<desc
.get_time_start().get_string(desc
.get_frame_rate())<<endl
;
686 arg_list
.erase(iter
);
690 synfig::warning("Gamma argument is currently ignored");
691 arg_list
.erase(iter
);
693 //desc.set_gamma(Gamma(atof(iter->c_str())));
694 arg_list
.erase(iter
);
696 else if (flag_requires_value(*iter
))
702 w
= desc
.get_w() * h
/ desc
.get_h();
704 h
= desc
.get_h() * w
/ desc
.get_w();
707 VERBOSE_OUT(1)<<strprintf(_("Resolution set to %dx%d"),w
,h
)<<endl
;
711 return SYNFIGTOOL_OK
;
714 int extract_quality(arg_list_t
&arg_list
,int &quality
)
716 arg_list_t::iterator iter
, next
;
717 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
721 arg_list
.erase(iter
);
723 quality
=atoi(iter
->c_str());
724 VERBOSE_OUT(1)<<strprintf(_("Quality set to %d"),quality
)<<endl
;
725 arg_list
.erase(iter
);
727 else if (flag_requires_value(*iter
))
731 return SYNFIGTOOL_OK
;
734 int extract_threads(arg_list_t
&arg_list
,int &threads
)
736 arg_list_t::iterator iter
, next
;
737 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
741 arg_list
.erase(iter
);
743 threads
=atoi(iter
->c_str());
744 VERBOSE_OUT(1)<<strprintf(_("Threads set to %d"),threads
)<<endl
;
745 arg_list
.erase(iter
);
747 else if (flag_requires_value(*iter
))
751 return SYNFIGTOOL_OK
;
754 int extract_target(arg_list_t
&arg_list
,string
&type
)
756 arg_list_t::iterator iter
, next
;
759 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
763 arg_list
.erase(iter
);
766 arg_list
.erase(iter
);
768 else if (flag_requires_value(*iter
))
772 return SYNFIGTOOL_OK
;
775 int extract_append(arg_list_t
&arg_list
,string
&filename
)
777 arg_list_t::iterator iter
, next
;
780 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
782 if(*iter
=="--append")
784 arg_list
.erase(iter
);
787 arg_list
.erase(iter
);
789 else if (flag_requires_value(*iter
))
793 return SYNFIGTOOL_OK
;
796 int extract_outfile(arg_list_t
&arg_list
,string
&outfile
)
798 arg_list_t::iterator iter
, next
;
799 int ret
=SYNFIGTOOL_FILENOTFOUND
;
802 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
806 arg_list
.erase(iter
);
809 arg_list
.erase(iter
);
812 else if (flag_requires_value(*iter
))
819 int extract_canvasid(arg_list_t
&arg_list
,string
&canvasid
)
821 arg_list_t::iterator iter
, next
;
824 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
828 arg_list
.erase(iter
);
831 arg_list
.erase(iter
);
833 else if (flag_requires_value(*iter
))
837 return SYNFIGTOOL_OK
;
840 int extract_list_canvases(arg_list_t
&arg_list
,bool &list_canvases
)
842 arg_list_t::iterator iter
, next
;
844 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
845 if(*iter
=="--list-canvases")
847 list_canvases
= true;
848 arg_list
.erase(iter
);
851 return SYNFIGTOOL_OK
;
854 void extract_canvas_info(arg_list_t
&arg_list
, Job
&job
)
856 arg_list_t::iterator iter
, next
;
858 for(next
=arg_list
.begin(),iter
=next
++;iter
!=arg_list
.end();iter
=next
++)
859 if(*iter
=="--canvas-info")
861 job
.canvas_info
= true;
862 arg_list
.erase(iter
);
864 String
values(*iter
), value
;
865 arg_list
.erase(iter
);
867 std::string::size_type pos
;
868 while (!values
.empty())
870 pos
= values
.find_first_of(',');
871 if (pos
== std::string::npos
)
878 value
= values
.substr(0, pos
);
879 values
= values
.substr(pos
+1);
883 job
.canvas_info_all
= true;
887 if (value
== "time_start") job
.canvas_info_time_start
= true;
888 else if (value
== "time_end") job
.canvas_info_time_end
= true;
889 else if (value
== "frame_rate") job
.canvas_info_frame_rate
= true;
890 else if (value
== "frame_start") job
.canvas_info_frame_start
= true;
891 else if (value
== "frame_end") job
.canvas_info_frame_end
= true;
892 else if (value
== "w") job
.canvas_info_w
= true;
893 else if (value
== "h") job
.canvas_info_h
= true;
894 else if (value
== "image_aspect") job
.canvas_info_image_aspect
= true;
895 else if (value
== "pw") job
.canvas_info_pw
= true;
896 else if (value
== "ph") job
.canvas_info_ph
= true;
897 else if (value
== "pixel_aspect") job
.canvas_info_pixel_aspect
= true;
898 else if (value
== "tl") job
.canvas_info_tl
= true;
899 else if (value
== "br") job
.canvas_info_br
= true;
900 else if (value
== "physical_w") job
.canvas_info_physical_w
= true;
901 else if (value
== "physical_h") job
.canvas_info_physical_h
= true;
902 else if (value
== "x_res") job
.canvas_info_x_res
= true;
903 else if (value
== "y_res") job
.canvas_info_y_res
= true;
904 else if (value
== "span") job
.canvas_info_span
= true;
905 else if (value
== "interlaced") job
.canvas_info_interlaced
= true;
906 else if (value
== "antialias") job
.canvas_info_antialias
= true;
907 else if (value
== "clamp") job
.canvas_info_clamp
= true;
908 else if (value
== "flags") job
.canvas_info_flags
= true;
909 else if (value
== "focus") job
.canvas_info_focus
= true;
910 else if (value
== "bg_color") job
.canvas_info_bg_color
= true;
911 else if (value
== "metadata") job
.canvas_info_metadata
= true;
914 cerr
<<_("Unrecognised canvas variable: ") << "'" << value
<< "'" << endl
;
915 cerr
<<_("Recognized variables are:") << endl
<<
916 " all, time_start, time_end, frame_rate, frame_start, frame_end, w, h," << endl
<<
917 " image_aspect, pw, ph, pixel_aspect, tl, br, physical_w, physical_h," << endl
<<
918 " x_res, y_res, span, interlaced, antialias, clamp, flags," << endl
<<
919 " focus, bg_color, metadata" << endl
;
922 if (pos
== std::string::npos
)
928 void list_child_canvases(string prefix
, Canvas::Handle canvas
)
930 Canvas::Children
children(canvas
->children());
931 for (Canvas::Children::iterator iter
= children
.begin(); iter
!= children
.end(); iter
++)
933 cout
<< prefix
<< ":" << (*iter
)->get_id() << endl
;
934 list_child_canvases(prefix
+ ":" + (*iter
)->get_id(), *iter
);
938 void list_canvas_info(Job job
)
940 Canvas::Handle
canvas(job
.canvas
);
941 const RendDesc
&rend_desc(canvas
->rend_desc());
943 if (job
.canvas_info_all
|| job
.canvas_info_time_start
)
945 cout
<< endl
<< "# " << _("Start Time") << endl
;
946 cout
<< "time_start" << "=" << rend_desc
.get_time_start().get_string().c_str() << endl
;
949 if (job
.canvas_info_all
|| job
.canvas_info_time_end
)
951 cout
<< endl
<< "# " << _("End Time") << endl
;
952 cout
<< "time_end" << "=" << rend_desc
.get_time_end().get_string().c_str() << endl
;
955 if (job
.canvas_info_all
|| job
.canvas_info_frame_rate
)
957 cout
<< endl
<< "# " << _("Frame Rate") << endl
;
958 cout
<< "frame_rate" << "=" << rend_desc
.get_frame_rate() << endl
;
961 if (job
.canvas_info_all
|| job
.canvas_info_frame_start
)
963 cout
<< endl
<< "# " << _("Start Frame") << endl
;
964 cout
<< "frame_start" << "=" << rend_desc
.get_frame_start() << endl
;
967 if (job
.canvas_info_all
|| job
.canvas_info_frame_end
)
969 cout
<< endl
<< "# " << _("End Frame") << endl
;
970 cout
<< "frame_end" << "=" << rend_desc
.get_frame_end() << endl
;
973 if (job
.canvas_info_all
)
976 if (job
.canvas_info_all
|| job
.canvas_info_w
)
978 cout
<< endl
<< "# " << _("Width") << endl
;
979 cout
<< "w" << "=" << rend_desc
.get_w() << endl
;
982 if (job
.canvas_info_all
|| job
.canvas_info_h
)
984 cout
<< endl
<< "# " << _("Height") << endl
;
985 cout
<< "h" << "=" << rend_desc
.get_h() << endl
;
988 if (job
.canvas_info_all
|| job
.canvas_info_image_aspect
)
990 cout
<< endl
<< "# " << _("Image Aspect Ratio") << endl
;
991 cout
<< "image_aspect" << "=" << rend_desc
.get_image_aspect() << endl
;
994 if (job
.canvas_info_all
)
997 if (job
.canvas_info_all
|| job
.canvas_info_pw
)
999 cout
<< endl
<< "# " << _("Pixel Width") << endl
;
1000 cout
<< "pw" << "=" << rend_desc
.get_pw() << endl
;
1003 if (job
.canvas_info_all
|| job
.canvas_info_ph
)
1005 cout
<< endl
<< "# " << _("Pixel Height") << endl
;
1006 cout
<< "ph" << "=" << rend_desc
.get_ph() << endl
;
1009 if (job
.canvas_info_all
|| job
.canvas_info_pixel_aspect
)
1011 cout
<< endl
<< "# " << _("Pixel Aspect Ratio") << endl
;
1012 cout
<< "pixel_aspect" << "=" << rend_desc
.get_pixel_aspect() << endl
;
1015 if (job
.canvas_info_all
)
1018 if (job
.canvas_info_all
|| job
.canvas_info_tl
)
1020 cout
<< endl
<< "# " << _("Top Left") << endl
;
1021 cout
<< "tl" << "=" << rend_desc
.get_tl()[0]
1022 << " " << rend_desc
.get_tl()[1] << endl
;
1025 if (job
.canvas_info_all
|| job
.canvas_info_br
)
1027 cout
<< endl
<< "# " << _("Bottom Right") << endl
;
1028 cout
<< "br" << "=" << rend_desc
.get_br()[0]
1029 << " " << rend_desc
.get_br()[1] << endl
;
1032 if (job
.canvas_info_all
|| job
.canvas_info_physical_w
)
1034 cout
<< endl
<< "# " << _("Physical Width") << endl
;
1035 cout
<< "physical_w" << "=" << rend_desc
.get_physical_w() << endl
;
1038 if (job
.canvas_info_all
|| job
.canvas_info_physical_h
)
1040 cout
<< endl
<< "# " << _("Physical Height") << endl
;
1041 cout
<< "physical_h" << "=" << rend_desc
.get_physical_h() << endl
;
1044 if (job
.canvas_info_all
|| job
.canvas_info_x_res
)
1046 cout
<< endl
<< "# " << _("X Resolution") << endl
;
1047 cout
<< "x_res" << "=" << rend_desc
.get_x_res() << endl
;
1050 if (job
.canvas_info_all
|| job
.canvas_info_y_res
)
1052 cout
<< endl
<< "# " << _("Y Resolution") << endl
;
1053 cout
<< "y_res" << "=" << rend_desc
.get_y_res() << endl
;
1056 if (job
.canvas_info_all
|| job
.canvas_info_span
)
1058 cout
<< endl
<< "# " << _("Diagonal Image Span") << endl
;
1059 cout
<< "span" << "=" << rend_desc
.get_span() << endl
;
1062 if (job
.canvas_info_all
)
1065 if (job
.canvas_info_all
|| job
.canvas_info_interlaced
)
1067 cout
<< endl
<< "# " << _("Interlaced") << endl
;
1068 cout
<< "interlaced" << "=" << rend_desc
.get_interlaced() << endl
;
1071 if (job
.canvas_info_all
|| job
.canvas_info_antialias
)
1073 cout
<< endl
<< "# " << _("Antialias") << endl
;
1074 cout
<< "antialias" << "=" << rend_desc
.get_antialias() << endl
;
1077 if (job
.canvas_info_all
|| job
.canvas_info_clamp
)
1079 cout
<< endl
<< "# " << _("Clamp") << endl
;
1080 cout
<< "clamp" << "=" << rend_desc
.get_clamp() << endl
;
1083 if (job
.canvas_info_all
|| job
.canvas_info_flags
)
1085 cout
<< endl
<< "# " << _("Flags") << endl
;
1086 cout
<< "flags" << "=" << rend_desc
.get_flags() << endl
;
1089 if (job
.canvas_info_all
|| job
.canvas_info_focus
)
1091 cout
<< endl
<< "# " << _("Focus") << endl
;
1092 cout
<< "focus" << "=" << rend_desc
.get_focus()[0]
1093 << " " << rend_desc
.get_focus()[1] << endl
;
1096 if (job
.canvas_info_all
|| job
.canvas_info_bg_color
)
1098 cout
<< endl
<< "# " << _("Background Color") << endl
;
1099 cout
<< "bg_color" << "=" << rend_desc
.get_bg_color().get_string().c_str() << endl
;
1102 if (job
.canvas_info_all
)
1105 if (job
.canvas_info_all
|| job
.canvas_info_metadata
)
1107 std::list
<String
> keys(canvas
->get_meta_data_keys());
1108 cout
<< endl
<< "# " << _("Metadata") << endl
;
1109 for (std::list
<String
>::iterator iter
= keys
.begin(); iter
!= keys
.end(); iter
++)
1110 cout
<< *iter
<< "=" << canvas
->get_meta_data(*iter
) << endl
;
1114 /* === M E T H O D S ======================================================= */
1116 /* === E N T R Y P O I N T ================================================= */
1118 int main(int argc
, char *argv
[])
1121 arg_list_t arg_list
;
1122 job_list_t job_list
;
1124 setlocale(LC_ALL
, "");
1127 bindtextdomain("synfig", LOCALEDIR
);
1128 bind_textdomain_codeset("synfig", "UTF-8");
1129 textdomain("synfig");
1133 Progress
p(argv
[0]);
1135 if(!SYNFIG_CHECK_VERSION())
1137 cerr
<<_("FATAL: Synfig Version Mismatch")<<endl
;
1138 return SYNFIGTOOL_BADVERSION
;
1144 return SYNFIGTOOL_BLANK
;
1148 arg_list
.push_back(argv
[i
]);
1150 if((i
=process_global_flags(arg_list
)))
1153 VERBOSE_OUT(1)<<_("verbosity set to ")<<verbosity
<<endl
;
1154 synfig::Main
synfig_main(dirname(progname
),&p
);
1157 arg_list_t defaults
, imageargs
;
1160 // Grab the defaults before the first file
1161 if ((ret
= extract_arg_cluster(arg_list
,defaults
)) != SYNFIGTOOL_OK
)
1164 while(arg_list
.size())
1167 job_list
.push_front(Job());
1171 job_list
.front().filename
=arg_list
.front();
1172 arg_list
.pop_front();
1174 if ((ret
= extract_arg_cluster(arg_list
,imageargs
)) != SYNFIGTOOL_OK
)
1177 // Open the composition
1178 String errors
, warnings
;
1181 job_list
.front().root
=open_canvas(job_list
.front().filename
, errors
, warnings
);
1183 catch(runtime_error x
)
1185 job_list
.front().root
= 0;
1188 if(!job_list
.front().root
)
1190 cerr
<<_("Unable to load '")<<job_list
.front().filename
<<"'."<<endl
;
1191 cerr
<<_("Throwing out job...")<<endl
;
1192 job_list
.pop_front();
1196 bool list_canvases
= false;
1197 extract_list_canvases(imageargs
, list_canvases
);
1198 job_list
.front().list_canvases
= list_canvases
;
1200 extract_canvas_info(imageargs
, job_list
.front());
1202 job_list
.front().root
->set_time(0);
1205 extract_canvasid(imageargs
,canvasid
);
1206 if(!canvasid
.empty())
1211 job_list
.front().canvas
=job_list
.front().root
->find_canvas(canvasid
, warnings
);
1213 catch(Exception::IDNotFound
)
1215 cerr
<<_("Unable to find canvas with ID \"")<<canvasid
<<_("\" in ")<<job_list
.front().filename
<<"."<<endl
;
1216 cerr
<<_("Throwing out job...")<<endl
;
1217 job_list
.pop_front();
1221 catch(Exception::BadLinkName
)
1223 cerr
<<_("Invalid canvas name \"")<<canvasid
<<_("\" in ")<<job_list
.front().filename
<<"."<<endl
;
1224 cerr
<<_("Throwing out job...")<<endl
;
1225 job_list
.pop_front();
1230 job_list
.front().canvas
=job_list
.front().root
;
1232 extract_RendDesc(imageargs
,job_list
.front().canvas
->rend_desc());
1233 extract_target(imageargs
,target_name
);
1234 extract_threads(imageargs
,threads
);
1235 job_list
.front().quality
=DEFAULT_QUALITY
;
1236 extract_quality(imageargs
,job_list
.front().quality
);
1237 VERBOSE_OUT(2)<<_("Quality set to ")<<job_list
.front().quality
<<endl
;
1238 job_list
.front().desc
=job_list
.front().canvas
->rend_desc();
1239 extract_outfile(imageargs
,job_list
.front().outfilename
);
1241 // Extract composite
1243 string composite_file
;
1244 extract_append(imageargs
,composite_file
);
1245 if(!composite_file
.empty())
1247 String errors
, warnings
;
1248 Canvas::Handle
composite(open_canvas(composite_file
, errors
, warnings
));
1251 cerr
<<_("Unable to append '")<<composite_file
<<"'."<<endl
;
1254 Canvas::reverse_iterator iter
;
1255 for(iter
=composite
->rbegin();iter
!=composite
->rend();++iter
)
1257 Layer::Handle
layer(*iter
);
1259 job_list
.front().canvas
->push_front(layer
->clone());
1261 VERBOSE_OUT(2)<<_("Appended contents of ")<<composite_file
<<endl
;
1265 VERBOSE_OUT(4)<<_("Attempting to determine target/outfile...")<<endl
;
1267 // If the target type is not yet defined,
1268 // try to figure it out from the outfile.
1269 if(target_name
.empty() && !job_list
.front().outfilename
.empty())
1271 VERBOSE_OUT(3)<<_("Target name undefined, attempting to figure it out")<<endl
;
1272 string ext
= filename_extension(job_list
.front().outfilename
);
1273 if (ext
.length()) ext
= ext
.substr(1);
1274 if(Target::ext_book().count(ext
))
1276 target_name
=Target::ext_book()[ext
];
1277 info("target name not specified - using %s", target_name
.c_str());
1281 string
lower_ext(ext
);
1283 for(unsigned int i
=0;i
<ext
.length();i
++)
1284 lower_ext
[i
] = tolower(ext
[i
]);
1286 if(Target::ext_book().count(lower_ext
))
1288 target_name
=Target::ext_book()[lower_ext
];
1289 info("target name not specified - using %s", target_name
.c_str());
1296 // If the target type is STILL not yet defined, then
1297 // set it to a some sort of default
1298 if(target_name
.empty())
1300 VERBOSE_OUT(2)<<_("Defaulting to PNG target...")<<endl
;
1304 // If no output filename was provided, then
1305 // create a output filename based on the
1306 // given input filename. (ie: change the extension)
1307 if(job_list
.front().outfilename
.empty())
1309 job_list
.front().outfilename
= filename_sans_extension(job_list
.front().filename
) + '.';
1310 if(Target::book().count(target_name
))
1311 job_list
.front().outfilename
+=Target::book()[target_name
].second
;
1313 job_list
.front().outfilename
+=target_name
;
1316 VERBOSE_OUT(4)<<"target_name="<<target_name
<<endl
;
1317 VERBOSE_OUT(4)<<"outfile_name="<<job_list
.front().outfilename
<<endl
;
1319 VERBOSE_OUT(4)<<_("Creating the target...")<<endl
;
1320 job_list
.front().target
=synfig::Target::create(target_name
,job_list
.front().outfilename
);
1322 if(target_name
=="sif")
1323 job_list
.front().sifout
=true;
1326 if(!job_list
.front().target
)
1328 cerr
<<_("Unknown target for ")<<job_list
.front().filename
<<": "<<target_name
<<endl
;
1329 cerr
<<_("Throwing out job...")<<endl
;
1330 job_list
.pop_front();
1333 job_list
.front().sifout
=false;
1336 // Set the Canvas on the Target
1337 if(job_list
.front().target
)
1339 VERBOSE_OUT(4)<<_("Setting the canvas on the target...")<<endl
;
1340 job_list
.front().target
->set_canvas(job_list
.front().canvas
);
1341 VERBOSE_OUT(4)<<_("Setting the quality of the target...")<<endl
;
1342 job_list
.front().target
->set_quality(job_list
.front().quality
);
1345 // Set the threads for the target
1346 if(job_list
.front().target
&& Target_Scanline::Handle::cast_dynamic(job_list
.front().target
))
1347 Target_Scanline::Handle::cast_dynamic(job_list
.front().target
)->set_threads(threads
);
1349 if(imageargs
.size())
1351 cerr
<<_("Unidentified arguments for ")<<job_list
.front().filename
<<": ";
1352 for(;imageargs
.size();imageargs
.pop_front())
1353 cerr
<<' '<<imageargs
.front();
1355 cerr
<<_("Throwing out job...")<<endl
;
1356 job_list
.pop_front();
1364 cerr
<<_("Unidentified arguments:");
1365 for(;arg_list
.size();arg_list
.pop_front())
1366 cerr
<<' '<<arg_list
.front();
1368 return SYNFIGTOOL_UNKNOWNARGUMENT
;
1371 if(!job_list
.size())
1373 cerr
<<_("Nothing to do!")<<endl
;
1374 return SYNFIGTOOL_BORED
;
1377 for(;job_list
.size();job_list
.pop_front())
1379 VERBOSE_OUT(3)<<job_list
.front().filename
<<" -- "<<endl
<<'\t'<<
1380 strprintf("w:%d, h:%d, a:%d, pxaspect:%f, imaspect:%f, span:%f",
1381 job_list
.front().desc
.get_w(),
1382 job_list
.front().desc
.get_h(),
1383 job_list
.front().desc
.get_antialias(),
1384 job_list
.front().desc
.get_pixel_aspect(),
1385 job_list
.front().desc
.get_image_aspect(),
1386 job_list
.front().desc
.get_span()
1388 strprintf("tl:[%f,%f], br:[%f,%f], focus:[%f,%f]",
1389 job_list
.front().desc
.get_tl()[0],job_list
.front().desc
.get_tl()[1],
1390 job_list
.front().desc
.get_br()[0],job_list
.front().desc
.get_br()[1],
1391 job_list
.front().desc
.get_focus()[0],job_list
.front().desc
.get_focus()[1]
1395 p
.task(job_list
.front().filename
+" ==> "+job_list
.front().outfilename
);
1396 if(job_list
.front().sifout
)
1398 if(!save_canvas(job_list
.front().outfilename
,job_list
.front().canvas
))
1400 cerr
<<"Render Failure."<<endl
;
1401 return SYNFIGTOOL_RENDERFAILURE
;
1404 else if (job_list
.front().list_canvases
)
1406 list_child_canvases(job_list
.front().filename
+ "#", job_list
.front().canvas
);
1409 else if (job_list
.front().canvas_info
)
1411 list_canvas_info(job_list
.front());
1416 VERBOSE_OUT(1)<<_("Rendering...")<<endl
;
1419 // Call the render member of the target
1420 if(!job_list
.front().target
->render(&p
))
1422 cerr
<<"Render Failure."<<endl
;
1423 return SYNFIGTOOL_RENDERFAILURE
;
1425 if(print_benchmarks
)
1426 cout
<<job_list
.front().filename
+": Rendered in "<<timer()<<" seconds."<<endl
;
1432 VERBOSE_OUT(1)<<_("Done.")<<endl
;
1434 return SYNFIGTOOL_OK
;