OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef MOJO_SERVICES_MEDIA_COMMON_CPP_LINEAR_FUNCTION_H_ | |
6 #define MOJO_SERVICES_MEDIA_COMMON_CPP_LINEAR_FUNCTION_H_ | |
7 | |
8 #include "mojo/public/cpp/environment/logging.h" | |
9 #include "mojo/services/media/common/cpp/ratio.h" | |
10 | |
11 namespace mojo { | |
12 namespace media { | |
13 | |
14 // TODO(dalesat): Consider always allowing inexact results. | |
15 | |
16 // A linear function from int64_t to int64_t with non-negative slope. The | |
17 // representation is in point-slope form. The point is represented as two | |
18 // int64_t values (domain_basis, range_basis), and the slope is represented as | |
19 // the ratio of two uint32_t values (range_delta / domain_delta). 'Domain' | |
20 // refers to the input space, and 'range' refers to the output space. | |
21 struct LinearFunction { | |
22 // Applies a linear function. | |
23 static int64_t Apply(int64_t domain_basis, | |
24 int64_t range_basis, | |
25 const Ratio& slope, // range_delta / domain_delta | |
26 int64_t domain_input); | |
27 | |
28 // Applies the inverse of a linear function. | |
29 static int64_t ApplyInverse(int64_t domain_basis, | |
30 int64_t range_basis, | |
31 const Ratio& slope, // range_delta / domain_delta | |
32 int64_t range_input) { | |
33 MOJO_DCHECK(slope.denominator() != 0u); | |
34 return Apply(range_basis, domain_basis, slope.Inverse(), range_input); | |
35 } | |
36 | |
37 // Composes two linear functions B->C and A->B producing A->C. If exact is | |
38 // true, DCHECKs on loss of precision. | |
39 static LinearFunction Compose(const LinearFunction& bc, | |
40 const LinearFunction& ab, | |
41 bool exact = true); | |
42 | |
43 LinearFunction() : domain_basis_(0), range_basis_(0) {} | |
44 | |
45 LinearFunction(int64_t domain_basis, | |
46 int64_t range_basis, | |
47 uint32_t domain_delta, | |
48 uint32_t range_delta) | |
49 : domain_basis_(domain_basis), | |
50 range_basis_(range_basis), | |
51 slope_(range_delta, domain_delta) {} | |
52 | |
53 LinearFunction(int64_t domain_basis, | |
54 int64_t range_basis, | |
55 const Ratio& slope) // range_delta / domain_delta | |
56 : domain_basis_(domain_basis), | |
57 range_basis_(range_basis), | |
58 slope_(slope) {} | |
59 | |
60 explicit LinearFunction(const Ratio& slope) // range_delta / domain_delta | |
61 : domain_basis_(0), | |
62 range_basis_(0), | |
63 slope_(slope) {} | |
64 | |
65 // Applies the function. Returns Ratio::kOverflow on overflow. | |
66 int64_t Apply(int64_t domain_input) const { | |
67 return Apply(domain_basis_, range_basis_, slope_, domain_input); | |
68 } | |
69 | |
70 // Applies the inverse of the function. Returns Ratio::kOverflow on overflow. | |
71 int64_t ApplyInverse(int64_t range_input) const { | |
72 MOJO_DCHECK(slope_.denominator() != 0u); | |
73 return ApplyInverse(domain_basis_, range_basis_, slope_, range_input); | |
74 } | |
75 | |
76 // Applies the function. Returns Ratio::kOverflow on overflow. | |
77 int64_t operator()(int64_t domain_input) const { return Apply(domain_input); } | |
78 | |
79 // Returns a linear function that is the inverse if this linear function. | |
80 LinearFunction Inverse() const { | |
81 MOJO_DCHECK(slope_.denominator() != 0u); | |
82 return LinearFunction(range_basis_, domain_basis_, slope_.Inverse()); | |
83 } | |
84 | |
85 int64_t domain_basis() const { return domain_basis_; } | |
86 | |
87 int64_t range_basis() const { return range_basis_; } | |
88 | |
89 const Ratio& slope() const { return slope_; } | |
90 | |
91 uint32_t domain_delta() const { return slope_.denominator(); } | |
92 | |
93 uint32_t range_delta() const { return slope_.numerator(); } | |
94 | |
95 int64_t domain_basis_; | |
96 int64_t range_basis_; | |
97 Ratio slope_; // range_delta / domain_delta | |
98 }; | |
99 | |
100 // Tests two linear functions for equality. Equality requires equal basis | |
101 // values. | |
102 inline bool operator==(const LinearFunction& a, const LinearFunction& b) { | |
103 return a.domain_basis() == b.domain_basis() && | |
104 a.range_basis() == b.range_basis() && a.slope() == b.slope(); | |
105 } | |
106 | |
107 // Tests two linear functions for inequality. Equality requires equal basis | |
108 // values. | |
109 inline bool operator!=(const LinearFunction& a, const LinearFunction& b) { | |
110 return !(a == b); | |
111 } | |
112 | |
113 // Composes two linear functions B->C and A->B producing A->C. DCHECKs on | |
114 // loss of precision. | |
115 inline LinearFunction operator*(const LinearFunction& bc, | |
116 const LinearFunction& ab) { | |
117 return LinearFunction::Compose(bc, ab); | |
118 } | |
119 | |
120 } // namespace media | |
121 } // namespace mojo | |
122 | |
123 #endif // MOJO_SERVICES_MEDIA_COMMON_CPP_LINEAR_FUNCTION_H_ | |
OLD | NEW |