r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / maskauto.C
blob8b7c925a96fe2adc8ef5b701369084a06b55e4a3
1 #include "clip.h"
2 #include "filexml.h"
3 #include "maskauto.h"
4 #include "maskautos.h"
6 #include <stdlib.h>
7 #include <string.h>
12 MaskPoint::MaskPoint()
14         x = 0;
15         y = 0;
16         control_x1 = 0;
17         control_y1 = 0;
18         control_x2 = 0;
19         control_y2 = 0;
22 MaskPoint& MaskPoint::operator=(MaskPoint& ptr)
24         this->x = ptr.x;
25         this->y = ptr.y;
26         this->control_x1 = ptr.control_x1;
27         this->control_y1 = ptr.control_y1;
28         this->control_x2 = ptr.control_x2;
29         this->control_y2 = ptr.control_y2;
32 int MaskPoint::operator==(MaskPoint& ptr)
34         return EQUIV(x, ptr.x) &&
35                 EQUIV(y, ptr.y) &&
36                 EQUIV(control_x1, ptr.control_x1) &&
37                 EQUIV(control_y1, ptr.control_y1) &&
38                 EQUIV(control_x2, ptr.control_x2) &&
39                 EQUIV(control_y2, ptr.control_y2);
42 SubMask::SubMask(MaskAuto *keyframe)
44         this->keyframe = keyframe;
47 SubMask::~SubMask()
51 int SubMask::operator==(SubMask& ptr)
53         if(points.total != ptr.points.total) return 0;
55         for(int i = 0; i < points.total; i++)
56         {
57                 if(!(*points.values[i] == *ptr.points.values[i]))
58                         return 0;
59         }
60         
61         return 1;
64 void SubMask::copy_from(SubMask& ptr)
66         points.remove_all_objects();
67         for(int i = 0; i < ptr.points.total; i++)
68         {
69                 MaskPoint *point = new MaskPoint;
70                 *point = *ptr.points.values[i];
71                 points.append(point);
72         }
75 void SubMask::load(FileXML *file)
77         points.remove_all_objects();
79         int result = 0;
80         while(!result)
81         {
82                 result = file->read_tag();
83                 
84                 if(!result)
85                 {
86                         if(file->tag.title_is("/MASK"))
87                         {
88                                 result = 1;
89                         }
90                         else
91                         if(file->tag.title_is("POINT"))
92                         {
93                                 char string[BCTEXTLEN];
94                                 string[0] = 0;
95                                 file->read_text_until("/POINT", string);
97                                 MaskPoint *point = new MaskPoint;
98                                 char *ptr = string;
99 //printf("MaskAuto::load 1 %s\n", ptr);
101                                 point->x = atof(ptr);
102                                 ptr = strchr(ptr, ',');
103 //printf("MaskAuto::load 2 %s\n", ptr + 1);
104                                 if(ptr) 
105                                 {
106                                         point->y = atof(ptr + 1);
107                                         ptr = strchr(ptr + 1, ',');
108                                 
109                                         if(ptr)
110                                         {
111 //printf("MaskAuto::load 3 %s\n", ptr + 1);
112                                                 point->control_x1 = atof(ptr + 1);
113                                                 ptr = strchr(ptr + 1, ',');
114                                                 if(ptr)
115                                                 {
116 //printf("MaskAuto::load 4 %s\n", ptr + 1);
117                                                         point->control_y1 = atof(ptr + 1);
118                                                         ptr = strchr(ptr + 1, ',');
119                                                         if(ptr)
120                                                         {
121 //printf("MaskAuto::load 5 %s\n", ptr + 1);
122                                                                 point->control_x2 = atof(ptr + 1);
123                                                                 ptr = strchr(ptr + 1, ',');
124                                                                 if(ptr) point->control_y2 = atof(ptr + 1);
125                                                         }
126                                                 }
127                                         }
128                                         
129                                 }
130                                 points.append(point);
131                         }
132                 }
133         }
136 void SubMask::copy(FileXML *file)
138         if(points.total)
139         {
140                 file->tag.set_title("MASK");
141                 file->tag.set_property("NUMBER", keyframe->masks.number_of(this));
142                 file->append_tag();
143                 file->append_newline();
145                 for(int i = 0; i < points.total; i++)
146                 {
147                         file->append_newline();
148                         file->tag.set_title("POINT");
149                         file->append_tag();
150                         char string[BCTEXTLEN];
151                         sprintf(string, "%.6e, %.6e, %.6e, %.6e, %.6e, %.6e", 
152                                 points.values[i]->x, 
153                                 points.values[i]->y, 
154                                 points.values[i]->control_x1, 
155                                 points.values[i]->control_y1, 
156                                 points.values[i]->control_x2, 
157                                 points.values[i]->control_y2);
158                         file->append_text(string);
159                         file->tag.set_title("/POINT");
160                         file->append_tag();
161                 }
162                 file->append_newline();
164                 file->tag.set_title("/MASK");
165                 file->append_tag();
166                 file->append_newline();
167         }
170 void SubMask::dump()
172         for(int i = 0; i < points.total; i++)
173         {
174                 printf("          point=%d x=%.2f y=%.2f in_x=%.2f in_y=%.2f out_x=%.2f out_y=%.2f\n",
175                         i,
176                         points.values[i]->x, 
177                         points.values[i]->y, 
178                         points.values[i]->control_x1, 
179                         points.values[i]->control_y1, 
180                         points.values[i]->control_x2, 
181                         points.values[i]->control_y2);
182         }
186 MaskAuto::MaskAuto(EDL *edl, MaskAutos *autos)
187  : Auto(edl, autos)
189         mode = MASK_SUBTRACT_ALPHA;
190         feather = 0;
191         value = 100;
193 // We define a fixed number of submasks so that interpolation for each
194 // submask matches.
196         for(int i = 0; i < SUBMASKS; i++)
197                 masks.append(new SubMask(this));
200 MaskAuto::~MaskAuto()
202         masks.remove_all_objects();
205 int MaskAuto::operator==(Auto &that)
207         return identical((MaskAuto*)&that);
212 int MaskAuto::operator==(MaskAuto &that)
214         return identical((MaskAuto*)&that);
218 int MaskAuto::identical(MaskAuto *src)
220         if(value != src->value ||
221                 mode != src->mode ||
222                 feather != src->feather ||
223                 masks.total != src->masks.total) return 0;
225         for(int i = 0; i < masks.total; i++)
226                 if(!(*masks.values[i] == *src->masks.values[i])) return 0;
228         return 1;
231 void MaskAuto::copy_from(Auto *src)
233         copy_from((MaskAuto*)src);
236 void MaskAuto::copy_from(MaskAuto *src)
238         Auto::copy_from(src);
240         mode = src->mode;
241         feather = src->feather;
242         value = src->value;
244         masks.remove_all_objects();
245         for(int i = 0; i < src->masks.total; i++)
246         {
247                 masks.append(new SubMask(this));
248                 masks.values[i]->copy_from(*src->masks.values[i]);
249         }
252 SubMask* MaskAuto::get_submask(int number)
254         CLAMP(number, 0, masks.total - 1);
255         return masks.values[number];
258 void MaskAuto::load(FileXML *file)
260         mode = file->tag.get_property("MODE", mode);
261         feather = file->tag.get_property("FEATHER", feather);
262         value = file->tag.get_property("VALUE", value);
263         for(int i = 0; i < masks.total; i++)
264         {
265                 delete masks.values[i];
266                 masks.values[i] = new SubMask(this);
267         }
269         int result = 0;
270         while(!result)
271         {
272                 result = file->read_tag();
274                 if(!result)
275                 {
276                         if(file->tag.title_is("/AUTO")) 
277                                 result = 1;
278                         else
279                         if(file->tag.title_is("MASK"))
280                         {
281                                 SubMask *mask = masks.values[file->tag.get_property("NUMBER", 0)];
282                                 mask->load(file);
283                         }
284                 }
285         }
286 //      dump();
289 void MaskAuto::copy(int64_t start, int64_t end, FileXML *file, int default_auto)
291         file->tag.set_title("AUTO");
292         file->tag.set_property("MODE", mode);
293         file->tag.set_property("VALUE", value);
294         file->tag.set_property("FEATHER", feather);
295         if(default_auto)
296                 file->tag.set_property("POSITION", 0);
297         else
298                 file->tag.set_property("POSITION", position - start);
299         file->append_tag();
300         file->append_newline();
302         for(int i = 0; i < masks.total; i++)
303         {
304                 masks.values[i]->copy(file);
305         }
307         file->append_newline();
308         file->tag.set_title("/AUTO");
309         file->append_tag();
310         file->append_newline();
313 void MaskAuto::dump()
315         printf("         mode=%d value=%d\n", mode, value);
316         for(int i = 0; i < masks.total; i++)
317         {
318                 printf("         submask %d\n", i);
319                 masks.values[i]->dump();
320         }