summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2011-03-12 17:46:11 +0000
committerVincent Sanders <vince@netsurf-browser.org>2011-03-12 17:46:11 +0000
commit5ca8e29dcfc73b13a3c4c32e58619d9c486df57b (patch)
tree0327c5f5737addbf6c31d54363ec6587e87aa05f /include
parentbcb95bf5fa2c5cfd2e7c80f211f7fd6db6ce2f9a (diff)
downloadlibcss-5ca8e29dcfc73b13a3c4c32e58619d9c486df57b.tar.gz
libcss-5ca8e29dcfc73b13a3c4c32e58619d9c486df57b.tar.bz2
Saturated maths in css fixed point
svn path=/trunk/libcss/; revision=11975
Diffstat (limited to 'include')
-rw-r--r--include/libcss/fpmath.h122
1 files changed, 105 insertions, 17 deletions
diff --git a/include/libcss/fpmath.h b/include/libcss/fpmath.h
index 3867f3a..36e0ab5 100644
--- a/include/libcss/fpmath.h
+++ b/include/libcss/fpmath.h
@@ -14,37 +14,120 @@ extern "C"
#endif
#include <stdint.h>
+#include <limits.h>
/* 22:10 fixed point math */
+#define CSS_RADIX_POINT 10
+
+/* type for fixed point numbers */
typedef int32_t css_fixed;
+static inline css_fixed
+css_add_fixed(const css_fixed x, const css_fixed y) {
+ int32_t ux = x;
+ int32_t uy = y;
+ int32_t res = ux + uy;
+
+ /* Calculate overflowed result. (Don't change the sign bit of ux) */
+ ux = (ux >> 31) + INT_MAX;
+
+ /* Force compiler to use cmovns instruction */
+ if ((int32_t) ((ux ^ uy) | ~(uy ^ res)) >= 0) {
+ res = ux;
+ }
+
+ return res;
+}
+
+static inline css_fixed
+css_subtract_fixed(const css_fixed x, const css_fixed y) {
+ int32_t ux = x;
+ int32_t uy = y;
+ int32_t res = ux - uy;
+
+ ux = (ux >> 31) + INT_MAX;
+
+ /* Force compiler to use cmovns instruction */
+ if ((int32_t)((ux ^ uy) & (ux ^ res)) < 0) {
+ res = ux;
+ }
+
+ return res;
+}
+
+static inline css_fixed
+css_divide_fixed(const css_fixed x, const css_fixed y) {
+ int64_t xx = ((int64_t)x << CSS_RADIX_POINT) / y;
+
+ if (xx < INT_MIN)
+ xx = INT_MIN;
+
+ if (xx > INT_MAX)
+ xx = INT_MAX;
+
+ return xx;
+}
+
+static inline css_fixed
+css_multiply_fixed(const css_fixed x, const css_fixed y) {
+ int64_t xx = ((int64_t)x * (int64_t)y) >> CSS_RADIX_POINT;
+
+ if (xx < INT_MIN)
+ xx = INT_MIN;
+
+ if (xx > INT_MAX)
+ xx = INT_MAX;
+
+ return xx;
+}
+
+static inline css_fixed
+css_int_to_fixed(const int a) {
+ int64_t xx = ((int64_t) a) << CSS_RADIX_POINT;
+
+ if (xx < INT_MIN)
+ xx = INT_MIN;
+
+ if (xx > INT_MAX)
+ xx = INT_MAX;
+
+ return xx;
+}
+
+static inline css_fixed
+css_float_to_fixed(const float a) {
+ float xx = a * (float) (1 << CSS_RADIX_POINT);
+
+ if (xx < INT_MIN)
+ xx = INT_MIN;
+
+ if (xx > INT_MAX)
+ xx = INT_MAX;
+
+ return xx;
+}
+
/* Add two fixed point values */
-#define FADD(a, b) ((a) + (b))
+#define FADD(a, b) (css_add_fixed((a), (b)))
/* Subtract two fixed point values */
-#define FSUB(a, b) ((a) - (b))
+#define FSUB(a, b) (css_subtract_fixed((a), (b)))
/* Multiply two fixed point values */
-#define FMUL(a, b) ((((int64_t) (a)) * ((int64_t) (b))) >> 10)
+#define FMUL(a, b) (css_multiply_fixed((a), (b)))
/* Divide two fixed point values */
-#define FDIV(a, b) ((((int64_t) (a)) << 10) / (b))
-
-/* Add an integer to a fixed point value */
-#define FADDI(a, b) ((a) + ((b) << 10))
-/* Subtract an integer from a fixed point value */
-#define FSUBI(a, b) ((a) - ((b) << 10))
-/* Multiply a fixed point value by an integer */
-#define FMULI(a, b) ((a) * (b))
-/* Divide a fixed point value by an integer */
-#define FDIVI(a, b) ((a) / (b))
+#define FDIV(a, b) (css_divide_fixed((a), (b)))
/* Convert a floating point value to fixed point */
-#define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << 10)))
+#define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << CSS_RADIX_POINT)))
/* Convert a fixed point value to floating point */
-#define FIXTOFLT(a) ((float) (a) / (float) (1 << 10))
+#define FIXTOFLT(a) ((float) (a) / (float) (1 << CSS_RADIX_POINT))
/* Convert an integer to a fixed point value */
-#define INTTOFIX(a) ((a) << 10)
+#define INTTOFIX(a) (css_int_to_fixed(a))
/* Convert a fixed point value to an integer */
-#define FIXTOINT(a) ((a) >> 10)
+#define FIXTOINT(a) ((a) >> CSS_RADIX_POINT)
+
+/* truncate a fixed point value */
+#define TRUNCATEFIX(a) (a & ~((1 << CSS_RADIX_POINT)- 1 ))
/* Useful values */
#define F_PI_2 0x00000648 /* 1.5708 (PI/2) */
@@ -57,8 +140,13 @@ typedef int32_t css_fixed;
#define F_270 0x00043800 /* 270 */
#define F_360 0x0005a000 /* 360 */
+#define F_0_5 0x00000200 /* 0.5 */
+#define F_1 0x00000400 /* 1 */
+#define F_10 0x00002800 /* 10 */
+#define F_72 0x00012000 /* 72 */
#define F_100 0x00019000 /* 100 */
#define F_200 0x00032000 /* 200 */
+#define F_255 0x0003FC00 /* 255 */
#define F_300 0x0004b000 /* 300 */
#define F_400 0x00064000 /* 400 */