// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MOJO_SERVICES_MEDIA_COMMON_CPP_LINEAR_TRANSFORM_H_ #define MOJO_SERVICES_MEDIA_COMMON_CPP_LINEAR_TRANSFORM_H_ #include #include namespace mojo { namespace media { // LinearTransform defines a structure which hold the definition of a // transformation from single dimensional coordinate system A into coordinate // system B (and back again). Values in A and in B are 64 bit, the linear // scale factor is expressed as a rational number using two 32 bit values. // // Specifically, let // f(a) = b // F(b) = f^-1(b) = a // then // // f(a) = (((a - a_zero) * scale.numerator) / scale.denominator) + b_zero; // // and // // F(b) = (((b - b_zero) * scale.denominator) / scale.numerator) + a_zero; // struct LinearTransform { struct Ratio { Ratio() { } Ratio(int32_t _numerator, uint32_t _denominator) : numerator(_numerator), denominator(_denominator) { Reduce(); } // Helper which will reduce the fraction numerator/denominator using // Euclid's method. static void Reduce(int32_t* numerator, uint32_t* denominator); // Reduce the internal scaling rational. void Reduce() { Reduce(&numerator, &denominator); } // Compute a * b, reduce and store in out. // // Returns true if the composition was computed and stored with no loss of // precision. Returns false if the reduced form of the composition could // not be stored as a 32 bit ratio and had to be shifted in order to be // stored. static bool Compose(const Ratio& a, const Ratio& b, Ratio* out); int32_t numerator = 1; uint32_t denominator = 1; }; LinearTransform() { } LinearTransform(int32_t numerator, uint32_t denominator) : scale(numerator, denominator) {} explicit LinearTransform(const Ratio& s) : scale(s) {} LinearTransform(int64_t az, int32_t numerator, uint32_t denominator, int64_t bz) : scale(numerator, denominator), a_zero(az), b_zero(bz) {} LinearTransform(int64_t az, const Ratio& s, int64_t bz) : scale(s), a_zero(az), b_zero(bz) {} // Transform from A->B // Returns true on success, or false in the case of a singularity or an // overflow. bool DoForwardTransform(int64_t a_in, int64_t* b_out) const; // Transform from B->A // Returns true on success, or false in the case of a singularity or an // overflow. bool DoReverseTransform(int64_t b_in, int64_t* a_out) const; Ratio scale; int64_t a_zero = 0; int64_t b_zero = 0; }; std::ostream& operator<<(std::ostream& os, const LinearTransform::Ratio& r); std::ostream& operator<<(std::ostream& os, const LinearTransform& lt); } // namespace media } // namespace mojo #endif // MOJO_SERVICES_MEDIA_COMMON_CPP_LINEAR_TRANSFORM_H_