4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <sys/types.h>
36 REGISTER_PLUGIN(SvgMain)
38 SvgConfig::SvgConfig()
46 int SvgConfig::equivalent(SvgConfig &that)
48 // out_x/out_y always used by overlayer
49 return !strcmp(svg_file, that.svg_file) &&
50 ms_time == that.ms_time;
53 void SvgConfig::copy_from(SvgConfig &that)
57 strcpy(svg_file, that.svg_file);
58 ms_time = that.ms_time;
61 void SvgConfig::interpolate(SvgConfig &prev, SvgConfig &next,
62 long prev_frame, long next_frame, long current_frame)
64 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
65 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
67 this->out_x = prev.out_x * prev_scale + next.out_x * next_scale;
68 this->out_y = prev.out_y * prev_scale + next.out_y * next_scale;
69 strcpy(this->svg_file, prev.svg_file);
70 this->ms_time = prev.ms_time;
74 SvgMain::SvgMain(PluginServer *server)
75 : PluginVClient(server)
88 const char* SvgMain::plugin_title() { return _("SVG via Inkscape"); }
89 int SvgMain::is_realtime() { return 1; }
90 int SvgMain::is_synthesis() { return 1; }
93 LOAD_CONFIGURATION_MACRO(SvgMain, SvgConfig)
95 void SvgMain::save_data(KeyFrame *keyframe)
99 // cause data to be stored directly in text
100 output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
102 output.tag.set_title("SVG");
103 output.tag.set_property("OUT_X", config.out_x);
104 output.tag.set_property("OUT_Y", config.out_y);
105 output.tag.set_property("SVG_FILE", config.svg_file);
106 output.tag.set_property("MS_TIME", config.ms_time);
108 output.tag.set_title("/SVG");
111 output.terminate_string();
114 void SvgMain::read_data(KeyFrame *keyframe)
118 const char *data = keyframe->get_data();
119 input.set_shared_input((char*)data, strlen(data));
122 while( !(result = input.read_tag()) ) {
123 if(input.tag.title_is("SVG")) {
124 config.out_x = input.tag.get_property("OUT_X", config.out_x);
125 config.out_y = input.tag.get_property("OUT_Y", config.out_y);
126 input.tag.get_property("SVG_FILE", config.svg_file);
127 config.ms_time = input.tag.get_property("MS_TIME", config.ms_time);
133 int SvgMain::process_realtime(VFrame *input, VFrame *output)
135 if( input != output )
136 output->copy_from(input);
138 need_reconfigure |= load_configuration();
139 if( need_reconfigure ) {
140 need_reconfigure = 0;
141 if( config.svg_file[0] == 0 ) return 0;
142 delete ofrm; ofrm = 0;
143 char filename_png[1024];
144 strcpy(filename_png, config.svg_file);
145 strncat(filename_png, ".png", sizeof(filename_png));
147 int64_t ms_time = stat(filename_png, &st_png) ? 0 :
148 st_png.st_mtim.tv_sec*1000 + st_png.st_mtim.tv_nsec/1000000;
149 int fd = ms_time < config.ms_time ? -1 : open(filename_png, O_RDWR);
150 if( fd < 0 ) { // file does not exist, export it
153 "inkscape --without-gui --export-background=0x000000 "
154 "--export-background-opacity=0 %s --export-png=%s",
155 config.svg_file, filename_png);
156 printf(_("Running command %s\n"), command);
158 // in order for lockf to work it has to be open for writing
159 fd = open(filename_png, O_RDWR);
161 printf(_("Export of %s to %s failed\n"), config.svg_file, filename_png);
166 unsigned char *png_buffer = (unsigned char *)
167 mmap (NULL, st_png.st_size, PROT_READ, MAP_SHARED, fd, 0);
168 if( png_buffer != MAP_FAILED ) {
169 if( png_buffer[0] == 0x89 && png_buffer[1] == 0x50 &&
170 png_buffer[2] == 0x4e && png_buffer[3] == 0x47 ) {
171 ofrm = new VFramePng(png_buffer, st_png.st_size, 1., 1.);
172 if( ofrm->get_color_model() != output->get_color_model() ) {
173 VFrame *vfrm = new VFrame(ofrm->get_w(), ofrm->get_h(),
174 output->get_color_model());
175 vfrm->transfer_from(ofrm);
176 delete ofrm; ofrm = vfrm;
180 printf (_("The file %s that was generated from %s is not in PNG format."
181 " Try to delete all *.png files.\n"), filename_png, config.svg_file);
182 munmap(png_buffer, st_png.st_size);
185 printf(_("Access mmap to %s as %s failed.\n"), config.svg_file, filename_png);
190 if(!overlayer) overlayer = new OverlayFrame(smp + 1);
191 overlayer->overlay(output, ofrm,
192 0, 0, ofrm->get_w(), ofrm->get_h(),
193 config.out_x, config.out_y,
194 config.out_x + ofrm->get_w(),
195 config.out_y + ofrm->get_h(),
197 get_interpolation_type());
203 NEW_WINDOW_MACRO(SvgMain, SvgWin)
205 void SvgMain::update_gui()
208 load_configuration();
209 SvgWin *window = (SvgWin*)thread->window;
210 window->update_gui(config);