remove whitespace at eol
[goodguy/history.git] / cinelerra-5.1 / plugins / zoom / zoom.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 "bchash.h"
23 #include "clip.h"
24 #include "filexml.h"
25 #include "zoom.h"
26 #include "edl.inc"
27 #include "overlayframe.h"
28 #include "language.h"
29 #include "theme.h"
30 #include "vframe.h"
31
32 #include <stdint.h>
33 #include <string.h>
34
35 REGISTER_PLUGIN(ZoomMain)
36
37
38
39 #define MIN_MAGNIFICATION 1.0
40 #define MAX_MAGNIFICATION 100.0
41
42
43 ZoomLimit::ZoomLimit(ZoomMain *plugin,
44         ZoomWindow *window,
45         float *output,
46         int x,
47         int y,
48         int w)
49  : BC_TumbleTextBox(window,
50         *output,
51         (float)MIN_MAGNIFICATION,
52         (float)MAX_MAGNIFICATION,
53         x,
54         y,
55         w)
56 {
57         this->output = output;
58         this->plugin = plugin;
59 }
60
61 int ZoomLimit::handle_event()
62 {
63         *output = atof(get_text());
64         plugin->send_configure_change();
65         return 1;
66 }
67
68
69
70
71
72
73
74
75 ZoomWindow::ZoomWindow(ZoomMain *plugin)
76  : PluginClientWindow(plugin,
77         250,
78         125,
79         250,
80         125,
81         0)
82 {
83         this->plugin = plugin;
84 }
85
86 ZoomWindow::~ZoomWindow()
87 {
88 }
89
90
91
92 void ZoomWindow::create_objects()
93 {
94         BC_Title *title = 0;
95         lock_window("ZoomWindow::create_objects");
96         int widget_border = plugin->get_theme()->widget_border;
97         int window_border = plugin->get_theme()->window_border;
98         int x = window_border, y = window_border;
99
100         add_subwindow(title = new BC_Title(x, y, _("X Magnification:")));
101         y += title->get_h() + widget_border;
102         limit_x = new ZoomLimit(plugin,
103                 this,
104                 &plugin->max_magnification_x,
105                 x,
106                 y,
107                 get_w() - window_border * 2 - widget_border - BC_Tumbler::calculate_w());
108         limit_x->create_objects();
109         y += limit_x->get_h() + widget_border;
110         add_subwindow(title = new BC_Title(x, y, _("Y Magnification:")));
111         y += title->get_h() + widget_border;
112         limit_y = new ZoomLimit(plugin,
113                 this,
114                 &plugin->max_magnification_y,
115                 x,
116                 y,
117                 get_w() - window_border * 2 - widget_border - BC_Tumbler::calculate_w());
118         limit_y->create_objects();
119
120         show_window();
121         unlock_window();
122 }
123
124
125
126
127
128
129
130
131
132 ZoomMain::ZoomMain(PluginServer *server)
133  : PluginVClient(server)
134 {
135         overlayer = 0;
136         temp = 0;
137         max_magnification_x = 10;
138         max_magnification_y = 10;
139 }
140
141 ZoomMain::~ZoomMain()
142 {
143         delete overlayer;
144         delete temp;
145 }
146
147 const char* ZoomMain::plugin_title() { return _("Zoom"); }
148 int ZoomMain::is_video() { return 1; }
149 int ZoomMain::is_transition() { return 1; }
150 int ZoomMain::uses_gui() { return 1; }
151
152
153
154
155
156 void ZoomMain::save_data(KeyFrame *keyframe)
157 {
158         FileXML output;
159         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
160         output.tag.set_title("ZOOMTRANSITION");
161         output.tag.set_property("MAGNIFICATION_X", max_magnification_x);
162         output.tag.set_property("MAGNIFICATION_Y", max_magnification_y);
163         output.append_tag();
164         output.tag.set_title("/ZOOMTRANSITION");
165         output.append_tag();
166         output.terminate_string();
167 }
168
169 void ZoomMain::read_data(KeyFrame *keyframe)
170 {
171         FileXML input;
172
173         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
174
175         while(!input.read_tag())
176         {
177                 if(input.tag.title_is("ZOOMTRANSITION"))
178                 {
179                         max_magnification_x = input.tag.get_property("MAGNIFICATION_X", max_magnification_x);
180                         max_magnification_y = input.tag.get_property("MAGNIFICATION_Y", max_magnification_y);
181                 }
182         }
183 }
184
185 int ZoomMain::load_configuration()
186 {
187         read_data(get_prev_keyframe(get_source_position()));
188         return 1;
189 }
190
191
192 NEW_WINDOW_MACRO(ZoomMain, ZoomWindow);
193
194 int ZoomMain::process_realtime(VFrame *incoming, VFrame *outgoing)
195 {
196         int half = PluginClient::get_total_len() / 2;
197         int position = half - labs(PluginClient::get_source_position() - half);
198         float fraction = (float)position / half;
199         is_before = PluginClient::get_source_position() < half;
200         int w = incoming->get_w();
201         int h = incoming->get_h();
202
203         load_configuration();
204         this->max_magnification_x = MAX(MIN_MAGNIFICATION, this->max_magnification_x);
205         this->max_magnification_y = MAX(MIN_MAGNIFICATION, this->max_magnification_y);
206         CLAMP(this->max_magnification_x, MIN_MAGNIFICATION, MAX_MAGNIFICATION);
207         CLAMP(this->max_magnification_y, MIN_MAGNIFICATION, MAX_MAGNIFICATION);
208
209         float min_magnification_x = MIN(1.0, this->max_magnification_x);
210         float max_magnification_x = MAX(1.0, this->max_magnification_x);
211         float min_magnification_y = MIN(1.0, this->max_magnification_y);
212         float max_magnification_y = MAX(1.0, this->max_magnification_y);
213
214         if(fraction > 0)
215         {
216                 in_w = (float)w / ((float)fraction *
217                         (max_magnification_x - min_magnification_x) +
218                         min_magnification_x);
219                 in_x = (float)w / 2 - in_w / 2;
220                 in_h = (float)h / ((float)fraction *
221                         (max_magnification_y - min_magnification_y) +
222                         min_magnification_y);
223                 in_y = (float)h / 2 - in_h / 2;
224         }
225         else
226         {
227                 in_w = w;
228                 in_h = h;
229                 in_x = 0;
230                 in_y = 0;
231         }
232
233 // printf("ZoomMain::process_realtime %f %f %f %f\n",
234 // fraction,
235 // ((float)fraction *
236 // (max_magnification_x - min_magnification_x) +
237 // min_magnification_x),
238 // in_x,
239 // in_y,
240 // in_x + in_w,
241 // in_y + in_h);
242
243
244 // Use hardware
245         if(get_use_opengl())
246         {
247                 run_opengl();
248                 return 0;
249         }
250
251 // Use software
252         if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1);
253
254         if(is_before)
255         {
256                 if(!temp) temp = new VFrame(outgoing->get_w(),
257                         outgoing->get_h(),
258                         outgoing->get_color_model());
259                 temp->clear_frame();
260                 overlayer->overlay(temp,
261                         outgoing,
262                         in_x,
263                         in_y,
264                         in_x + in_w,
265                         in_y + in_h,
266                         0,
267                         0,
268                         temp->get_w(),
269                         temp->get_h(),
270                         1.0,
271                         TRANSFER_REPLACE,
272                         CUBIC_LINEAR);
273                 outgoing->copy_from(temp);
274         }
275         else
276         {
277                 outgoing->clear_frame();
278                 overlayer->overlay(outgoing,
279                         incoming,
280                         in_x,
281                         in_y,
282                         in_x + in_w,
283                         in_y + in_h,
284                         0,
285                         0,
286                         temp->get_w(),
287                         temp->get_h(),
288                         1.0,
289                         TRANSFER_REPLACE,
290                         CUBIC_LINEAR);
291         }
292
293         return 0;
294 }
295
296
297 int ZoomMain::handle_opengl()
298 {
299 #ifdef HAVE_GL
300
301         if(is_before)
302         {
303 // Read images from RAM
304                 get_output()->to_texture();
305
306 // Create output pbuffer
307                 get_output()->enable_opengl();
308                 VFrame::init_screen(get_output()->get_w(), get_output()->get_h());
309
310 // Enable output texture
311                 get_output()->bind_texture(0);
312 // Draw output texture
313 // printf("ZoomMain::handle_opengl %f %f %f %f\n",
314 // in_x,
315 // in_y,
316 // in_x + in_w,
317 // in_y + in_h);
318                 get_output()->draw_texture(in_x,
319                         in_y,
320                         in_x + in_w,
321                         in_y + in_h,
322                         0,
323                         0,
324                         get_output()->get_w(),
325                         get_output()->get_h());
326         }
327         else
328         {
329 // Read images from RAM
330                 get_input()->to_texture();
331
332 // Create output pbuffer
333                 get_output()->enable_opengl();
334                 VFrame::init_screen(get_output()->get_w(), get_output()->get_h());
335
336 // Enable output texture
337                 get_input()->bind_texture(0);
338 // Draw input texture on output pbuffer
339                 get_output()->draw_texture(in_x,
340                         in_y,
341                         in_x + in_w,
342                         in_y + in_h,
343                         0,
344                         0,
345                         get_output()->get_w(),
346                         get_output()->get_h());
347         }
348
349         get_output()->set_opengl_state(VFrame::SCREEN);
350
351         return 1;
352
353 #endif
354
355         return 0;
356 }
357
358