blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

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))))