2 * GreyCStoration plugin for Cinelerra
3 * Copyright (C) 2013 Slock Ruddy
4 * Copyright (C) 2014-2015 Nicola Ferralis <feranick at hotmail dot com>
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.
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.
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
23 #include "bccmodels.h"
26 #include "greycstorationplugin.h"
27 #include "greycstorationwindow.h"
35 #define cimg_plugin "greycstoration.h"
38 using namespace cimg_library;
40 REGISTER_PLUGIN(GreyCStorationMain)
43 GreyCStorationConfig::GreyCStorationConfig()
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)");
51 void GreyCStorationConfig::copy_from(GreyCStorationConfig &that)
53 amplitude = that.amplitude;
54 sharpness = that.sharpness;
55 anisotropy = that.anisotropy;
56 noise_scale = that.noise_scale;
59 int GreyCStorationConfig::equivalent(GreyCStorationConfig &that)
62 anisotropy == that.anisotropy &&
63 sharpness == that.sharpness &&
64 noise_scale == that.noise_scale &&
65 amplitude == that.amplitude;
68 void GreyCStorationConfig::interpolate(GreyCStorationConfig &prev,
69 GreyCStorationConfig &next,
72 int64_t current_frame)
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;
84 GreyCStorationMain::GreyCStorationMain(PluginServer *server)
85 : PluginVClient(server)
91 GreyCStorationMain::~GreyCStorationMain()
96 const char* GreyCStorationMain::plugin_title() { return N_("GreyCStoration"); }
97 int GreyCStorationMain::is_realtime() { return 1; }
100 void GreyCStorationMain::
101 GREYCSTORATION(VFrame *frame)
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();
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]; }
124 img_colormodel = BC_RGBA_FLOATP;
126 BC_CModels::transfer(
127 imgp, img_colormodel, 0,0, w,h, w,
128 frmp, frm_colormodel, 0,0, w,h, w, 0);
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;
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,
156 BC_CModels::transfer(
157 frmp, frm_colormodel, 0,0, w,h, w,
158 imgp, img_colormodel, 0,0, w,h, w, 0);
161 int GreyCStorationMain::process_buffer(VFrame *frame,
162 int64_t start_position, double frame_rate)
164 load_configuration();
165 read_frame(frame, 0, get_source_position(), get_framerate(), get_use_opengl());
166 GREYCSTORATION(frame);
171 NEW_WINDOW_MACRO(GreyCStorationMain, GreyCStorationWindow)
172 LOAD_CONFIGURATION_MACRO(GreyCStorationMain, GreyCStorationConfig)
174 void GreyCStorationMain::update_gui()
177 load_configuration();
178 GreyCStorationWindow *wdw = (GreyCStorationWindow*)thread->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();
188 // these will end up into your project file (xml)
189 void GreyCStorationMain::save_data(KeyFrame *keyframe)
193 // cause data to be stored directly in text
194 output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
195 output.tag.set_title("GREYCSTORATION");
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);
203 output.tag.set_title("/GREYCSTORATION");
205 output.terminate_string();
206 // data is now in *text
209 void GreyCStorationMain::read_data(KeyFrame *keyframe)
212 input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
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);