edl plugin names eng, fix segv for opengl brender, renderfarm rework strategy, perf...
[goodguy/history.git] / cinelerra-5.1 / plugins / bandwipe / bandwipe.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 "bandwipe.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
35
36
37
38
39
40 REGISTER_PLUGIN(BandWipeMain)
41
42
43
44
45
46 BandWipeCount::BandWipeCount(BandWipeMain *plugin,
47         BandWipeWindow *window,
48         int x,
49         int y)
50  : BC_TumbleTextBox(window,
51                 (int64_t)plugin->bands,
52                 (int64_t)0,
53                 (int64_t)1000,
54                 x,
55                 y,
56                 50)
57 {
58         this->plugin = plugin;
59         this->window = window;
60 }
61
62 int BandWipeCount::handle_event()
63 {
64         plugin->bands = atol(get_text());
65         plugin->send_configure_change();
66         return 0;
67 }
68
69
70 BandWipeIn::BandWipeIn(BandWipeMain *plugin,
71         BandWipeWindow *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 BandWipeIn::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 BandWipeOut::BandWipeOut(BandWipeMain *plugin,
93         BandWipeWindow *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 BandWipeOut::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 BandWipeWindow::BandWipeWindow(BandWipeMain *plugin)
121  : PluginClientWindow(plugin,
122         320,
123         50,
124         320,
125         50,
126         0)
127 {
128         this->plugin = plugin;
129 }
130
131
132 void BandWipeWindow::create_objects()
133 {
134         int x = 10, y = 10;
135         add_subwindow(new BC_Title(x, y, _("Bands:")));
136         x += 50;
137         count = new BandWipeCount(plugin,
138                 this,
139                 x,
140                 y);
141         count->create_objects();
142 //      y += 30;
143 //      add_subwindow(new BC_Title(x, y, _("Direction:")));
144 //      x += 100;
145 //      add_subwindow(in = new BandWipeIn(plugin,
146 //              this,
147 //              x,
148 //              y));
149 //      x += 100;
150 //      x = 10;
151 //      add_subwindow(out = new BandWipeOut(plugin,
152 //              this,
153 //              x,
154 //              y));
155
156         show_window();
157         flush();
158 }
159
160
161
162
163
164
165
166
167
168 BandWipeMain::BandWipeMain(PluginServer *server)
169  : PluginVClient(server)
170 {
171         bands = 9;
172         direction = 0;
173
174 }
175
176 BandWipeMain::~BandWipeMain()
177 {
178
179 }
180
181 const char* BandWipeMain::plugin_title() { return N_("BandWipe"); }
182 int BandWipeMain::is_transition() { return 1; }
183 int BandWipeMain::uses_gui() { return 1; }
184
185 NEW_WINDOW_MACRO(BandWipeMain, BandWipeWindow);
186
187
188 void BandWipeMain::save_data(KeyFrame *keyframe)
189 {
190         FileXML output;
191         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
192         output.tag.set_title("BANDWIPE");
193         output.tag.set_property("BANDS", bands);
194         output.tag.set_property("DIRECTION", direction);
195         output.append_tag();
196         output.tag.set_title("/BANDWIPE");
197         output.append_tag();
198         output.append_newline();
199         output.terminate_string();
200 }
201
202 void BandWipeMain::read_data(KeyFrame *keyframe)
203 {
204         FileXML input;
205
206         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
207
208         while(!input.read_tag())
209         {
210                 if(input.tag.title_is("BANDWIPE"))
211                 {
212                         bands = input.tag.get_property("BANDS", bands);
213                         direction = input.tag.get_property("DIRECTION", direction);
214                 }
215         }
216 }
217
218 int BandWipeMain::load_configuration()
219 {
220         read_data(get_prev_keyframe(get_source_position()));
221         return 1;
222 }
223
224
225
226 #define BANDWIPE(type, components) \
227 { \
228         if(direction == 0) \
229         { \
230                 int x = w * \
231                         PluginClient::get_source_position() / \
232                         PluginClient::get_total_len(); \
233  \
234                 for(int i = 0; i < bands; i++) \
235                 { \
236                         for(int j = 0; j < band_h; j++) \
237                         { \
238                                 int row = i * band_h + j; \
239                                  \
240                                 if(row >= 0 && row < h) \
241                                 { \
242                                         type *in_row = (type*)incoming->get_rows()[row]; \
243                                         type *out_row = (type*)outgoing->get_rows()[row]; \
244  \
245                                         if(i % 2) \
246                                         { \
247                                                 for(int k = 0; k < x; k++) \
248                                                 { \
249                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
250                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
251                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
252                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
253                                                 } \
254                                         } \
255                                         else \
256                                         { \
257                                                 for(int k = w - x; k < w; k++) \
258                                                 { \
259                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
260                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
261                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
262                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
263                                                 } \
264                                         } \
265                                 } \
266                         } \
267                 } \
268         } \
269         else \
270         { \
271                 int x = w - w * \
272                         PluginClient::get_source_position() / \
273                         PluginClient::get_total_len(); \
274  \
275                 for(int i = 0; i < bands; i++) \
276                 { \
277                         for(int j = 0; j < band_h; j++) \
278                         { \
279                                 int row = i * band_h + j; \
280                                  \
281                                 if(row >= 0 && row < h) \
282                                 { \
283                                         type *in_row = (type*)incoming->get_rows()[row]; \
284                                         type *out_row = (type*)outgoing->get_rows()[row]; \
285  \
286                                         if(i % 2) \
287                                         { \
288                                                 for(int k = x; k < w; k++) \
289                                                 { \
290                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
291                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
292                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
293                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
294                                                 } \
295                                         } \
296                                         else \
297                                         { \
298                                                 for(int k = 0; k < w - x; k++) \
299                                                 { \
300                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
301                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
302                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
303                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
304                                                 } \
305                                         } \
306                                 } \
307                         } \
308                 } \
309         } \
310 }
311
312
313
314 int BandWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
315 {
316         load_configuration();
317
318         int w = incoming->get_w();
319         int h = incoming->get_h();
320         int band_h = ((bands == 0) ? h : (h / bands + 1));
321
322         switch(incoming->get_color_model())
323         {
324                 case BC_RGB888:
325                 case BC_YUV888:
326                         BANDWIPE(unsigned char, 3)
327                         break;
328                 case BC_RGB_FLOAT:
329                         BANDWIPE(float, 3);
330                         break;
331                 case BC_RGBA8888:
332                 case BC_YUVA8888:
333                         BANDWIPE(unsigned char, 4)
334                         break;
335                 case BC_RGBA_FLOAT:
336                         BANDWIPE(float, 4);
337                         break;
338                 case BC_RGB161616:
339                 case BC_YUV161616:
340                         BANDWIPE(uint16_t, 3)
341                         break;
342                 case BC_RGBA16161616:
343                 case BC_YUVA16161616:
344                         BANDWIPE(uint16_t, 4)
345                         break;
346         }
347
348         return 0;
349 }