Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-09-18 14:03:10 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-09-18 16:55:41 +0300
commitc4fc9c4a8ecc421fdbf1f5d06d3b67ac4c8c1895 (patch)
tree448296ec632d616303dc9385654d4da135cda497
parenta6b156bf57864072aa2cab8b251a8fb3b0ee7b34 (diff)
Math Lib: clamped rounding utility functions
-rw-r--r--source/blender/blenlib/BLI_math_base.h14
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c34
2 files changed, 48 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index c44b666faea..e7e89a6424a 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -153,6 +153,20 @@ MINLINE int iroundf(float a);
MINLINE int divide_round_i(int a, int b);
MINLINE int mod_i(int i, int n);
+MINLINE signed char round_fl_to_char_clamp(float a);
+MINLINE unsigned char round_fl_to_uchar_clamp(float a);
+MINLINE short round_fl_to_short_clamp(float a);
+MINLINE unsigned short round_fl_to_ushort_clamp(float a);
+MINLINE int round_fl_to_int_clamp(float a);
+MINLINE unsigned int round_fl_to_uint_clamp(float a);
+
+MINLINE signed char round_db_to_char_clamp(double a);
+MINLINE unsigned char round_db_to_uchar_clamp(double a);
+MINLINE short round_db_to_short_clamp(double a);
+MINLINE unsigned short round_db_to_ushort_clamp(double a);
+MINLINE int round_db_to_int_clamp(double a);
+MINLINE unsigned int round_db_to_uint_clamp(double a);
+
int pow_i(int base, int exp);
double double_round(double x, int ndigits);
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 5ae2b1a70a7..37efe95791c 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -33,6 +33,7 @@
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#ifdef __SSE2__
# include <emmintrin.h>
@@ -181,11 +182,44 @@ MINLINE unsigned power_of_2_min_u(unsigned x)
return x - (x >> 1);
}
+/* rounding and clamping */
+
MINLINE int iroundf(float a)
{
return (int)floorf(a + 0.5f);
}
+#define _round_clamp_fl_impl(arg, ty, min, max) { \
+ float r = floorf(arg + 0.5f); \
+ if (UNLIKELY(r <= (float)min)) return (ty)min; \
+ else if (UNLIKELY(r >= (float)max)) return (ty)max; \
+ else return (ty)r; \
+}
+
+#define _round_clamp_db_impl(arg, ty, min, max) { \
+ double r = floor(arg + 0.5); \
+ if (UNLIKELY(r <= (double)min)) return (ty)min; \
+ else if (UNLIKELY(r >= (double)max)) return (ty)max; \
+ else return (ty)r; \
+}
+
+MINLINE signed char round_fl_to_char_clamp(float a) { _round_clamp_fl_impl(a, signed char, SCHAR_MIN, SCHAR_MAX) }
+MINLINE unsigned char round_fl_to_uchar_clamp(float a) { _round_clamp_fl_impl(a, unsigned char, 0, UCHAR_MAX) }
+MINLINE short round_fl_to_short_clamp(float a) { _round_clamp_fl_impl(a, short, SHRT_MIN, SHRT_MAX) }
+MINLINE unsigned short round_fl_to_ushort_clamp(float a) { _round_clamp_fl_impl(a, unsigned short, 0, USHRT_MAX) }
+MINLINE int round_fl_to_int_clamp(float a) { _round_clamp_fl_impl(a, int, INT_MIN, INT_MAX) }
+MINLINE unsigned int round_fl_to_uint_clamp(float a) { _round_clamp_fl_impl(a, unsigned int, 0, UINT_MAX) }
+
+MINLINE signed char round_db_to_char_clamp(double a) { _round_clamp_db_impl(a, signed char, SCHAR_MIN, SCHAR_MAX) }
+MINLINE unsigned char round_db_to_uchar_clamp(double a) { _round_clamp_db_impl(a, unsigned char, 0, UCHAR_MAX) }
+MINLINE short round_db_to_short_clamp(double a) { _round_clamp_db_impl(a, short, SHRT_MIN, SHRT_MAX) }
+MINLINE unsigned short round_db_to_ushort_clamp(double a) { _round_clamp_db_impl(a, unsigned short, 0, USHRT_MAX) }
+MINLINE int round_db_to_int_clamp(double a) { _round_clamp_db_impl(a, int, INT_MIN, INT_MAX) }
+MINLINE unsigned int round_db_to_uint_clamp(double a) { _round_clamp_db_impl(a, unsigned int, 0, UINT_MAX) }
+
+#undef _round_clamp_fl_impl
+#undef _round_clamp_db_impl
+
/* integer division that rounds 0.5 up, particularly useful for color blending
* with integers, to avoid gradual darkening when rounding down */
MINLINE int divide_round_i(int a, int b)