14 #define _(String) gettext(String)
15 #define gettext_noop(String) String
16 #define N_(String) gettext_noop (String)
18 #include "empty_svg.h"
21 char rawc[5]; // Null terminated "RAWC" string
22 int32_t struct_version; // currently 1 (bumped at each destructive change)
23 int32_t struct_size; // size of this struct in bytes
24 int32_t width; // logical width of image
26 int32_t pitch; // physical width of image in memory
27 int32_t color_model; // as BC_ constant, currently only BC_RGBA8888 is supported
28 int64_t time_of_creation; // in milliseconds - calculated as (tv_sec * 1000 + tv_usec / 1000);
29 // we can't trust date on the file, due to different reasons
33 REGISTER_PLUGIN(SvgMain)
35 SvgConfig::SvgConfig()
49 int SvgConfig::equivalent(SvgConfig &that)
51 return EQUIV(in_x, that.in_x) &&
52 EQUIV(in_y, that.in_y) &&
53 EQUIV(in_w, that.in_w) &&
54 EQUIV(in_h, that.in_h) &&
55 EQUIV(out_x, that.out_x) &&
56 EQUIV(out_y, that.out_y) &&
57 EQUIV(out_w, that.out_w) &&
58 EQUIV(out_h, that.out_h) &&
59 !strcmp(svg_file, that.svg_file);
62 void SvgConfig::copy_from(SvgConfig &that)
72 last_load = that.last_load;
73 strcpy(svg_file, that.svg_file);
76 void SvgConfig::interpolate(SvgConfig &prev,
82 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
83 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
85 this->in_x = prev.in_x * prev_scale + next.in_x * next_scale;
86 this->in_y = prev.in_y * prev_scale + next.in_y * next_scale;
87 this->in_w = prev.in_w * prev_scale + next.in_w * next_scale;
88 this->in_h = prev.in_h * prev_scale + next.in_h * next_scale;
89 this->out_x = prev.out_x * prev_scale + next.out_x * next_scale;
90 this->out_y = prev.out_y * prev_scale + next.out_y * next_scale;
91 this->out_w = prev.out_w * prev_scale + next.out_w * next_scale;
92 this->out_h = prev.out_h * prev_scale + next.out_h * next_scale;
93 strcpy(this->svg_file, prev.svg_file);
103 SvgMain::SvgMain(PluginServer *server)
104 : PluginVClient(server)
108 need_reconfigure = 0;
109 force_raw_render = 0;
110 PLUGIN_CONSTRUCTOR_MACRO
115 PLUGIN_DESTRUCTOR_MACRO
117 if(temp_frame) delete temp_frame;
119 if(overlayer) delete overlayer;
123 char* SvgMain::plugin_title() { return N_("SVG via Sodipodi"); }
124 int SvgMain::is_realtime() { return 1; }
126 NEW_PICON_MACRO(SvgMain)
128 int SvgMain::load_defaults()
130 char directory[1024], string[1024];
131 // set the default directory
132 sprintf(directory, "%ssvg.rc", BCASTDIR);
135 defaults = new Defaults(directory);
139 config.in_x = defaults->get("IN_X", config.in_x);
140 config.in_y = defaults->get("IN_Y", config.in_y);
141 config.in_w = defaults->get("IN_W", config.in_w);
142 config.in_h = defaults->get("IN_H", config.in_h);
143 config.out_x = defaults->get("OUT_X", config.out_x);
144 config.out_y = defaults->get("OUT_Y", config.out_y);
145 config.out_w = defaults->get("OUT_W", config.out_w);
146 config.out_h = defaults->get("OUT_H", config.out_h);
147 strcpy(config.svg_file, "");
148 // defaults->get("SVG_FILE", config.svg_file);
151 int SvgMain::save_defaults()
153 defaults->update("IN_X", config.in_x);
154 defaults->update("IN_Y", config.in_y);
155 defaults->update("IN_W", config.in_w);
156 defaults->update("IN_H", config.in_h);
157 defaults->update("OUT_X", config.out_x);
158 defaults->update("OUT_Y", config.out_y);
159 defaults->update("OUT_W", config.out_w);
160 defaults->update("OUT_H", config.out_h);
161 defaults->update("SVG_FILE", config.svg_file);
165 LOAD_CONFIGURATION_MACRO(SvgMain, SvgConfig)
167 void SvgMain::save_data(KeyFrame *keyframe)
171 // cause data to be stored directly in text
172 output.set_shared_string(keyframe->data, MESSAGESIZE);
175 output.tag.set_title("SVG");
176 output.tag.set_property("IN_X", config.in_x);
177 output.tag.set_property("IN_Y", config.in_y);
178 output.tag.set_property("IN_W", config.in_w);
179 output.tag.set_property("IN_H", config.in_h);
180 output.tag.set_property("OUT_X", config.out_x);
181 output.tag.set_property("OUT_Y", config.out_y);
182 output.tag.set_property("OUT_W", config.out_w);
183 output.tag.set_property("OUT_H", config.out_h);
184 output.tag.set_property("SVG_FILE", config.svg_file);
187 output.terminate_string();
188 // data is now in *text
191 void SvgMain::read_data(KeyFrame *keyframe)
195 input.set_shared_string(keyframe->data, strlen(keyframe->data));
201 result = input.read_tag();
205 if(input.tag.title_is("SVG"))
207 config.in_x = input.tag.get_property("IN_X", config.in_x);
208 config.in_y = input.tag.get_property("IN_Y", config.in_y);
209 config.in_w = input.tag.get_property("IN_W", config.in_w);
210 config.in_h = input.tag.get_property("IN_H", config.in_h);
211 config.out_x = input.tag.get_property("OUT_X", config.out_x);
212 config.out_y = input.tag.get_property("OUT_Y", config.out_y);
213 config.out_w = input.tag.get_property("OUT_W", config.out_w);
214 config.out_h = input.tag.get_property("OUT_H", config.out_h);
215 input.tag.get_property("SVG_FILE", config.svg_file);
228 int SvgMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
230 char filename_raw[1024];
233 VFrame *input, *output;
236 unsigned char * raw_buffer;
237 struct raw_struct *raw_data;
239 need_reconfigure |= load_configuration();
241 if (config.svg_file[0] == 0) {
242 output->copy_from(input);
246 strcpy(filename_raw, config.svg_file);
247 strcat(filename_raw, ".raw");
248 fh_raw = open(filename_raw, O_RDWR); // in order for lockf to work it has to be open for writing
250 if (fh_raw == -1 || force_raw_render) // file does not exist, export it
252 need_reconfigure = 1;
255 "sodipodi --without-gui --cinelerra-export-file=%s %s",
256 filename_raw, config.svg_file);
257 printf(_("Running command %s\n"), command);
259 stat(filename_raw, &st_raw);
260 force_raw_render = 0;
261 fh_raw = open(filename_raw, O_RDWR); // in order for lockf to work it has to be open for writing
263 printf(_("Export of %s to %s failed\n"), config.svg_file, filename_raw);
269 // file exists, ... lock it, mmap it and check time_of_creation
270 lockf(fh_raw, F_LOCK, 0); // Blocking call - will wait for sodipodi to finish!
271 fstat (fh_raw, &st_raw);
272 raw_buffer = (unsigned char *)mmap (NULL, st_raw.st_size, PROT_READ, MAP_SHARED, fh_raw, 0);
273 raw_data = (struct raw_struct *) raw_buffer;
275 if (strcmp(raw_data->rawc, "RAWC"))
277 printf (_("The file %s that was generated from %s is not in RAWC format. Try to delete all *.raw files.\n"), filename_raw, config.svg_file);
278 lockf(fh_raw, F_ULOCK, 0);
282 if (raw_data->struct_version > 1)
284 printf (_("Unsupported version of RAWC file %s. This means your Sodipodi uses newer RAWC format than Cinelerra. Please upgrade Cinelerra.\n"), filename_raw);
285 lockf(fh_raw, F_ULOCK, 0);
289 // Ok, we can now be sure we have valid RAWC file on our hands
290 if (need_reconfigure || config.last_load < raw_data->time_of_creation) { // the file was updated or is new (then last_load is zero)
293 !temp_frame->params_match(raw_data->width, raw_data->height, output_ptr->get_color_model()))
295 // parameters don't match
300 temp_frame = new VFrame(0,
303 output_ptr->get_color_model());
305 // temp_frame is ready by now, we can do the loading
306 unsigned char ** raw_rows;
307 raw_rows = new unsigned char*[raw_data->height]; // this could be optimized, so new isn't used every time
308 for (int i = 0; i < raw_data->height; i++) {
309 raw_rows[i] = raw_buffer + raw_data->struct_size + raw_data->pitch * i * 4;
311 cmodel_transfer(temp_frame->get_rows(),
328 temp_frame->get_color_model(),
331 temp_frame->get_w());
333 munmap(raw_buffer, st_raw.st_size);
334 lockf(fh_raw, F_ULOCK, 0);
339 // by now we have temp_frame ready, we just need to overylay it
343 overlayer = new OverlayFrame(smp + 1);
348 // printf("SvgMain::process_realtime 3 output=%p input=%p config.w=%f config.h=%f"
349 // "%f %f %f %f -> %f %f %f %f\n",
363 output->copy_from(input);
364 overlayer->overlay(output,
372 config.out_x + temp_frame->get_w(),
373 config.out_y + temp_frame->get_h(),
376 get_interpolation_type());
384 SHOW_GUI_MACRO(SvgMain, SvgThread)
386 RAISE_WINDOW_MACRO(SvgMain)
388 SET_STRING_MACRO(SvgMain)
390 void SvgMain::update_gui()
394 load_configuration();
395 thread->window->lock_window();
396 // thread->window->in_x->update(config.in_x);
397 // thread->window->in_y->update(config.in_y);
398 // thread->window->in_w->update(config.in_w);
399 // thread->window->in_h->update(config.in_h);
400 thread->window->out_x->update(config.out_x);
401 thread->window->out_y->update(config.out_y);
402 // thread->window->out_w->update(config.out_w);
403 // thread->window->out_h->update(config.out_h);
404 thread->window->svg_file_title->update(config.svg_file);
405 thread->window->unlock_window();