## ffmpeg / libavutil / rational.c @ ed90d370

History | View | Annotate | Download (2.89 KB)

1 | 5ff85f1d | Michael Niedermayer | ```
/*
``` |
---|---|---|---|

2 | ```
* Rational numbers
``` |
||

3 | ```
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
``` |
||

4 | ```
*
``` |
||

5 | ```
* This library is free software; you can redistribute it and/or
``` |
||

6 | ```
* modify it under the terms of the GNU Lesser General Public
``` |
||

7 | ```
* License as published by the Free Software Foundation; either
``` |
||

8 | ```
* version 2 of the License, or (at your option) any later version.
``` |
||

9 | ```
*
``` |
||

10 | ```
* This library is distributed in the hope that it will be useful,
``` |
||

11 | ```
* but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |
||

12 | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |
||

13 | ```
* Lesser General Public License for more details.
``` |
||

14 | ```
*
``` |
||

15 | ```
* You should have received a copy of the GNU Lesser General Public
``` |
||

16 | ```
* License along with this library; if not, write to the Free Software
``` |
||

17 | 5509bffa | Diego Biurrun | ```
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
``` |

18 | 5ff85f1d | Michael Niedermayer | ```
*
``` |

19 | ```
*/
``` |
||

20 | 115329f1 | Diego Biurrun | |

21 | 5ff85f1d | Michael Niedermayer | ```
/**
``` |

22 | ```
* @file rational.c
``` |
||

23 | ```
* Rational numbers
``` |
||

24 | ```
* @author Michael Niedermayer <michaelni@gmx.at>
``` |
||

25 | ```
*/
``` |
||

26 | |||

27 | ```
//#include <math.h>
``` |
||

28 | #include <limits.h> |
||

29 | 115329f1 | Diego Biurrun | |

30 | 5ff85f1d | Michael Niedermayer | #include "common.h" |

31 | c11c2bc2 | Alexander Strasser | #include "mathematics.h" |

32 | 5ff85f1d | Michael Niedermayer | #include "rational.h" |

33 | |||

34 | c11c2bc2 | Alexander Strasser | int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ |

35 | AVRational a0={0,1}, a1={1,0}; |
||

36 | int sign= (nom<0) ^ (den<0); |
||

37 | int64_t gcd= ff_gcd(ABS(nom), ABS(den)); |
||

38 | |||

39 | nom = ABS(nom)/gcd; |
||

40 | den = ABS(den)/gcd; |
||

41 | ```
if(nom<=max && den<=max){
``` |
||

42 | a1= (AVRational){nom, den}; |
||

43 | ```
den=0;
``` |
||

44 | } |
||

45 | 115329f1 | Diego Biurrun | |

46 | c11c2bc2 | Alexander Strasser | ```
while(den){
``` |

47 | int64_t x = nom / den; |
||

48 | int64_t next_den= nom - den*x; |
||

49 | int64_t a2n= x*a1.num + a0.num; |
||

50 | int64_t a2d= x*a1.den + a0.den; |
||

51 | |||

52 | if(a2n > max || a2d > max) break; |
||

53 | |||

54 | a0= a1; |
||

55 | a1= (AVRational){a2n, a2d}; |
||

56 | nom= den; |
||

57 | den= next_den; |
||

58 | } |
||

59 | ```
assert(ff_gcd(a1.num, a1.den) == 1);
``` |
||

60 | 115329f1 | Diego Biurrun | |

61 | c11c2bc2 | Alexander Strasser | *dst_nom = sign ? -a1.num : a1.num; |

62 | *dst_den = a1.den; |
||

63 | 115329f1 | Diego Biurrun | |

64 | c11c2bc2 | Alexander Strasser | return den==0; |

65 | } |
||

66 | |||

67 | 5c07b9e9 | Michael Niedermayer | ```
/**
``` |

68 | ```
* returns b*c.
``` |
||

69 | ```
*/
``` |
||

70 | 5ff85f1d | Michael Niedermayer | AVRational av_mul_q(AVRational b, AVRational c){ |

71 | av_reduce(&b.num, &b.den, b.num * (int64_t)c.num, b.den * (int64_t)c.den, INT_MAX); |
||

72 | ```
return b;
``` |
||

73 | } |
||

74 | |||

75 | 5c07b9e9 | Michael Niedermayer | ```
/**
``` |

76 | ```
* returns b/c.
``` |
||

77 | ```
*/
``` |
||

78 | 5ff85f1d | Michael Niedermayer | AVRational av_div_q(AVRational b, AVRational c){ |

79 | av_reduce(&b.num, &b.den, b.num * (int64_t)c.den, b.den * (int64_t)c.num, INT_MAX); |
||

80 | ```
return b;
``` |
||

81 | } |
||

82 | |||

83 | 5c07b9e9 | Michael Niedermayer | ```
/**
``` |

84 | ```
* returns b+c.
``` |
||

85 | ```
*/
``` |
||

86 | 5ff85f1d | Michael Niedermayer | AVRational av_add_q(AVRational b, AVRational c){ |

87 | av_reduce(&b.num, &b.den, b.num * (int64_t)c.den + c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); |
||

88 | ```
return b;
``` |
||

89 | } |
||

90 | |||

91 | 5c07b9e9 | Michael Niedermayer | ```
/**
``` |

92 | ```
* returns b-c.
``` |
||

93 | ```
*/
``` |
||

94 | 5ff85f1d | Michael Niedermayer | AVRational av_sub_q(AVRational b, AVRational c){ |

95 | av_reduce(&b.num, &b.den, b.num * (int64_t)c.den - c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); |
||

96 | ```
return b;
``` |
||

97 | } |
||

98 | |||

99 | bf63eb4b | Michael Niedermayer | ```
/**
``` |

100 | ```
* Converts a double precission floating point number to a AVRational.
``` |
||

101 | ```
* @param max the maximum allowed numerator and denominator
``` |
||

102 | ```
*/
``` |
||

103 | 5ff85f1d | Michael Niedermayer | AVRational av_d2q(double d, int max){ |

104 | AVRational a; |
||

105 | 33a6984b | Michael Niedermayer | int exponent= FFMAX( (int)(log(ABS(d) + 1e-20)/log(2)), 0); |

106 | 5ff85f1d | Michael Niedermayer | int64_t den= 1LL << (61 - exponent); |

107 | av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max); |
||

108 | |||

109 | ```
return a;
``` |
||

110 | } |