video-math.h (4992B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <math.h> 3 4 static inline double 5 nnpow_d(double a, double b) 6 { 7 int neg = a < 0; 8 a = pow(neg ? -a : a, b); 9 return neg ? -a : a; 10 } 11 12 static inline float 13 nnpow_f(float a, float b) 14 { 15 int neg = a < 0; 16 a = powf(neg ? -a : a, b); 17 return neg ? -a : a; 18 } 19 20 static inline double 21 posmod_d(double a, double b) 22 { 23 double x = fmod(a, b); 24 return x < 0 ? x + b : x; 25 } 26 27 static inline float 28 posmod_f(float a, float b) 29 { 30 float x = fmodf(a, b); 31 return x < 0 ? x + b : x; 32 } 33 34 static inline double 35 degsin_d(double u) 36 { 37 if (!fmod(u, 90)) { 38 int64_t v = (int64_t)u; 39 v = ((v / 90) % 4 + 4) % 4; 40 return ((double[]){0, 1, 0, -1})[v]; 41 } 42 return sin(u * (M_PI / 180)); 43 } 44 45 static inline float 46 degsin_f(float u) 47 { 48 if (!fmodf(u, 90)) { 49 int64_t v = (int64_t)u; 50 v = ((v / 90) % 4 + 4) % 4; 51 return ((float[]){0, 1, 0, -1})[v]; 52 } 53 return sinf(u * (float)(M_PI / 180)); 54 } 55 56 static inline double 57 degcos_d(double u) 58 { 59 if (!fmod(u, 90)) { 60 int64_t v = (int64_t)u; 61 v = ((v / 90) % 4 + 4) % 4; 62 return ((double[]){1, 0, -1, 0})[v]; 63 } 64 return cos(u * (M_PI / 180)); 65 } 66 67 static inline float 68 degcos_f(float u) 69 { 70 if (!fmodf(u, 90)) { 71 int64_t v = (int64_t)u; 72 v = ((v / 90) % 4 + 4) % 4; 73 return ((float[]){1, 0, -1, 0})[v]; 74 } 75 return cosf(u * (float)(M_PI / 180)); 76 } 77 78 #define GENERIC(TYPE, FUNC, ...)\ 79 TYPE: FUNC(__VA_ARGS__),\ 80 TYPE *: FUNC(__VA_ARGS__),\ 81 TYPE **: FUNC(__VA_ARGS__),\ 82 TYPE ***: FUNC(__VA_ARGS__),\ 83 const TYPE: FUNC(__VA_ARGS__),\ 84 const TYPE *: FUNC(__VA_ARGS__),\ 85 const TYPE **: FUNC(__VA_ARGS__),\ 86 const TYPE ***: FUNC(__VA_ARGS__) 87 88 #define MATH_GENERIC_1(FUNC, A) (_Generic((A),\ 89 GENERIC(double, FUNC, A),\ 90 GENERIC(float, FUNC##f, A))) 91 92 #define MATH_GENERIC_N(FUNC, A, ...) (_Generic((A),\ 93 GENERIC(double, FUNC, A, __VA_ARGS__),\ 94 GENERIC(float, FUNC##f, A, __VA_ARGS__))) 95 96 #define BLIND_GENERIC_1(FUNC, A) (_Generic((A),\ 97 GENERIC(double, FUNC##_d, A),\ 98 GENERIC(float, FUNC##_f, A))) 99 100 #define BLIND_GENERIC_N(FUNC, A, ...) (_Generic((A),\ 101 GENERIC(double, FUNC##_d, A, __VA_ARGS__), \ 102 GENERIC(float, FUNC##_f, A, __VA_ARGS__))) 103 104 #define pow(...) MATH_GENERIC_N(pow, __VA_ARGS__) 105 #define log2(...) MATH_GENERIC_1(log2, __VA_ARGS__) 106 #define log(...) MATH_GENERIC_1(log, __VA_ARGS__) 107 #define abs(...) MATH_GENERIC_1(fabs, __VA_ARGS__) 108 #define sqrt(...) MATH_GENERIC_1(sqrt, __VA_ARGS__) 109 #define exp(...) MATH_GENERIC_1(exp, __VA_ARGS__) 110 #define g_isnan(...) MATH_GENERIC_1(isnan, __VA_ARGS__) 111 #define g_isinf(...) MATH_GENERIC_1(isinf, __VA_ARGS__) 112 #define g_isfinite(...) MATH_GENERIC_1(isfinite, __VA_ARGS__) 113 #define mod(...) MATH_GENERIC_N(fmod, __VA_ARGS__) 114 #define cos(...) MATH_GENERIC_1(cos, __VA_ARGS__) 115 #define sin(...) MATH_GENERIC_1(sin, __VA_ARGS__) 116 #define tan(...) MATH_GENERIC_1(tan, __VA_ARGS__) 117 #define atan2(...) MATH_GENERIC_N(atan2, __VA_ARGS__) 118 119 #define nnpow(...) BLIND_GENERIC_N(nnpow, __VA_ARGS__) 120 #define posmod(...) BLIND_GENERIC_N(posmod, __VA_ARGS__) 121 #define degcos(...) BLIND_GENERIC_1(degcos, __VA_ARGS__) 122 #define degsin(...) BLIND_GENERIC_1(degsin, __VA_ARGS__) 123 #define srgb_encode(...) BLIND_GENERIC_1(srgb_encode, __VA_ARGS__) 124 #define srgb_decode(...) BLIND_GENERIC_1(srgb_decode, __VA_ARGS__) 125 126 #define yuv_to_srgb(a, b, c, d, e, f)\ 127 BLIND_GENERIC_N(yuv_to_srgb, (a), (b), (c), (void *)(d), (void *)(e), (void *)(f)) 128 #define srgb_to_yuv(a, b, c, d, e, f)\ 129 BLIND_GENERIC_N(srgb_to_yuv, (a), (b), (c), (void *)(d), (void *)(e), (void *)(f)) 130 #define ciexyz_to_srgb(a, b, c, d, e, f)\ 131 BLIND_GENERIC_N(ciexyz_to_srgb, (a), (b), (c), (void *)(d), (void *)(e), (void *)(f)) 132 #define srgb_to_ciexyz(a, b, c, d, e, f)\ 133 BLIND_GENERIC_N(srgb_to_ciexyz, (a), (b), (c), (void *)(d), (void *)(e), (void *)(f)) 134 #define scaled_yuv_to_ciexyz(a, b, c, d, e, f)\ 135 BLIND_GENERIC_N(scaled_yuv_to_ciexyz, (a), (b), (c), (void *)(d), (void *)(e), (void *)(f)) 136 #define ciexyz_to_scaled_yuv(a, b, c, d, e, f)\ 137 BLIND_GENERIC_N(ciexyz_to_scaled_yuv, (a), (b), (c), (void *)(d), (void *)(e), (void *)(f)) 138 139 #define htole(A) (_Generic((A),\ 140 uint8_t: (A),\ 141 int8_t: (uint8_t)(A),\ 142 uint16_t: htole16((uint16_t)(A)),\ 143 int16_t: (uint16_t)htole16((uint16_t)(A)),\ 144 uint32_t: htole32((uint32_t)(A)),\ 145 int32_t: (uint32_t)htole32((uint32_t)(A)),\ 146 uint64_t: htole64((uint64_t)(A)),\ 147 int64_t: (uint64_t)htole64((uint64_t)(A)))) 148 149 #define letoh(A) (_Generic((A),\ 150 uint8_t: (A),\ 151 int8_t: (uint8_t)(A),\ 152 uint16_t: le16toh((uint16_t)(A)),\ 153 int16_t: (uint16_t)le16toh((uint16_t)(A)),\ 154 uint32_t: le32toh((uint32_t)(A)),\ 155 int32_t: (uint32_t)le32toh((uint32_t)(A)),\ 156 uint64_t: le64toh((uint64_t)(A)),\ 157 int64_t: (uint64_t)le64toh((uint64_t)(A))))