From 7be8c7f90868895abddcbafda66ede5632752a70 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 7 Sep 2016 14:35:08 -0600 Subject: [PATCH] svg plugin upgrades, filepng improvements --- cinelerra-5.1/cinelerra/filepng.C | 32 ++++----- cinelerra-5.1/plugins/svg/svg.C | 70 ++++++++++++------ cinelerra-5.1/plugins/svg/svg.h | 4 +- cinelerra-5.1/plugins/svg/svgwin.C | 110 +++++++++++++++++++++++------ cinelerra-5.1/plugins/svg/svgwin.h | 39 ++++++++-- 5 files changed, 189 insertions(+), 66 deletions(-) diff --git a/cinelerra-5.1/cinelerra/filepng.C b/cinelerra-5.1/cinelerra/filepng.C index 6ccbf288..889ee240 100644 --- a/cinelerra-5.1/cinelerra/filepng.C +++ b/cinelerra-5.1/cinelerra/filepng.C @@ -254,27 +254,27 @@ int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) //printf("FilePNG::write_frame 1\n"); png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if( png_ptr && !setjmp(png_jmpbuf(png_ptr)) ) { - info_ptr = png_create_info_struct(png_ptr); - png_set_write_fn(png_ptr, data, - (png_rw_ptr)write_function, (png_flush_ptr)flush_function); - png_set_compression_level(png_ptr, 5); - - png_set_IHDR(png_ptr, info_ptr, asset->width, asset->height, 8, - asset->png_use_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_write_info(png_ptr, info_ptr); - png_write_image(png_ptr, output_frame->get_rows()); - png_write_end(png_ptr, info_ptr); + if( png_ptr ) { + if( !setjmp(png_jmpbuf(png_ptr)) ) { + info_ptr = png_create_info_struct(png_ptr); + png_set_write_fn(png_ptr, data, + (png_rw_ptr)write_function, (png_flush_ptr)flush_function); + png_set_compression_level(png_ptr, 5); + + png_set_IHDR(png_ptr, info_ptr, asset->width, asset->height, 8, + asset->png_use_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_write_info(png_ptr, info_ptr); + png_write_image(png_ptr, output_frame->get_rows()); + png_write_end(png_ptr, info_ptr); + result = 0; + } png_destroy_write_struct(&png_ptr, &info_ptr); - result = 0; } - else { + if( result ) { char error[256]; png_error(png_ptr, error); fprintf(stderr, "FilePNG::write_frame failed: %s\n", error); } - - png_destroy_write_struct(&png_ptr, &info_ptr); //printf("FilePNG::write_frame 3 %d\n", data->get_compressed_size()); return result; } diff --git a/cinelerra-5.1/plugins/svg/svg.C b/cinelerra-5.1/plugins/svg/svg.C index 49551cfb..27881f2c 100644 --- a/cinelerra-5.1/plugins/svg/svg.C +++ b/cinelerra-5.1/plugins/svg/svg.C @@ -16,7 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include "clip.h" @@ -24,6 +23,8 @@ #include "language.h" #include "svg.h" #include "svgwin.h" +#include "overlayframe.inc" + #include #include #include @@ -37,16 +38,21 @@ REGISTER_PLUGIN(SvgMain) SvgConfig::SvgConfig() { - out_x = 0; - out_y = 0; + out_x = 0; out_y = 0; + out_w = 640; out_h = 480; + dpi = 90; strcpy(svg_file, ""); ms_time = 0; } int SvgConfig::equivalent(SvgConfig &that) { - // out_x/out_y always used by overlayer - return !strcmp(svg_file, that.svg_file) && + return EQUIV(dpi, that.dpi) && + EQUIV(out_x, that.out_x) && + EQUIV(out_y, that.out_y) && + EQUIV(out_w, that.out_w) && + EQUIV(out_h, that.out_h) && + !strcmp(svg_file, that.svg_file) && ms_time == that.ms_time; } @@ -54,11 +60,14 @@ void SvgConfig::copy_from(SvgConfig &that) { out_x = that.out_x; out_y = that.out_y; + out_w = that.out_w; + out_h = that.out_h; + dpi = that.dpi; strcpy(svg_file, that.svg_file); ms_time = that.ms_time; } -void SvgConfig::interpolate(SvgConfig &prev, SvgConfig &next, +void SvgConfig::interpolate(SvgConfig &prev, SvgConfig &next, long prev_frame, long next_frame, long current_frame) { double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); @@ -66,6 +75,9 @@ void SvgConfig::interpolate(SvgConfig &prev, SvgConfig &next, this->out_x = prev.out_x * prev_scale + next.out_x * next_scale; this->out_y = prev.out_y * prev_scale + next.out_y * next_scale; + this->out_w = prev.out_w * prev_scale + next.out_w * next_scale; + this->out_h = prev.out_h * prev_scale + next.out_h * next_scale; + this->dpi = prev.dpi; strcpy(this->svg_file, prev.svg_file); this->ms_time = prev.ms_time; } @@ -102,6 +114,9 @@ void SvgMain::save_data(KeyFrame *keyframe) output.tag.set_title("SVG"); output.tag.set_property("OUT_X", config.out_x); output.tag.set_property("OUT_Y", config.out_y); + output.tag.set_property("OUT_W", config.out_w); + output.tag.set_property("OUT_H", config.out_h); + output.tag.set_property("DPI", config.dpi); output.tag.set_property("SVG_FILE", config.svg_file); output.tag.set_property("MS_TIME", config.ms_time); output.append_tag(); @@ -121,8 +136,11 @@ void SvgMain::read_data(KeyFrame *keyframe) while( !(result = input.read_tag()) ) { if(input.tag.title_is("SVG")) { - config.out_x = input.tag.get_property("OUT_X", config.out_x); - config.out_y = input.tag.get_property("OUT_Y", config.out_y); + config.out_x = input.tag.get_property("OUT_X", config.out_x); + config.out_y = input.tag.get_property("OUT_Y", config.out_y); + config.out_w = input.tag.get_property("OUT_W", config.out_w); + config.out_h = input.tag.get_property("OUT_H", config.out_h); + config.dpi = input.tag.get_property("DPI", config.dpi); input.tag.get_property("SVG_FILE", config.svg_file); config.ms_time = input.tag.get_property("MS_TIME", config.ms_time); } @@ -135,24 +153,35 @@ int SvgMain::process_realtime(VFrame *input, VFrame *output) if( input != output ) output->copy_from(input); - need_reconfigure |= load_configuration(); - if( need_reconfigure ) { + int need_export = 0; + float last_dpi = config.dpi; + char last_svg_file[BCTEXTLEN]; + strcpy(last_svg_file, config.svg_file); + int64_t last_ms_time = config.ms_time; + load_configuration(); + if( last_dpi != config.dpi ) + need_export = 1; + if( strcmp(last_svg_file, config.svg_file) || + last_ms_time != config.ms_time ) + need_reconfigure = 1; + + if( need_reconfigure || need_export ) { need_reconfigure = 0; if( config.svg_file[0] == 0 ) return 0; delete ofrm; ofrm = 0; - char filename_png[1024]; + char filename_png[BCTEXTLEN]; strcpy(filename_png, config.svg_file); strncat(filename_png, ".png", sizeof(filename_png)); struct stat st_png; - int64_t ms_time = stat(filename_png, &st_png) ? 0 : + int64_t ms_time = need_export || stat(filename_png, &st_png) ? 0 : st_png.st_mtim.tv_sec*1000 + st_png.st_mtim.tv_nsec/1000000; int fd = ms_time < config.ms_time ? -1 : open(filename_png, O_RDWR); if( fd < 0 ) { // file does not exist, export it - char command[1024]; + char command[BCTEXTLEN]; sprintf(command, "inkscape --without-gui --export-background=0x000000 " - "--export-background-opacity=0 %s --export-png=%s", - config.svg_file, filename_png); + "--export-background-opacity=0 -d %f %s --export-png=%s", + config.dpi, config.svg_file, filename_png); printf(_("Running command %s\n"), command); system(command); // in order for lockf to work it has to be open for writing @@ -164,7 +193,7 @@ int SvgMain::process_realtime(VFrame *input, VFrame *output) struct stat st_png; fstat(fd, &st_png); unsigned char *png_buffer = (unsigned char *) - mmap (NULL, st_png.st_size, PROT_READ, MAP_SHARED, fd, 0); + mmap (NULL, st_png.st_size, PROT_READ, MAP_SHARED, fd, 0); if( png_buffer != MAP_FAILED ) { if( png_buffer[0] == 0x89 && png_buffer[1] == 0x50 && png_buffer[2] == 0x4e && png_buffer[3] == 0x47 ) { @@ -190,11 +219,10 @@ int SvgMain::process_realtime(VFrame *input, VFrame *output) if(!overlayer) overlayer = new OverlayFrame(smp + 1); overlayer->overlay(output, ofrm, 0, 0, ofrm->get_w(), ofrm->get_h(), - config.out_x, config.out_y, - config.out_x + ofrm->get_w(), - config.out_y + ofrm->get_h(), - 1, TRANSFER_NORMAL, - get_interpolation_type()); + config.out_x, config.out_y, + config.out_x + config.out_w, + config.out_y + config.out_h, + 1, TRANSFER_NORMAL, LINEAR_LINEAR); } return 0; } diff --git a/cinelerra-5.1/plugins/svg/svg.h b/cinelerra-5.1/plugins/svg/svg.h index e0cd1317..e3343a4f 100644 --- a/cinelerra-5.1/plugins/svg/svg.h +++ b/cinelerra-5.1/plugins/svg/svg.h @@ -41,10 +41,10 @@ public: SvgConfig(); int equivalent(SvgConfig &that); void copy_from(SvgConfig &that); - void interpolate(SvgConfig &prev, SvgConfig &next, + void interpolate(SvgConfig &prev, SvgConfig &next, long prev_frame, long next_frame, long current_frame); - float out_x, out_y; + float out_x, out_y, out_w, out_h, dpi; char svg_file[BCTEXTLEN]; int64_t ms_time; }; diff --git a/cinelerra-5.1/plugins/svg/svgwin.C b/cinelerra-5.1/plugins/svg/svgwin.C index 9b4ec707..d5f8b978 100644 --- a/cinelerra-5.1/plugins/svg/svgwin.C +++ b/cinelerra-5.1/plugins/svg/svgwin.C @@ -19,11 +19,10 @@ * */ -#include "bcdisplayinfo.h" -#include "clip.h" #include "svgwin.h" #include "filexml.h" #include "language.h" + #include #include #include @@ -41,9 +40,9 @@ struct fifo_struct { }; SvgWin::SvgWin(SvgMain *client) - : PluginClientWindow(client, 300, 180, 300, 180, 1) -{ - this->client = client; + : PluginClientWindow(client, 420, 210, 420, 210, 1) +{ + this->client = client; this->editing = 0; } @@ -54,22 +53,51 @@ SvgWin::~SvgWin() void SvgWin::create_objects() { BC_Title *title; - int x = 10, y = 10; - add_tool(title = new BC_Title(x, y, _("Out X:"))); - int x1 = x + title->get_w() + 10; + int x0 = 10, y = 10; + + add_tool(title = new BC_Title(x0, y, _("Out X:"))); + int x1 = x0 + title->get_w() + 10; out_x = new SvgCoord(this, client, x1, y, &client->config.out_x); out_x->create_objects(); + int x2 = x1 + out_x->get_w() + 15; + add_tool(title = new BC_Title(x2, y, _("Out W:"))); + int x3 = x2 + title->get_w() + 10; + out_w = new SvgCoord(this, client, x3, y, &client->config.out_w); + out_w->create_objects(); y += out_x->get_h() + 5; - add_tool(new BC_Title(x, y, _("Out Y:"))); + + add_tool(new BC_Title(x0, y, _("Out Y:"))); out_y = new SvgCoord(this, client, x1, y, &client->config.out_y); out_y->create_objects(); + add_tool(title = new BC_Title(x2, y, _("Out H:"))); + out_h = new SvgCoord(this, client, x3, y, &client->config.out_h); + out_h->create_objects(); y += out_y->get_h() + 20; - add_tool(new_svg_button = new NewSvgButton(client, this, x, y)); - add_tool(edit_svg_button = new EditSvgButton(client, this, x+190, y)); + add_tool(title = new BC_Title(x0, y, _("DPI:"))); + dpi = new DpiValue(this, client, x1, y, &client->config.dpi); + dpi->create_objects(); + add_tool(dpi_button = new DpiButton(this, client, x2, y)); + dpi_button->create_objects(); + y += dpi->get_h() + 20; + + add_tool(svg_file_title = new BC_Title(x0, y, client->config.svg_file)); + y += svg_file_title->get_h() + 5; + struct stat st; + int64_t ms_time = stat(client->config.svg_file, &st) ? 0 : + st.st_mtim.tv_sec*1000 + st.st_mtim.tv_nsec/1000000; + char mtime[BCSTRLEN]; mtime[0] = 0; + if( ms_time > 0 ) { + time_t tm = ms_time/1000; + ctime_r(&tm ,mtime); + } + add_tool(svg_file_mstime = new BC_Title(x0, y, mtime)); + y += svg_file_mstime->get_h() + 15; - add_tool(svg_file_title = new BC_Title(x, y+=42, client->config.svg_file)); - add_tool(svg_file_mstime = new BC_Title(x, y+=26, "")); + y = get_h() - NewSvgButton::calculate_h() - 5; + add_tool(new_svg_button = new NewSvgButton(client, this, x0, y)); + y = get_h() - EditSvgButton::calculate_h() - 5; + add_tool(edit_svg_button = new EditSvgButton(client, this, x0+300, y)); show_window(); flush(); @@ -82,12 +110,21 @@ int SvgWin::close_event() return 1; } +int SvgWin::hide_window(int flush) +{ + edit_svg_button->stop(); + return BC_WindowBase::hide_window(flush); +} + void SvgWin::update_gui(SvgConfig &config) { lock_window("SvgWin::update_gui"); out_x->update(config.out_x); out_y->update(config.out_y); + out_w->update(config.out_w); + out_h->update(config.out_h); + dpi->update(config.dpi); svg_file_title->update(config.svg_file); char mtime[BCSTRLEN]; mtime[0] = 0; if( config.ms_time > 0 ) { @@ -185,8 +222,8 @@ void NewSvgButton::run() } // Extend the filename with .svg - if(strlen(filename) < 4 || - strcasecmp(&filename[strlen(filename) - 4], ".svg")) { + if( strlen(filename) < 4 || + strcasecmp(&filename[strlen(filename) - 4], ".svg") ) { strcat(filename, ".svg"); } @@ -247,8 +284,7 @@ int EditSvgButton::handle_event() { window->editing_lock.lock(); - if (!window->editing && client->config.svg_file[0] != 0) - { + if( !window->editing && client->config.svg_file[0] != 0 ) { window->editing = 1; window->editing_lock.unlock(); start(); @@ -353,18 +389,50 @@ void SvgInkscapeThread::run() NewSvgWindow::NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory) : BC_FileBox(0, BC_WindowBase::get_resources()->filebox_h / 2, - init_directory, - _("SVG Plugin: Pick SVG file"), + init_directory, + _("SVG Plugin: Pick SVG file"), _("Open an existing SVG file or create a new one")) -{ - this->window = window; +{ + this->window = window; } NewSvgWindow::~NewSvgWindow() {} +DpiValue::DpiValue(SvgWin *win, SvgMain *client, int x, int y, float *value) + : BC_TumbleTextBox(win, *value, (float)10, (float)1000, x, y, 100) +{ +//printf("SvgWidth::SvgWidth %f\n", client->config.w); + this->client = client; + this->win = win; + this->value = value; +} + +DpiValue::~DpiValue() +{ +} + +int DpiValue::handle_event() +{ + *value = atof(get_text()); + return 1; +} +DpiButton::DpiButton( SvgWin *window, SvgMain *client, int x, int y) + : BC_GenericButton(x, y, _("update dpi")) +{ + this->client = client; + this->window = window; +} +DpiButton::~DpiButton() +{ +} +int DpiButton::handle_event() +{ + client->send_configure_change(); + return 1; +}; diff --git a/cinelerra-5.1/plugins/svg/svgwin.h b/cinelerra-5.1/plugins/svg/svgwin.h index 279bc507..bbbc6414 100644 --- a/cinelerra-5.1/plugins/svg/svgwin.h +++ b/cinelerra-5.1/plugins/svg/svgwin.h @@ -36,6 +36,8 @@ class SvgCoord; class NewSvgButton; class NewSvgWindow; class EditSvgButton; +class DpiValue; +class DpiButton; class SvgWin : public PluginClientWindow { @@ -46,8 +48,11 @@ public: void create_objects(); int close_event(); void update_gui(SvgConfig &config); + int hide_window(int flush = 1); - SvgCoord *in_x, *in_y, *in_w, *in_h, *out_x, *out_y, *out_w, *out_h; + SvgCoord *out_x, *out_y, *out_w, *out_h; + DpiValue *dpi; + DpiButton *dpi_button; SvgMain *client; BC_Title *svg_file_title; BC_Title *svg_file_mstime; @@ -62,11 +67,8 @@ public: class SvgCoord : public BC_TumbleTextBox { public: - SvgCoord(SvgWin *win, - SvgMain *client, - int x, - int y, - float *value); + SvgCoord(SvgWin *win, SvgMain *client, + int x, int y, float *value); ~SvgCoord(); int handle_event(); @@ -119,5 +121,30 @@ public: SvgWin *window; }; +class DpiValue : public BC_TumbleTextBox +{ +public: + DpiValue(SvgWin *win, SvgMain *client, + int x, int y, float *value); + ~DpiValue(); + int handle_event(); + + SvgMain *client; + SvgWin *win; + float *value; + +}; + +class DpiButton : public BC_GenericButton +{ +public: + DpiButton( SvgWin *window, SvgMain *client, int x, int y); + ~DpiButton(); + int handle_event(); + + SvgMain *client; + SvgWin *window; +}; + #endif -- 2.26.2