libavutil/rational.h
5ff85f1d
 /*
89c9ff50
  * rational numbers
5ff85f1d
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
b78e7197
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
5ff85f1d
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
b78e7197
  * version 2.1 of the License, or (at your option) any later version.
5ff85f1d
  *
b78e7197
  * FFmpeg is distributed in the hope that it will be useful,
5ff85f1d
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
b78e7197
  * License along with FFmpeg; if not, write to the Free Software
5509bffa
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5ff85f1d
  */
115329f1
 
5ff85f1d
 /**
ba87f080
  * @file
952c4cf7
  * @ingroup lavu_math_rational
  * Utilties for rational number calculation.
5ff85f1d
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
98790382
 #ifndef AVUTIL_RATIONAL_H
 #define AVUTIL_RATIONAL_H
5ff85f1d
 
99545457
 #include <stdint.h>
dec11269
 #include <limits.h>
2ed6f399
 #include "attributes.h"
99545457
 
5c07b9e9
 /**
952c4cf7
  * @defgroup lavu_math_rational AVRational
  * @ingroup lavu_math
  * Rational number calculation.
  *
  * While rational numbers can be expressed as floating-point numbers, the
  * conversion process is a lossy one, so are floating-point operations. On the
  * other hand, the nature of FFmpeg demands highly accurate calculation of
  * timestamps. This set of rational number utilities serves as a generic
  * interface for manipulating rational numbers as pairs of numerators and
  * denominators.
  *
  * Many of the functions that operate on AVRational's have the suffix `_q`, in
  * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all
  * rational numbers.
  *
757cd8d8
  * @{
  */
 
 /**
952c4cf7
  * Rational number (pair of numerator and denominator).
5c07b9e9
  */
5ff85f1d
 typedef struct AVRational{
952c4cf7
     int num; ///< Numerator
     int den; ///< Denominator
5ff85f1d
 } AVRational;
 
5c07b9e9
 /**
952c4cf7
  * Create an AVRational.
  *
3532dd52
  * Useful for compilers that do not support compound literals.
952c4cf7
  *
  * @note The return value is not reduced.
  * @see av_reduce()
3532dd52
  */
 static inline AVRational av_make_q(int num, int den)
 {
     AVRational r = { num, den };
     return r;
 }
 
 /**
49bd8e4b
  * Compare two rationals.
952c4cf7
  *
  * @param a First rational
  * @param b Second rational
  *
  * @return One of the following values:
  *         - 0 if `a == b`
  *         - 1 if `a > b`
  *         - -1 if `a < b`
  *         - `INT_MIN` if one of the values is of the form `0 / 0`
5c07b9e9
  */
5ff85f1d
 static inline int av_cmp_q(AVRational a, AVRational b){
     const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;
 
16c3ed58
     if(tmp) return (int)((tmp ^ a.den ^ b.den)>>63)|1;
dec11269
     else if(b.den && a.den) return 0;
     else if(a.num && b.num) return (a.num>>31) - (b.num>>31);
     else                    return INT_MIN;
5ff85f1d
 }
 
5c07b9e9
 /**
952c4cf7
  * Convert an AVRational to a `double`.
  * @param a AVRational to convert
  * @return `a` in floating-point form
  * @see av_d2q()
5c07b9e9
  */
5ff85f1d
 static inline double av_q2d(AVRational a){
     return a.num / (double) a.den;
 }
 
c11c2bc2
 /**
49bd8e4b
  * Reduce a fraction.
952c4cf7
  *
804de96a
  * This is useful for framerate calculations.
952c4cf7
  *
  * @param[out] dst_num Destination numerator
  * @param[out] dst_den Destination denominator
  * @param[in]      num Source numerator
  * @param[in]      den Source denominator
  * @param[in]      max Maximum allowed values for `dst_num` & `dst_den`
  * @return 1 if the operation is exact, 0 otherwise
c11c2bc2
  */
674bd4f6
 int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max);
c11c2bc2
 
0b006599
 /**
49bd8e4b
  * Multiply two rationals.
952c4cf7
  * @param b First rational
  * @param c Second rational
89c9ff50
  * @return b*c
0b006599
  */
85074d3c
 AVRational av_mul_q(AVRational b, AVRational c) av_const;
0b006599
 
 /**
49bd8e4b
  * Divide one rational by another.
952c4cf7
  * @param b First rational
  * @param c Second rational
89c9ff50
  * @return b/c
0b006599
  */
85074d3c
 AVRational av_div_q(AVRational b, AVRational c) av_const;
0b006599
 
 /**
49bd8e4b
  * Add two rationals.
952c4cf7
  * @param b First rational
  * @param c Second rational
89c9ff50
  * @return b+c
0b006599
  */
85074d3c
 AVRational av_add_q(AVRational b, AVRational c) av_const;
0b006599
 
 /**
49bd8e4b
  * Subtract one rational from another.
952c4cf7
  * @param b First rational
  * @param c Second rational
89c9ff50
  * @return b-c
0b006599
  */
85074d3c
 AVRational av_sub_q(AVRational b, AVRational c) av_const;
0b006599
 
 /**
82494835
  * Invert a rational.
  * @param q value
  * @return 1 / q
  */
 static av_always_inline AVRational av_inv_q(AVRational q)
 {
     AVRational r = { q.den, q.num };
     return r;
 }
 
 /**
49bd8e4b
  * Convert a double precision floating point number to a rational.
6b4ed22f
  *
952c4cf7
  * In case of infinity, the returned value is expressed as `{1, 0}` or
  * `{-1, 0}` depending on the sign.
  *
  * @param d   `double` to convert
  * @param max Maximum allowed numerator and denominator
  * @return `d` in AVRational form
  * @see av_q2d()
0b006599
  */
85074d3c
 AVRational av_d2q(double d, int max) av_const;
5ff85f1d
 
05b90fc0
 /**
952c4cf7
  * Find which of the two rationals is closer to another rational.
  *
  * @param q     Rational to be compared against
  * @param q1,q2 Rationals to be tested
  * @return One of the following values:
  *         - 1 if `q1` is nearer to `q` than `q2`
  *         - -1 if `q2` is nearer to `q` than `q1`
  *         - 0 if they have the same distance
05b90fc0
  */
 int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
 
 /**
952c4cf7
  * Find the value in a list of rationals nearest a given reference rational.
  *
  * @param q      Reference rational
  * @param q_list Array of rationals terminated by `{0, 0}`
  * @return Index of the nearest value found in the array
05b90fc0
  */
 int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
 
757cd8d8
 /**
952c4cf7
  * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point
  * format.
1fb9b2a2
  *
952c4cf7
  * @param q Rational to be converted
  * @return Equivalent floating-point value, expressed as an unsigned 32-bit
  *         integer.
  * @note The returned value is platform-indepedant.
1fb9b2a2
  */
 uint32_t av_q2intfloat(AVRational q);
 
 /**
757cd8d8
  * @}
  */
 
98790382
 #endif /* AVUTIL_RATIONAL_H */