11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkMath_DEFINED
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkMath_DEFINED
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypes.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//! Returns the number of leading zero bits (0...32)
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkCLZ_portable(uint32_t);
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Computes the 64bit product of a * b, and then shifts the answer down by
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    shift bits, returning the low 32bits. shift must be [0..63]
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    e.g. to perform a fixedmul, call SkMulShift(a, b, 16)
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkMulShift(int32_t a, int32_t b, unsigned shift);
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Computes numer1 * numer2 / denom in full 64 intermediate precision.
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    It is an error for denom to be 0. There is no special handling if
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    the result overflows 32bits.
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Computes (numer1 << shift) / denom in full 64 intermediate precision.
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    It is an error for denom to be 0. There is no special handling if
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    the result overflows 32bits.
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkDivBits(int32_t numer, int32_t denom, int shift);
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return the integer square root of value, with a bias of bitBias
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkSqrtBits(int32_t value, int bitBias);
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return the integer square root of n, treated as a SkFixed (16.16)
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSqrt32(n)         SkSqrtBits(n, 15)
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return the integer cube root of value, with a bias of bitBias
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkCubeRootBits(int32_t value, int bitBias);
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns -1 if n < 0, else returns 0
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkExtractSign(n)    ((int32_t)(n) >> 31)
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** If sign == -1, returns -n, else sign must be 0, and returns n.
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Typically used in conjunction with SkExtractSign().
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int32_t SkApplySign(int32_t n, int32_t sign) {
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(sign == 0 || sign == -1);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (n ^ sign) - sign;
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
601c980e0d7772f05f570ae0227d91635f017c2227Mike Reed/** Return x with the sign of y */
611c980e0d7772f05f570ae0227d91635f017c2227Mike Reedstatic inline int32_t SkCopySign32(int32_t x, int32_t y) {
621c980e0d7772f05f570ae0227d91635f017c2227Mike Reed    return SkApplySign(x, SkExtractSign(x ^ y));
631c980e0d7772f05f570ae0227d91635f017c2227Mike Reed}
641c980e0d7772f05f570ae0227d91635f017c2227Mike Reed
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkClampPos(int value) {
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return value & ~(value >> 31);
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Given an integer and a positive (max) integer, return the value
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    pinned against 0 and max, inclusive.
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    @param value    The value we want returned pinned between [0...max]
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    @param max      The positive max value
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    @return 0 if value < 0, max if value > max, else value
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkClampMax(int value, int max) {
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // ensure that max is positive
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(max >= 0);
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value < 0) {
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value = 0;
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value > max) {
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value = max;
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return value;
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Given a positive value and a positive max, return the value
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    pinned against max.
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Note: only works as long as max - value doesn't wrap around
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    @return max if value >= max, else value
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline unsigned SkClampUMax(unsigned value, unsigned max) {
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value > max) {
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value = max;
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return value;
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int diff = max - value;
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // clear diff if diff is positive
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    diff &= diff >> 31;
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return value + diff;
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#if defined(__arm__)
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define SkCLZ(x)    __builtin_clz(x)
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkCLZ
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define SkCLZ(x)    SkCLZ_portable(x)
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns the smallest power-of-2 that is >= the specified value. If value
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    is already a power of 2, then it is returned unchanged. It is undefined
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if value is <= 0.
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkNextPow2(int value) {
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(value > 0);
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return 1 << (32 - SkCLZ(value - 1));
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns the log2 of the specified value, were that value to be rounded up
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    to the next power of 2. It is undefined to pass 0. Examples:
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project         SkNextLog2(1) -> 0
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project         SkNextLog2(2) -> 1
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project         SkNextLog2(3) -> 2
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project         SkNextLog2(4) -> 2
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project         SkNextLog2(5) -> 3
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkNextLog2(uint32_t value) {
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(value != 0);
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return 32 - SkCLZ(value - 1);
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/** Returns true if value is a power of 2. Does not explicitly check for
14440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    value <= 0.
14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */
14640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool SkIsPow2(int value) {
14740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return (value & (value - 1)) == 0;
14840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
14940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    With this requirement, we can generate faster instructions on some
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    architectures.
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
1563026a9ec59b285412941d278a570e382088f8adaMike Reed#if defined(__arm__) \
1573026a9ec59b285412941d278a570e382088f8adaMike Reed  && !defined(__thumb__) \
158396008a4fc955119355c57bc41a3d9119c8e22d6Jean-Baptiste Queru  && !defined(__ARM_ARCH_4T__) \
1593026a9ec59b285412941d278a570e382088f8adaMike Reed  && !defined(__ARM_ARCH_5T__)
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((int16_t)x == x);
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((int16_t)y == y);
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int32_t product;
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        asm("smulbb %0, %1, %2 \n"
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            : "=r"(product)
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            : "r"(x), "r"(y)
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            );
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return product;
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #ifdef SK_DEBUG
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT((int16_t)x == x);
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT((int16_t)y == y);
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return x * y;
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #else
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        #define SkMulS16(x, y)  ((x) * (y))
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #endif
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return a*b/255, truncating away any fractional bits. Only valid if both
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    a and b are 0..255
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((uint8_t)a == a);
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((uint8_t)b == b);
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned prod = SkMulS16(a, b) + 1;
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (prod + (prod >> 8)) >> 8;
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return a*b/255, rounding any fractional bits. Only valid if both
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    a and b are 0..255
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((uint8_t)a == a);
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((uint8_t)b == b);
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned prod = SkMulS16(a, b) + 128;
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (prod + (prod >> 8)) >> 8;
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if
20340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    both a and b are 0..255. The expected result equals (a * b + 254) / 255.
20440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */
20540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) {
20640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkASSERT((uint8_t)a == a);
20740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkASSERT((uint8_t)b == b);
20840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    unsigned prod = SkMulS16(a, b) + 255;
20940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return (prod + (prod >> 8)) >> 8;
21040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
21140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(a <= 32767);
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= 32767);
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(shift > 0 && shift <= 8);
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (prod + (prod >> shift)) >> shift;
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2239f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed/** Just the rounding step in SkDiv255Round: round(value / 255)
2249f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed */
2259f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline unsigned SkDiv255Round(unsigned prod) {
2269f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed    prod += 128;
2279f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed    return (prod + (prod >> 8)) >> 8;
2289f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed}
2299f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
232