Andrew contribution to add preference method for Fast/Slow speed
[goodguy/cinelerra.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                 xS(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         xS(320),
123         yS(50),
124         xS(320),
125         yS(50),
126         0)
127 {
128         this->plugin = plugin;
129 }
130
131
132 void BandWipeWindow::create_objects()
133 {
134         int xs50 = xS(50);
135         int x = xS(10), y = yS(10);
136         add_subwindow(new BC_Title(x, y, _("Bands:")));
137         x += xs50;
138         count = new BandWipeCount(plugin,
139                 this,
140                 x,
141                 y);
142         count->create_objects();
143 //      y += yS(30);
144 //      add_subwindow(new BC_Title(x, y, _("Direction:")));
145 //      x += yS(100);
146 //      add_subwindow(in = new BandWipeIn(plugin,
147 //              this,
148 //              x,
149 //              y));
150 //      x += xS(100);
151 //      x = xS(10);
152 //      add_subwindow(out = new BandWipeOut(plugin,
153 //              this,
154 //              x,
155 //              y));
156
157         show_window();
158         flush();
159 }
160
161
162
163
164
165
166
167
168
169 BandWipeMain::BandWipeMain(PluginServer *server)
170  : PluginVClient(server)
171 {
172         bands = 9;
173         direction = 0;
174
175 }
176
177 BandWipeMain::~BandWipeMain()
178 {
179
180 }
181
182 const char* BandWipeMain::plugin_title() { return N_("BandWipe"); }
183 int BandWipeMain::is_transition() { return 1; }
184 int BandWipeMain::uses_gui() { return 1; }
185
186 NEW_WINDOW_MACRO(BandWipeMain, BandWipeWindow);
187
188
189 void BandWipeMain::save_data(KeyFrame *keyframe)
190 {
191         FileXML output;
192         output.set_shared_output(keyframe->xbuf);
193         output.tag.set_title("BANDWIPE");
194         output.tag.set_property("BANDS", bands);
195         output.tag.set_property("DIRECTION", direction);
196         output.append_tag();
197         output.tag.set_title("/BANDWIPE");
198         output.append_tag();
199         output.append_newline();
200         output.terminate_string();
201 }
202
203 void BandWipeMain::read_data(KeyFrame *keyframe)
204 {
205         FileXML input;
206
207         input.set_shared_input(keyframe->xbuf);
208
209         while(!input.read_tag())
210         {
211                 if(input.tag.title_is("BANDWIPE"))
212                 {
213                         bands = input.tag.get_property("BANDS", bands);
214                         direction = input.tag.get_property("DIRECTION", direction);
215                 }
216         }
217 }
218
219 int BandWipeMain::load_configuration()
220 {
221         read_data(get_prev_keyframe(get_source_position()));
222         return 1;
223 }
224
225
226
227 #define BANDWIPE(type, components) \
228 { \
229         if(direction == 0) \
230         { \
231                 int x = w * \
232                         PluginClient::get_source_position() / \
233                         PluginClient::get_total_len(); \
234  \
235                 for(int i = 0; i < bands; i++) \
236                 { \
237                         for(int j = 0; j < band_h; j++) \
238                         { \
239                                 int row = i * band_h + j; \
240                                  \
241                                 if(row >= 0 && row < h) \
242                                 { \
243                                         type *in_row = (type*)incoming->get_rows()[row]; \
244                                         type *out_row = (type*)outgoing->get_rows()[row]; \
245  \
246                                         if(i % 2) \
247                                         { \
248                                                 for(int k = 0; k < x; k++) \
249                                                 { \
250                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
251                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
252                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
253                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
254                                                 } \
255                                         } \
256                                         else \
257                                         { \
258                                                 for(int k = w - x; k < w; k++) \
259                                                 { \
260                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
261                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
262                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
263                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
264                                                 } \
265                                         } \
266                                 } \
267                         } \
268                 } \
269         } \
270         else \
271         { \
272                 int x = w - w * \
273                         PluginClient::get_source_position() / \
274                         PluginClient::get_total_len(); \
275  \
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                                                 for(int k = x; k < w; k++) \
290                                                 { \
291                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
292                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
293                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
294                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
295                                                 } \
296                                         } \
297                                         else \
298                                         { \
299                                                 for(int k = 0; k < w - x; k++) \
300                                                 { \
301                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
302                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
303                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
304                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
305                                                 } \
306                                         } \
307                                 } \
308                         } \
309                 } \
310         } \
311 }
312
313
314
315 int BandWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
316 {
317         load_configuration();
318
319         int w = incoming->get_w();
320         int h = incoming->get_h();
321         int band_h = ((bands == 0) ? h : (h / bands + 1));
322
323         switch(incoming->get_color_model())
324         {
325                 case BC_RGB888:
326                 case BC_YUV888:
327                         BANDWIPE(unsigned char, 3)
328                         break;
329                 case BC_RGB_FLOAT:
330                         BANDWIPE(float, 3);
331                         break;
332                 case BC_RGBA8888:
333                 case BC_YUVA8888:
334                         BANDWIPE(unsigned char, 4)
335                         break;
336                 case BC_RGBA_FLOAT:
337                         BANDWIPE(float, 4);
338                         break;
339                 case BC_RGB161616:
340                 case BC_YUV161616:
341                         BANDWIPE(uint16_t, 3)
342                         break;
343                 case BC_RGBA16161616:
344                 case BC_YUVA16161616:
345                         BANDWIPE(uint16_t, 4)
346                         break;
347         }
348
349         return 0;
350 }