/** Parse a SMIL clock value.
*
* \private \memberof mlt_property_s
+ * \param self a property
* \param s the string to parse
* \param fps frames per second
* \param locale the locale to use for parsing a real number value
* \return position in frames
*/
-static int time_clock_to_frames( const char *s, double fps, locale_t locale )
+static int time_clock_to_frames( mlt_property self, const char *s, double fps, locale_t locale )
{
char *pos, *copy = strdup( s );
int hours = 0, minutes = 0;
s = copy;
pos = strrchr( s, ':' );
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+ char *orig_localename = NULL;
+ if ( locale )
+ {
+ // Protect damaging the global locale from a temporary locale on another thread.
+ pthread_mutex_lock( &self->mutex );
+
+ // Get the current locale
+ orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+
+ // Set the new locale
+ setlocale( LC_NUMERIC, locale );
+ }
+#endif
+
if ( pos ) {
#if defined(__GLIBC__) || defined(__DARWIN__)
if ( locale )
#endif
seconds = strtod( s, NULL );
}
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+ if ( locale ) {
+ // Restore the current locale
+ setlocale( LC_NUMERIC, orig_localename );
+ free( orig_localename );
+ pthread_mutex_unlock( &self->mutex );
+ }
+#endif
+
free( copy );
return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) );
/** Parse a SMPTE timecode string.
*
* \private \memberof mlt_property_s
+ * \param self a property
* \param s the string to parse
* \param fps frames per second
* \return position in frames
*/
-static int time_code_to_frames( const char *s, double fps )
+static int time_code_to_frames( mlt_property self, const char *s, double fps )
{
char *pos, *copy = strdup( s );
int hours = 0, minutes = 0, seconds = 0, frames;
* contains a period or comma character, the string is parsed as a clock value:
* HH:MM:SS. Otherwise, the time value is parsed as a SMPTE timecode: HH:MM:SS:FF.
* \private \memberof mlt_property_s
- * \param value a string to convert
+ * \param self a property
* \param fps frames per second, used when converting from time value
* \param locale the locale to use when converting from time clock value
* \return the resultant integer
*/
-static int mlt_property_atoi( const char *value, double fps, locale_t locale )
+static int mlt_property_atoi( mlt_property self, double fps, locale_t locale )
{
+ const char *value = self->prop_string;
+
// Parse a hex color value as #RRGGBB or #AARRGGBB.
if ( value[0] == '#' )
{
else if ( fps > 0 && strchr( value, ':' ) )
{
if ( strchr( value, '.' ) || strchr( value, ',' ) )
- return time_clock_to_frames( value, fps, locale );
+ return time_clock_to_frames( self, value, fps, locale );
else
- return time_code_to_frames( value, fps );
+ return time_code_to_frames( self, value, fps );
}
else
{
else if ( self->types & mlt_prop_rect && self->data )
return ( int ) ( (mlt_rect*) self->data )->x;
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return mlt_property_atoi( self->prop_string, fps, locale );
+ return mlt_property_atoi( self, fps, locale );
return 0;
}
* If the numeric string ends with '%' then the value is divided by 100 to convert
* it into a ratio.
* \private \memberof mlt_property_s
- * \param value the string to convert
+ * \param self a property
* \param fps frames per second, used when converting from time value
* \param locale the locale to use when converting from time clock value
* \return the resultant real number
*/
-static double mlt_property_atof( const char *value, double fps, locale_t locale )
+static double mlt_property_atof( mlt_property self, double fps, locale_t locale )
{
- if ( fps > 0 && strchr( value, ':' ) )
+ const char *value = self->prop_string;
+
+ if ( fps > 0 && strchr( value, ':' ) )
{
if ( strchr( value, '.' ) || strchr( value, ',' ) )
- return time_clock_to_frames( value, fps, locale );
+ return time_clock_to_frames( self, value, fps, locale );
else
- return time_code_to_frames( value, fps );
+ return time_code_to_frames( self, value, fps );
}
else
{
char *end = NULL;
double result;
+
#if defined(__GLIBC__) || defined(__DARWIN__)
if ( locale )
result = strtod_l( value, &end, locale );
- else
+ else
+#else
+ char *orig_localename = NULL;
+ if ( locale ) {
+ // Protect damaging the global locale from a temporary locale on another thread.
+ pthread_mutex_lock( &self->mutex );
+
+ // Get the current locale
+ orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+
+ // Set the new locale
+ setlocale( LC_NUMERIC, locale );
+ }
#endif
+
result = strtod( value, &end );
if ( end && end[0] == '%' )
result /= 100.0;
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+ if ( locale ) {
+ // Restore the current locale
+ setlocale( LC_NUMERIC, orig_localename );
+ free( orig_localename );
+ pthread_mutex_unlock( &self->mutex );
+ }
+#endif
+
return result;
}
}
else if ( self->types & mlt_prop_rect && self->data )
return ( (mlt_rect*) self->data )->x;
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return mlt_property_atof( self->prop_string, fps, locale );
+ return mlt_property_atof( self, fps, locale );
return 0;
}
else if ( self->types & mlt_prop_rect && self->data )
return ( mlt_position ) ( (mlt_rect*) self->data )->x;
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
- return ( mlt_position )mlt_property_atoi( self->prop_string, fps, locale );
+ return ( mlt_position )mlt_property_atoi( self, fps, locale );
return 0;
}
#elif defined(__GLIBC__)
const char *localename = locale->__names[ LC_NUMERIC ];
#else
- // TODO: not yet sure what to do on other platforms
- const char *localename = NULL;
+ const char *localename = locale;
#endif
// Protect damaging the global locale from a temporary locale on another thread.
pthread_mutex_lock( &self->mutex );
char *mlt_property_get_time( mlt_property self, mlt_time_format format, double fps, locale_t locale )
{
char *orig_localename = NULL;
- const char *localename = NULL;
+ const char *localename = "C";
// Optimization for mlt_time_frames
if ( format == mlt_time_frames )
{
double temp;
char *p = NULL;
+
#if defined(__GLIBC__) || defined(__DARWIN__)
if ( locale )
temp = strtod_l( self->prop_string, &p, locale );
else
+#else
+ char *orig_localename = NULL;
+ if ( locale ) {
+ // Protect damaging the global locale from a temporary locale on another thread.
+ pthread_mutex_lock( &self->mutex );
+
+ // Get the current locale
+ orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+
+ // Set the new locale
+ setlocale( LC_NUMERIC, locale );
+ }
#endif
+
temp = strtod( self->prop_string, &p );
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+ if ( locale ) {
+ // Restore the current locale
+ setlocale( LC_NUMERIC, orig_localename );
+ free( orig_localename );
+ pthread_mutex_unlock( &self->mutex );
+ }
+#endif
+
result = ( p != self->prop_string );
}
return result;
}
else
{
- double value;
+ double value = 0.0;
if ( interp == mlt_keyframe_linear )
{
double points[2];
rect.x = ( double )self->prop_int64;
else if ( ( self->types & mlt_prop_string ) && self->prop_string )
{
- //return mlt_property_atof( self->prop_string, fps, locale );
char *value = self->prop_string;
char *p = NULL;
int count = 0;
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+ char *orig_localename = NULL;
+ if ( locale ) {
+ // Protect damaging the global locale from a temporary locale on another thread.
+ pthread_mutex_lock( &self->mutex );
+
+ // Get the current locale
+ orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+
+ // Set the new locale
+ setlocale( LC_NUMERIC, locale );
+ }
+#endif
+
while ( *value )
{
double temp;
value = p;
count ++;
}
- }
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+ if ( locale ) {
+ // Restore the current locale
+ setlocale( LC_NUMERIC, orig_localename );
+ free( orig_localename );
+ pthread_mutex_unlock( &self->mutex );
+ }
+#endif
+ }
return rect;
}