1/*
2 * Copyright 2008 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#include "include/core/SkScalar.h"
9#include "include/private/SkFixed.h"
10#include "include/private/SkFloatBits.h"
11#include "include/private/SkFloatingPoint.h"
12#include "src/core/SkMathPriv.h"
13#include "src/core/SkSafeMath.h"
14
15#define sub_shift(zeros, x, n) \
16 zeros -= n; \
17 x >>= n
18
19int SkCLZ_portable(uint32_t x) {
20 if (x == 0) {
21 return 32;
22 }
23
24 int zeros = 31;
25 if (x & 0xFFFF0000) {
26 sub_shift(zeros, x, 16);
27 }
28 if (x & 0x0000FF00) {
29 sub_shift(zeros, x, 8);
30 }
31 if (x & 0x000000F0) {
32 sub_shift(zeros, x, 4);
33 }
34 if (x & 0x0000000C) {
35 sub_shift(zeros, x, 2);
36 }
37 if (x & 0x00000002) {
38 sub_shift(zeros, x, 1);
39 }
40
41 return zeros;
42}
43
44#define add_shift(zeros, x, n) \
45 zeros += n; \
46 x >>= n
47
48int SkCTZ_portable(uint32_t x) {
49 if (x == 0) {
50 return 32;
51 }
52
53 int zeros = 0;
54 if (!(x & 0x0000FFFF)) {
55 add_shift(zeros, x, 16);
56 }
57 if (!(x & 0x000000FF)) {
58 add_shift(zeros, x, 8);
59 }
60 if (!(x & 0x0000000F)) {
61 add_shift(zeros, x, 4);
62 }
63 if (!(x & 0x00000003)) {
64 add_shift(zeros, x, 2);
65 }
66 if (!(x & 0x00000001)) {
67 add_shift(zeros, x, 1);
68 }
69
70 return zeros;
71}
72
73///////////////////////////////////////////////////////////////////////////////
74
75/* www.worldserver.com/turk/computergraphics/FixedSqrt.pdf
76*/
77int32_t SkSqrtBits(int32_t x, int count) {
78 SkASSERT(x >= 0 && count > 0 && (unsigned)count <= 30);
79
80 uint32_t root = 0;
81 uint32_t remHi = 0;
82 uint32_t remLo = x;
83
84 do {
85 root <<= 1;
86
87 remHi = (remHi<<2) | (remLo>>30);
88 remLo <<= 2;
89
90 uint32_t testDiv = (root << 1) + 1;
91 if (remHi >= testDiv) {
92 remHi -= testDiv;
93 root++;
94 }
95 } while (--count >= 0);
96
97 return root;
98}
99
100///////////////////////////////////////////////////////////////////////////////////////////////////
101
102size_t SkSafeMath::Add(size_t x, size_t y) {
103 SkSafeMath tmp;
104 size_t sum = tmp.add(x, y);
105 return tmp.ok() ? sum : SIZE_MAX;
106}
107
108size_t SkSafeMath::Mul(size_t x, size_t y) {
109 SkSafeMath tmp;
110 size_t prod = tmp.mul(x, y);
111 return tmp.ok() ? prod : SIZE_MAX;
112}
113
114///////////////////////////////////////////////////////////////////////////////////////////////////
115
116bool sk_floats_are_unit(const float array[], size_t count) {
117 bool is_unit = true;
118 for (size_t i = 0; i < count; ++i) {
119 is_unit &= (array[i] >= 0) & (array[i] <= 1);
120 }
121 return is_unit;
122}
123