71b1d722ef4b6f7b947a88e6353489a57e4dfb63
[goodguy/history.git] / cinelerra-5.1 / plugins / wipe / wipe.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 "bcdisplayinfo.h"
23 #include "bchash.h"
24 #include "edl.inc"
25 #include "filexml.h"
26 #include "language.h"
27 #include "overlayframe.h"
28 #include "vframe.h"
29 #include "wipe.h"
30
31
32 #include <stdint.h>
33 #include <string.h>
34
35
36 REGISTER_PLUGIN(WipeMain)
37
38
39
40
41
42 WipeLeft::WipeLeft(WipeMain *plugin,
43         WipeWindow *window,
44         int x,
45         int y)
46  : BC_Radial(x,
47                 y,
48                 plugin->direction == 0,
49                 _("Left"))
50 {
51         this->plugin = plugin;
52         this->window = window;
53 }
54
55 int WipeLeft::handle_event()
56 {
57         update(1);
58         plugin->direction = 0;
59         window->right->update(0);
60         plugin->send_configure_change();
61         return 0;
62 }
63
64 WipeRight::WipeRight(WipeMain *plugin,
65         WipeWindow *window,
66         int x,
67         int y)
68  : BC_Radial(x,
69                 y,
70                 plugin->direction == 1,
71                 _("Right"))
72 {
73         this->plugin = plugin;
74         this->window = window;
75 }
76
77 int WipeRight::handle_event()
78 {
79         update(1);
80         plugin->direction = 1;
81         window->left->update(0);
82         plugin->send_configure_change();
83         return 0;
84 }
85
86
87
88
89
90
91
92
93 WipeWindow::WipeWindow(WipeMain *plugin)
94  : PluginClientWindow(plugin,
95         320,
96         50,
97         320,
98         50,
99         0)
100 {
101         this->plugin = plugin;
102 }
103
104
105
106
107 void WipeWindow::create_objects()
108 {
109         int x = 10, y = 10;
110         add_subwindow(new BC_Title(x, y, _("Direction:")));
111         x += 100;
112         add_subwindow(left = new WipeLeft(plugin,
113                 this,
114                 x,
115                 y));
116         x += 100;
117         add_subwindow(right = new WipeRight(plugin,
118                 this,
119                 x,
120                 y));
121         show_window();
122         flush();
123 }
124
125
126
127
128
129
130
131
132
133
134 WipeMain::WipeMain(PluginServer *server)
135  : PluginVClient(server)
136 {
137         direction = 0;
138
139 }
140
141 WipeMain::~WipeMain()
142 {
143
144 }
145
146 const char* WipeMain::plugin_title() { return N_("Wipe"); }
147 int WipeMain::is_video() { return 1; }
148 int WipeMain::is_transition() { return 1; }
149 int WipeMain::uses_gui() { return 1; }
150
151 NEW_WINDOW_MACRO(WipeMain, WipeWindow)
152
153
154 void WipeMain::save_data(KeyFrame *keyframe)
155 {
156         FileXML output;
157         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
158         output.tag.set_title("WIPE");
159         output.tag.set_property("DIRECTION", direction);
160         output.append_tag();
161         output.tag.set_title("/WIPE");
162         output.append_tag();
163         output.append_newline();
164         output.terminate_string();
165 }
166
167 void WipeMain::read_data(KeyFrame *keyframe)
168 {
169         FileXML input;
170
171         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
172
173         while(!input.read_tag())
174         {
175                 if(input.tag.title_is("WIPE"))
176                 {
177                         direction = input.tag.get_property("DIRECTION", direction);
178                 }
179         }
180 }
181
182 int WipeMain::load_configuration()
183 {
184         read_data(get_prev_keyframe(get_source_position()));
185         return 1;
186 }
187
188
189
190
191
192
193 #define WIPE(type, components) \
194 { \
195         if(direction == 0) \
196         { \
197                 for(int j = 0; j < h; j++) \
198                 { \
199                         type *in_row = (type*)incoming->get_rows()[j]; \
200                         type *out_row = (type*)outgoing->get_rows()[j]; \
201                         int x = incoming->get_w() *  \
202                                 PluginClient::get_source_position() /  \
203                                 PluginClient::get_total_len(); \
204  \
205                         for(int k = 0; k < x; k++) \
206                         { \
207                                 out_row[k * components + 0] = in_row[k * components + 0]; \
208                                 out_row[k * components + 1] = in_row[k * components + 1]; \
209                                 out_row[k * components + 2] = in_row[k * components + 2]; \
210                                 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
211                         } \
212                 } \
213         } \
214         else \
215         { \
216                 for(int j = 0; j < h; j++) \
217                 { \
218                         type *in_row = (type*)incoming->get_rows()[j]; \
219                         type *out_row = (type*)outgoing->get_rows()[j]; \
220                         int x = incoming->get_w() - incoming->get_w() *  \
221                                 PluginClient::get_source_position() /  \
222                                 PluginClient::get_total_len(); \
223  \
224                         for(int k = x; k < w; k++) \
225                         { \
226                                 out_row[k * components + 0] = in_row[k * components + 0]; \
227                                 out_row[k * components + 1] = in_row[k * components + 1]; \
228                                 out_row[k * components + 2] = in_row[k * components + 2]; \
229                                 if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
230                         } \
231                 } \
232         } \
233 }
234
235
236
237
238
239 int WipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
240 {
241         load_configuration();
242
243         int w = incoming->get_w();
244         int h = incoming->get_h();
245
246
247         switch(incoming->get_color_model())
248         {
249                 case BC_RGB_FLOAT:
250                         WIPE(float, 3)
251                         break;
252                 case BC_RGB888:
253                 case BC_YUV888:
254                         WIPE(unsigned char, 3)
255                         break;
256                 case BC_RGBA_FLOAT:
257                         WIPE(float, 4)
258                         break;
259                 case BC_RGBA8888:
260                 case BC_YUVA8888:
261                         WIPE(unsigned char, 4)
262                         break;
263                 case BC_RGB161616:
264                 case BC_YUV161616:
265                         WIPE(uint16_t, 3)
266                         break;
267                 case BC_RGBA16161616:
268                 case BC_YUVA16161616:
269                         WIPE(uint16_t, 4)
270                         break;
271         }
272         return 0;
273 }