edl plugin names eng, fix segv for opengl brender, renderfarm rework strategy, perf...
[goodguy/history.git] / cinelerra-5.1 / plugins / greycstoration / greycstorationplugin.C
1 /*
2  * GreyCStoration plugin for Cinelerra
3  * Copyright (C) 2013 Slock Ruddy
4  * Copyright (C) 2014-2015 Nicola Ferralis <feranick at hotmail dot com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "clip.h"
23 #include "bccmodels.h"
24 #include "bchash.h"
25 #include "filexml.h"
26 #include "greycstorationplugin.h"
27 #include "greycstorationwindow.h"
28 #include "language.h"
29 #include "vframe.h"
30
31
32 #include <stdint.h>
33 #include <string.h>
34
35 #define cimg_plugin "greycstoration.h"
36 #include "CImg.h"
37
38 using namespace cimg_library;
39
40 REGISTER_PLUGIN(GreyCStorationMain)
41
42
43 GreyCStorationConfig::GreyCStorationConfig()
44 {
45         amplitude    = 40.0f; //cimg_option("-dt",40.0f,"Regularization strength for one iteration (>=0)");
46         sharpness    = 0.8f; // cimg_option("-p",0.8f,"Contour preservation for regularization (>=0)");
47         anisotropy   = 0.8f; // cimg_option("-a",0.8f,"Regularization anisotropy (0<=a<=1)");
48         noise_scale = 0.8f; // const float alpha = 0.6f; // cimg_option("-alpha",0.6f,"Noise scale(>=0)");
49 }
50
51 void GreyCStorationConfig::copy_from(GreyCStorationConfig &that)
52 {
53         amplitude = that.amplitude;
54         sharpness = that.sharpness;
55         anisotropy = that.anisotropy;
56         noise_scale = that.noise_scale;
57 }
58
59 int GreyCStorationConfig::equivalent(GreyCStorationConfig &that)
60 {
61         return
62                 anisotropy == that.anisotropy &&
63                 sharpness == that.sharpness &&
64                 noise_scale == that.noise_scale &&
65                 amplitude == that.amplitude;
66 }
67
68 void GreyCStorationConfig::interpolate(GreyCStorationConfig &prev,
69         GreyCStorationConfig &next,
70         int64_t prev_frame,
71         int64_t next_frame,
72         int64_t current_frame)
73 {
74         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
75         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
76         this->amplitude = prev.amplitude * prev_scale + next.amplitude * next_scale;
77         this->sharpness = prev.sharpness * prev_scale + next.sharpness * next_scale;
78         this->anisotropy = prev.anisotropy * prev_scale + next.anisotropy * next_scale;
79         this->noise_scale = prev.noise_scale * prev_scale + next.noise_scale * next_scale;
80 }
81
82
83
84 GreyCStorationMain::GreyCStorationMain(PluginServer *server)
85  : PluginVClient(server)
86 {
87         alpha = 0;
88         alpha_size = 0;
89 }
90
91 GreyCStorationMain::~GreyCStorationMain()
92 {
93         delete [] alpha;
94 }
95
96 const char* GreyCStorationMain::plugin_title() { return N_("GreyCStoration"); }
97 int GreyCStorationMain::is_realtime() { return 1; }
98
99
100 void GreyCStorationMain::
101 GREYCSTORATION(VFrame *frame)
102 {
103         int w = frame->get_w(), h = frame->get_h();
104         CImg<float> image(w,h,1,3);
105         int frm_colormodel = frame->get_color_model();
106         int components = BC_CModels::components(frm_colormodel);
107         uint8_t *frm[components], **frmp = frm;
108         if( BC_CModels::is_planar(frm_colormodel) ) {
109                 frmp[0] = frame->get_y();
110                 frmp[1] = frame->get_u();
111                 frmp[2] = frame->get_v();
112         }
113         else
114                 frmp = frame->get_rows();
115         uint8_t *img[components], **imgp = img;
116         for( int i=0; i<3; ++i )
117                 imgp[i] = (uint8_t *)image.data(0,0,0,i);
118         int img_colormodel = BC_RGB_FLOATP;
119         if( BC_CModels::has_alpha(frm_colormodel) ) {
120                 int sz = w*h*components * sizeof(float);
121                 if( sz != alpha_size ) { delete [] alpha; alpha = 0; }
122                 if( !alpha ) { alpha = new uint8_t[alpha_size = sz]; }
123                 imgp[3] = alpha;
124                 img_colormodel = BC_RGBA_FLOATP;
125         }
126         BC_CModels::transfer(
127                 imgp, img_colormodel, 0,0, w,h, w,
128                 frmp, frm_colormodel, 0,0, w,h, w, 0);
129
130 //cimg_option("-iter",3,"Number of regularization iterations (>0)");
131 //      const unsigned int nb_iter  = 1;
132 // cimg_option("-sigma",1.1f,"Geometry regularity (>=0)");
133         const float sigma           = 1.1f;
134 // cimg_option("-fast",true,"Use fast approximation for regularization (0 or 1)");
135         const bool fast_approx      = false;
136 // cimg_option("-prec",2.0f,"Precision of the gaussian function for regularization (>0)");
137         const float gauss_prec      = 2.0f;
138 // cimg_option("-dl",0.8f,"Spatial integration step for regularization (0<=dl<=1)");
139         const float dl              = 0.8f;
140 // cimg_option("-da",30.0f,"Angular integration step for regulatization (0<=da<=90)");
141         const float da              = 30.0f;
142 // cimg_option("-interp",0,"Interpolation type (0=Nearest-neighbor, 1=Linear, 2=Runge-Kutta)");
143         const unsigned int interp   = 0;
144 // cimg_option("-tile",0,"Use tiled mode (reduce memory usage");
145         const unsigned int tile     = 0;
146 // cimg_option("-btile",4,"Size of tile overlapping regions");
147         const unsigned int btile    = 4;
148 //cimg_option("-threads",1,"Number of threads used");
149         const unsigned int threads  = 0;
150
151         image.greycstoration_run(config.amplitude, config.sharpness,
152                 config.anisotropy, config.noise_scale, sigma, 1.0f,
153                 dl, da, gauss_prec, interp, fast_approx, tile, btile,
154                 threads);
155
156         BC_CModels::transfer(
157                 frmp, frm_colormodel, 0,0, w,h, w,
158                 imgp, img_colormodel, 0,0, w,h, w, 0);
159 }
160
161 int GreyCStorationMain::process_buffer(VFrame *frame,
162                 int64_t start_position, double frame_rate)
163 {
164         load_configuration();
165         read_frame(frame, 0, get_source_position(), get_framerate(), get_use_opengl());
166         GREYCSTORATION(frame);
167         return 0;
168 }
169
170
171 NEW_WINDOW_MACRO(GreyCStorationMain, GreyCStorationWindow)
172 LOAD_CONFIGURATION_MACRO(GreyCStorationMain, GreyCStorationConfig)
173
174 void GreyCStorationMain::update_gui()
175 {
176         if(thread) {
177                 load_configuration();
178                 GreyCStorationWindow *wdw = (GreyCStorationWindow*)thread->window;
179                 wdw->lock_window();
180                 wdw->greycamp_slider->update((int)config.amplitude);
181                 wdw->greycsharp_slider->update(config.sharpness);
182                 wdw->greycani_slider->update(config.anisotropy);
183                 wdw->greycnoise_slider->update(config.noise_scale);
184                 wdw->unlock_window();
185         }
186 }
187
188 // these will end up into your project file (xml)
189 void GreyCStorationMain::save_data(KeyFrame *keyframe)
190 {
191         FileXML output;
192
193 // cause data to be stored directly in text
194         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
195         output.tag.set_title("GREYCSTORATION");
196
197         output.tag.set_property("AMPLITUDE", config.amplitude);
198         output.tag.set_property("SHARPNESS", config.sharpness);
199         output.tag.set_property("ANISOTROPHY", config.anisotropy);
200         output.tag.set_property("NOISE_SCALE", config.noise_scale);
201         output.append_tag();
202
203         output.tag.set_title("/GREYCSTORATION");
204         output.append_tag();
205         output.terminate_string();
206 // data is now in *text
207 }
208
209 void GreyCStorationMain::read_data(KeyFrame *keyframe)
210 {
211         FileXML input;
212         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
213
214         while( !input.read_tag() ) {
215                 if(input.tag.title_is("GREYCSTORATION")) {
216                         config.amplitude = input.tag.get_property("AMPLITUDE", config.amplitude);
217                         config.sharpness = input.tag.get_property("SHARPNESS", config.sharpness);
218                         config.anisotropy = input.tag.get_property("ANISOTROPHY", config.anisotropy);
219                         config.noise_scale = input.tag.get_property("NOISE_SCALE", config.noise_scale);
220                 }
221         }
222 }
223