| 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 |