initial commit
[goodguy/history.git] / cinelerra-5.0 / 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.terminate_string();
197 }
198
199 void BandWipeMain::read_data(KeyFrame *keyframe)
200 {
201         FileXML input;
202
203         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
204
205         while(!input.read_tag())
206         {
207                 if(input.tag.title_is("BANDWIPE"))
208                 {
209                         bands = input.tag.get_property("BANDS", bands);
210                         direction = input.tag.get_property("DIRECTION", direction);
211                 }
212         }
213 }
214
215 int BandWipeMain::load_configuration()
216 {
217         read_data(get_prev_keyframe(get_source_position()));
218         return 1;
219 }
220
221
222
223 #define BANDWIPE(type, components) \
224 { \
225         if(direction == 0) \
226         { \
227                 int x = w * \
228                         PluginClient::get_source_position() / \
229                         PluginClient::get_total_len(); \
230  \
231                 for(int i = 0; i < bands; i++) \
232                 { \
233                         for(int j = 0; j < band_h; j++) \
234                         { \
235                                 int row = i * band_h + j; \
236                                  \
237                                 if(row >= 0 && row < h) \
238                                 { \
239                                         type *in_row = (type*)incoming->get_rows()[row]; \
240                                         type *out_row = (type*)outgoing->get_rows()[row]; \
241  \
242                                         if(i % 2) \
243                                         { \
244                                                 for(int k = 0; k < x; k++) \
245                                                 { \
246                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
247                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
248                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
249                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
250                                                 } \
251                                         } \
252                                         else \
253                                         { \
254                                                 for(int k = w - x; k < w; k++) \
255                                                 { \
256                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
257                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
258                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
259                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
260                                                 } \
261                                         } \
262                                 } \
263                         } \
264                 } \
265         } \
266         else \
267         { \
268                 int x = w - w * \
269                         PluginClient::get_source_position() / \
270                         PluginClient::get_total_len(); \
271  \
272                 for(int i = 0; i < bands; i++) \
273                 { \
274                         for(int j = 0; j < band_h; j++) \
275                         { \
276                                 int row = i * band_h + j; \
277                                  \
278                                 if(row >= 0 && row < h) \
279                                 { \
280                                         type *in_row = (type*)incoming->get_rows()[row]; \
281                                         type *out_row = (type*)outgoing->get_rows()[row]; \
282  \
283                                         if(i % 2) \
284                                         { \
285                                                 for(int k = x; k < w; k++) \
286                                                 { \
287                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
288                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
289                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
290                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
291                                                 } \
292                                         } \
293                                         else \
294                                         { \
295                                                 for(int k = 0; k < w - x; k++) \
296                                                 { \
297                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
298                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
299                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
300                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
301                                                 } \
302                                         } \
303                                 } \
304                         } \
305                 } \
306         } \
307 }
308
309
310
311 int BandWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
312 {
313         load_configuration();
314
315         int w = incoming->get_w();
316         int h = incoming->get_h();
317         int band_h = ((bands == 0) ? h : (h / bands + 1));
318
319         switch(incoming->get_color_model())
320         {
321                 case BC_RGB888:
322                 case BC_YUV888:
323                         BANDWIPE(unsigned char, 3)
324                         break;
325                 case BC_RGB_FLOAT:
326                         BANDWIPE(float, 3);
327                         break;
328                 case BC_RGBA8888:
329                 case BC_YUVA8888:
330                         BANDWIPE(unsigned char, 4)
331                         break;
332                 case BC_RGBA_FLOAT:
333                         BANDWIPE(float, 4);
334                         break;
335                 case BC_RGB161616:
336                 case BC_YUV161616:
337                         BANDWIPE(uint16_t, 3)
338                         break;
339                 case BC_RGBA16161616:
340                 case BC_YUVA16161616:
341                         BANDWIPE(uint16_t, 4)
342                         break;
343         }
344
345         return 0;
346 }