52073c10c7ebdf19e987d1ee42d6818596f359b5
[goodguy/history.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 _("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->get_data(), MESSAGESIZE);
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->get_data(), strlen(keyframe->get_data()));
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 //printf("ScaleRatioMain::process_realtime 1 %p\n", input);
175         if( input->get_rows()[0] == output->get_rows()[0] ) {
176                 if( temp_frame && (
177                     temp_frame->get_w() != input_ptr->get_w() ||
178                     temp_frame->get_h() != input_ptr->get_h() ||
179                     temp_frame->get_color_model() != input_ptr->get_color_model() ) ) {
180                         delete temp_frame;
181                         temp_frame = 0;
182                 }
183                 if(!temp_frame)
184                         temp_frame = new VFrame(input_ptr->get_w(), input_ptr->get_h(),
185                                 input->get_color_model(), 0);
186                 temp_frame->copy_from(input);
187                 input = temp_frame;
188         }
189 //printf("ScaleRatioMain::process_realtime 2 %p\n", input);
190
191
192         if(!overlayer) {
193                 overlayer = new OverlayFrame(smp + 1);
194         }
195
196         output->clear_frame();
197
198         if( config.src_w < EPSILON ) return 1;
199         if( config.src_h < EPSILON ) return 1;
200         if( config.dst_w < EPSILON ) return 1;
201         if( config.dst_h < EPSILON ) return 1;
202         float ix0 = (input->get_w() - config.src_w)/2 + config.src_x;
203         float iy0 = (input->get_h() - config.src_h)/2 + config.src_y;
204         float ix1 = ix0, ix2 = ix1 + config.src_w;
205         float iy1 = iy0, iy2 = iy1 + config.src_h;
206         float ox0 = (output->get_w() - config.dst_w)/2 + config.dst_x;
207         float oy0 = (output->get_h() - config.dst_h)/2 + config.dst_y;
208         float ox1 = ox0, ox2 = ox1 + config.dst_w;
209         float oy1 = oy0, oy2 = oy1 + config.dst_h;
210
211         overlayer->overlay(output, input,
212                 ix1, iy1, ix2, iy2,
213                 ox1, oy1, ox2, oy2,
214                 1, TRANSFER_REPLACE,
215                 get_interpolation_type());
216
217         return 0;
218 }
219
220 NEW_WINDOW_MACRO(ScaleRatioMain, ScaleRatioWin)
221
222 void ScaleRatioMain::update_gui()
223 {
224         if( !thread ) return;
225         ScaleRatioWin *window = (ScaleRatioWin*)thread->get_window();
226         window->lock_window("ScaleRatio::update_gui");
227         if( load_configuration() )
228                 window->update_gui();
229         window->unlock_window();
230 }
231
232