]> git.sesse.net Git - mlt/commitdiff
Make animation length optional.
authorDan Dennedy <dan@dennedy.org>
Thu, 30 May 2013 04:06:23 +0000 (21:06 -0700)
committerDan Dennedy <dan@dennedy.org>
Fri, 31 May 2013 23:58:13 +0000 (16:58 -0700)
It is only really needed when using negative time values.
With some fixes for parsing negatives in time code/clock values.

src/framework/Makefile
src/framework/mlt_animation.c
src/framework/mlt_profile.c
src/framework/mlt_property.c
src/mlt++/MltProperties.h
src/tests/test_properties/test_properties.cpp

index 046bd8f6772bf43147b4a3f036652ccbb0741423..2c3eac9d5804e7b7a70640ce0a74e0669b70421c 100644 (file)
@@ -87,7 +87,7 @@ endif
 
 CFLAGS += $(RDYNAMIC) -DPREFIX_DATA="\"$(mltdatadir)\"" -DPREFIX_LIB="\"$(moduledir)\""
 
-LDFLAGS += $(LIBDL) -lpthread
+LDFLAGS += $(LIBDL) -lpthread -lm
 
 all:   $(TARGET)
 
index 32cdb1d9adbd96dd1d74ee7b9f8db58c4c328eb3..4d52b082ff66c803fbe738ff5994e4e7dcad2473 100644 (file)
@@ -174,7 +174,7 @@ int mlt_animation_parse(mlt_animation self, const char *data, int length, double
 }
 
 // Conditionally refresh in case of a change
-int mlt_animation_refresh(mlt_animation self, const char *data, int length)
+int mlt_animation_refresh( mlt_animation self, const char *data, int length )
 {
        if ( ( length != self->length )|| ( data && ( !self->data || strcmp( data, self->data ) ) ) )
                return mlt_animation_parse( self, data, length, self->fps, self->locale );
@@ -183,10 +183,21 @@ int mlt_animation_refresh(mlt_animation self, const char *data, int length)
 
 int mlt_animation_get_length( mlt_animation self )
 {
-       if ( self )
-               return self->length;
-       else
-               return 0;
+       int length = 0;
+       if ( self ) {
+               if ( self->length > 0 ) {
+                       length = self->length;
+               }
+               else if ( self->nodes ) {
+                       animation_node node = self->nodes;
+                       while ( node ) {
+                               if ( node->item.frame > length )
+                                       length = node->item.frame;
+                               node = node->next;
+                       }
+               }
+       }
+       return length;
 }
 
 void mlt_animation_set_length( mlt_animation self, int length )
@@ -204,33 +215,16 @@ int mlt_animation_parse_item( mlt_animation self, mlt_animation_item item, const
                // Determine if a position has been specified
                if ( strchr( value, '=' ) )
                {
-                       double temp;
-                       char *p = NULL;
-#if defined(__GLIBC__) || defined(__DARWIN__)
-                       if ( self->locale )
-                               temp = strtod_l( value, &p, self->locale );
-                       else
-#endif
-                       temp = strtod( value, &p );
-                       // If p == value then it is likely a time clock or time code.
-                       if ( temp > -1.0 && temp < 1.0 && p != value )
-                       {
-                               // Parse a relative time (-1, 1).
-                               item->frame = temp * self->length;
-                       }
-                       else
-                       {
-                               // Parse an absolute time value.
-                               // Null terminate the string at the equal sign to prevent interpreting
-                               // a colon in the part to the right of the equal sign as indicative of a
-                               // a time value string.
-                               char *s = strdup( value );
-                               p = strchr( s, '=' );
-                               p[0] = '\0';
-                               mlt_property_set_string( item->property, s );
-                               item->frame = mlt_property_get_int( item->property, self->fps, self->locale );
-                               free( s );
-                       }
+                       // Parse an absolute time value.
+                       // Null terminate the string at the equal sign to prevent interpreting
+                       // a colon in the part to the right of the equal sign as indicative of a
+                       // a time value string.
+                       char *s = strdup( value );
+                       char *p = strchr( s, '=' );
+                       p[0] = '\0';
+                       mlt_property_set_string( item->property, s );
+                       item->frame = mlt_property_get_int( item->property, self->fps, self->locale );
+                       free( s );
 
                        // The character preceeding the equal sign indicates interpolation method.
                        p = strchr( value, '=' ) - 1;
@@ -245,7 +239,7 @@ int mlt_animation_parse_item( mlt_animation self, mlt_animation_item item, const
 
                // Special case - frame < 0
                if ( item->frame < 0 )
-                       item->frame += self->length;
+                       item->frame += mlt_animation_get_length( self );
 
                // Set remainder of string as item value.
                mlt_property_set_string( item->property, value );
@@ -538,7 +532,7 @@ char *mlt_animation_serialize_cut( mlt_animation self, int in, int out )
 // Serialise the current geometry
 char *mlt_animation_serialize( mlt_animation self )
 {
-       char *ret = mlt_animation_serialize_cut( self, 0, self->length );
+       char *ret = mlt_animation_serialize_cut( self, -1, -1 );
        if ( ret )
        {
                if ( self->data )
index bb496eb3cd3353dda4024d871e5f36f3407cfbb2..ad51e54dd9dd1f7f00a1fe1f3161c4cf192ada87 100644 (file)
@@ -417,7 +417,8 @@ void mlt_profile_from_producer( mlt_profile profile, mlt_producer producer )
                        mlt_service_get_frame( MLT_PRODUCER_SERVICE(producer), &fr, 0 );
                        p = MLT_FRAME_PROPERTIES( fr );
 //                     mlt_properties_dump(p, stderr);
-                       if ( mlt_properties_get_int( p, "meta.media.frame_rate_den" ) && mlt_properties_get_int( p, "meta.media.sample_aspect_den" ) )
+                       if ( mlt_properties_get_int( p, "meta.media.frame_rate_den" ) &&
+                                mlt_properties_get_int( p, "meta.media.sample_aspect_den" ) )
                        {
                                profile->width = mlt_properties_get_int( p, "meta.media.width" );
                                profile->height = mlt_properties_get_int( p, "meta.media.height" );
@@ -432,7 +433,8 @@ void mlt_profile_from_producer( mlt_profile profile, mlt_producer producer )
                                profile->sample_aspect_num = mlt_properties_get_int( p, "meta.media.sample_aspect_num" );
                                profile->sample_aspect_den = mlt_properties_get_int( p, "meta.media.sample_aspect_den" );
                                profile->colorspace = mlt_properties_get_int( p, "meta.media.colorspace" );
-                               profile->display_aspect_num = (int) ( (double) profile->sample_aspect_num * profile->width / profile->sample_aspect_den + 0.5 );
+                               profile->display_aspect_num = lrint( (double) profile->sample_aspect_num * profile->width
+                                       / profile->sample_aspect_den );
                                profile->display_aspect_den = profile->height;
                                free( profile->description );
                                profile->description = strdup( "automatic" );
index bbc02ee0d7c49940dcea22bbdbf7e15a34fb2104..0edd0161bbf5bd9fcdf878108a34b3ba1c2ed1ea 100644 (file)
@@ -35,6 +35,7 @@
 #include <locale.h>
 #include <pthread.h>
 #include <float.h>
+#include <math.h>
 
 
 /** Bit pattern used internally to indicated representations available.
@@ -305,7 +306,7 @@ static int time_clock_to_frames( const char *s, double fps, locale_t locale )
        }
        free( copy );
 
-       return fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5;
+       return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) );
 }
 
 /** Parse a SMPTE timecode string.
@@ -351,7 +352,7 @@ static int time_code_to_frames( const char *s, double fps )
        }
        free( copy );
 
-       return frames + ( fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5 );
+       return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) + frames );
 }
 
 /** Convert a string to an integer.
index 78e3405cf9fecf383b1a090e80e7f98f27c4effd..a2a68fa8bc22bec54967728c3b8becefceaacf9d 100644 (file)
@@ -99,21 +99,21 @@ namespace Mlt
                        char *get_time( const char *name, mlt_time_format = mlt_time_smpte );
                        mlt_color get_color( const char *name );
 
-                       char* anim_get( const char *name, int position, int length );
-                       int anim_set( const char *name, const char *value, int position, int length );
-                       int anim_get_int( const char *name, int position, int length );
-                       int anim_set( const char *name, int value, int position, int length,
+                       char* anim_get( const char *name, int position, int length = 0 );
+                       int anim_set( const char *name, const char *value, int position, int length = 0 );
+                       int anim_get_int( const char *name, int position, int length = 0 );
+                       int anim_set( const char *name, int value, int position, int length = 0,
                                mlt_keyframe_type keyframe_type = mlt_keyframe_linear );
-                       double anim_get_double( const char *name, int position, int length );
-                       int anim_set( const char *name, double value, int position, int length,
+                       double anim_get_double( const char *name, int position, int length = 0 );
+                       int anim_set( const char *name, double value, int position, int length = 0,
                                mlt_keyframe_type keyframe_type = mlt_keyframe_linear );
 
                        int set( const char *name, mlt_rect value );
                        int set( const char *name, double x, double y, double w, double h, double opacity = 1.0 );
                        mlt_rect get_rect( const char* name );
-                       int anim_set( const char *name, mlt_rect value, int position, int length,
+                       int anim_set( const char *name, mlt_rect value, int position, int length = 0,
                                mlt_keyframe_type keyframe_type = mlt_keyframe_linear );
-                       mlt_rect anim_get_rect( const char *name, int position, int length );
+                       mlt_rect anim_get_rect( const char *name, int position, int length = 0 );
        };
 }
 
index 8e04e7061a991cda98638b1c39a8652e43c738af..fb95480c8dc22c5c2352aed4995d3eea571cecc4 100644 (file)
@@ -511,12 +511,13 @@ private Q_SLOTS:
     void test_property_anim_get_double()
     {
         double fps = 25.0;
+        int len = 0;
         mlt_property p = mlt_property_init();
         mlt_property_set_string(p, "10=100; 20=200");
         QCOMPARE(mlt_property_get_double(p, fps, locale), 10.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 0, 100), 100.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 15, 100), 150.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 20, 100), 200.0);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale,  0, len), 100.0);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 15, len), 150.0);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 20, len), 200.0);
 
         mlt_property_set_string(p, "1.5");
         QCOMPARE(mlt_property_get_double(p, fps, locale), 1.5);
@@ -528,12 +529,13 @@ private Q_SLOTS:
     void test_property_anim_get_int()
     {
         double fps = 25.0;
+        int len = 100;
         mlt_property p = mlt_property_init();
         mlt_property_set_string(p, "10=100; 20=200");
         QCOMPARE(mlt_property_get_int(p, fps, locale), 10);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 0, 100), 100);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 15, 100), 150);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 20, 100), 200);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale,  0, len), 100);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 15, len), 150);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 20, len), 200);
 
         mlt_property_set_string(p, "1.5");
         QCOMPARE(mlt_property_get_int(p, fps, locale), 1);
@@ -589,30 +591,32 @@ private Q_SLOTS:
     void test_property_anim_set_double()
     {
         double fps = 25.0;
+        int len = 100;
         mlt_property p = mlt_property_init();
         mlt_property_set_string(p, "10=100; 20=200");
-        mlt_property_anim_set_double(p, 1.5, fps, locale, mlt_keyframe_linear, 30, 100);
+        mlt_property_anim_set_double(p, 1.5, fps, locale, mlt_keyframe_linear, 30, len);
         QCOMPARE(mlt_property_get_double(p, fps, locale), 10.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 0, 100), 100.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 15, 100), 150.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 20, 100), 200.0);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 25, 100), 100.75);
-        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 30, 100), 1.5);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale,  0, len), 100.0);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 15, len), 150.0);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 20, len), 200.0);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 25, len), 100.75);
+        QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 30, len), 1.5);
         mlt_property_close(p);
     }
 
     void test_property_anim_set_int()
     {
         double fps = 25.0;
+        int len = 0;
         mlt_property p = mlt_property_init();
         mlt_property_set_string(p, "10=100; 20=200");
-        mlt_property_anim_set_int(p, 300, fps, locale, mlt_keyframe_linear, 30, 100);
+        mlt_property_anim_set_int(p, 300, fps, locale, mlt_keyframe_linear, 30, len);
         QCOMPARE(mlt_property_get_int(p, fps, locale), 10);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 0, 100), 100);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 15, 100), 150);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 20, 100), 200);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 25, 100), 250);
-        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 30, 100), 300);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale,  0, len), 100);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 15, len), 150);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 20, len), 200);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 25, len), 250);
+        QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 30, len), 300);
         mlt_property_close(p);
     }
 
@@ -627,75 +631,72 @@ private Q_SLOTS:
 
     void PropertiesAnimInt()
     {
-        int len = 50;
         Properties p;
         p.set_lcnumeric("POSIX");
 
         // Construct animation from scratch
-        p.anim_set("foo",   0,  0, len);
-        p.anim_set("foo", 100, 50, len, mlt_keyframe_smooth);
-        QCOMPARE(p.anim_get_int("foo",  0, len), 0);
-        QCOMPARE(p.anim_get_int("foo", 25, len), 50);
-        QCOMPARE(p.anim_get_int("foo", 50, len), 100);
+        p.anim_set("foo",   0,  0);
+        p.anim_set("foo", 100, 50, -1, mlt_keyframe_smooth);
+        QCOMPARE(p.anim_get_int("foo",  0), 0);
+        QCOMPARE(p.anim_get_int("foo", 25), 50);
+        QCOMPARE(p.anim_get_int("foo", 50), 100);
         QCOMPARE(p.get("foo"), "0=0;50~=100");
 
         // Animation from string value
         p.set("foo", "10=100;20=200");
-        QCOMPARE(p.anim_get_int("foo",  0, len), 100);
-        QCOMPARE(p.anim_get_int("foo", 15, len), 150);
-        QCOMPARE(p.anim_get_int("foo", 20, len), 200);
+        QCOMPARE(p.anim_get_int("foo",  0), 100);
+        QCOMPARE(p.anim_get_int("foo", 15), 150);
+        QCOMPARE(p.anim_get_int("foo", 20), 200);
 
         // Animation from string using time clock values
         // Need to set a profile so fps can be used to convert time to frames.
         Profile profile("dv_pal");
         p.set("_profile", profile.get_profile(), 0);
         p.set("foo", ":0.0=100; :2.0=200");
-        QCOMPARE(p.anim_get_int("foo",  0, len), 100);
-        QCOMPARE(p.anim_get_int("foo", 25, len), 150);
-        QCOMPARE(p.anim_get_int("foo", 50, len), 200);
+        QCOMPARE(p.anim_get_int("foo",  0), 100);
+        QCOMPARE(p.anim_get_int("foo", 25), 150);
+        QCOMPARE(p.anim_get_int("foo", 50), 200);
     }
 
     void PropertiesAnimDouble()
     {
-        int len = 50;
         Properties p;
         p.set_lcnumeric("POSIX");
 
         // Construct animation from scratch
-        p.anim_set("foo",   0.0,  0, len);
-        p.anim_set("foo", 100.0, 50, len, mlt_keyframe_smooth);
-        QCOMPARE(p.anim_get_double("foo",  0, len), 0.0);
-        QCOMPARE(p.anim_get_double("foo", 25, len), 50.0);
-        QCOMPARE(p.anim_get_double("foo", 50, len), 100.0);
+        p.anim_set("foo",   0.0,  0);
+        p.anim_set("foo", 100.0, 50, -1, mlt_keyframe_smooth);
+        QCOMPARE(p.anim_get_double("foo",  0), 0.0);
+        QCOMPARE(p.anim_get_double("foo", 25), 50.0);
+        QCOMPARE(p.anim_get_double("foo", 50), 100.0);
         QCOMPARE(p.get("foo"), "0=0;50~=100");
 
         // Animation from string value
         p.set("foo", "10=100.2;20=200.8");
-        QCOMPARE(p.anim_get_double("foo",  0, len), 100.2);
-        QCOMPARE(p.anim_get_double("foo", 15, len), 150.5);
-        QCOMPARE(p.anim_get_double("foo", 20, len), 200.8);
+        QCOMPARE(p.anim_get_double("foo",  0), 100.2);
+        QCOMPARE(p.anim_get_double("foo", 15), 150.5);
+        QCOMPARE(p.anim_get_double("foo", 20), 200.8);
 
         // Animation from string using time clock values
         // Need to set a profile so fps can be used to convert time to frames.
         Profile profile("dv_pal");
         p.set("_profile", profile.get_profile(), 0);
         p.set("foo", ":0.0=100; :2.0=200");
-        QCOMPARE(p.anim_get_double("foo",  0, len), 100.0);
-        QCOMPARE(p.anim_get_double("foo", 25, len), 150.0);
-        QCOMPARE(p.anim_get_double("foo", 50, len), 200.0);
+        QCOMPARE(p.anim_get_double("foo",  0), 100.0);
+        QCOMPARE(p.anim_get_double("foo", 25), 150.0);
+        QCOMPARE(p.anim_get_double("foo", 50), 200.0);
     }
 
     void PropertiesStringAnimation()
     {
         Properties p;
-        int len = 50;
-        p.anim_set("key", "foo", 10, len);
-        p.anim_set("key", "bar", 30, len);
+        p.anim_set("key", "foo", 10);
+        p.anim_set("key", "bar", 30);
         QCOMPARE(p.get("key"), "10|=foo;30|=bar");
         p.set("key", "0=; 10=foo bar; 30=hello world");
-        QCOMPARE(p.anim_get("key",  1, len), "");
-        QCOMPARE(p.anim_get("key", 15, len), "foo bar");
-        QCOMPARE(p.anim_get("key", 45, len), "hello world");
+        QCOMPARE(p.anim_get("key",  1), "");
+        QCOMPARE(p.anim_get("key", 15), "foo bar");
+        QCOMPARE(p.anim_get("key", 45), "hello world");
     }
 
     void test_mlt_rect()
@@ -777,63 +778,62 @@ private Q_SLOTS:
 
     void RectAnimation()
     {
-        int len = 50;
         mlt_rect r1 = { 0, 0, 200, 200, 0 };
         mlt_rect r2 = { 100, 100, 400, 400, 1.0 };
         Properties p;
         p.set_lcnumeric("POSIX");
 
         // Construct animation from scratch
-        p.anim_set("key", r1,  0, len);
-        p.anim_set("key", r2, 50, len);
-        QCOMPARE(p.anim_get_rect("key",  0, len).x, 0.0);
-        QCOMPARE(p.anim_get_rect("key", 25, len).x, 50.0);
-        QCOMPARE(p.anim_get_rect("key", 25, len).y, 50.0);
-        QCOMPARE(p.anim_get_rect("key", 25, len).w, 300.0);
-        QCOMPARE(p.anim_get_rect("key", 25, len).h, 300.0);
-        QCOMPARE(p.anim_get_rect("key", 25, len).o, 0.5);
-        QCOMPARE(p.anim_get_rect("key", 50, len).x, 100.0);
+        p.anim_set("key", r1,  0);
+        p.anim_set("key", r2, 50);
+        QCOMPARE(p.anim_get_rect("key",  0).x, 0.0);
+        QCOMPARE(p.anim_get_rect("key", 25).x, 50.0);
+        QCOMPARE(p.anim_get_rect("key", 25).y, 50.0);
+        QCOMPARE(p.anim_get_rect("key", 25).w, 300.0);
+        QCOMPARE(p.anim_get_rect("key", 25).h, 300.0);
+        QCOMPARE(p.anim_get_rect("key", 25).o, 0.5);
+        QCOMPARE(p.anim_get_rect("key", 50).x, 100.0);
         QCOMPARE(p.get("key"), "0=0 0 200 200 0;50=100 100 400 400 1");
 
         // Animation from string value
-        QCOMPARE(p.anim_get_rect("key",  0, len).x, 0.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).y, 0.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).w, 200.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).h, 200.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).o, 0.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).x, 100.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).y, 100.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).w, 400.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).h, 400.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).o, 1.0);
-        QCOMPARE(p.anim_get_rect("key", 15, len).x, 30.0);
-        QCOMPARE(p.anim_get_rect("key", 15, len).y, 30.0);
-        QCOMPARE(p.anim_get_rect("key", 15, len).w, 260.0);
-        QCOMPARE(p.anim_get_rect("key", 15, len).h, 260.0);
-        QCOMPARE(p.anim_get_rect("key", 15, len).o, 0.3);
+        QCOMPARE(p.anim_get_rect("key",  0).x, 0.0);
+        QCOMPARE(p.anim_get_rect("key",  0).y, 0.0);
+        QCOMPARE(p.anim_get_rect("key",  0).w, 200.0);
+        QCOMPARE(p.anim_get_rect("key",  0).h, 200.0);
+        QCOMPARE(p.anim_get_rect("key",  0).o, 0.0);
+        QCOMPARE(p.anim_get_rect("key", 50).x, 100.0);
+        QCOMPARE(p.anim_get_rect("key", 50).y, 100.0);
+        QCOMPARE(p.anim_get_rect("key", 50).w, 400.0);
+        QCOMPARE(p.anim_get_rect("key", 50).h, 400.0);
+        QCOMPARE(p.anim_get_rect("key", 50).o, 1.0);
+        QCOMPARE(p.anim_get_rect("key", 15).x, 30.0);
+        QCOMPARE(p.anim_get_rect("key", 15).y, 30.0);
+        QCOMPARE(p.anim_get_rect("key", 15).w, 260.0);
+        QCOMPARE(p.anim_get_rect("key", 15).h, 260.0);
+        QCOMPARE(p.anim_get_rect("key", 15).o, 0.3);
 
         // Smooth animation
         p.set("key", "0~=0/0:200x200:0; 50=100/100:400x400:1");
-        QCOMPARE(p.anim_get_rect("key",  0, len).x, 0.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).y, 0.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).w, 200.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).h, 200.0);
-        QCOMPARE(p.anim_get_rect("key",  0, len).o, 0.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).x, 100.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).y, 100.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).w, 400.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).h, 400.0);
-        QCOMPARE(p.anim_get_rect("key", 50, len).o, 1.0);
-        QCOMPARE(p.anim_get_rect("key", 15, len).x, 25.8);
-        QCOMPARE(p.anim_get_rect("key", 15, len).y, 25.8);
-        QCOMPARE(p.anim_get_rect("key", 15, len).w, 251.6);
-        QCOMPARE(p.anim_get_rect("key", 15, len).h, 251.6);
-        QCOMPARE(p.anim_get_rect("key", 15, len).o, 0.258);
+        QCOMPARE(p.anim_get_rect("key",  0).x, 0.0);
+        QCOMPARE(p.anim_get_rect("key",  0).y, 0.0);
+        QCOMPARE(p.anim_get_rect("key",  0).w, 200.0);
+        QCOMPARE(p.anim_get_rect("key",  0).h, 200.0);
+        QCOMPARE(p.anim_get_rect("key",  0).o, 0.0);
+        QCOMPARE(p.anim_get_rect("key", 50).x, 100.0);
+        QCOMPARE(p.anim_get_rect("key", 50).y, 100.0);
+        QCOMPARE(p.anim_get_rect("key", 50).w, 400.0);
+        QCOMPARE(p.anim_get_rect("key", 50).h, 400.0);
+        QCOMPARE(p.anim_get_rect("key", 50).o, 1.0);
+        QCOMPARE(p.anim_get_rect("key", 15).x, 25.8);
+        QCOMPARE(p.anim_get_rect("key", 15).y, 25.8);
+        QCOMPARE(p.anim_get_rect("key", 15).w, 251.6);
+        QCOMPARE(p.anim_get_rect("key", 15).h, 251.6);
+        QCOMPARE(p.anim_get_rect("key", 15).o, 0.258);
 
         // Using percentages
         p.set("key", "0=0 0; 50=100% 200%");
-        QCOMPARE(p.anim_get_rect("key", 25, len).x, 0.5);
-        QCOMPARE(p.anim_get_rect("key", 25, len).y, 1.0);
+        QCOMPARE(p.anim_get_rect("key", 25).x, 0.5);
+        QCOMPARE(p.anim_get_rect("key", 25).y, 1.0);
     }
 
     void ColorFromInt()
@@ -867,6 +867,38 @@ private Q_SLOTS:
         QCOMPARE(color.b, quint8(0x0d));
         QCOMPARE(color.a, quint8(0xde));
     }
+
+    void SetIntAndGetAnim()
+    {
+        Properties p;
+        p.set_lcnumeric("POSIX");
+        p.set("key", 123);
+        QCOMPARE(p.anim_get_int("key", 10, 50), 123);
+        p.set("key", "123");
+        QCOMPARE(p.anim_get_int("key", 10, 50), 123);
+    }
+
+    void SetDoubleAndGetAnim()
+    {
+        Properties p;
+        p.set_lcnumeric("POSIX");
+        p.set("key", 123.0);
+        QCOMPARE(p.anim_get_double("key", 10, 50), 123.0);
+        p.set("key", "123");
+        QCOMPARE(p.anim_get_double("key", 10, 50), 123.0);
+    }
+
+    void AnimNegativeTimevalue()
+    {
+        Properties p;
+        Profile profile("dv_pal");
+        p.set("_profile", profile.get_profile(), 0);
+        p.set_lcnumeric("POSIX");
+        p.set("key", "0=100; -1=200");
+        QCOMPARE(p.anim_get_int("key", 75, 100), 175);
+        p.set("key", "0=100; -1:=200");
+        QCOMPARE(p.anim_get_int("key", 75, 125), 175);
+    }
 };
 
 QTEST_APPLESS_MAIN(TestProperties)