add auto zoombar/status color, fix 3 batchrender boobies, rotate plugin tweaks, add...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / scaleratio / scaleratio.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 "clip.h"
23 #include "filexml.h"
24 #include "language.h"
25 #include "scaleratio.h"
26 #include "scaleratiowin.h"
27
28 #include <string.h>
29
30
31
32
33 REGISTER_PLUGIN(ScaleRatioMain)
34
35 ScaleRatioConfig::ScaleRatioConfig()
36 {
37         type = 0;
38         in_w = 720;   in_h = 480;   in_r = 1;
39         out_w = 720;  out_h = 480;  out_r = 1;
40         src_x = src_y = 0;  src_w = 720;  src_h = 480;
41         dst_x = dst_y = 0;  dst_w = 720;  dst_h = 480;
42 }
43
44 int ScaleRatioConfig::equivalent(ScaleRatioConfig &that)
45 {
46         return EQUIV(src_x, that.src_x) && EQUIV(src_y, that.src_y) &&
47                 EQUIV(src_w, that.src_w) && EQUIV(src_h, that.src_h) &&
48                 EQUIV(dst_x, that.dst_x) && EQUIV(dst_y, that.dst_y) &&
49                 EQUIV(dst_w, that.dst_w) && EQUIV(dst_h, that.dst_h);
50 }
51
52 void ScaleRatioConfig::copy_from(ScaleRatioConfig &that)
53 {
54         in_w  = that.in_w;   in_h  = that.in_h;   in_r  = that.in_r;
55         out_w = that.out_w;  out_h = that.out_h;  out_r = that.out_r;
56         src_x = that.src_x;  src_y = that.src_y;
57         src_w = that.src_w;  src_h = that.src_h;
58         dst_x = that.dst_x;  dst_y = that.dst_y;
59         dst_w = that.dst_w;  dst_h = that.dst_h;
60 }
61
62 void ScaleRatioConfig::interpolate(ScaleRatioConfig &prev, ScaleRatioConfig &next,
63         int64_t prev_frame, int64_t next_frame, int64_t current_frame)
64 {
65         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
66         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
67
68         this->src_x = prev.src_x * prev_scale + next.src_x * next_scale;
69         this->src_y = prev.src_y * prev_scale + next.src_y * next_scale;
70         this->src_w = prev.src_w * prev_scale + next.src_w * next_scale;
71         this->src_h = prev.src_h * prev_scale + next.src_h * next_scale;
72         this->dst_x = prev.dst_x * prev_scale + next.dst_x * next_scale;
73         this->dst_y = prev.dst_y * prev_scale + next.dst_y * next_scale;
74         this->dst_w = prev.dst_w * prev_scale + next.dst_w * next_scale;
75         this->dst_h = prev.dst_h * prev_scale + next.dst_h * next_scale;
76 }
77
78
79 ScaleRatioMain::ScaleRatioMain(PluginServer *server)
80  : PluginVClient(server)
81 {
82         overlayer = 0;
83         temp_frame = 0;
84 }
85
86 ScaleRatioMain::~ScaleRatioMain()
87 {
88
89
90         if(temp_frame) delete temp_frame;
91         temp_frame = 0;
92         if(overlayer) delete overlayer;
93         overlayer = 0;
94 }
95
96 const char* ScaleRatioMain::plugin_title() { return N_("Scale Ratio"); }
97 int ScaleRatioMain::is_realtime() { return 1; }
98
99
100
101 LOAD_CONFIGURATION_MACRO(ScaleRatioMain, ScaleRatioConfig)
102
103 void ScaleRatioMain::save_data(KeyFrame *keyframe)
104 {
105         FileXML output;
106
107 // cause data to be stored directly in text
108         output.set_shared_output(keyframe->xbuf);
109
110 // Store data
111         output.tag.set_title("SCALERATIO");
112         output.tag.set_property("TYPE", config.type);
113         output.tag.set_property("IN_W", config.in_w);
114         output.tag.set_property("IN_H", config.in_h);
115         output.tag.set_property("IN_ASPECT_RATIO", config.in_r);
116         output.tag.set_property("OUT_W", config.out_w);
117         output.tag.set_property("OUT_H", config.out_h);
118         output.tag.set_property("OUT_ASPECT_RATIO", config.out_r);
119         output.tag.set_property("SRC_X", config.src_x);
120         output.tag.set_property("SRC_Y", config.src_y);
121         output.tag.set_property("SRC_W", config.src_w);
122         output.tag.set_property("SRC_H", config.src_h);
123         output.tag.set_property("DST_X", config.dst_x);
124         output.tag.set_property("DST_Y", config.dst_y);
125         output.tag.set_property("DST_W", config.dst_w);
126         output.tag.set_property("DST_H", config.dst_h);
127         output.append_tag();
128         output.tag.set_title("/SCALERATIO");
129         output.append_tag();
130         output.append_newline();
131         output.terminate_string();
132 // data is now in *text
133 }
134
135 void ScaleRatioMain::read_data(KeyFrame *keyframe)
136 {
137         FileXML input;
138
139         input.set_shared_input(keyframe->xbuf);
140
141         int result = 0;
142
143         while( !(result = input.read_tag()) ) {
144                 if(input.tag.title_is("SCALERATIO")) {
145                         config.type  = input.tag.get_property("TYPE", config.type);
146                         config.in_w  = input.tag.get_property("IN_W", config.in_w);
147                         config.in_h  = input.tag.get_property("IN_H", config.in_h);
148                         config.in_r  = input.tag.get_property("IN_ASPECT_RATIO", config.in_r);
149                         config.out_w = input.tag.get_property("OUT_W", config.out_w);
150                         config.out_h = input.tag.get_property("OUT_H", config.out_h);
151                         config.out_r = input.tag.get_property("OUT_ASPECT_RATIO", config.out_r);
152                         config.src_x = input.tag.get_property("SRC_X", config.src_x);
153                         config.src_y = input.tag.get_property("SRC_Y", config.src_y);
154                         config.src_w = input.tag.get_property("SRC_W", config.src_w);
155                         config.src_h = input.tag.get_property("SRC_H", config.src_h);
156                         config.dst_x = input.tag.get_property("DST_X", config.dst_x);
157                         config.dst_y = input.tag.get_property("DST_Y", config.dst_y);
158                         config.dst_w = input.tag.get_property("DST_W", config.dst_w);
159                         config.dst_h = input.tag.get_property("DST_H", config.dst_h);
160                 }
161         }
162 }
163
164
165 #define EPSILON 0.001
166
167 int ScaleRatioMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
168 {
169         VFrame *input = input_ptr;
170         VFrame *output = output_ptr;
171
172         load_configuration();
173
174         if(get_use_opengl()) return run_opengl();
175
176 //printf("ScaleRatioMain::process_realtime 1 %p\n", input);
177         if( input->get_rows()[0] == output->get_rows()[0] ) {
178                 if( temp_frame && (
179                     temp_frame->get_w() != input_ptr->get_w() ||
180                     temp_frame->get_h() != input_ptr->get_h() ||
181                     temp_frame->get_color_model() != input_ptr->get_color_model() ) ) {
182                         delete temp_frame;
183                         temp_frame = 0;
184                 }
185                 if(!temp_frame)
186                         temp_frame = new VFrame(input_ptr->get_w(), input_ptr->get_h(),
187                                 input->get_color_model(), 0);
188                 temp_frame->copy_from(input);
189                 input = temp_frame;
190         }
191 //printf("ScaleRatioMain::process_realtime 2 %p\n", input);
192
193
194         if(!overlayer) {
195                 overlayer = new OverlayFrame(smp + 1);
196         }
197
198         output->clear_frame();
199
200         if( config.src_w < EPSILON ) return 1;
201         if( config.src_h < EPSILON ) return 1;
202         if( config.dst_w < EPSILON ) return 1;
203         if( config.dst_h < EPSILON ) return 1;
204         float ix0 = (input->get_w() - config.src_w)/2 + config.src_x;
205         float iy0 = (input->get_h() - config.src_h)/2 + config.src_y;
206         float ix1 = ix0, ix2 = ix1 + config.src_w;
207         float iy1 = iy0, iy2 = iy1 + config.src_h;
208         float ox0 = (output->get_w() - config.dst_w)/2 + config.dst_x;
209         float oy0 = (output->get_h() - config.dst_h)/2 + config.dst_y;
210         float ox1 = ox0, ox2 = ox1 + config.dst_w;
211         float oy1 = oy0, oy2 = oy1 + config.dst_h;
212
213         overlayer->overlay(output, input,
214                 ix1, iy1, ix2, iy2,
215                 ox1, oy1, ox2, oy2,
216                 1, TRANSFER_REPLACE,
217                 get_interpolation_type());
218
219         return 0;
220 }
221
222 NEW_WINDOW_MACRO(ScaleRatioMain, ScaleRatioWin)
223
224 void ScaleRatioMain::update_gui()
225 {
226         if( !thread ) return;
227         ScaleRatioWin *window = (ScaleRatioWin*)thread->get_window();
228         window->lock_window("ScaleRatio::update_gui");
229         if( load_configuration() )
230                 window->update_gui();
231         window->unlock_window();
232 }
233
234
235 int ScaleRatioMain::handle_opengl()
236 {
237 #ifdef HAVE_GL
238         VFrame *input = get_input(), *output = get_output();
239         float ix1 = (input->get_w() - config.src_w)/2 + config.src_x;
240         float iy1 = (input->get_h() - config.src_h)/2 + config.src_y;
241         float ix2 = ix1 + config.src_w;
242         float iy2 = iy1 + config.src_h;
243         float ox1 = (output->get_w() - config.dst_w)/2 + config.dst_x;
244         float oy1 = (output->get_h() - config.dst_h)/2 + config.dst_y;
245         float ox2 = ox1 + config.dst_w;
246         float oy2 = oy1 + config.dst_h;
247
248         output->to_texture();
249         output->enable_opengl();
250         output->init_screen();
251         output->clear_pbuffer();
252         output->bind_texture(0);
253         output->draw_texture(ix1,iy1, ix2,iy2, ox1,oy1, ox2,oy2);
254         output->set_opengl_state(VFrame::SCREEN);
255 #endif
256         return 0;
257 }
258
259