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