]> git.sesse.net Git - mlt/blobdiff - src/framework/mlt_properties.c
Implement LC_NUMERIC handling for non-glibc and non-Darwin OS.
[mlt] / src / framework / mlt_properties.c
index c649137616a5e8305de0d83a373a531550c2ca84..887562c3467fee9dff0de058e5e04d885497f054 100644 (file)
@@ -3,7 +3,7 @@
  * \brief Properties class definition
  * \see mlt_properties_s
  *
- * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2013 Ushodaya Enterprises Limited
  * \author Charles Yates <charles.yates@pandora.be>
  * \author Dan Dennedy <dan@dennedy.org>
  *
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+// For strtod_l
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include "mlt_properties.h"
 #include "mlt_property.h"
 #include "mlt_deque.h"
@@ -139,12 +144,15 @@ int mlt_properties_set_lcnumeric( mlt_properties self, const char *locale )
        {
                property_list *list = self->local;
 
-#if defined(__linux__) || defined(__DARWIN__)
+#if defined(__GLIBC__) || defined(__DARWIN__)
                if ( list->locale )
                        freelocale( list->locale );
                list->locale = newlocale( LC_NUMERIC_MASK, locale, NULL );
+#else
+               if ( list->locale )
+                       free( list->locale );
+               list->locale = strdup( locale );
 #endif
-               error = list->locale == NULL;
        }
        else
                error = 1;
@@ -168,13 +176,13 @@ const char* mlt_properties_get_lcnumeric( mlt_properties self )
        if ( list->locale )
        {
 #if defined(__DARWIN__)
-               result = querylocale( LC_NUMERIC, list->locale );
-#elif defined(__linux__)
-               result = list->locale->__names[ LC_NUMERIC ];
+        result = querylocale( LC_NUMERIC, list->locale );
+#elif defined(__GLIBC__)
+        result = list->locale->__names[ LC_NUMERIC ];
 #else
-               // TODO: not yet sure what to do on other platforms
+               result = list->locale;
 #endif
-       }
+    }
        return result;
 }
 
@@ -323,11 +331,10 @@ int mlt_properties_preset( mlt_properties self, const char *name )
 
 static inline int generate_hash( const char *name )
 {
-       int hash = 0;
-       int i = 1;
+       unsigned int hash = 5381;
        while ( *name )
-               hash = ( hash + ( i ++ * ( *name ++ & 31 ) ) ) % 199;
-       return hash;
+               hash = hash * 33 + (unsigned int) ( *name ++ );
+       return hash % 199;
 }
 
 /** Copy a serializable property to a properties list that is mirroring this one.
@@ -503,13 +510,12 @@ static inline mlt_property mlt_properties_find( mlt_properties self, const char
        {
                // Check if we're hashed
                if ( list->count > 0 &&
-                       name[ 0 ] == list->name[ i ][ 0 ] &&
                        !strcmp( list->name[ i ], name ) )
                        value = list->value[ i ];
 
                // Locate the item
                for ( i = list->count - 1; value == NULL && i >= 0; i -- )
-                       if ( name[ 0 ] == list->name[ i ][ 0 ] && !strcmp( list->name[ i ], name ) )
+                       if ( !strcmp( list->name[ i ], name ) )
                                value = list->value[ i ];
        }
        mlt_properties_unlock( self );
@@ -705,8 +711,8 @@ int mlt_properties_set( mlt_properties self, const char *name, const char *value
                                property_list *list = self->local;
                                if ( list->locale )
                                        current = strtod_l( id, NULL, list->locale );
+                else
 #endif
-                               else
                                        current = strtod( id, NULL );
                        }
                        else
@@ -772,9 +778,14 @@ int mlt_properties_set_or_default( mlt_properties self, const char *name, const
 
 char *mlt_properties_get( mlt_properties self, const char *name )
 {
+       char *result = NULL;
        mlt_property value = mlt_properties_find( self, name );
-       property_list *list = self->local;
-       return value == NULL ? NULL : mlt_property_get_string_l( value, list->locale );
+       if ( value )
+       {
+               property_list *list = self->local;
+               result = mlt_property_get_string_l( value, list->locale );
+       }
+       return result;
 }
 
 /** Get a property name by index.
@@ -901,11 +912,16 @@ int mlt_properties_parse( mlt_properties self, const char *namevalue )
 
 int mlt_properties_get_int( mlt_properties self, const char *name )
 {
-       mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
-       double fps = mlt_profile_fps( profile );
-       property_list *list = self->local;
+       int result = 0;
        mlt_property value = mlt_properties_find( self, name );
-       return value == NULL ? 0 : mlt_property_get_int( value, fps, list->locale );
+       if ( value )
+       {
+               mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+               double fps = mlt_profile_fps( profile );
+               property_list *list = self->local;
+               result = mlt_property_get_int( value, fps, list->locale );
+       }
+       return result;
 }
 
 /** Set a property to an integer value.
@@ -992,11 +1008,16 @@ int mlt_properties_set_int64( mlt_properties self, const char *name, int64_t val
 
 double mlt_properties_get_double( mlt_properties self, const char *name )
 {
-       mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
-       double fps = mlt_profile_fps( profile );
+       double result = 0;
        mlt_property value = mlt_properties_find( self, name );
-       property_list *list = self->local;
-       return value == NULL ? 0 : mlt_property_get_double( value, fps, list->locale );
+       if ( value )
+       {
+               mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+               double fps = mlt_profile_fps( profile );
+               property_list *list = self->local;
+               result = mlt_property_get_double( value, fps, list->locale );
+       }
+       return result;
 }
 
 /** Set a property to a floating point value.
@@ -1039,11 +1060,16 @@ int mlt_properties_set_double( mlt_properties self, const char *name, double val
 
 mlt_position mlt_properties_get_position( mlt_properties self, const char *name )
 {
-       mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
-       double fps = mlt_profile_fps( profile );
-       property_list *list = self->local;
+       mlt_position result = 0;
        mlt_property value = mlt_properties_find( self, name );
-       return value == NULL ? 0 : mlt_property_get_position( value, fps, list->locale );
+       if ( value )
+       {
+               mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+               double fps = mlt_profile_fps( profile );
+               property_list *list = self->local;
+               result = mlt_property_get_position( value, fps, list->locale );
+       }
+       return result;
 }
 
 /** Set a property to a position value.
@@ -1371,10 +1397,13 @@ void mlt_properties_close( mlt_properties self )
                                free( list->name[ index ] );
                        }
 
-#if defined(__linux__) || defined(__DARWIN__)
+#if defined(__GLIBC__) || defined(__DARWIN__)
                        // Cleanup locale
                        if ( list->locale )
                                freelocale( list->locale );
+#else
+                       if ( list->locale )
+                               free( list->locale );
 #endif
 
                        // Clear up the list
@@ -2067,6 +2096,49 @@ char *mlt_properties_get_time( mlt_properties self, const char* name, mlt_time_f
        return NULL;
 }
 
+/** Convert a frame count to a time string.
+ *
+ * Do not free the returned string. It's lifetime is controlled by the property.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param frames the frame count to convert
+ * \param format the time format that you want
+ * \return the time string or NULL if error, e.g. there is no profile
+ */
+
+char *mlt_properties_frames_to_time( mlt_properties self, mlt_position frames, mlt_time_format format )
+{
+       const char *name = "_mlt_properties_time";
+       mlt_properties_set_position( self, name, frames );
+       return mlt_properties_get_time( self, name, format );
+}
+
+/** Convert a time string to a frame count.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param time the time string to convert
+ * \return a frame count or a negative value if error, e.g. there is no profile
+ */
+
+mlt_position mlt_properties_time_to_frames( mlt_properties self, const char *time )
+{
+       const char *name = "_mlt_properties_time";
+       mlt_properties_set( self, name, time );
+       return mlt_properties_get_position( self, name );
+}
+
+/** Convert a numeric property to a tuple of color components.
+ *
+ * If the property's string is red, green, blue, white, or black, then it
+ * is converted to the corresponding opaque color tuple. Otherwise, the property
+ * is fetched as an integer and then converted.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \return a color structure
+ */
+
 mlt_color mlt_properties_get_color( mlt_properties self, const char* name )
 {
        mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
@@ -2119,7 +2191,7 @@ mlt_color mlt_properties_get_color( mlt_properties self, const char* name )
  * \public \memberof mlt_properties_s
  * \param self a properties list
  * \param name the property to set
- * \param value the color
+ * \param color the color
  * \return true if error
  */
 
@@ -2145,13 +2217,16 @@ int mlt_properties_set_color( mlt_properties self, const char *name, mlt_color c
        return error;
 }
 
-/** Get a string value by name.
+/** Get a string value by name at a frame position.
  *
  * Do not free the returned string. It's lifetime is controlled by the property
  * and this properties object.
  * \public \memberof mlt_properties_s
  * \param self a properties list
  * \param name the property to get
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
  * \return the property's string value or NULL if it does not exist
  */
 
@@ -2164,7 +2239,7 @@ char* mlt_properties_anim_get( mlt_properties self, const char *name, int positi
        return value == NULL ? NULL : mlt_property_anim_get_string( value, fps, list->locale, position, length );
 }
 
-/** Set a property to a string.
+/** Set a property to a string at a frame position.
  *
  * The event "property-changed" is fired after the property has been set.
  *
@@ -2173,6 +2248,9 @@ char* mlt_properties_anim_get( mlt_properties self, const char *name, int positi
  * \param self a properties list
  * \param name the property to set
  * \param value the property's new value
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
  * \return true if error
  */
 
@@ -2206,7 +2284,10 @@ int mlt_properties_anim_set( mlt_properties self, const char *name, const char *
  * \public \memberof mlt_properties_s
  * \param self a properties list
  * \param name the property to get
- * \return The integer value, 0 if not found (which may also be a legitimate value)
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
+ * \return the integer value, 0 if not found (which may also be a legitimate value)
  */
 
 int mlt_properties_anim_get_int( mlt_properties self, const char *name, int position, int length )
@@ -2224,6 +2305,10 @@ int mlt_properties_anim_get_int( mlt_properties self, const char *name, int posi
  * \param self a properties list
  * \param name the property to set
  * \param value the integer
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
+ * \param keyframe_type the interpolation method for this keyframe
  * \return true if error
  */
 
@@ -2257,7 +2342,10 @@ int mlt_properties_anim_set_int( mlt_properties self, const char *name, int valu
  * \public \memberof mlt_properties_s
  * \param self a properties list
  * \param name the property to get
- * \return The real number, 0 if not found (which may also be a legitimate value)
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
+ * \return the real number, 0 if not found (which may also be a legitimate value)
  */
 
 double mlt_properties_anim_get_double( mlt_properties self, const char *name, int position, int length )
@@ -2275,6 +2363,10 @@ double mlt_properties_anim_get_double( mlt_properties self, const char *name, in
  * \param self a properties list
  * \param name the property to set
  * \param value the real number
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
+ * \param keyframe_type the interpolation method for this keyframe
  * \return true if error
  */
 
@@ -2303,6 +2395,20 @@ int mlt_properties_anim_set_double( mlt_properties self, const char *name, doubl
        return error;
 }
 
+/** Get the animation associated to the name.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \return The animation object or NULL if the property has no animation
+ */
+
+mlt_animation mlt_properties_get_animation( mlt_properties self, const char *name )
+{
+       mlt_property value = mlt_properties_find( self, name );
+       return value == NULL ? NULL : mlt_property_get_animation( value );
+}
+
 /** Set a property to a rectangle value.
  *
  * \public \memberof mlt_properties_s
@@ -2338,7 +2444,7 @@ extern int mlt_properties_set_rect( mlt_properties self, const char *name, mlt_r
  * \public \memberof mlt_properties_s
  * \param self a properties list
  * \param name the property to get
- * \return The rectangle value, the rectangle fields will be DBL_MIN if not found
+ * \return the rectangle value, the rectangle fields will be DBL_MIN if not found
  */
 
 extern mlt_rect mlt_properties_get_rect( mlt_properties self, const char* name )
@@ -2355,6 +2461,10 @@ extern mlt_rect mlt_properties_get_rect( mlt_properties self, const char* name )
  * \param self a properties list
  * \param name the property to set
  * \param value the rectangle
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
+ * \param keyframe_type the interpolation method for this keyframe
  * \return true if error
  */
 
@@ -2383,12 +2493,15 @@ extern int mlt_properties_anim_set_rect( mlt_properties self, const char *name,
        return error;
 }
 
-/** Get a rectangle associated to the name.
+/** Get a rectangle associated to the name at a frame position.
  *
  * \public \memberof mlt_properties_s
  * \param self a properties list
  * \param name the property to get
- * \return The rectangle value, the rectangle fields will be DBL_MIN if not found
+ * \param position the frame number
+ * \param length the maximum number of frames when interpreting negative keyframe times,
+ *  <=0 if you don't care or need that
+ * \return the rectangle value, the rectangle fields will be DBL_MIN if not found
  */
 
 extern mlt_rect mlt_properties_anim_get_rect( mlt_properties self, const char *name, int position, int length )