Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / plugins / flip / flip.C
blob4806c35221abbce15c925fc02105e0483b3d428b
1 #include "clip.h"
2 #include "colormodels.h"
3 #include "bchash.h"
4 #include "filexml.h"
5 #include "flip.h"
6 #include "flipwindow.h"
7 #include "language.h"
8 #include "picon_png.h"
10 #include <stdint.h>
11 #include <string.h>
13 REGISTER_PLUGIN(FlipMain)
20 FlipConfig::FlipConfig()
22         flip_horizontal = 0;
23         flip_vertical = 0;
26 void FlipConfig::copy_from(FlipConfig &that)
28         flip_horizontal = that.flip_horizontal;
29         flip_vertical = that.flip_vertical;
32 int FlipConfig::equivalent(FlipConfig &that)
34         return flip_horizontal == that.flip_horizontal &&
35                 flip_vertical == that.flip_vertical;
38 void FlipConfig::interpolate(FlipConfig &prev, 
39         FlipConfig &next, 
40         long prev_frame, 
41         long next_frame, 
42         long current_frame)
44         this->flip_horizontal = prev.flip_horizontal;
45         this->flip_vertical = prev.flip_vertical;
57 FlipMain::FlipMain(PluginServer *server)
58  : PluginVClient(server)
60         PLUGIN_CONSTRUCTOR_MACRO
63 FlipMain::~FlipMain()
65         PLUGIN_DESTRUCTOR_MACRO
68 char* FlipMain::plugin_title() { return N_("Flip"); }
69 int FlipMain::is_realtime() { return 1; }
70         
72 #define SWAP_PIXELS(type, components, in, out) \
73 { \
74         type temp = in[0]; \
75         in[0] = out[0]; \
76         out[0] = temp; \
77  \
78         temp = in[1]; \
79         in[1] = out[1]; \
80         out[1] = temp; \
81  \
82         temp = in[2]; \
83         in[2] = out[2]; \
84         out[2] = temp; \
85  \
86         if(components == 4) \
87         { \
88                 temp = in[3]; \
89                 in[3] = out[3]; \
90                 out[3] = temp; \
91         } \
94 #define FLIP_MACRO(type, components) \
95 { \
96         type **input_rows, **output_rows; \
97         type *input_row, *output_row; \
98         input_rows = ((type**)frame->get_rows()); \
99         output_rows = ((type**)frame->get_rows()); \
101         if(config.flip_vertical) \
102         { \
103                 for(i = 0, j = h - 1; i < h / 2; i++, j--) \
104                 { \
105                         input_row = input_rows[i]; \
106                         output_row = output_rows[j]; \
107                         for(k = 0; k < w; k++) \
108                         { \
109                                 SWAP_PIXELS(type, components, output_row, input_row); \
110                                 output_row += components; \
111                                 input_row += components; \
112                         } \
113                 } \
114         } \
116         if(config.flip_horizontal) \
117         { \
118                 for(i = 0; i < h; i++) \
119                 { \
120                         input_row = input_rows[i]; \
121                         output_row = output_rows[i] + (w - 1) * components; \
122                         for(k = 0; k < w / 2; k++) \
123                         { \
124                                 SWAP_PIXELS(type, components, output_row, input_row); \
125                                 input_row += components; \
126                                 output_row -= components; \
127                         } \
128                 } \
129         } \
132 int FlipMain::process_buffer(VFrame *frame,
133                 int64_t start_position,
134                 double frame_rate)
136         int i, j, k, l;
137         int w = frame->get_w();
138         int h = frame->get_h();
139         int colormodel = frame->get_color_model();
141         load_configuration();
143         read_frame(frame,
144                 0,
145                 get_source_position(),
146                 get_framerate(),
147                 get_use_opengl());
151         if(get_use_opengl()) 
152         {
153                 if(config.flip_vertical || config.flip_horizontal)
154                         return run_opengl();
155                 else
156                         return 0;
157         }
159         switch(colormodel)
160         {
161                 case BC_RGB888:
162                 case BC_YUV888:
163                         FLIP_MACRO(unsigned char, 3);
164                         break;
165                 case BC_RGB_FLOAT:
166                         FLIP_MACRO(float, 3);
167                         break;
168                 case BC_RGB161616:
169                 case BC_YUV161616:
170                         FLIP_MACRO(uint16_t, 3);
171                         break;
172                 case BC_RGBA8888:
173                 case BC_YUVA8888:
174                         FLIP_MACRO(unsigned char, 4);
175                         break;
176                 case BC_RGBA_FLOAT:
177                         FLIP_MACRO(float, 4);
178                         break;
179                 case BC_RGBA16161616:
180                 case BC_YUVA16161616:
181                         FLIP_MACRO(uint16_t, 4);
182                         break;
183         }
184         return 0;
188 SHOW_GUI_MACRO(FlipMain, FlipThread)
190 RAISE_WINDOW_MACRO(FlipMain)
192 SET_STRING_MACRO(FlipMain)
194 NEW_PICON_MACRO(FlipMain)
196 LOAD_CONFIGURATION_MACRO(FlipMain, FlipConfig)
198 void FlipMain::update_gui()
200         if(thread)
201         {
202                 load_configuration();
203                 thread->window->lock_window();
204                 thread->window->flip_vertical->update((int)config.flip_vertical);
205                 thread->window->flip_horizontal->update((int)config.flip_horizontal);
206                 thread->window->unlock_window();
207         }
210 void FlipMain::save_data(KeyFrame *keyframe)
212         FileXML output;
214 // cause data to be stored directly in text
215         output.set_shared_string(keyframe->data, MESSAGESIZE);
216         output.tag.set_title("FLIP");
217         output.append_tag();
218         if(config.flip_vertical)
219         {
220                 output.tag.set_title("VERTICAL");
221                 output.append_tag();
222         }
224         if(config.flip_horizontal)
225         {       
226                 output.tag.set_title("HORIZONTAL");
227                 output.append_tag();
228         }
229         output.terminate_string();
230 // data is now in *text
233 void FlipMain::read_data(KeyFrame *keyframe)
235         FileXML input;
237         input.set_shared_string(keyframe->data, strlen(keyframe->data));
239         int result = 0;
240         config.flip_vertical = config.flip_horizontal = 0;
242         while(!result)
243         {
244                 result = input.read_tag();
246                 if(!result)
247                 {
248                         if(input.tag.title_is("VERTICAL"))
249                         {
250                                 config.flip_vertical = 1;
251                         }
252                         else
253                         if(input.tag.title_is("HORIZONTAL"))
254                         {
255                                 config.flip_horizontal = 1;
256                         }
257                 }
258         }
261 int FlipMain::load_defaults()
263         char directory[BCTEXTLEN], string[BCTEXTLEN];
264 // set the default directory
265         sprintf(directory, "%sflip.rc", BCASTDIR);
267 // load the defaults
268         defaults = new BC_Hash(directory);
269         defaults->load();
271         config.flip_horizontal = defaults->get("FLIP_HORIZONTAL", config.flip_horizontal);
272         config.flip_vertical = defaults->get("FLIP_VERTICAL", config.flip_vertical);
273         return 0;
276 int FlipMain::save_defaults()
278         defaults->update("FLIP_HORIZONTAL", config.flip_horizontal);
279         defaults->update("FLIP_VERTICAL", config.flip_vertical);
280         defaults->save();
281         return 0;
284 int FlipMain::handle_opengl()
286 #ifdef HAVE_GL
287         get_output()->to_texture();
288         get_output()->enable_opengl();
289         get_output()->init_screen();
290         get_output()->bind_texture(0);
292         if(config.flip_vertical && !config.flip_horizontal)
293         {
294                 get_output()->draw_texture(0,
295                         0,
296                         get_output()->get_w(),
297                         get_output()->get_h(),
298                         0,
299                         get_output()->get_h(),
300                         get_output()->get_w(),
301                         0);
302         }
304         if(config.flip_horizontal && !config.flip_vertical)
305         {
306                 get_output()->draw_texture(0,
307                         0,
308                         get_output()->get_w(),
309                         get_output()->get_h(),
310                         get_output()->get_w(),
311                         0,
312                         0,
313                         get_output()->get_h());
314         }
316         if(config.flip_vertical && config.flip_horizontal)
317         {
318                 get_output()->draw_texture(0,
319                         0,
320                         get_output()->get_w(),
321                         get_output()->get_h(),
322                         get_output()->get_w(),
323                         get_output()->get_h(),
324                         0,
325                         0);
326         }
328         get_output()->set_opengl_state(VFrame::SCREEN);
329 #endif