00001 #include "clip.h"
00002 #include "filexml.h"
00003 #include "picon_png.h"
00004 #include "svg.h"
00005 #include "svgwin.h"
00006 #include <unistd.h>
00007 #include <fcntl.h>
00008 #include <string.h>
00009 #include <errno.h>
00010 #include <sys/mman.h>
00011
00012
00013 #include <libintl.h>
00014 #define _(String) gettext(String)
00015 #define gettext_noop(String) String
00016 #define N_(String) gettext_noop (String)
00017
00018 #include "empty_svg.h"
00019
00020 struct raw_struct {
00021 char rawc[5];
00022 int32_t struct_version;
00023 int32_t struct_size;
00024 int32_t width;
00025 int32_t height;
00026 int32_t pitch;
00027 int32_t color_model;
00028 int64_t time_of_creation;
00029
00030 };
00031
00032
00033 REGISTER_PLUGIN(SvgMain)
00034
00035 SvgConfig::SvgConfig()
00036 {
00037 in_x = 0;
00038 in_y = 0;
00039 in_w = 720;
00040 in_h = 480;
00041 out_x = 0;
00042 out_y = 0;
00043 out_w = 720;
00044 out_h = 480;
00045 last_load = 0;
00046 strcpy(svg_file, "");
00047 }
00048
00049 int SvgConfig::equivalent(SvgConfig &that)
00050 {
00051 return EQUIV(in_x, that.in_x) &&
00052 EQUIV(in_y, that.in_y) &&
00053 EQUIV(in_w, that.in_w) &&
00054 EQUIV(in_h, that.in_h) &&
00055 EQUIV(out_x, that.out_x) &&
00056 EQUIV(out_y, that.out_y) &&
00057 EQUIV(out_w, that.out_w) &&
00058 EQUIV(out_h, that.out_h) &&
00059 !strcmp(svg_file, that.svg_file);
00060 }
00061
00062 void SvgConfig::copy_from(SvgConfig &that)
00063 {
00064 in_x = that.in_x;
00065 in_y = that.in_y;
00066 in_w = that.in_w;
00067 in_h = that.in_h;
00068 out_x = that.out_x;
00069 out_y = that.out_y;
00070 out_w = that.out_w;
00071 out_h = that.out_h;
00072 last_load = that.last_load;
00073 strcpy(svg_file, that.svg_file);
00074 }
00075
00076 void SvgConfig::interpolate(SvgConfig &prev,
00077 SvgConfig &next,
00078 long prev_frame,
00079 long next_frame,
00080 long current_frame)
00081 {
00082 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
00083 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
00084
00085 this->in_x = prev.in_x * prev_scale + next.in_x * next_scale;
00086 this->in_y = prev.in_y * prev_scale + next.in_y * next_scale;
00087 this->in_w = prev.in_w * prev_scale + next.in_w * next_scale;
00088 this->in_h = prev.in_h * prev_scale + next.in_h * next_scale;
00089 this->out_x = prev.out_x * prev_scale + next.out_x * next_scale;
00090 this->out_y = prev.out_y * prev_scale + next.out_y * next_scale;
00091 this->out_w = prev.out_w * prev_scale + next.out_w * next_scale;
00092 this->out_h = prev.out_h * prev_scale + next.out_h * next_scale;
00093 strcpy(this->svg_file, prev.svg_file);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103 SvgMain::SvgMain(PluginServer *server)
00104 : PluginVClient(server)
00105 {
00106 temp_frame = 0;
00107 overlayer = 0;
00108 need_reconfigure = 0;
00109 force_raw_render = 0;
00110 PLUGIN_CONSTRUCTOR_MACRO
00111 }
00112
00113 SvgMain::~SvgMain()
00114 {
00115 PLUGIN_DESTRUCTOR_MACRO
00116
00117 if(temp_frame) delete temp_frame;
00118 temp_frame = 0;
00119 if(overlayer) delete overlayer;
00120 overlayer = 0;
00121 }
00122
00123 char* SvgMain::plugin_title() { return N_("SVG via Inkscape"); }
00124 int SvgMain::is_realtime() { return 1; }
00125 int SvgMain::is_synthesis() { return 1; }
00126
00127 NEW_PICON_MACRO(SvgMain)
00128
00129 int SvgMain::load_defaults()
00130 {
00131 char directory[1024], string[1024];
00132
00133 sprintf(directory, "%ssvg.rc", BCASTDIR);
00134
00135
00136 defaults = new BC_Hash(directory);
00137 defaults->load();
00138
00139
00140 config.in_x = defaults->get("IN_X", config.in_x);
00141 config.in_y = defaults->get("IN_Y", config.in_y);
00142 config.in_w = defaults->get("IN_W", config.in_w);
00143 config.in_h = defaults->get("IN_H", config.in_h);
00144 config.out_x = defaults->get("OUT_X", config.out_x);
00145 config.out_y = defaults->get("OUT_Y", config.out_y);
00146 config.out_w = defaults->get("OUT_W", config.out_w);
00147 config.out_h = defaults->get("OUT_H", config.out_h);
00148 strcpy(config.svg_file, "");
00149
00150 }
00151
00152 int SvgMain::save_defaults()
00153 {
00154 defaults->update("IN_X", config.in_x);
00155 defaults->update("IN_Y", config.in_y);
00156 defaults->update("IN_W", config.in_w);
00157 defaults->update("IN_H", config.in_h);
00158 defaults->update("OUT_X", config.out_x);
00159 defaults->update("OUT_Y", config.out_y);
00160 defaults->update("OUT_W", config.out_w);
00161 defaults->update("OUT_H", config.out_h);
00162 defaults->update("SVG_FILE", config.svg_file);
00163 defaults->save();
00164 }
00165
00166 LOAD_CONFIGURATION_MACRO(SvgMain, SvgConfig)
00167
00168 void SvgMain::save_data(KeyFrame *keyframe)
00169 {
00170 FileXML output;
00171
00172
00173 output.set_shared_string(keyframe->data, MESSAGESIZE);
00174
00175
00176 output.tag.set_title("SVG");
00177 output.tag.set_property("IN_X", config.in_x);
00178 output.tag.set_property("IN_Y", config.in_y);
00179 output.tag.set_property("IN_W", config.in_w);
00180 output.tag.set_property("IN_H", config.in_h);
00181 output.tag.set_property("OUT_X", config.out_x);
00182 output.tag.set_property("OUT_Y", config.out_y);
00183 output.tag.set_property("OUT_W", config.out_w);
00184 output.tag.set_property("OUT_H", config.out_h);
00185 output.tag.set_property("SVG_FILE", config.svg_file);
00186 output.append_tag();
00187 output.tag.set_title("/SVG");
00188 output.append_tag();
00189
00190 output.terminate_string();
00191
00192 }
00193
00194 void SvgMain::read_data(KeyFrame *keyframe)
00195 {
00196 FileXML input;
00197
00198 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00199
00200 int result = 0;
00201
00202 while(!result)
00203 {
00204 result = input.read_tag();
00205
00206 if(!result)
00207 {
00208 if(input.tag.title_is("SVG"))
00209 {
00210 config.in_x = input.tag.get_property("IN_X", config.in_x);
00211 config.in_y = input.tag.get_property("IN_Y", config.in_y);
00212 config.in_w = input.tag.get_property("IN_W", config.in_w);
00213 config.in_h = input.tag.get_property("IN_H", config.in_h);
00214 config.out_x = input.tag.get_property("OUT_X", config.out_x);
00215 config.out_y = input.tag.get_property("OUT_Y", config.out_y);
00216 config.out_w = input.tag.get_property("OUT_W", config.out_w);
00217 config.out_h = input.tag.get_property("OUT_H", config.out_h);
00218 input.tag.get_property("SVG_FILE", config.svg_file);
00219 }
00220 }
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231 int SvgMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
00232 {
00233 char filename_raw[1024];
00234 int fh_raw;
00235 struct stat st_raw;
00236 VFrame *input, *output;
00237 input = input_ptr;
00238 output = output_ptr;
00239 unsigned char * raw_buffer;
00240 struct raw_struct *raw_data;
00241
00242 need_reconfigure |= load_configuration();
00243
00244 if (config.svg_file[0] == 0) {
00245 output->copy_from(input);
00246 return(0);
00247 }
00248
00249 strcpy(filename_raw, config.svg_file);
00250 strcat(filename_raw, ".raw");
00251 fh_raw = open(filename_raw, O_RDWR);
00252
00253 if (fh_raw == -1 || force_raw_render)
00254 {
00255 need_reconfigure = 1;
00256 char command[1024];
00257 sprintf(command,
00258 "inkscape --without-gui --cinelerra-export-file=%s %s",
00259 filename_raw, config.svg_file);
00260 printf(_("Running command %s\n"), command);
00261 system(command);
00262 stat(filename_raw, &st_raw);
00263 force_raw_render = 0;
00264 fh_raw = open(filename_raw, O_RDWR);
00265 if (!fh_raw) {
00266 printf(_("Export of %s to %s failed\n"), config.svg_file, filename_raw);
00267 return 0;
00268 }
00269 }
00270
00271
00272
00273 lockf(fh_raw, F_LOCK, 0);
00274 fstat (fh_raw, &st_raw);
00275 raw_buffer = (unsigned char *)mmap (NULL, st_raw.st_size, PROT_READ, MAP_SHARED, fh_raw, 0);
00276 raw_data = (struct raw_struct *) raw_buffer;
00277
00278 if (strcmp(raw_data->rawc, "RAWC"))
00279 {
00280 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);
00281 lockf(fh_raw, F_ULOCK, 0);
00282 close(fh_raw);
00283 return (0);
00284 }
00285 if (raw_data->struct_version > 1)
00286 {
00287 printf (_("Unsupported version of RAWC file %s. This means your Inkscape uses newer RAWC format than Cinelerra. Please upgrade Cinelerra.\n"), filename_raw);
00288 lockf(fh_raw, F_ULOCK, 0);
00289 close(fh_raw);
00290 return (0);
00291 }
00292
00293 if (need_reconfigure || config.last_load < raw_data->time_of_creation) {
00294
00295 if (temp_frame &&
00296 !temp_frame->params_match(raw_data->width, raw_data->height, output_ptr->get_color_model()))
00297 {
00298
00299 delete temp_frame;
00300 temp_frame = 0;
00301 }
00302 if (!temp_frame)
00303 temp_frame = new VFrame(0,
00304 raw_data->width,
00305 raw_data->height,
00306 output_ptr->get_color_model());
00307
00308
00309 unsigned char ** raw_rows;
00310 raw_rows = new unsigned char*[raw_data->height];
00311 for (int i = 0; i < raw_data->height; i++) {
00312 raw_rows[i] = raw_buffer + raw_data->struct_size + raw_data->pitch * i * 4;
00313 }
00314 cmodel_transfer(temp_frame->get_rows(),
00315 raw_rows,
00316 0,
00317 0,
00318 0,
00319 0,
00320 0,
00321 0,
00322 0,
00323 0,
00324 raw_data->width,
00325 raw_data->height,
00326 0,
00327 0,
00328 temp_frame->get_w(),
00329 temp_frame->get_h(),
00330 BC_RGBA8888,
00331 temp_frame->get_color_model(),
00332 0,
00333 raw_data->pitch,
00334 temp_frame->get_w());
00335 delete [] raw_rows;
00336 munmap(raw_buffer, st_raw.st_size);
00337 lockf(fh_raw, F_ULOCK, 0);
00338 close(fh_raw);
00339
00340
00341 }
00342
00343
00344 if(!overlayer)
00345 {
00346 overlayer = new OverlayFrame(smp + 1);
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 output->copy_from(input);
00366 overlayer->overlay(output,
00367 temp_frame,
00368 0,
00369 0,
00370 temp_frame->get_w(),
00371 temp_frame->get_h(),
00372 config.out_x,
00373 config.out_y,
00374 config.out_x + temp_frame->get_w(),
00375 config.out_y + temp_frame->get_h(),
00376 1,
00377 TRANSFER_NORMAL,
00378 get_interpolation_type());
00379
00380 return(0);
00381 }
00382
00383
00384
00385
00386 SHOW_GUI_MACRO(SvgMain, SvgThread)
00387
00388 RAISE_WINDOW_MACRO(SvgMain)
00389
00390 SET_STRING_MACRO(SvgMain)
00391
00392 void SvgMain::update_gui()
00393 {
00394 if(thread)
00395 {
00396 load_configuration();
00397 thread->window->lock_window();
00398
00399
00400
00401
00402 thread->window->out_x->update(config.out_x);
00403 thread->window->out_y->update(config.out_y);
00404
00405
00406 thread->window->svg_file_title->update(config.svg_file);
00407 thread->window->unlock_window();
00408 }
00409 }