Commit e2776598 authored by Gildas Bazin's avatar Gildas Bazin

* include/vlc_common.h, src/extras/libc.c: added GCD() and vlc_reduce().

parent 01993028
......@@ -475,6 +475,12 @@ typedef int ( * vlc_callback_t ) ( vlc_object_t *, /* variable's object */
# define __MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
#endif
static int64_t GCD( int64_t a, int64_t b )
{
if( b ) return GCD( b, a % b );
else return a;
}
/* Dynamic array handling: realloc array, move data, increment position */
#define INSERT_ELEM( p_ar, i_oldsize, i_pos, elem ) \
do \
......@@ -908,6 +914,8 @@ typedef __int64 off_t;
# define vlc_lseek NULL
#endif
VLC_EXPORT( vlc_bool_t, vlc_reduce, ( int *, int *, int64_t, int64_t, int64_t ) );
/* vlc_wraptext (defined in src/extras/libc.c) */
#define wraptext vlc_wraptext
VLC_EXPORT( char *, vlc_wraptext, ( const char *, int, vlc_bool_t ) );
......
......@@ -421,3 +421,68 @@ int vlc_iconv_close( vlc_iconv_t cd )
return 0;
#endif
}
/*****************************************************************************
* reduce a fraction
* (adapted from libavcodec, author Michael Niedermayer <michaelni@gmx.at>)
*****************************************************************************/
vlc_bool_t vlc_reduce( int *pi_dst_nom, int *pi_dst_den,
int64_t i_nom, int64_t i_den, int64_t i_max )
{
vlc_bool_t b_exact = 1, b_sign = 0;
int64_t i_gcd;
if( i_den == 0 )
{
i_nom = 0;
i_den = 1;
return 1;
}
if( i_den < 0 )
{
i_den = - i_den;
i_nom = - i_nom;
}
if( i_nom < 0 )
{
i_nom = - i_nom;
b_sign = 1;
}
i_gcd = GCD( i_nom, i_den );
i_nom /= i_gcd;
i_den /= i_gcd;
if( i_nom > i_max || i_den > i_max )
{
int i_a0_num = 0, i_a0_den = 1, i_a1_num = 1, i_a1_den = 0;
b_exact = 0;
for( ; ; )
{
int64_t i_x = i_nom / i_den;
int64_t i_a2n = i_x * i_a1_num + i_a0_num;
int64_t i_a2d = i_x * i_a1_den + i_a0_den;
if( i_a2n > i_max || i_a2d > i_max ) break;
i_nom %= i_den;
i_a0_num = i_a1_num; i_a0_den = i_a1_den;
i_a1_num = i_a2n; i_a1_den = i_a2d;
if( i_nom == 0 ) break;
i_x = i_nom; i_nom = i_den; i_den = i_x;
}
i_nom = i_a1_num;
i_den = i_a1_den;
}
if( b_sign ) i_nom = - i_nom;
*pi_dst_nom = i_nom;
*pi_dst_den = i_den;
return b_exact;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment