SkMath.h revision 1c980e0d7772f05f570ae0227d91635f017c2227
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * you may not use this file except in compliance with the License. 60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * You may obtain a copy of the License at 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * See the License for the specific language governing permissions and 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * limitations under the License. 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkMath_DEFINED 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkMath_DEFINED 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypes.h" 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//! Returns the number of leading zero bits (0...32) 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkCLZ_portable(uint32_t); 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Computes the 64bit product of a * b, and then shifts the answer down by 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project shift bits, returning the low 32bits. shift must be [0..63] 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project e.g. to perform a fixedmul, call SkMulShift(a, b, 16) 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkMulShift(int32_t a, int32_t b, unsigned shift); 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Computes numer1 * numer2 / denom in full 64 intermediate precision. 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project It is an error for denom to be 0. There is no special handling if 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project the result overflows 32bits. 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom); 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Computes (numer1 << shift) / denom in full 64 intermediate precision. 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project It is an error for denom to be 0. There is no special handling if 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project the result overflows 32bits. 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkDivBits(int32_t numer, int32_t denom, int shift); 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return the integer square root of value, with a bias of bitBias 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkSqrtBits(int32_t value, int bitBias); 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return the integer square root of n, treated as a SkFixed (16.16) 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkSqrt32(n) SkSqrtBits(n, 15) 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return the integer cube root of value, with a bias of bitBias 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint32_t SkCubeRootBits(int32_t value, int bitBias); 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns -1 if n < 0, else returns 0 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkExtractSign(n) ((int32_t)(n) >> 31) 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** If sign == -1, returns -n, else sign must be 0, and returns n. 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Typically used in conjunction with SkExtractSign(). 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int32_t SkApplySign(int32_t n, int32_t sign) { 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(sign == 0 || sign == -1); 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (n ^ sign) - sign; 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 671c980e0d7772f05f570ae0227d91635f017c2227Mike Reed/** Return x with the sign of y */ 681c980e0d7772f05f570ae0227d91635f017c2227Mike Reedstatic inline int32_t SkCopySign32(int32_t x, int32_t y) { 691c980e0d7772f05f570ae0227d91635f017c2227Mike Reed return SkApplySign(x, SkExtractSign(x ^ y)); 701c980e0d7772f05f570ae0227d91635f017c2227Mike Reed} 711c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches) 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkClampPos(int value) { 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value & ~(value >> 31); 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Given an integer and a positive (max) integer, return the value 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pinned against 0 and max, inclusive. 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Note: only works as long as max - value doesn't wrap around 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param value The value we want returned pinned between [0...max] 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param max The positive max value 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @return 0 if value < 0, max if value > max, else value 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkClampMax(int value, int max) { 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // ensure that max is positive 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(max >= 0); 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // ensure that if value is negative, max - value doesn't wrap around 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(value >= 0 || max - value > 0); 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (value < 0) { 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project value = 0; 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (value > max) { 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project value = max; 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value; 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 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 // clear the result if value < 0 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (value + diff) & ~(value >> 31); 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Given a positive value and a positive max, return the value 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pinned against max. 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Note: only works as long as max - value doesn't wrap around 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @return max if value >= max, else value 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline unsigned SkClampUMax(unsigned value, unsigned max) { 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (value > max) { 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project value = max; 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value; 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int diff = max - value; 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // clear diff if diff is positive 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project diff &= diff >> 31; 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value + diff; 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if defined(__arm__) && !defined(__thumb__) 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #define SkCLZ(x) __builtin_clz(x) 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkCLZ 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #define SkCLZ(x) SkCLZ_portable(x) 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns the smallest power-of-2 that is >= the specified value. If value 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project is already a power of 2, then it is returned unchanged. It is undefined 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if value is <= 0. 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkNextPow2(int value) { 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(value > 0); 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 1 << (32 - SkCLZ(value - 1)); 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Returns the log2 of the specified value, were that value to be rounded up 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project to the next power of 2. It is undefined to pass 0. Examples: 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkNextLog2(1) -> 0 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkNextLog2(2) -> 1 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkNextLog2(3) -> 2 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkNextLog2(4) -> 2 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkNextLog2(5) -> 3 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline int SkNextLog2(uint32_t value) { 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(value != 0); 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 32 - SkCLZ(value - 1); 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t. 1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project With this requirement, we can generate faster instructions on some 1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project architectures. 1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 1703026a9ec59b285412941d278a570e382088f8adaMike Reed#if defined(__arm__) \ 1713026a9ec59b285412941d278a570e382088f8adaMike Reed && !defined(__thumb__) \ 172396008a4fc955119355c57bc41a3d9119c8e22d6Jean-Baptiste Queru && !defined(__ARM_ARCH_4T__) \ 1733026a9ec59b285412941d278a570e382088f8adaMike Reed && !defined(__ARM_ARCH_5T__) 1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static inline int32_t SkMulS16(S16CPU x, S16CPU y) { 1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int16_t)x == x); 1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int16_t)y == y); 1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int32_t product; 1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project asm("smulbb %0, %1, %2 \n" 1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : "=r"(product) 1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : "r"(x), "r"(y) 1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ); 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return product; 1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #ifdef SK_DEBUG 1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static inline int32_t SkMulS16(S16CPU x, S16CPU y) { 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int16_t)x == x); 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int16_t)y == y); 1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return x * y; 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #else 1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #define SkMulS16(x, y) ((x) * (y)) 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #endif 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return a*b/255, truncating away any fractional bits. Only valid if both 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a and b are 0..255 1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) { 2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((uint8_t)a == a); 2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((uint8_t)b == b); 2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned prod = SkMulS16(a, b) + 1; 2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (prod + (prod >> 8)) >> 8; 2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return a*b/255, rounding any fractional bits. Only valid if both 2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a and b are 0..255 2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) { 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((uint8_t)a == a); 2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((uint8_t)b == b); 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned prod = SkMulS16(a, b) + 128; 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (prod + (prod >> 8)) >> 8; 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Return a*b/((1 << shift) - 1), rounding any fractional bits. 2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8 2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) { 2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(a <= 32767); 2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(b <= 32767); 2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(shift > 0 && shift <= 8); 2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned prod = SkMulS16(a, b) + (1 << (shift - 1)); 2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (prod + (prod >> shift)) >> shift; 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2279f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed/** Just the rounding step in SkDiv255Round: round(value / 255) 2289f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed */ 2299f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline unsigned SkDiv255Round(unsigned prod) { 2309f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed prod += 128; 2319f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return (prod + (prod >> 8)) >> 8; 2329f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2339f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 236