edl plugin names eng, fix segv for opengl brender, renderfarm rework strategy, perf...
[goodguy/history.git] / cinelerra-5.1 / plugins / bandslide / bandslide.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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 "bandslide.h"
23 #include "bcdisplayinfo.h"
24 #include "bchash.h"
25 #include "edl.inc"
26 #include "filexml.h"
27 #include "language.h"
28 #include "overlayframe.h"
29 #include "vframe.h"
30
31
32 #include <stdint.h>
33 #include <string.h>
34 #include <libintl.h>
35
36
37
38
39
40
41 REGISTER_PLUGIN(BandSlideMain)
42
43
44
45
46
47 BandSlideCount::BandSlideCount(BandSlideMain *plugin,
48         BandSlideWindow *window,
49         int x,
50         int y)
51  : BC_TumbleTextBox(window,
52                 (int64_t)plugin->bands,
53                 (int64_t)0,
54                 (int64_t)1000,
55                 x,
56                 y,
57                 50)
58 {
59         this->plugin = plugin;
60         this->window = window;
61 }
62
63 int BandSlideCount::handle_event()
64 {
65         plugin->bands = atol(get_text());
66         plugin->send_configure_change();
67         return 0;
68 }
69
70 BandSlideIn::BandSlideIn(BandSlideMain *plugin,
71         BandSlideWindow *window,
72         int x,
73         int y)
74  : BC_Radial(x,
75                 y,
76                 plugin->direction == 0,
77                 _("In"))
78 {
79         this->plugin = plugin;
80         this->window = window;
81 }
82
83 int BandSlideIn::handle_event()
84 {
85         update(1);
86         plugin->direction = 0;
87         window->out->update(0);
88         plugin->send_configure_change();
89         return 0;
90 }
91
92 BandSlideOut::BandSlideOut(BandSlideMain *plugin,
93         BandSlideWindow *window,
94         int x,
95         int y)
96  : BC_Radial(x,
97                 y,
98                 plugin->direction == 1,
99                 _("Out"))
100 {
101         this->plugin = plugin;
102         this->window = window;
103 }
104
105 int BandSlideOut::handle_event()
106 {
107         update(1);
108         plugin->direction = 1;
109         window->in->update(0);
110         plugin->send_configure_change();
111         return 0;
112 }
113
114
115
116
117
118
119
120
121 BandSlideWindow::BandSlideWindow(BandSlideMain *plugin)
122  : PluginClientWindow(plugin,
123         320,
124         100,
125         320,
126         100,
127         0)
128 {
129         this->plugin = plugin;
130 }
131
132
133 void BandSlideWindow::create_objects()
134 {
135         int x = 10, y = 10;
136         add_subwindow(new BC_Title(x, y, _("Bands:")));
137         x += 50;
138         count = new BandSlideCount(plugin,
139                 this,
140                 x,
141                 y);
142         count->create_objects();
143
144         y += 30;
145         x = 10;
146         add_subwindow(new BC_Title(x, y, _("Direction:")));
147         x += 100;
148         add_subwindow(in = new BandSlideIn(plugin,
149                 this,
150                 x,
151                 y));
152         x += 100;
153         add_subwindow(out = new BandSlideOut(plugin,
154                 this,
155                 x,
156                 y));
157
158         show_window();
159         flush();
160 }
161
162
163
164
165
166
167
168
169
170
171 BandSlideMain::BandSlideMain(PluginServer *server)
172  : PluginVClient(server)
173 {
174         bands = 9;
175         direction = 0;
176
177 }
178
179 BandSlideMain::~BandSlideMain()
180 {
181
182 }
183
184 const char* BandSlideMain::plugin_title() { return N_("BandSlide"); }
185 int BandSlideMain::is_transition() { return 1; }
186 int BandSlideMain::uses_gui() { return 1; }
187
188 NEW_WINDOW_MACRO(BandSlideMain, BandSlideWindow);
189
190
191 void BandSlideMain::save_data(KeyFrame *keyframe)
192 {
193         FileXML output;
194         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
195         output.tag.set_title("BANDSLIDE");
196         output.tag.set_property("BANDS", bands);
197         output.tag.set_property("DIRECTION", direction);
198         output.append_tag();
199         output.tag.set_title("/BANDSLIDE");
200         output.append_tag();
201         output.append_newline();
202         output.terminate_string();
203 }
204
205 void BandSlideMain::read_data(KeyFrame *keyframe)
206 {
207         FileXML input;
208
209         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
210
211         while(!input.read_tag())
212         {
213                 if(input.tag.title_is("BANDSLIDE"))
214                 {
215                         bands = input.tag.get_property("BANDS", bands);
216                         direction = input.tag.get_property("DIRECTION", direction);
217                 }
218         }
219 }
220
221 int BandSlideMain::load_configuration()
222 {
223         read_data(get_prev_keyframe(get_source_position()));
224         return 1;
225 }
226
227
228
229 #define BANDSLIDE(type, components) \
230 { \
231         if(direction == 0) \
232         { \
233                 int x = w * \
234                         PluginClient::get_source_position() / \
235                         PluginClient::get_total_len(); \
236                 for(int i = 0; i < bands; i++) \
237                 { \
238                         for(int j = 0; j < band_h; j++) \
239                         { \
240                                 int row = i * band_h + j; \
241                                  \
242                                 if(row >= 0 && row < h) \
243                                 { \
244                                         type *in_row = (type*)incoming->get_rows()[row]; \
245                                         type *out_row = (type*)outgoing->get_rows()[row]; \
246                                          \
247                                         if(i % 2) \
248                                         { \
249                                                 for(int k = 0, l = w - x; k < x; k++, l++) \
250                                                 { \
251                                                         out_row[k * components + 0] = in_row[l * components + 0]; \
252                                                         out_row[k * components + 1] = in_row[l * components + 1]; \
253                                                         out_row[k * components + 2] = in_row[l * components + 2]; \
254                                                         if(components == 4) out_row[k * components + 3] = in_row[l * components + 3]; \
255                                                 } \
256                                         } \
257                                         else \
258                                         { \
259                                                 for(int k = w - x, l = 0; k < w; k++, l++) \
260                                                 { \
261                                                         out_row[k * components + 0] = in_row[l * components + 0]; \
262                                                         out_row[k * components + 1] = in_row[l * components + 1]; \
263                                                         out_row[k * components + 2] = in_row[l * components + 2]; \
264                                                         if(components == 4) out_row[k * components + 3] = in_row[l * components + 3]; \
265                                                 } \
266                                         } \
267                                 } \
268                         } \
269                 } \
270         } \
271         else \
272         { \
273                 int x = w - w * \
274                         PluginClient::get_source_position() / \
275                         PluginClient::get_total_len(); \
276                 for(int i = 0; i < bands; i++) \
277                 { \
278                         for(int j = 0; j < band_h; j++) \
279                         { \
280                                 int row = i * band_h + j; \
281  \
282                                 if(row >= 0 && row < h) \
283                                 { \
284                                         type *in_row = (type*)incoming->get_rows()[row]; \
285                                         type *out_row = (type*)outgoing->get_rows()[row]; \
286  \
287                                         if(i % 2) \
288                                         { \
289                                                 int k, l; \
290                                                 for(k = 0, l = w - x; k < x; k++, l++) \
291                                                 { \
292                                                         out_row[k * components + 0] = out_row[l * components + 0]; \
293                                                         out_row[k * components + 1] = out_row[l * components + 1]; \
294                                                         out_row[k * components + 2] = out_row[l * components + 2]; \
295                                                         if(components == 4) out_row[k * components + 3] = out_row[l * components + 3]; \
296                                                 } \
297                                                 for( ; k < w; k++) \
298                                                 { \
299                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
300                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
301                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
302                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
303                                                 } \
304                                         } \
305                                         else \
306                                         { \
307                                                 for(int k = w - 1, l = x - 1; k >= w - x; k--, l--) \
308                                                 { \
309                                                         out_row[k * components + 0] = out_row[l * components + 0]; \
310                                                         out_row[k * components + 1] = out_row[l * components + 1]; \
311                                                         out_row[k * components + 2] = out_row[l * components + 2]; \
312                                                         if(components == 4) out_row[k * components + 3] = out_row[l * components + 3]; \
313                                                 } \
314                                                 for(int k = 0; k < w - x; k++) \
315                                                 { \
316                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
317                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
318                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
319                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
320                                                 } \
321                                         } \
322                                 } \
323                         } \
324                 } \
325         } \
326 }
327
328
329
330 int BandSlideMain::process_realtime(VFrame *incoming, VFrame *outgoing)
331 {
332         load_configuration();
333
334         int w = incoming->get_w();
335         int h = incoming->get_h();
336         int band_h = ((bands == 0) ? h : (h / bands + 1));
337
338         switch(incoming->get_color_model())
339         {
340                 case BC_RGB888:
341                 case BC_YUV888:
342                         BANDSLIDE(unsigned char, 3)
343                         break;
344                 case BC_RGB_FLOAT:
345                         BANDSLIDE(float, 3);
346                         break;
347                 case BC_RGBA8888:
348                 case BC_YUVA8888:
349                         BANDSLIDE(unsigned char, 4)
350                         break;
351                 case BC_RGBA_FLOAT:
352                         BANDSLIDE(float, 4);
353                         break;
354                 case BC_RGB161616:
355                 case BC_YUV161616:
356                         BANDSLIDE(uint16_t, 3)
357                         break;
358                 case BC_RGBA16161616:
359                 case BC_YUVA16161616:
360                         BANDSLIDE(uint16_t, 4)
361                         break;
362         }
363
364         return 0;
365 }