Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkMath_DEFINED
      9 #define SkMath_DEFINED
     10 
     11 #include "SkTypes.h"
     12 
     13 // 64bit -> 32bit utilities
     14 
     15 // Handy util that can be passed two ints, and will automatically promote to
     16 // 64bits before the multiply, so the caller doesn't have to remember to cast
     17 // e.g. (int64_t)a * b;
     18 static inline int64_t sk_64_mul(int64_t a, int64_t b) {
     19     return a * b;
     20 }
     21 
     22 ///////////////////////////////////////////////////////////////////////////////
     23 
     24 /** Given an integer and a positive (max) integer, return the value
     25  *  pinned against 0 and max, inclusive.
     26  *  @param value    The value we want returned pinned between [0...max]
     27  *  @param max      The positive max value
     28  *  @return 0 if value < 0, max if value > max, else value
     29  */
     30 static inline int SkClampMax(int value, int max) {
     31     // ensure that max is positive
     32     SkASSERT(max >= 0);
     33     if (value < 0) {
     34         value = 0;
     35     }
     36     if (value > max) {
     37         value = max;
     38     }
     39     return value;
     40 }
     41 
     42 /**
     43  *  Returns true if value is a power of 2. Does not explicitly check for
     44  *  value <= 0.
     45  */
     46 template <typename T> constexpr inline bool SkIsPow2(T value) {
     47     return (value & (value - 1)) == 0;
     48 }
     49 
     50 ///////////////////////////////////////////////////////////////////////////////
     51 
     52 /**
     53  *  Return a*b/((1 << shift) - 1), rounding any fractional bits.
     54  *  Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
     55  */
     56 static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
     57     SkASSERT(a <= 32767);
     58     SkASSERT(b <= 32767);
     59     SkASSERT(shift > 0 && shift <= 8);
     60     unsigned prod = a*b + (1 << (shift - 1));
     61     return (prod + (prod >> shift)) >> shift;
     62 }
     63 
     64 /**
     65  *  Return a*b/255, rounding any fractional bits.
     66  *  Only valid if a and b are unsigned and <= 32767.
     67  */
     68 static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
     69     SkASSERT(a <= 32767);
     70     SkASSERT(b <= 32767);
     71     unsigned prod = a*b + 128;
     72     return (prod + (prod >> 8)) >> 8;
     73 }
     74 
     75 #endif
     76