r864: Merge 2.1:
[cinelerra_cv.git] / plugins / bandwipe / bandwipe.C
blob798cf134c9c3f72bba30c724a6a8bfab6e39f4d3
1 #include "bandwipe.h"
2 #include "bcdisplayinfo.h"
3 #include "bchash.h"
4 #include "edl.inc"
5 #include "filexml.h"
6 #include "language.h"
7 #include "overlayframe.h"
8 #include "picon_png.h"
9 #include "vframe.h"
12 #include <stdint.h>
13 #include <string.h>
20 REGISTER_PLUGIN(BandWipeMain)
26 BandWipeCount::BandWipeCount(BandWipeMain *plugin, 
27         BandWipeWindow *window,
28         int x,
29         int y)
30  : BC_TumbleTextBox(window, 
31                 (int64_t)plugin->bands,
32                 (int64_t)0,
33                 (int64_t)1000,
34                 x, 
35                 y, 
36                 50)
38         this->plugin = plugin;
39         this->window = window;
42 int BandWipeCount::handle_event()
44         plugin->bands = atol(get_text());
45         plugin->send_configure_change();
46         return 0;
50 BandWipeIn::BandWipeIn(BandWipeMain *plugin, 
51         BandWipeWindow *window,
52         int x,
53         int y)
54  : BC_Radial(x, 
55                 y, 
56                 plugin->direction == 0, 
57                 _("In"))
59         this->plugin = plugin;
60         this->window = window;
63 int BandWipeIn::handle_event()
65         update(1);
66         plugin->direction = 0;
67         window->out->update(0);
68         plugin->send_configure_change();
69         return 0;
72 BandWipeOut::BandWipeOut(BandWipeMain *plugin, 
73         BandWipeWindow *window,
74         int x,
75         int y)
76  : BC_Radial(x, 
77                 y, 
78                 plugin->direction == 1, 
79                 _("Out"))
81         this->plugin = plugin;
82         this->window = window;
85 int BandWipeOut::handle_event()
87         update(1);
88         plugin->direction = 1;
89         window->in->update(0);
90         plugin->send_configure_change();
91         return 0;
100 BandWipeWindow::BandWipeWindow(BandWipeMain *plugin, int x, int y)
101  : BC_Window(plugin->gui_string, 
102         x, 
103         y, 
104         320, 
105         50, 
106         320, 
107         50, 
108         0, 
109         0,
110         1)
112         this->plugin = plugin;
116 int BandWipeWindow::close_event()
118         set_done(1);
119         return 1;
122 void BandWipeWindow::create_objects()
124         int x = 10, y = 10;
125         add_subwindow(new BC_Title(x, y, _("Bands:")));
126         x += 50;
127         count = new BandWipeCount(plugin, 
128                 this,
129                 x,
130                 y);
131         count->create_objects();
132 //      y += 30;
133 //      add_subwindow(new BC_Title(x, y, _("Direction:")));
134 //      x += 100;
135 //      add_subwindow(in = new BandWipeIn(plugin, 
136 //              this,
137 //              x,
138 //              y));
139 //      x += 100;
140 //      x = 10;
141 //      add_subwindow(out = new BandWipeOut(plugin, 
142 //              this,
143 //              x,
144 //              y));
145         
146         show_window();
147         flush();
153 PLUGIN_THREAD_OBJECT(BandWipeMain, BandWipeThread, BandWipeWindow)
160 BandWipeMain::BandWipeMain(PluginServer *server)
161  : PluginVClient(server)
163         bands = 9;
164         direction = 0;
165         PLUGIN_CONSTRUCTOR_MACRO
168 BandWipeMain::~BandWipeMain()
170         PLUGIN_DESTRUCTOR_MACRO
173 char* BandWipeMain::plugin_title() { return N_("BandWipe"); }
174 int BandWipeMain::is_video() { return 1; }
175 int BandWipeMain::is_transition() { return 1; }
176 int BandWipeMain::uses_gui() { return 1; }
178 SHOW_GUI_MACRO(BandWipeMain, BandWipeThread);
179 SET_STRING_MACRO(BandWipeMain)
180 RAISE_WINDOW_MACRO(BandWipeMain)
183 VFrame* BandWipeMain::new_picon()
185         return new VFrame(picon_png);
188 int BandWipeMain::load_defaults()
190         char directory[BCTEXTLEN];
191 // set the default directory
192         sprintf(directory, "%sbandwipe.rc", BCASTDIR);
194 // load the defaults
195         defaults = new BC_Hash(directory);
196         defaults->load();
198         bands = defaults->get("BANDS", bands);
199         direction = defaults->get("DIRECTION", direction);
200         return 0;
203 int BandWipeMain::save_defaults()
205         defaults->update("BANDS", bands);
206         defaults->update("DIRECTION", direction);
207         defaults->save();
208         return 0;
211 void BandWipeMain::save_data(KeyFrame *keyframe)
213         FileXML output;
214         output.set_shared_string(keyframe->data, MESSAGESIZE);
215         output.tag.set_title("BANDWIPE");
216         output.tag.set_property("BANDS", bands);
217         output.tag.set_property("DIRECTION", direction);
218         output.append_tag();
219         output.terminate_string();
222 void BandWipeMain::read_data(KeyFrame *keyframe)
224         FileXML input;
226         input.set_shared_string(keyframe->data, strlen(keyframe->data));
228         while(!input.read_tag())
229         {
230                 if(input.tag.title_is("BANDWIPE"))
231                 {
232                         bands = input.tag.get_property("BANDS", bands);
233                         direction = input.tag.get_property("DIRECTION", direction);
234                 }
235         }
238 void BandWipeMain::load_configuration()
240         read_data(get_prev_keyframe(get_source_position()));
245 #define BANDWIPE(type, components) \
246 { \
247         if(direction == 0) \
248         { \
249                 int x = w * \
250                         PluginClient::get_source_position() / \
251                         PluginClient::get_total_len(); \
253                 for(int i = 0; i < bands; i++) \
254                 { \
255                         for(int j = 0; j < band_h; j++) \
256                         { \
257                                 int row = i * band_h + j; \
258                                  \
259                                 if(row >= 0 && row < h) \
260                                 { \
261                                         type *in_row = (type*)incoming->get_rows()[row]; \
262                                         type *out_row = (type*)outgoing->get_rows()[row]; \
264                                         if(i % 2) \
265                                         { \
266                                                 for(int k = 0; k < x; k++) \
267                                                 { \
268                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
269                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
270                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
271                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
272                                                 } \
273                                         } \
274                                         else \
275                                         { \
276                                                 for(int k = w - x; k < w; k++) \
277                                                 { \
278                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
279                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
280                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
281                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
282                                                 } \
283                                         } \
284                                 } \
285                         } \
286                 } \
287         } \
288         else \
289         { \
290                 int x = w - w * \
291                         PluginClient::get_source_position() / \
292                         PluginClient::get_total_len(); \
294                 for(int i = 0; i < bands; i++) \
295                 { \
296                         for(int j = 0; j < band_h; j++) \
297                         { \
298                                 int row = i * band_h + j; \
299                                  \
300                                 if(row >= 0 && row < h) \
301                                 { \
302                                         type *in_row = (type*)incoming->get_rows()[row]; \
303                                         type *out_row = (type*)outgoing->get_rows()[row]; \
305                                         if(i % 2) \
306                                         { \
307                                                 for(int k = x; k < w; k++) \
308                                                 { \
309                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
310                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
311                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
312                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
313                                                 } \
314                                         } \
315                                         else \
316                                         { \
317                                                 for(int k = 0; k < w - x; k++) \
318                                                 { \
319                                                         out_row[k * components + 0] = in_row[k * components + 0]; \
320                                                         out_row[k * components + 1] = in_row[k * components + 1]; \
321                                                         out_row[k * components + 2] = in_row[k * components + 2]; \
322                                                         if(components == 4) out_row[k * components + 3] = in_row[k * components + 3]; \
323                                                 } \
324                                         } \
325                                 } \
326                         } \
327                 } \
328         } \
333 int BandWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing)
335         load_configuration();
337         int w = incoming->get_w();
338         int h = incoming->get_h();
339         int band_h = ((bands == 0) ? h : (h / bands + 1));
341         switch(incoming->get_color_model())
342         {
343                 case BC_RGB888:
344                 case BC_YUV888:
345                         BANDWIPE(unsigned char, 3)
346                         break;
347                 case BC_RGB_FLOAT:
348                         BANDWIPE(float, 3);
349                         break;
350                 case BC_RGBA8888:
351                 case BC_YUVA8888:
352                         BANDWIPE(unsigned char, 4)
353                         break;
354                 case BC_RGBA_FLOAT:
355                         BANDWIPE(float, 4);
356                         break;
357                 case BC_RGB161616:
358                 case BC_YUV161616:
359                         BANDWIPE(uint16_t, 3)
360                         break;
361                 case BC_RGBA16161616:
362                 case BC_YUVA16161616:
363                         BANDWIPE(uint16_t, 4)
364                         break;
365         }
367         return 0;