12 MaskPoint::MaskPoint()
22 MaskPoint& MaskPoint::operator=(MaskPoint& ptr)
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) &&
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;
51 int SubMask::operator==(SubMask& ptr)
53 if(points.total != ptr.points.total) return 0;
55 for(int i = 0; i < points.total; i++)
57 if(!(*points.values[i] == *ptr.points.values[i]))
64 void SubMask::copy_from(SubMask& ptr)
66 points.remove_all_objects();
67 //printf("SubMask::copy_from 1 %p %d\n", this, ptr.points.total);
68 for(int i = 0; i < ptr.points.total; i++)
70 MaskPoint *point = new MaskPoint;
71 *point = *ptr.points.values[i];
76 void SubMask::load(FileXML *file)
78 points.remove_all_objects();
83 result = file->read_tag();
87 if(file->tag.title_is("/MASK"))
92 if(file->tag.title_is("POINT"))
94 char string[BCTEXTLEN];
96 file->read_text_until("/POINT", string, BCTEXTLEN);
98 MaskPoint *point = new MaskPoint;
100 //printf("MaskAuto::load 1 %s\n", ptr);
102 point->x = atof(ptr);
103 ptr = strchr(ptr, ',');
104 //printf("MaskAuto::load 2 %s\n", ptr + 1);
107 point->y = atof(ptr + 1);
108 ptr = strchr(ptr + 1, ',');
112 //printf("MaskAuto::load 3 %s\n", ptr + 1);
113 point->control_x1 = atof(ptr + 1);
114 ptr = strchr(ptr + 1, ',');
117 //printf("MaskAuto::load 4 %s\n", ptr + 1);
118 point->control_y1 = atof(ptr + 1);
119 ptr = strchr(ptr + 1, ',');
122 //printf("MaskAuto::load 5 %s\n", ptr + 1);
123 point->control_x2 = atof(ptr + 1);
124 ptr = strchr(ptr + 1, ',');
125 if(ptr) point->control_y2 = atof(ptr + 1);
131 points.append(point);
137 void SubMask::copy(FileXML *file)
141 file->tag.set_title("MASK");
142 file->tag.set_property("NUMBER", keyframe->masks.number_of(this));
144 file->append_newline();
146 for(int i = 0; i < points.total; i++)
148 file->append_newline();
149 file->tag.set_title("POINT");
151 char string[BCTEXTLEN];
152 //printf("SubMask::copy 1 %p %d %p\n", this, i, points.values[i]);
153 sprintf(string, "%.7g, %.7g, %.7g, %.7g, %.7g, %.7g",
156 points.values[i]->control_x1,
157 points.values[i]->control_y1,
158 points.values[i]->control_x2,
159 points.values[i]->control_y2);
160 //printf("SubMask::copy 2\n");
161 file->append_text(string);
162 file->tag.set_title("/POINT");
165 file->append_newline();
167 file->tag.set_title("/MASK");
169 file->append_newline();
175 for(int i = 0; i < points.total; i++)
177 printf(" point=%d x=%.2f y=%.2f in_x=%.2f in_y=%.2f out_x=%.2f out_y=%.2f\n",
181 points.values[i]->control_x1,
182 points.values[i]->control_y1,
183 points.values[i]->control_x2,
184 points.values[i]->control_y2);
189 MaskAuto::MaskAuto(EDL *edl, MaskAutos *autos)
192 mode = MASK_SUBTRACT_ALPHA;
195 apply_before_plugins = 0;
197 // We define a fixed number of submasks so that interpolation for each
200 for(int i = 0; i < SUBMASKS; i++)
201 masks.append(new SubMask(this));
204 MaskAuto::~MaskAuto()
206 masks.remove_all_objects();
209 int MaskAuto::operator==(Auto &that)
211 return identical((MaskAuto*)&that);
216 int MaskAuto::operator==(MaskAuto &that)
218 return identical((MaskAuto*)&that);
222 int MaskAuto::identical(MaskAuto *src)
224 if(value != src->value ||
226 feather != src->feather ||
227 masks.total != src->masks.total ||
228 apply_before_plugins != src->apply_before_plugins) return 0;
230 for(int i = 0; i < masks.total; i++)
231 if(!(*masks.values[i] == *src->masks.values[i])) return 0;
236 void MaskAuto::copy_from(Auto *src)
238 copy_from((MaskAuto*)src);
241 void MaskAuto::copy_from(MaskAuto *src)
243 Auto::copy_from(src);
246 feather = src->feather;
248 apply_before_plugins = src->apply_before_plugins;
250 masks.remove_all_objects();
251 for(int i = 0; i < src->masks.total; i++)
253 masks.append(new SubMask(this));
254 masks.values[i]->copy_from(*src->masks.values[i]);
259 int MaskAuto::interpolate_from(Auto *a1, Auto *a2, int64_t position) {
260 MaskAuto *mask_auto1 = (MaskAuto *)a1;
261 MaskAuto *mask_auto2 = (MaskAuto *)a2;
263 if (!mask_auto2 || mask_auto2->masks.total == 0) // if mask_auto == null, copy from first
265 copy_from(mask_auto1);
268 this->mode = mask_auto1->mode;
269 this->feather = mask_auto1->feather;
270 this->value = mask_auto1->value;
271 this->apply_before_plugins = mask_auto1->apply_before_plugins;
272 this->position = position;
273 masks.remove_all_objects();
276 i < mask_auto1->masks.total;
279 SubMask *new_submask = new SubMask(this);
280 masks.append(new_submask);
281 SubMask *mask1 = mask_auto1->masks.values[i];
282 SubMask *mask2 = mask_auto2->masks.values[i];
284 // just in case, should never happen
285 int total_points = MIN(mask1->points.total, mask2->points.total);
286 for(int j = 0; j < total_points; j++)
288 MaskPoint *point = new MaskPoint;
289 MaskAutos::avg_points(point,
290 mask1->points.values[j],
291 mask2->points.values[j],
293 mask_auto1->position,
294 mask_auto2->position);
295 new_submask->points.append(point);
304 SubMask* MaskAuto::get_submask(int number)
306 CLAMP(number, 0, masks.total - 1);
307 return masks.values[number];
310 void MaskAuto::load(FileXML *file)
312 mode = file->tag.get_property("MODE", mode);
313 feather = file->tag.get_property("FEATHER", feather);
314 value = file->tag.get_property("VALUE", value);
315 apply_before_plugins = file->tag.get_property("APPLY_BEFORE_PLUGINS", apply_before_plugins);
316 for(int i = 0; i < masks.total; i++)
318 delete masks.values[i];
319 masks.values[i] = new SubMask(this);
325 result = file->read_tag();
329 if(file->tag.title_is("/AUTO"))
332 if(file->tag.title_is("MASK"))
334 SubMask *mask = masks.values[file->tag.get_property("NUMBER", 0)];
342 void MaskAuto::copy(int64_t start, int64_t end, FileXML *file, int default_auto)
344 file->tag.set_title("AUTO");
345 file->tag.set_property("MODE", mode);
346 file->tag.set_property("VALUE", value);
347 file->tag.set_property("FEATHER", feather);
348 file->tag.set_property("APPLY_BEFORE_PLUGINS", apply_before_plugins);
351 file->tag.set_property("POSITION", 0);
353 file->tag.set_property("POSITION", position - start);
355 file->append_newline();
357 for(int i = 0; i < masks.total; i++)
359 //printf("MaskAuto::copy 1 %p %d %p\n", this, i, masks.values[i]);
360 masks.values[i]->copy(file);
361 //printf("MaskAuto::copy 10\n");
364 file->append_newline();
365 file->tag.set_title("/AUTO");
367 file->append_newline();
370 void MaskAuto::dump()
372 printf(" mode=%d value=%d\n", mode, value);
373 for(int i = 0; i < masks.total; i++)
375 printf(" submask %d\n", i);
376 masks.values[i]->dump();
380 void MaskAuto::translate_submasks(float translate_x, float translate_y)
382 for(int i = 0; i < masks.total; i++)
384 SubMask *mask = get_submask(i);
385 for (int j = 0; j < mask->points.total; j++)
387 mask->points.values[j]->x += translate_x;
388 mask->points.values[j]->y += translate_y;