Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

maskauto.C

Go to the documentation of this file.
00001 #include "clip.h"
00002 #include "filexml.h"
00003 #include "maskauto.h"
00004 #include "maskautos.h"
00005 
00006 #include <stdlib.h>
00007 #include <string.h>
00008 
00009 
00010 
00011 
00012 MaskPoint::MaskPoint()
00013 {
00014         x = 0;
00015         y = 0;
00016         control_x1 = 0;
00017         control_y1 = 0;
00018         control_x2 = 0;
00019         control_y2 = 0;
00020 }
00021 
00022 MaskPoint& MaskPoint::operator=(MaskPoint& ptr)
00023 {
00024         this->x = ptr.x;
00025         this->y = ptr.y;
00026         this->control_x1 = ptr.control_x1;
00027         this->control_y1 = ptr.control_y1;
00028         this->control_x2 = ptr.control_x2;
00029         this->control_y2 = ptr.control_y2;
00030 }
00031 
00032 int MaskPoint::operator==(MaskPoint& ptr)
00033 {
00034         return EQUIV(x, ptr.x) &&
00035                 EQUIV(y, ptr.y) &&
00036                 EQUIV(control_x1, ptr.control_x1) &&
00037                 EQUIV(control_y1, ptr.control_y1) &&
00038                 EQUIV(control_x2, ptr.control_x2) &&
00039                 EQUIV(control_y2, ptr.control_y2);
00040 }
00041 
00042 SubMask::SubMask(MaskAuto *keyframe)
00043 {
00044         this->keyframe = keyframe;
00045 }
00046 
00047 SubMask::~SubMask()
00048 {
00049 }
00050 
00051 int SubMask::operator==(SubMask& ptr)
00052 {
00053         if(points.total != ptr.points.total) return 0;
00054 
00055         for(int i = 0; i < points.total; i++)
00056         {
00057                 if(!(*points.values[i] == *ptr.points.values[i]))
00058                         return 0;
00059         }
00060         
00061         return 1;
00062 }
00063 
00064 void SubMask::copy_from(SubMask& ptr)
00065 {
00066         points.remove_all_objects();
00067 //printf("SubMask::copy_from 1 %p %d\n", this, ptr.points.total);
00068         for(int i = 0; i < ptr.points.total; i++)
00069         {
00070                 MaskPoint *point = new MaskPoint;
00071                 *point = *ptr.points.values[i];
00072                 points.append(point);
00073         }
00074 }
00075 
00076 void SubMask::load(FileXML *file)
00077 {
00078         points.remove_all_objects();
00079 
00080         int result = 0;
00081         while(!result)
00082         {
00083                 result = file->read_tag();
00084                 
00085                 if(!result)
00086                 {
00087                         if(file->tag.title_is("/MASK"))
00088                         {
00089                                 result = 1;
00090                         }
00091                         else
00092                         if(file->tag.title_is("POINT"))
00093                         {
00094                                 char string[BCTEXTLEN];
00095                                 string[0] = 0;
00096                                 file->read_text_until("/POINT", string, BCTEXTLEN);
00097 
00098                                 MaskPoint *point = new MaskPoint;
00099                                 char *ptr = string;
00100 //printf("MaskAuto::load 1 %s\n", ptr);
00101 
00102                                 point->x = atof(ptr);
00103                                 ptr = strchr(ptr, ',');
00104 //printf("MaskAuto::load 2 %s\n", ptr + 1);
00105                                 if(ptr) 
00106                                 {
00107                                         point->y = atof(ptr + 1);
00108                                         ptr = strchr(ptr + 1, ',');
00109                                 
00110                                         if(ptr)
00111                                         {
00112 //printf("MaskAuto::load 3 %s\n", ptr + 1);
00113                                                 point->control_x1 = atof(ptr + 1);
00114                                                 ptr = strchr(ptr + 1, ',');
00115                                                 if(ptr)
00116                                                 {
00117 //printf("MaskAuto::load 4 %s\n", ptr + 1);
00118                                                         point->control_y1 = atof(ptr + 1);
00119                                                         ptr = strchr(ptr + 1, ',');
00120                                                         if(ptr)
00121                                                         {
00122 //printf("MaskAuto::load 5 %s\n", ptr + 1);
00123                                                                 point->control_x2 = atof(ptr + 1);
00124                                                                 ptr = strchr(ptr + 1, ',');
00125                                                                 if(ptr) point->control_y2 = atof(ptr + 1);
00126                                                         }
00127                                                 }
00128                                         }
00129                                         
00130                                 }
00131                                 points.append(point);
00132                         }
00133                 }
00134         }
00135 }
00136 
00137 void SubMask::copy(FileXML *file)
00138 {
00139         if(points.total)
00140         {
00141                 file->tag.set_title("MASK");
00142                 file->tag.set_property("NUMBER", keyframe->masks.number_of(this));
00143                 file->append_tag();
00144                 file->append_newline();
00145 
00146                 for(int i = 0; i < points.total; i++)
00147                 {
00148                         file->append_newline();
00149                         file->tag.set_title("POINT");
00150                         file->append_tag();
00151                         char string[BCTEXTLEN];
00152 //printf("SubMask::copy 1 %p %d %p\n", this, i, points.values[i]);
00153                         sprintf(string, "%.6e, %.6e, %.6e, %.6e, %.6e, %.6e", 
00154                                 points.values[i]->x, 
00155                                 points.values[i]->y, 
00156                                 points.values[i]->control_x1, 
00157                                 points.values[i]->control_y1, 
00158                                 points.values[i]->control_x2, 
00159                                 points.values[i]->control_y2);
00160 //printf("SubMask::copy 2\n");
00161                         file->append_text(string);
00162                         file->tag.set_title("/POINT");
00163                         file->append_tag();
00164                 }
00165                 file->append_newline();
00166 
00167                 file->tag.set_title("/MASK");
00168                 file->append_tag();
00169                 file->append_newline();
00170         }
00171 }
00172 
00173 void SubMask::dump()
00174 {
00175         for(int i = 0; i < points.total; i++)
00176         {
00177                 printf("          point=%d x=%.2f y=%.2f in_x=%.2f in_y=%.2f out_x=%.2f out_y=%.2f\n",
00178                         i,
00179                         points.values[i]->x, 
00180                         points.values[i]->y, 
00181                         points.values[i]->control_x1, 
00182                         points.values[i]->control_y1, 
00183                         points.values[i]->control_x2, 
00184                         points.values[i]->control_y2);
00185         }
00186 }
00187 
00188 
00189 MaskAuto::MaskAuto(EDL *edl, MaskAutos *autos)
00190  : Auto(edl, autos)
00191 {
00192         mode = MASK_SUBTRACT_ALPHA;
00193         feather = 0;
00194         value = 100;
00195 
00196 // We define a fixed number of submasks so that interpolation for each
00197 // submask matches.
00198 
00199         for(int i = 0; i < SUBMASKS; i++)
00200                 masks.append(new SubMask(this));
00201 }
00202 
00203 MaskAuto::~MaskAuto()
00204 {
00205         masks.remove_all_objects();
00206 }
00207 
00208 int MaskAuto::operator==(Auto &that)
00209 {
00210         return identical((MaskAuto*)&that);
00211 }
00212 
00213 
00214 
00215 int MaskAuto::operator==(MaskAuto &that)
00216 {
00217         return identical((MaskAuto*)&that);
00218 }
00219 
00220 
00221 int MaskAuto::identical(MaskAuto *src)
00222 {
00223         if(value != src->value ||
00224                 mode != src->mode ||
00225                 feather != src->feather ||
00226                 masks.total != src->masks.total) return 0;
00227 
00228         for(int i = 0; i < masks.total; i++)
00229                 if(!(*masks.values[i] == *src->masks.values[i])) return 0;
00230 
00231         return 1;
00232 }
00233 
00234 void MaskAuto::copy_from(Auto *src)
00235 {
00236         copy_from((MaskAuto*)src);
00237 }
00238 
00239 void MaskAuto::copy_from(MaskAuto *src)
00240 {
00241         Auto::copy_from(src);
00242 
00243         mode = src->mode;
00244         feather = src->feather;
00245         value = src->value;
00246 
00247         masks.remove_all_objects();
00248         for(int i = 0; i < src->masks.total; i++)
00249         {
00250                 masks.append(new SubMask(this));
00251                 masks.values[i]->copy_from(*src->masks.values[i]);
00252         }
00253 }
00254 
00255 
00256 int MaskAuto::interpolate_from(Auto *a1, Auto *a2, int64_t position) {
00257         MaskAuto  *mask_auto1 = (MaskAuto *)a1;
00258         MaskAuto  *mask_auto2 = (MaskAuto *)a2;
00259 
00260         if (!mask_auto2 || mask_auto2->masks.total == 0) // if mask_auto == null, copy from first
00261         {
00262                 copy_from(mask_auto1);
00263                 return 0;
00264         }
00265         this->mode = mask_auto1->mode;
00266         this->feather = mask_auto1->feather;
00267         this->value = mask_auto1->value;
00268         this->position = position;
00269         masks.remove_all_objects();
00270 
00271         for(int i = 0; 
00272                 i < mask_auto1->masks.total; 
00273                 i++)
00274         {
00275                 SubMask *new_submask = new SubMask(this);
00276                 masks.append(new_submask);
00277                 SubMask *mask1 = mask_auto1->masks.values[i];
00278                 SubMask *mask2 = mask_auto2->masks.values[i];
00279 
00280                 // just in case, should never happen
00281                 int total_points = MIN(mask1->points.total, mask2->points.total);
00282                 for(int j = 0; j < total_points; j++)
00283                 {
00284                         MaskPoint *point = new MaskPoint;
00285                         MaskAutos::avg_points(point, 
00286                                 mask1->points.values[j], 
00287                                 mask2->points.values[j],
00288                                 position,
00289                                 mask_auto1->position,
00290                                 mask_auto2->position);
00291                         new_submask->points.append(point);
00292                 }
00293 
00294         }
00295 
00296 
00297 }
00298 
00299 
00300 SubMask* MaskAuto::get_submask(int number)
00301 {
00302         CLAMP(number, 0, masks.total - 1);
00303         return masks.values[number];
00304 }
00305 
00306 void MaskAuto::load(FileXML *file)
00307 {
00308         mode = file->tag.get_property("MODE", mode);
00309         feather = file->tag.get_property("FEATHER", feather);
00310         value = file->tag.get_property("VALUE", value);
00311         for(int i = 0; i < masks.total; i++)
00312         {
00313                 delete masks.values[i];
00314                 masks.values[i] = new SubMask(this);
00315         }
00316 
00317         int result = 0;
00318         while(!result)
00319         {
00320                 result = file->read_tag();
00321 
00322                 if(!result)
00323                 {
00324                         if(file->tag.title_is("/AUTO")) 
00325                                 result = 1;
00326                         else
00327                         if(file->tag.title_is("MASK"))
00328                         {
00329                                 SubMask *mask = masks.values[file->tag.get_property("NUMBER", 0)];
00330                                 mask->load(file);
00331                         }
00332                 }
00333         }
00334 //      dump();
00335 }
00336 
00337 void MaskAuto::copy(int64_t start, int64_t end, FileXML *file, int default_auto)
00338 {
00339         file->tag.set_title("AUTO");
00340         file->tag.set_property("MODE", mode);
00341         file->tag.set_property("VALUE", value);
00342         file->tag.set_property("FEATHER", feather);
00343         if(default_auto)
00344                 file->tag.set_property("POSITION", 0);
00345         else
00346                 file->tag.set_property("POSITION", position - start);
00347         file->append_tag();
00348         file->append_newline();
00349 
00350         for(int i = 0; i < masks.total; i++)
00351         {
00352 //printf("MaskAuto::copy 1 %p %d %p\n", this, i, masks.values[i]);
00353                 masks.values[i]->copy(file);
00354 //printf("MaskAuto::copy 10\n");
00355         }
00356 
00357         file->append_newline();
00358         file->tag.set_title("/AUTO");
00359         file->append_tag();
00360         file->append_newline();
00361 }
00362 
00363 void MaskAuto::dump()
00364 {
00365         printf("         mode=%d value=%d\n", mode, value);
00366         for(int i = 0; i < masks.total; i++)
00367         {
00368                 printf("         submask %d\n", i);
00369                 masks.values[i]->dump();
00370         }
00371 }
00372 
00373 void MaskAuto::translate_submasks(float translate_x, float translate_y)
00374 {
00375         for(int i = 0; i < masks.total; i++)
00376         {
00377                 SubMask *mask = get_submask(i);
00378                 for (int j = 0; j < mask->points.total; j++) 
00379                 {
00380                         mask->points.values[j]->x += translate_x;
00381                         mask->points.values[j]->y += translate_y;
00382                 }
00383         }
00384 }
00385 
00386 
00387 

Generated on Sun Jan 8 13:38:57 2006 for Cinelerra-svn by  doxygen 1.4.4