add crop plugin, add timeline bars, render setup err chks, minor tweaks
authorGood Guy <good1.2guy@gmail.com>
Wed, 4 Sep 2019 18:26:37 +0000 (12:26 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 4 Sep 2019 18:26:37 +0000 (12:26 -0600)
18 files changed:
cinelerra-5.1/cinelerra/batchrender.C
cinelerra-5.1/cinelerra/batchrender.h
cinelerra-5.1/cinelerra/packagedispatcher.C
cinelerra-5.1/cinelerra/render.C
cinelerra-5.1/cinelerra/render.h
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/cinelerra/versioninfo.h
cinelerra-5.1/configure.ac
cinelerra-5.1/expanders.txt
cinelerra-5.1/lv2_blacklist.txt
cinelerra-5.1/msg/txt
cinelerra-5.1/plugins/Makefile
cinelerra-5.1/plugins/crop/Makefile [new file with mode: 0644]
cinelerra-5.1/plugins/crop/crop.C [new file with mode: 0644]
cinelerra-5.1/plugins/crop/crop.h [new file with mode: 0644]
cinelerra-5.1/plugins/crop/cropwin.C [new file with mode: 0644]
cinelerra-5.1/plugins/crop/cropwin.h [new file with mode: 0644]
cinelerra-5.1/thirdparty/downloads.txt

index e3ff86e127727d2d10141e12769fa50eea9ed89e..6f1129f0afcee60f51c86c9c45ae89d7327b0845 100644 (file)
@@ -409,6 +409,26 @@ char* BatchRenderThread::get_current_edl()
        return get_current_job()->edl_path;
 }
 
        return get_current_job()->edl_path;
 }
 
+int BatchRenderThread::test_errmsg(BatchRenderWarnJobs &err_jobs, const char *msg, int *warn)
+{
+       int count = err_jobs.size();
+       if( !count ) return 0;
+       fprintf(stderr, msg, count);
+       char string[BCTEXTLEN], *sp = string, *ep = sp+sizeof(string)-1;
+       sp += snprintf(sp,ep-sp, msg,count);
+       for( int i=0; i<count; ++i ) {
+               int no = err_jobs[i].no;
+               const char *path = err_jobs[i].path;
+               fprintf(stderr, "%d: %s\n", no, path);
+               sp += snprintf(sp,ep-sp, "%d: %s\n", no, path);
+       }
+       sp += snprintf(sp,ep-sp, _("press cancel to abandon batch render"));
+       mwindow->show_warning(warn, string);
+       if( mwindow->wait_warning() ) {
+               gui->button_enable();
+       }
+       return 1;
+}
 
 // Test EDL files for existence
 int BatchRenderThread::test_edl_files()
 
 // Test EDL files for existence
 int BatchRenderThread::test_edl_files()
@@ -417,10 +437,12 @@ int BatchRenderThread::test_edl_files()
        const char *path = 0;
        BatchRenderWarnJobs not_equiv;
        BatchRenderWarnJobs empty_jobs;
        const char *path = 0;
        BatchRenderWarnJobs not_equiv;
        BatchRenderWarnJobs empty_jobs;
+       BatchRenderWarnJobs no_labels;
+       BatchRenderWarnJobs no_rendering;
 
        for( int i=0; !ret && i<jobs.size(); ++i ) {
                if( !jobs.values[i]->enabled ) continue;
 
        for( int i=0; !ret && i<jobs.size(); ++i ) {
                if( !jobs.values[i]->enabled ) continue;
-               path = jobs.values[i]->edl_path;
+               path = jobs[i]->edl_path;
                int is_script = *path == '@' ? 1 : 0;
                if( is_script ) ++path;
                FILE *fp = fopen(path, "r");
                int is_script = *path == '@' ? 1 : 0;
                if( is_script ) ++path;
                FILE *fp = fopen(path, "r");
@@ -443,10 +465,17 @@ int BatchRenderThread::test_edl_files()
                                        file.set_shared_input(&data);
                                        edl->load_xml(&file, LOAD_ALL); }
                                        double pos = edl->equivalent_output(mwindow->edl);
                                        file.set_shared_input(&data);
                                        edl->load_xml(&file, LOAD_ALL); }
                                        double pos = edl->equivalent_output(mwindow->edl);
-                                       if( pos >= 0 ) not_equiv.add(i+1, path);
+                                       if( pos >= 0 )
+                                               not_equiv.add(i+1, path);
                                        double length = edl->tracks->total_playable_length();
                                        double start = edl->local_session->get_selectionstart(1);
                                        double length = edl->tracks->total_playable_length();
                                        double start = edl->local_session->get_selectionstart(1);
-                                       if( start >= length ) empty_jobs.add(i+1, path);
+                                       if( start >= length )
+                                               empty_jobs.add(i+1, path);
+                                       if( jobs[i]->labeled && !edl->labels->first)
+                                               no_labels.add(i+1,path);
+                                       Asset *asset = jobs[i]->asset;
+                                       if( !asset->audio_data && !asset->video_data )
+                                               no_rendering.add(i+1,path);
                                        edl->remove_user();
                                }
                                delete [] bfr;
                                        edl->remove_user();
                                }
                                delete [] bfr;
@@ -472,47 +501,21 @@ int BatchRenderThread::test_edl_files()
                        fprintf(stderr, "%s", string);
                }
                is_rendering = 0;
                        fprintf(stderr, "%s", string);
                }
                is_rendering = 0;
+               ret = 1;
        }
 
        }
 
-       int mismatched = not_equiv.size();
-       if( is_rendering && warn && mwindow && mismatched > 0 ) {
-               fprintf(stderr, _("%d job EDLs do not match session edl\n"), mismatched);
-               char string[BCTEXTLEN], *sp = string, *ep = sp+sizeof(string)-1;
-               sp += snprintf(sp,ep-sp, _("%d job EDLs do not match session edl\n"),mismatched);
-               for( int i=0; i<mismatched; ++i ) {
-                       int no = not_equiv[i].no;  const char *path = not_equiv[i].path;
-                       fprintf(stderr, "%d: %s\n", no, path);
-                       sp += snprintf(sp,ep-sp, "%d: %s\n", no, path);
-               }
-               sp += snprintf(sp,ep-sp, _("press cancel to abandon batch render"));
-               mwindow->show_warning(&warn, string);
-               if( mwindow->wait_warning() ) {
-                       gui->button_enable();
-                       is_rendering = 0;
-                       ret = 1;
-               }
-               gui->warning->update(warn);
+       if( !ret && warn && mwindow ) {
+               ret = test_errmsg(not_equiv, _("%d job EDLs do not match session edl\n"), &warn);
+               if( !warn ) gui->warning->update(0);
        }
        }
-
-       int empty = empty_jobs.size();
-       if( is_rendering && empty > 0 ) {
-               fprintf(stderr, _("%d job EDLs begin position beyond end of media\n"), empty);
-               char string[BCTEXTLEN], *sp = string, *ep = sp+sizeof(string)-1;
-               sp += snprintf(sp,ep-sp, _("%d job EDLs begin position beyond end of media\n"), empty);
-               for( int i=0; i<empty; ++i ) {
-                       int no = empty_jobs[i].no;  const char *path = empty_jobs[i].path;
-                       fprintf(stderr, "%d: %s\n", no, path);
-                       sp += snprintf(sp,ep-sp, "%d: %s\n", no, path);
-               }
-               sp += snprintf(sp,ep-sp, _("press cancel to abandon batch render"));
-               mwindow->show_warning(0, string);
-               if( mwindow->wait_warning() ) {
-                       gui->button_enable();
-                       is_rendering = 0;
-                       ret = 1;
-               }
-       }
-
+       if( !ret && mwindow )
+               ret = test_errmsg(empty_jobs, _("%d job EDLs begin position beyond end of media\n"), 0);
+       if( !ret && mwindow )
+               ret = test_errmsg(no_rendering, _("%d job EDLs no audio or video in render asset format\n"), 0);
+       if( !ret && mwindow )
+               ret = test_errmsg(no_labels, _("%d job EDLs render file per label and no labels\n"), 0);
+       if( ret )
+               is_rendering = 0;
        return ret;
 }
 
        return ret;
 }
 
@@ -538,12 +541,13 @@ void BatchRenderThread::calculate_dest_paths(ArrayList<char*> *paths,
                        command->playback_range_adjust_inout();
 
 // Create test packages
                        command->playback_range_adjust_inout();
 
 // Create test packages
-                       packages->create_packages(mwindow, command->get_edl(),
+                       int result = packages->create_packages(mwindow, command->get_edl(),
                                preferences, job->get_strategy(), job->asset,
                                command->start_position, command->end_position, 0);
                                preferences, job->get_strategy(), job->asset,
                                command->start_position, command->end_position, 0);
+                       if( !result )
+                               packages->get_package_paths(paths);
 
 // Append output paths allocated to total
 
 // Append output paths allocated to total
-                       packages->get_package_paths(paths);
 
 // Delete package harness
                        delete packages;
 
 // Delete package harness
                        delete packages;
index 5fcff0864f614740006a36766f5e97742b763362..57309895827b3d42faef5d3c3b86d1cdf108a79f 100644 (file)
@@ -110,6 +110,7 @@ public:
        BC_Window* new_gui();
 
        int test_edl_files();
        BC_Window* new_gui();
 
        int test_edl_files();
+       int test_errmsg(BatchRenderWarnJobs &err_jobs, const char *msg, int *warn);
        void calculate_dest_paths(ArrayList<char*> *paths,
                Preferences *preferences);
        void reset(const char *path=0);
        void calculate_dest_paths(ArrayList<char*> *paths,
                Preferences *preferences);
        void reset(const char *path=0);
index f6d69734d3738741e51108abbf817f569aea8ed7..9ef9df07033529d9d04440d49d406e79658c473b 100644 (file)
@@ -25,6 +25,7 @@
 #include "edl.h"
 #include "edlsession.h"
 #include "labels.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "labels.h"
+#include "mainerror.h"
 #include "mutex.h"
 #include "mwindow.h"
 #include "packagedispatcher.h"
 #include "mutex.h"
 #include "mwindow.h"
 #include "packagedispatcher.h"
@@ -110,6 +111,11 @@ int PackageDispatcher::create_packages(MWindow *mwindow, EDL *edl,
                label = edl->labels->first;
                total_packages = 0;
                packages = new RenderPackage*[edl->labels->total() + 2];
                label = edl->labels->first;
                total_packages = 0;
                packages = new RenderPackage*[edl->labels->total() + 2];
+               if( !label ) {
+                       eprintf(_("Render file per label and no labels\n"));
+                       result = 1;
+                       break;
+               }
 
                Render::get_starting_number(default_asset->path,
                        current_number, number_start, total_digits, 3);
 
                Render::get_starting_number(default_asset->path,
                        current_number, number_start, total_digits, 3);
@@ -197,8 +203,7 @@ void PackageDispatcher::get_package_paths(ArrayList<char*> *path_list)
                        packaging_engine->get_package_paths(path_list);
                else {
                        for( int i=0; i<total_allocated; ++i )
                        packaging_engine->get_package_paths(path_list);
                else {
                        for( int i=0; i<total_allocated; ++i )
-                               path_list->append(strdup(packages[i]->path));
-                       path_list->set_free();
+                               path_list->append(cstrdup(packages[i]->path));
                }
 
 }
                }
 
 }
index 7a7d5407e9785482cca0ae46f55993bb47f98c8f..5d4875fcb1acf415518ede28d9b82fa49b82927e 100644 (file)
@@ -49,6 +49,7 @@
 #include "language.h"
 #include "loadmode.h"
 #include "localsession.h"
 #include "language.h"
 #include "loadmode.h"
 #include "localsession.h"
+#include "mainerror.h"
 #include "mainprogress.h"
 #include "mainsession.h"
 #include "mainundo.h"
 #include "mainprogress.h"
 #include "mainsession.h"
 #include "mainundo.h"
@@ -330,15 +331,24 @@ void Render::handle_close_event(int result)
                err_msg = _("zero render range");
                result = 1;
        }
                err_msg = _("zero render range");
                result = 1;
        }
+       if( !result && !asset->audio_data && !asset->video_data ) {
+               err_msg = _("no audio or video in render asset format\n");
+               result = 1;
+       }
+       EDL *edl = mwindow->edl;
+       if( !result && use_labels && !edl->labels->first ) {
+               eprintf(_("render file per label and no labels\n"));
+               result = 1;
+       }
        if( !result && asset->video_data ) {
        if( !result && asset->video_data ) {
-               double frame_rate = mwindow->edl->session->frame_rate;
+               double frame_rate = edl->session->frame_rate;
                if( frame_rate > 0 && render_range+1e-3 < 1./frame_rate ) {
                        err_msg = _("Video data and range less than 1 frame");
                        result = 1;
                }
        }
        if( !result && asset->audio_data ) {
                if( frame_rate > 0 && render_range+1e-3 < 1./frame_rate ) {
                        err_msg = _("Video data and range less than 1 frame");
                        result = 1;
                }
        }
        if( !result && asset->audio_data ) {
-               double sample_rate = mwindow->edl->session->sample_rate;
+               double sample_rate = edl->session->sample_rate;
                if( sample_rate > 0 && render_range+1e-6 < 1./sample_rate ) {
                        err_msg = _("Audio data and range less than 1 sample");
                        result = 1;
                if( sample_rate > 0 && render_range+1e-6 < 1./sample_rate ) {
                        err_msg = _("Audio data and range less than 1 sample");
                        result = 1;
@@ -346,7 +356,7 @@ void Render::handle_close_event(int result)
        }
        if( !result && File::is_image_render(asset->format) ) {
                if( asset->video_data ) {
        }
        if( !result && File::is_image_render(asset->format) ) {
                if( asset->video_data ) {
-                       double frames = render_range * mwindow->edl->session->frame_rate;
+                       double frames = render_range * edl->session->frame_rate;
                        if( !EQUIV(frames, 1.) ) {
                                err_msg = _("Image format and not 1 frame");
                                result = 1;
                        if( !EQUIV(frames, 1.) ) {
                                err_msg = _("Image format and not 1 frame");
                                result = 1;
@@ -357,6 +367,7 @@ void Render::handle_close_event(int result)
                        result = 1;
                }
        }
                        result = 1;
                }
        }
+
        if( err_msg ) {
                int cx, cy;
                mwindow->gui->get_abs_cursor(cx, cy, 1);
        if( err_msg ) {
                int cx, cy;
                mwindow->gui->get_abs_cursor(cx, cy, 1);
@@ -721,6 +732,7 @@ void RenderThread::render_single(int test_overwrite, Asset *asset, EDL *edl,
                        render->result = 1;
                }
        }
                        render->result = 1;
                }
        }
+
        render_frames = render->default_asset->frame_rate * total_length;
 
 // Generate packages
        render_frames = render->default_asset->frame_rate * total_length;
 
 // Generate packages
@@ -999,8 +1011,8 @@ void RenderWindow::create_objects()
 {
        int x = 10, y = 10;
        lock_window("RenderWindow::create_objects");
 {
        int x = 10, y = 10;
        lock_window("RenderWindow::create_objects");
-       add_subwindow(new BC_Title(x, y,
-               (char*)(render->use_labels ?
+       add_subwindow(file_format = new BC_Title(x, y,
+               (render->use_labels ?
                        _("Select the first file to render to:") :
                        _("Select a file to render to:"))));
        y += 25;
                        _("Select the first file to render to:") :
                        _("Select a file to render to:"))));
        y += 25;
@@ -1178,7 +1190,6 @@ void RenderFormat::update_format()
        FormatTools::update_format();
        RenderWindow *render_window = (RenderWindow *)window;
        if( render_window->is_hidden() ) return;
        FormatTools::update_format();
        RenderWindow *render_window = (RenderWindow *)window;
        if( render_window->is_hidden() ) return;
-
        int is_image = File::is_image_render(asset->format);
        if( is_image ) {
                render_window->update_range_type(RANGE_1FRAME);
        int is_image = File::is_image_render(asset->format);
        if( is_image ) {
                render_window->update_range_type(RANGE_1FRAME);
@@ -1187,6 +1198,15 @@ void RenderFormat::update_format()
        else
                render_window->enable_render_range(1);
 }
        else
                render_window->enable_render_range(1);
 }
+int RenderFormat::handle_event()
+{
+       RenderWindow *render_window = (RenderWindow *)window;
+       render_window->file_format->update(
+               (render_window->render->use_labels ?
+                       _("Select the first file to render to:") :
+                       _("Select a file to render to:")));
+       return 1;
+}
 
 RenderBeepOnDone::RenderBeepOnDone(RenderWindow *rwindow, int x, int y)
  : BC_CheckBox(x, y, rwindow->render->beep, _("Beep on done"))
 
 RenderBeepOnDone::RenderBeepOnDone(RenderWindow *rwindow, int x, int y)
  : BC_CheckBox(x, y, rwindow->render->beep, _("Beep on done"))
index 37c2c103c307733cf496d52cef163d9da8a90c05..d7cd443dd32fa6c99435ed4333579022f58b312c 100644 (file)
@@ -285,6 +285,7 @@ public:
        RenderFormat(MWindow *mwindow, BC_WindowBase *window, Asset *asset);
        ~RenderFormat();
        void update_format();
        RenderFormat(MWindow *mwindow, BC_WindowBase *window, Asset *asset);
        ~RenderFormat();
        void update_format();
+       int handle_event();
 };
 
 
 };
 
 
@@ -322,6 +323,7 @@ public:
        RenderProfile *renderprofile;
 
        LoadMode *loadmode;
        RenderProfile *renderprofile;
 
        LoadMode *loadmode;
+       BC_Title *file_format;
        RenderFormat *render_format;
 
        MWindow *mwindow;
        RenderFormat *render_format;
 
        MWindow *mwindow;
index ab9cf977261b71712f96966afafad16136752dd5..771b88e7845b13b7405d0ec14a20369143567d9b 100644 (file)
@@ -880,6 +880,14 @@ void TrackCanvas::draw_resources(int mode,
 
                        }
                }
 
                        }
                }
+               int64_t track_x, track_y, track_w, track_h;
+               track_dimensions(current,
+                       track_x, track_y, track_w, track_h);
+               set_color((~get_resources()->get_bg_color()) & 0xffffff);
+               set_opaque();
+               int x1 = track_x, x2 = x1+track_w;
+               int y1 = track_y+track_h-1;
+               draw_line(x1,y1, x2,y1, background_pixmap);
        }
 
 
        }
 
 
index c1007785df1342dcc2da61feb3af4b97584d6b0f..70ed4824f5821d29c418c2d69696e1a343187ca9 100644 (file)
@@ -3,9 +3,9 @@
 
 #define CINELERRA_VERSION "Infinity"
 #define REPOMAINTXT "git://git.cinelerra-gg.org/goodguy/cinelerra.git\n"
 
 #define CINELERRA_VERSION "Infinity"
 #define REPOMAINTXT "git://git.cinelerra-gg.org/goodguy/cinelerra.git\n"
-#define COPYRIGHT_DATE "2018"
-#define COPYRIGHTTEXT1 "(c) 2006-2018 Heroine Virtual Ltd. by Adam Williams\n"
-#define COPYRIGHTTEXT2 "(c) 2007-2018 cin5 derivative by W.P. Morrow aka goodguy\n"
+#define COPYRIGHT_DATE "2019"
+#define COPYRIGHTTEXT1 "(c) 2006-2019 Heroine Virtual Ltd. by Adam Williams\n"
+#define COPYRIGHTTEXT2 "(c) 2007-2019 cin5 derivative by W.P. Morrow aka goodguy\n"
 #undef COMPILEDATE
 
 #endif
 #undef COMPILEDATE
 
 #endif
index a9fd117f69c3c8dc046e712993f485f6e4405e4b..14e03257ec31154f8636589d11803493f995dfcb 100644 (file)
@@ -473,6 +473,11 @@ if test "x$I86$X86" != "x00" ; then
   rm -f conftest.asm conftest.o
   REQUIRE_PROG(YASM, [yasm])
 fi
   rm -f conftest.asm conftest.o
   REQUIRE_PROG(YASM, [yasm])
 fi
+if test "x$X86" = "x0" ; then
+  # incompatible instruction set
+  PKG_dav1d=no
+fi
+
 ## end arch dep tests
 
 REQUIRE_PROG(OBJCOPY, [objcopy])
 ## end arch dep tests
 
 REQUIRE_PROG(OBJCOPY, [objcopy])
index 1ed811e02404d712a284189761da13514f974c57..1138f800f9f882a3a26f0dac06af007587c99955 100644 (file)
@@ -109,6 +109,7 @@ Video Effects
                F_lumakey
        - Geometry
                Auto Scale
                F_lumakey
        - Geometry
                Auto Scale
+               Crop & Position
                Flip
                Lens
                Perspective
                Flip
                Lens
                Perspective
index d497af49ce303651cbcab967014a0a3499a13822..ceb8b249d8f60d7a7aa86db8692050878642f513 100644 (file)
@@ -54,6 +54,8 @@ http://www.wodgod.com/newtonator/1.0
 https://sami.boukortt.com/plugins/intersect#Intersect
 https://sami.boukortt.com/plugins/intersect#SymmetricDifference
 https://sami.boukortt.com/plugins/intersect#Upmix
 https://sami.boukortt.com/plugins/intersect#Intersect
 https://sami.boukortt.com/plugins/intersect#SymmetricDifference
 https://sami.boukortt.com/plugins/intersect#Upmix
+http://drumkv1.sourceforge.net/lv2
+http://rakarrack.sourceforge.net/effects.html#awha
 #
 # Rakarrack takes special handling to get these lv2 plugins to work;
 # the library needs to be linked using  -Bsymbolic-functions ;
 #
 # Rakarrack takes special handling to get these lv2 plugins to work;
 # the library needs to be linked using  -Bsymbolic-functions ;
index 54df92397d515116f65631c056afc1850c6194ae..d5a364b6451262d1f9ee379532dfc1b9da1abe08 100644 (file)
@@ -8,6 +8,11 @@ Cinfinity icons selected in Preferences Sam (CC BY 3.0,
 Cakewalk and Neophyte themes by Olaf Wolff (CC BY 4.0,
   https://creativecommons.org/licenses/by/4.0/)
 .
 Cakewalk and Neophyte themes by Olaf Wolff (CC BY 4.0,
   https://creativecommons.org/licenses/by/4.0/)
 .
+August 2019 New Features of note:
+  FFmpeg in use with Cinelerra is now version 4.2.
+  Lipvpx has been upgraded to version 1.8.1.
+  Dav1d is now the default/faster decoder for AV1 media.
+  Performance improvements were added for Mask feathering.
 July 2019 New Features of note:
   Completion of Masking improvements with Preset Shapes, Center
     and Normalize buttons, plus x/y scaling in 1 direction only.
 July 2019 New Features of note:
   Completion of Masking improvements with Preset Shapes, Center
     and Normalize buttons, plus x/y scaling in 1 direction only.
index 2bf29432dd7deb59cdeb6ddcfd94f0c80f8e4a1a..51b071907ce9408c1702d23c98f12321e5271f05 100644 (file)
@@ -42,6 +42,7 @@ DIRS = $(OPENCV_OBJS) \
        colorbalance \
        compressor \
        crikey \
        colorbalance \
        compressor \
        crikey \
+       crop \
        crossfade \
        dcoffset \
        decimate \
        crossfade \
        dcoffset \
        decimate \
diff --git a/cinelerra-5.1/plugins/crop/Makefile b/cinelerra-5.1/plugins/crop/Makefile
new file mode 100644 (file)
index 0000000..13cc444
--- /dev/null
@@ -0,0 +1,11 @@
+include ../../plugin_defs
+
+OBJS =         $(OBJDIR)/crop.o  \
+       $(OBJDIR)/cropwin.o
+
+PLUGIN = crop
+
+include ../../plugin_config
+
+$(OBJDIR)/crop.o: crop.C
+$(OBJDIR)/cropwin.o: cropwin.C
diff --git a/cinelerra-5.1/plugins/crop/crop.C b/cinelerra-5.1/plugins/crop/crop.C
new file mode 100644 (file)
index 0000000..d2687b7
--- /dev/null
@@ -0,0 +1,342 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+/*
+ * 2019. Derivative by Translate plugin. This plugin works also with Proxy.
+ * It uses Percent values instead of Pixel value coordinates.
+*/
+
+#include "clip.h"
+#include "filexml.h"
+#include "language.h"
+#include "crop.h"
+#include "cropwin.h"
+
+#include <string.h>
+
+
+
+
+REGISTER_PLUGIN(CropMain)
+
+CropConfig::CropConfig()
+{
+       reset(RESET_DEFAULT_SETTINGS);
+}
+
+void CropConfig::reset(int clear)
+{
+       switch(clear) {
+               case RESET_LEFT :
+                       crop_l = 0.0;
+                       break;
+               case RESET_TOP :
+                       crop_t = 0.0;
+                       break;
+               case RESET_RIGHT :
+                       crop_r = 0.0;
+                       break;
+               case RESET_BOTTOM :
+                       crop_b = 0.0;
+                       break;
+               case RESET_POSITION_X :
+                       position_x = 0.0;
+                       break;
+               case RESET_POSITION_Y :
+                       position_y = 0.0;
+                       break;
+               case RESET_ALL :
+               case RESET_DEFAULT_SETTINGS :
+               default:
+                       crop_l = 0.0;
+                       crop_t = 0.0;
+                       crop_r = 0.0;
+                       crop_b = 0.0;
+
+                       position_x = 0.0;
+                       position_y = 0.0;
+                       break;
+       }
+}
+
+
+int CropConfig::equivalent(CropConfig &that)
+{
+       return EQUIV(crop_l, that.crop_l) &&
+               EQUIV(crop_t, that.crop_t) &&
+               EQUIV(crop_r, that.crop_r) &&
+               EQUIV(crop_b, that.crop_b) &&
+               EQUIV(position_x, that.position_x) &&
+               EQUIV(position_y, that.position_y);
+}
+
+void CropConfig::copy_from(CropConfig &that)
+{
+       crop_l = that.crop_l;
+       crop_t = that.crop_t;
+       crop_r = that.crop_r;
+       crop_b = that.crop_b;
+       position_x = that.position_x;
+       position_y = that.position_y;
+}
+
+void CropConfig::interpolate(CropConfig &prev,
+       CropConfig &next,
+       int64_t prev_frame,
+       int64_t next_frame,
+       int64_t current_frame)
+{
+       double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
+       double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
+
+       this->crop_l = prev.crop_l * prev_scale + next.crop_l * next_scale;
+       this->crop_t = prev.crop_t * prev_scale + next.crop_t * next_scale;
+       this->crop_r = prev.crop_r * prev_scale + next.crop_r * next_scale;
+       this->crop_b = prev.crop_b * prev_scale + next.crop_b * next_scale;
+       this->position_x = prev.position_x * prev_scale + next.position_x * next_scale;
+       this->position_y = prev.position_y * prev_scale + next.position_y * next_scale;
+}
+
+
+
+
+
+
+
+
+CropMain::CropMain(PluginServer *server)
+ : PluginVClient(server)
+{
+       temp_frame = 0;
+       overlayer = 0;
+
+}
+
+CropMain::~CropMain()
+{
+
+
+       if(temp_frame) delete temp_frame;
+       temp_frame = 0;
+       if(overlayer) delete overlayer;
+       overlayer = 0;
+}
+
+const char* CropMain::plugin_title() { return N_("Crop & Position"); }
+int CropMain::is_realtime() { return 1; }
+
+
+
+LOAD_CONFIGURATION_MACRO(CropMain, CropConfig)
+
+void CropMain::save_data(KeyFrame *keyframe)
+{
+       FileXML output;
+
+// cause data to be stored directly in text
+       output.set_shared_output(keyframe->xbuf);
+
+// Store data
+       output.tag.set_title("CROP");
+       output.tag.set_property("LEFT", config.crop_l);
+       output.tag.set_property("TOP", config.crop_t);
+       output.tag.set_property("RIGHT", config.crop_r);
+       output.tag.set_property("BOTTOM", config.crop_b);
+       output.tag.set_property("POSITION_X", config.position_x);
+       output.tag.set_property("POSITION_Y", config.position_y);
+       output.append_tag();
+       output.tag.set_title("/CROP");
+       output.append_tag();
+       output.append_newline();
+       output.terminate_string();
+// data is now in *text
+}
+
+void CropMain::read_data(KeyFrame *keyframe)
+{
+       FileXML input;
+
+       input.set_shared_input(keyframe->xbuf);
+
+       int result = 0;
+
+       while(!result)
+       {
+               result = input.read_tag();
+
+               if(!result)
+               {
+                       if(input.tag.title_is("CROP"))
+                       {
+                               config.crop_l = input.tag.get_property("LEFT", config.crop_l);
+                               config.crop_t = input.tag.get_property("TOP", config.crop_t);
+                               config.crop_r = input.tag.get_property("RIGHT", config.crop_r);
+                               config.crop_b = input.tag.get_property("BOTTOM", config.crop_b);
+                               config.position_x = input.tag.get_property("POSITION_X", config.position_x);
+                               config.position_y = input.tag.get_property("POSITION_Y", config.position_y);
+                       }
+               }
+       }
+}
+
+
+#define EPSILON 0.001
+
+int CropMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
+{
+       VFrame *input = input_ptr;
+       VFrame *output = output_ptr;
+
+       load_configuration();
+
+//printf("CropMain::process_realtime 1 %p\n", input);
+       if( input->get_rows()[0] == output->get_rows()[0] ) {
+               if( temp_frame && (
+                   temp_frame->get_w() != input_ptr->get_w() ||
+                   temp_frame->get_h() != input_ptr->get_h() ||
+                   temp_frame->get_color_model() != input_ptr->get_color_model() ) ) {
+                       delete temp_frame;
+                       temp_frame = 0;
+               }
+               if(!temp_frame)
+                       temp_frame = new VFrame(input_ptr->get_w(), input_ptr->get_h(),
+                               input->get_color_model(), 0);
+               temp_frame->copy_from(input);
+               input = temp_frame;
+       }
+//printf("CropMain::process_realtime 2 %p\n", input);
+
+
+       if(!overlayer)
+       {
+               overlayer = new OverlayFrame(smp + 1);
+       }
+
+       output->clear_frame();
+
+/* OLD code by "Translate" plugin
+       if( config.in_w < EPSILON ) return 1;
+       if( config.in_h < EPSILON ) return 1;
+       if( config.out_w < EPSILON ) return 1;
+       if( config.out_h < EPSILON ) return 1;
+*/
+
+
+/*
+   *** Little description of the points ***
+   Points (ix1, iy1) and (ix2, iy2) are the Camera coordinates:
+     (ix1, iy1) is the point on top-left,
+     (ix2, iy2) is the point on bottom-right.
+   Points (ox1, oy1) and (ox2, oy2) are the Projector coordinates:
+     (ox1, oy1) is the point on top-left,
+     (ox2, oy2) is the point on bottom-right.
+*/
+
+// Convert from Percent to Pixel coordinate (Percent value in plugin GUI)
+// so it works also for Proxy
+       float ix1 = config.crop_l / 100 * output->get_w();
+       float ox1 = ix1;
+       ox1 += config.position_x / 100 * output->get_w();
+       float ix2 = ((100.00 - config.crop_r) / 100) * output->get_w();
+
+       if( ix1 < 0 ) {
+               ox1 -= ix1;
+               ix1 = 0;
+       }
+
+       if(ix2 > output->get_w())
+               ix2 = output->get_w();
+
+// Convert from Percent to Pixel coordinate (Percent value in plugin GUI)
+// so it works also for Proxy
+       float iy1 = config.crop_t / 100 * output->get_h();
+       float oy1 = iy1;
+       oy1 += config.position_y / 100 * output->get_h();
+       float iy2 = ((100.00 - config.crop_b) / 100) * output->get_h();
+
+       if( iy1 < 0 ) {
+               oy1 -= iy1;
+               iy1 = 0;
+       }
+
+       if( iy2 > output->get_h() )
+               iy2 = output->get_h();
+
+// Scale features: OLD code by "Translate" plugin.
+// (I leave here for future development)  
+// Scale_: scale_x=scale_y=1. It means NO SCALE.
+       float cx = 1.00;
+       float cy = cx;
+
+       float ox2 = ox1 + (ix2 - ix1) * cx;
+       float oy2 = oy1 + (iy2 - iy1) * cy;
+
+       if( ox1 < 0 ) {
+               ix1 += -ox1 / cx;
+               ox1 = 0;
+       }
+       if( oy1 < 0 ) {
+               iy1 += -oy1 / cy;
+               oy1 = 0;
+       }
+       if( ox2 > output->get_w() ) {
+               ix2 -= (ox2 - output->get_w()) / cx;
+               ox2 = output->get_w();
+       }
+       if( oy2 > output->get_h() ) {
+               iy2 -= (oy2 - output->get_h()) / cy;
+               oy2 = output->get_h();
+       }
+
+       if( ix1 >= ix2 ) return 1;
+       if( iy1 >= iy2 ) return 1;
+       if( ox1 >= ox2 ) return 1;
+       if( oy1 >= oy2 ) return 1;
+
+       overlayer->overlay(output, input,
+               ix1, iy1, ix2, iy2,
+               ox1, oy1, ox2, oy2,
+               1, TRANSFER_REPLACE,
+               get_interpolation_type());
+       return 0;
+}
+
+NEW_WINDOW_MACRO(CropMain, CropWin)
+
+void CropMain::update_gui()
+{
+       if( !thread ) return;
+       if( !load_configuration() ) return;
+
+       CropWin *window = (CropWin*)thread->window;
+       window->lock_window();
+/*
+       window->crop_l->update(config.crop_l);
+       window->crop_t->update(config.crop_t);
+       window->crop_r->update(config.crop_r);
+       window->crop_b->update(config.crop_b);
+       window->position_x->update(config.position_x);
+       window->position_y->update(config.position_y);
+*/
+       window->update(RESET_ALL);
+
+       window->unlock_window();
+}
diff --git a/cinelerra-5.1/plugins/crop/crop.h b/cinelerra-5.1/plugins/crop/crop.h
new file mode 100644 (file)
index 0000000..43cca2f
--- /dev/null
@@ -0,0 +1,78 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+/*
+ * 2019. Derivative by Translate plugin. This plugin works also with Proxy.
+ * It uses Percent values instead of Pixel value coordinates.
+*/
+
+#ifndef CROP_H
+#define CROP_H
+
+// the simplest plugin possible
+
+class CropMain;
+
+#include "bchash.h"
+#include "mutex.h"
+#include "cropwin.h"
+#include "overlayframe.h"
+#include "pluginvclient.h"
+
+class CropConfig
+{
+public:
+       CropConfig();
+       void reset(int clear);
+       int equivalent(CropConfig &that);
+       void copy_from(CropConfig &that);
+       void interpolate(CropConfig &prev,
+               CropConfig &next,
+               int64_t prev_frame,
+               int64_t next_frame,
+               int64_t current_frame);
+
+       float crop_l, crop_t, crop_r, crop_b;
+       float position_x, position_y;
+};
+
+
+class CropMain : public PluginVClient
+{
+public:
+       CropMain(PluginServer *server);
+       ~CropMain();
+
+// required for all realtime plugins
+       PLUGIN_CLASS_MEMBERS(CropConfig)
+       int process_realtime(VFrame *input_ptr, VFrame *output_ptr);
+       int is_realtime();
+       void update_gui();
+       void save_data(KeyFrame *keyframe);
+       void read_data(KeyFrame *keyframe);
+
+
+       OverlayFrame *overlayer;   // To translate images
+       VFrame *temp_frame;
+};
+
+
+#endif
diff --git a/cinelerra-5.1/plugins/crop/cropwin.C b/cinelerra-5.1/plugins/crop/cropwin.C
new file mode 100644 (file)
index 0000000..654263b
--- /dev/null
@@ -0,0 +1,550 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+/*
+ * 2019. Derivative by Translate plugin. This plugin works also with Proxy.
+ * It uses Percent values instead of Pixel value coordinates.
+*/
+
+#include "bcdisplayinfo.h"
+#include "clip.h"
+#include "language.h"
+#include "theme.h"
+#include "crop.h"
+#include "cropwin.h"
+
+
+
+
+
+
+
+
+
+
+
+
+CropWin::CropWin(CropMain *client)
+ : PluginClientWindow(client,
+       420,
+       290,
+       420,
+       290,
+       0)
+{
+       this->client = client;
+}
+
+CropWin::~CropWin()
+{
+}
+
+void CropWin::create_objects()
+{
+       int x = 10, x1 = 40, x2 = 80, x_middle= (get_w() / 2), x3 = 180;
+       int y = 10;
+       int clr_x = get_w()-x - 22; // note: clrBtn_w = 22
+
+       BC_TitleBar *title_bar;
+       BC_Bar *bar;
+
+// Crop section
+       add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Crop")));
+       y += 20;
+       add_tool(new BC_Title(x, y, _("Left")));
+       add_tool(new BC_Title((x2-x), y, _("%")));
+       crop_left_text = new CropLeftText(this, client, (x + x2), y);
+       crop_left_text->create_objects();
+       crop_left_slider = new CropLeftSlider(this, client, x3, y, 200);
+       add_subwindow(crop_left_slider);
+       clr_x = x3 + crop_left_slider->get_w() + x;
+       add_subwindow(crop_left_clr = new CropEdgesClr(this, client,
+               clr_x, y, RESET_LEFT));
+       y += 30;
+       add_tool(new BC_Title(x, y, _("Top")));
+       add_tool(new BC_Title((x2-x), y, _("%")));
+       crop_top_text = new CropTopText(this, client, (x + x2), y);
+       crop_top_text->create_objects();
+       crop_top_slider = new CropTopSlider(this, client, x3, y, 200);
+       add_subwindow(crop_top_slider);
+       add_subwindow(crop_top_clr = new CropEdgesClr(this, client,
+               clr_x, y, RESET_TOP));
+       y += 30;
+       add_tool(new BC_Title(x, y, _("Right")));
+       add_tool(new BC_Title((x2-x), y, _("%")));
+       crop_right_text = new CropRightText(this, client, (x + x2), y);
+       crop_right_text->create_objects();
+       crop_right_slider = new CropRightSlider(this, client, x3, y, 200);
+       add_subwindow(crop_right_slider);
+       add_subwindow(crop_right_clr = new CropEdgesClr(this, client,
+               clr_x, y, RESET_RIGHT));
+       y += 30;
+       add_tool(new BC_Title(x, y, _("Bottom")));
+       add_tool(new BC_Title((x2-x), y, _("%")));
+       crop_bottom_text = new CropBottomText(this, client, (x + x2), y);
+       crop_bottom_text->create_objects();
+       crop_bottom_slider = new CropBottomSlider(this, client, x3, y, 200);
+       add_subwindow(crop_bottom_slider);
+       add_subwindow(crop_bottom_clr = new CropEdgesClr(this, client,
+               clr_x, y, RESET_BOTTOM));
+       y += 40;
+
+// Position section
+       add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Position")));
+       y += 20;
+       add_tool(new BC_Title(x, y, _("X")));
+       add_tool(new BC_Title((x2-x), y, _("%")));
+       crop_position_x_text = new CropPositionXText(this, client, (x + x2), y);
+       crop_position_x_text->create_objects();
+       crop_position_x_slider = new CropPositionXSlider(this, client, x3, y, 200);
+       add_subwindow(crop_position_x_slider);
+       add_subwindow(crop_position_x_clr = new CropEdgesClr(this, client,
+               clr_x, y, RESET_POSITION_X));
+       y += 30;
+       add_tool(new BC_Title(x, y, _("Y")));
+       add_tool(new BC_Title((x2-x), y, _("%")));
+       crop_position_y_text = new CropPositionYText(this, client, (x + x2), y);
+       crop_position_y_text->create_objects();
+       crop_position_y_slider = new CropPositionYSlider(this, client, x3, y, 200);
+       add_subwindow(crop_position_y_slider);
+       add_subwindow(crop_position_y_clr = new CropEdgesClr(this, client,
+               clr_x, y, RESET_POSITION_Y));
+       y += 40;
+
+// Reset section
+       add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x));
+       y += 10;
+       add_tool(reset = new CropReset(client, this, x, y));
+
+       show_window();
+       flush();
+}
+
+void CropWin::update(int clear)
+{
+       switch(clear) {
+               case RESET_LEFT :
+                       crop_left_text->update((float)client->config.crop_l);
+                       crop_left_slider->update((float)client->config.crop_l);
+                       break;
+               case RESET_TOP :
+                       crop_top_text->update((float)client->config.crop_t);
+                       crop_top_slider->update((float)client->config.crop_t);
+                       break;
+               case RESET_RIGHT :
+                       crop_right_text->update((float)client->config.crop_r);
+                       crop_right_slider->update((float)client->config.crop_r);
+                       break;
+               case RESET_BOTTOM :
+                       crop_bottom_text->update((float)client->config.crop_b);
+                       crop_bottom_slider->update((float)client->config.crop_b);
+                       break;
+               case RESET_POSITION_X :
+                       crop_position_x_text->update((float)client->config.position_x);
+                       crop_position_x_slider->update((float)client->config.position_x);
+                       break;
+               case RESET_POSITION_Y :
+                       crop_position_y_text->update((float)client->config.position_y);
+                       crop_position_y_slider->update((float)client->config.position_y);
+                       break;
+               case RESET_ALL :
+               case RESET_DEFAULT_SETTINGS :
+               default:
+                       crop_left_text->update((float)client->config.crop_l);
+                       crop_left_slider->update((float)client->config.crop_l);
+                       crop_top_text->update((float)client->config.crop_t);
+                       crop_top_slider->update((float)client->config.crop_t);
+                       crop_right_text->update((float)client->config.crop_r);
+                       crop_right_slider->update((float)client->config.crop_r);
+                       crop_bottom_text->update((float)client->config.crop_b);
+                       crop_bottom_slider->update((float)client->config.crop_b);
+
+                       crop_position_x_text->update((float)client->config.position_x);
+                       crop_position_x_slider->update((float)client->config.position_x);
+                       crop_position_y_text->update((float)client->config.position_y);
+                       crop_position_y_slider->update((float)client->config.position_y);
+                       break;
+       }
+}
+
+
+
+
+
+
+
+/* *********************************** */
+/* **** CROP LEFT ******************** */
+CropLeftText::CropLeftText(CropWin *win,
+       CropMain *client,
+       int x,
+       int y)
+ : BC_TumbleTextBox(win,
+       client->config.crop_l,
+       (float)0.00,
+       (float)100.00,
+       x,
+       y,
+       60, 2)
+{
+       this->win = win;
+       this->client = client;
+}
+
+CropLeftText::~CropLeftText()
+{
+}
+
+int CropLeftText::handle_event()
+{
+       client->config.crop_l = atof(get_text());
+       win->crop_left_slider->update(client->config.crop_l);
+       client->send_configure_change();
+       return 1;
+}
+
+CropLeftSlider::CropLeftSlider(CropWin *win, CropMain *client,
+       int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, 0.00, 100.00, client->config.crop_l)
+{
+       this->win = win;
+       this->client = client;
+       enable_show_value(0); // Hide caption
+       set_precision(0.01);
+}
+
+CropLeftSlider::~CropLeftSlider()
+{
+}
+
+int CropLeftSlider::handle_event()
+{
+       client->config.crop_l = get_value();
+       win->crop_left_text->update(client->config.crop_l);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
+/* *********************************** */
+
+/* *********************************** */
+/* **** CROP TOP  ******************** */
+CropTopText::CropTopText(CropWin *win,
+       CropMain *client,
+       int x,
+       int y)
+ : BC_TumbleTextBox(win,
+       client->config.crop_t,
+       (float)0.00,
+       (float)100.00,
+       x,
+       y,
+       60, 2)
+{
+       this->win = win;
+       this->client = client;
+}
+
+CropTopText::~CropTopText()
+{
+}
+
+int CropTopText::handle_event()
+{
+       client->config.crop_t = atof(get_text());
+       win->crop_top_slider->update(client->config.crop_t);
+       client->send_configure_change();
+       return 1;
+}
+
+CropTopSlider::CropTopSlider(CropWin *win, CropMain *client,
+       int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, 0.00, 100.00, client->config.crop_t)
+{
+       this->win = win;
+       this->client = client;
+       enable_show_value(0); // Hide caption
+       set_precision(0.01);
+}
+
+CropTopSlider::~CropTopSlider()
+{
+}
+
+int CropTopSlider::handle_event()
+{
+       client->config.crop_t = get_value();
+       win->crop_top_text->update(client->config.crop_t);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
+/* *********************************** */
+
+/* *********************************** */
+/* **** CROP RIGHT ******************* */
+CropRightText::CropRightText(CropWin *win, CropMain *client,
+       int x,
+       int y)
+ : BC_TumbleTextBox(win,
+       client->config.crop_r,
+       (float)0.00,
+       (float)100.00,
+       x,
+       y,
+       60, 2)
+{
+       this->win = win;
+       this->client = client;
+}
+
+CropRightText::~CropRightText()
+{
+}
+
+int CropRightText::handle_event()
+{
+       client->config.crop_r = atof(get_text());
+       win->crop_right_slider->update(client->config.crop_r);
+       client->send_configure_change();
+       return 1;
+}
+
+CropRightSlider::CropRightSlider(CropWin *win, CropMain *client,
+       int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, 0.00, 100.00, client->config.crop_r)
+{
+       this->win = win;
+       this->client = client;
+       enable_show_value(0); // Hide caption
+       set_precision(0.01);
+}
+
+CropRightSlider::~CropRightSlider()
+{
+}
+
+int CropRightSlider::handle_event()
+{
+       client->config.crop_r = get_value();
+       win->crop_right_text->update(client->config.crop_r);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
+/* *********************************** */
+
+/* *********************************** */
+/* **** CROP BOTTOM ****************** */
+CropBottomText::CropBottomText(CropWin *win, CropMain *client,
+       int x,
+       int y)
+ : BC_TumbleTextBox(win,
+       client->config.crop_b,
+       (float)0.00,
+       (float)100.00,
+       x,
+       y,
+       60, 2)
+{
+       this->win = win;
+       this->client = client;
+}
+
+CropBottomText::~CropBottomText()
+{
+}
+
+int CropBottomText::handle_event()
+{
+       client->config.crop_b = atof(get_text());
+       win->crop_bottom_slider->update(client->config.crop_b);
+       client->send_configure_change();
+       return 1;
+}
+
+CropBottomSlider::CropBottomSlider(CropWin *win, CropMain *client,
+       int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, 0.00, 100.00, client->config.crop_b)
+{
+       this->win = win;
+       this->client = client;
+       enable_show_value(0); // Hide caption
+       set_precision(0.01);
+}
+
+CropBottomSlider::~CropBottomSlider()
+{
+}
+
+int CropBottomSlider::handle_event()
+{
+       client->config.crop_b = get_value();
+       win->crop_bottom_text->update(client->config.crop_b);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
+/* *********************************** */
+
+/* *********************************** */
+/* **** CROP POSITION X ************** */
+CropPositionXText::CropPositionXText(CropWin *win, CropMain *client,
+       int x,
+       int y)
+ : BC_TumbleTextBox(win,
+       client->config.position_x,
+       (float)-100.00,
+       (float)100.00,
+       x,
+       y,
+       60, 2)
+{
+       this->win = win;
+       this->client = client;
+}
+
+CropPositionXText::~CropPositionXText()
+{
+}
+
+int CropPositionXText::handle_event()
+{
+       client->config.position_x = atof(get_text());
+       win->crop_position_x_slider->update(client->config.position_x);
+       client->send_configure_change();
+       return 1;
+}
+
+CropPositionXSlider::CropPositionXSlider(CropWin *win, CropMain *client,
+       int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, -100.00, 100.00, client->config.position_x)
+{
+       this->win = win;
+       this->client = client;
+       enable_show_value(0); // Hide caption
+       set_precision(0.01);
+}
+
+CropPositionXSlider::~CropPositionXSlider()
+{
+}
+
+int CropPositionXSlider::handle_event()
+{
+       client->config.position_x = get_value();
+       win->crop_position_x_text->update(client->config.position_x);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
+/* *********************************** */
+
+/* *********************************** */
+/* **** CROP POSITION Y ************** */
+CropPositionYText::CropPositionYText(CropWin *win, CropMain *client,
+       int x,
+       int y)
+ : BC_TumbleTextBox(win,
+       client->config.position_y,
+       (float)-100.00,
+       (float)100.00,
+       x,
+       y,
+       60, 2)
+{
+       this->win = win;
+       this->client = client;
+}
+
+CropPositionYText::~CropPositionYText()
+{
+}
+
+int CropPositionYText::handle_event()
+{
+       client->config.position_y = atof(get_text());
+       win->crop_position_y_slider->update(client->config.position_y);
+       client->send_configure_change();
+       return 1;
+}
+
+CropPositionYSlider::CropPositionYSlider(CropWin *win, CropMain *client,
+       int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, -100.00, 100.00, client->config.position_y)
+{
+       this->win = win;
+       this->client = client;
+       enable_show_value(0); // Hide caption
+       set_precision(0.01);
+}
+
+CropPositionYSlider::~CropPositionYSlider()
+{
+}
+
+int CropPositionYSlider::handle_event()
+{
+       client->config.position_y = get_value();
+       win->crop_position_y_text->update(client->config.position_y);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
+/* *********************************** */
+
+
+CropEdgesClr::CropEdgesClr(CropWin *win, CropMain *client, int x, int y, int clear)
+ : BC_Button(x, y, client->get_theme()->get_image_set("reset_button"))
+{
+       this->win = win;
+       this->client = client;
+       this->clear = clear;
+}
+CropEdgesClr::~CropEdgesClr()
+{
+}
+int CropEdgesClr::handle_event()
+{
+       client->config.reset(clear);
+       win->update(clear);
+       client->send_configure_change();
+       return 1;
+}
+
+CropReset::CropReset(CropMain *client, CropWin *win, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+       this->client = client;
+       this->win = win;
+}
+
+CropReset::~CropReset()
+{
+}
+
+int CropReset::handle_event()
+{
+       client->config.reset(RESET_ALL);
+       win->update(RESET_ALL);
+       client->send_configure_change();
+       return 1;
+}
diff --git a/cinelerra-5.1/plugins/crop/cropwin.h b/cinelerra-5.1/plugins/crop/cropwin.h
new file mode 100644 (file)
index 0000000..80561d8
--- /dev/null
@@ -0,0 +1,270 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+/*
+ * 2019. Derivative by Translate plugin. This plugin works also with Proxy.
+ * It uses Percent values instead of Pixel value coordinates.
+*/
+
+#ifndef CROPWIN_H
+#define CROPWIN_H
+
+
+class CropThread;
+class CropWin;
+class CropLeftText;
+class CropLeftSlider;
+class CropTopText;
+class CropTopSlider;
+class CropRightText;
+class CropRightSlider;
+class CropBottomText;
+class CropBottomSlider;
+class CropPositionXText;
+class CropPositionXSlider;
+class CropPositionYText;
+class CropPositionYSlider;
+class CropReset;
+class CropEdgesClr;
+
+#include "guicast.h"
+#include "filexml.h"
+#include "mutex.h"
+#include "pluginclient.h"
+#include "crop.h"
+
+#define RESET_DEFAULT_SETTINGS 10
+#define RESET_ALL    0
+#define RESET_LEFT   1
+#define RESET_TOP    2
+#define RESET_RIGHT  3
+#define RESET_BOTTOM 4
+#define RESET_POSITION_X 5
+#define RESET_POSITION_Y 6
+
+
+class CropWin : public PluginClientWindow
+{
+public:
+       CropWin(CropMain *client);
+       ~CropWin();
+
+       void create_objects();
+       void update(int clear);
+
+       // Crop: Left, Top, Right, Bottom
+       CropLeftText *crop_left_text;
+       CropLeftSlider *crop_left_slider;
+       CropEdgesClr *crop_left_clr;
+
+       CropTopText *crop_top_text;
+       CropTopSlider *crop_top_slider;
+       CropEdgesClr *crop_top_clr;
+
+       CropRightText *crop_right_text;
+       CropRightSlider *crop_right_slider;
+       CropEdgesClr *crop_right_clr;
+
+       CropBottomText *crop_bottom_text;
+       CropBottomSlider *crop_bottom_slider;
+       CropEdgesClr *crop_bottom_clr;
+
+       // Crop: Position_X, Position_Y
+       CropPositionXText *crop_position_x_text;
+       CropPositionXSlider *crop_position_x_slider;
+       CropEdgesClr *crop_position_x_clr;
+
+       CropPositionYText *crop_position_y_text;
+       CropPositionYSlider *crop_position_y_slider;
+       CropEdgesClr *crop_position_y_clr;
+
+       CropMain *client;
+       CropReset *reset;
+};
+
+
+class CropLeftText : public BC_TumbleTextBox
+{
+public:
+       CropLeftText(CropWin *win,
+               CropMain *client,
+               int x,
+               int y);
+       ~CropLeftText();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+class CropLeftSlider : public BC_FSlider
+{
+public:
+       CropLeftSlider(CropWin *win, CropMain *client,
+               int x, int y, int w);
+       ~CropLeftSlider();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+};
+
+class CropTopText : public BC_TumbleTextBox
+{
+public:
+       CropTopText(CropWin *win,
+               CropMain *client,
+               int x,
+               int y);
+       ~CropTopText();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+class CropTopSlider : public BC_FSlider
+{
+public:
+       CropTopSlider(CropWin *win, CropMain *client,
+               int x, int y, int w);
+       ~CropTopSlider();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+};
+
+class CropRightText : public BC_TumbleTextBox
+{
+public:
+       CropRightText(CropWin *win,
+               CropMain *client,
+               int x,
+               int y);
+       ~CropRightText();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+class CropRightSlider : public BC_FSlider
+{
+public:
+       CropRightSlider(CropWin *win, CropMain *client,
+               int x, int y, int w);
+       ~CropRightSlider();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+};
+
+class CropBottomText : public BC_TumbleTextBox
+{
+public:
+       CropBottomText(CropWin *win,
+               CropMain *client,
+               int x,
+               int y);
+       ~CropBottomText();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+class CropBottomSlider : public BC_FSlider
+{
+public:
+       CropBottomSlider(CropWin *win, CropMain *client,
+               int x, int y, int w);
+       ~CropBottomSlider();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+};
+
+class CropPositionXText : public BC_TumbleTextBox
+{
+public:
+       CropPositionXText(CropWin *win,
+               CropMain *client,
+               int x,
+               int y);
+       ~CropPositionXText();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+class CropPositionXSlider : public BC_FSlider
+{
+public:
+       CropPositionXSlider(CropWin *win, CropMain *client,
+               int x, int y, int w);
+       ~CropPositionXSlider();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+};
+
+class CropPositionYText : public BC_TumbleTextBox
+{
+public:
+       CropPositionYText(CropWin *win,
+               CropMain *client,
+               int x,
+               int y);
+       ~CropPositionYText();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+class CropPositionYSlider : public BC_FSlider
+{
+public:
+       CropPositionYSlider(CropWin *win, CropMain *client,
+               int x, int y, int w);
+       ~CropPositionYSlider();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+};
+
+class CropEdgesClr : public BC_Button
+{
+public:
+       CropEdgesClr(CropWin *win, CropMain *client,
+               int x, int y, int clear);
+       ~CropEdgesClr();
+       int handle_event();
+       CropWin *win;
+       CropMain *client;
+       int clear;
+};
+
+class CropReset : public BC_GenericButton
+{
+public:
+       CropReset(CropMain *client, CropWin *win, int x, int y);
+       ~CropReset();
+       int handle_event();
+       CropMain *client;
+       CropWin *win;
+};
+
+#endif
index 2b0c152b947b92175ff6e1a026a15d586059d642..11df06ed211d16cbc4bbd574f6b3d2ebefa1b452 100644 (file)
@@ -30,8 +30,9 @@ https://download.osgeo.org/libtiff/tiff-4.0.10.tar.gz
 https://sourceforge.net/projects/libuuid/files/latest/download?source=directory - 1.0.3
 ftp://ftp.videolan.org/pub/x264/snapshots/x264-snapshot-20190131-2245-stable.tar.bz2
 https://bitbucket.org/multicoreware/x265/downloads/x265_3.0.tar.gz
 https://sourceforge.net/projects/libuuid/files/latest/download?source=directory - 1.0.3
 ftp://ftp.videolan.org/pub/x264/snapshots/x264-snapshot-20190131-2245-stable.tar.bz2
 https://bitbucket.org/multicoreware/x265/downloads/x265_3.0.tar.gz
-http://ffmpeg.org/releases/ffmpeg-4.1.tar.gz
-https://github.com/webmproject/libvpx/releases/tag/v1.7.0
+https://ffmpeg.org/releases/ffmpeg-4.2.tar.bz2
+https://github.com/webmproject/libvpx/archive/v1.8.1.tar.gz
+https://code.videolan.org/videolan/dav1d/-/archive/0.4.0/dav1d-0.4.0.tar.gz
 https://github.com/swh/ladspa/releases/tag/v0.4.17, plugin.org.uk
 https://archive.mozilla.org/pub/opus/opus-1.3.tar.gz
 https://github.com/webmproject/libwebp = libwebp-1.0.2
 https://github.com/swh/ladspa/releases/tag/v0.4.17, plugin.org.uk
 https://archive.mozilla.org/pub/opus/opus-1.3.tar.gz
 https://github.com/webmproject/libwebp = libwebp-1.0.2