aboutsummaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/colour.h49
-rw-r--r--src/util/efflush.h12
-rw-r--r--src/util/emalloc.h23
-rw-r--r--src/util/eopen.h14
-rw-r--r--src/util/eprintf.h10
-rw-r--r--src/util/fshut.h36
-rw-r--r--src/util/io.h12
-rw-r--r--src/util/to.h135
8 files changed, 291 insertions, 0 deletions
diff --git a/src/util/colour.h b/src/util/colour.h
new file mode 100644
index 0000000..ff40841
--- /dev/null
+++ b/src/util/colour.h
@@ -0,0 +1,49 @@
+/* See LICENSE file for copyright and license details. */
+#include <math.h>
+
+#define D65_XYY_X 0.312726871026564878786047074755
+#define D65_XYY_Y 0.329023206641284038376227272238
+
+static inline double
+srgb_encode(double t)
+{
+ double sign = 1;
+ if (t < 0) {
+ t = -t;
+ sign = -1;
+ }
+ t = t <= 0.0031306684425217108 ? 12.92 * t : 1.055 * pow(t, 1 / 2.4) - 0.055;
+ return t * sign;
+}
+
+static inline double
+srgb_decode(double t)
+{
+ double sign = 1;
+ if (t < 0) {
+ t = -t;
+ sign = -1;
+ }
+ t = t <= 0.0031306684425217108 * 12.92 ? t / 12.92 : pow((t + 0.055) / 1.055, 2.4);
+ return t * sign;
+}
+
+static inline void
+ciexyz_to_srgb(double x, double y, double z, double *r, double *g, double *b)
+{
+#define MULTIPLY(CX, CY, CZ) ((CX) * x + (CY) * y + (CZ) * z)
+ *r = MULTIPLY(3.240446254647737500675930277794, -1.537134761820080575134284117667, -0.498530193022728718155178739835);
+ *g = MULTIPLY(-0.969266606244679751469561779231, 1.876011959788370209167851498933, 0.041556042214430065351304932619);
+ *b = MULTIPLY(0.055643503564352832235773149705, -0.204026179735960239147729566866, 1.057226567722703292062647051353);
+#undef MULTIPLY
+}
+
+static inline void
+srgb_to_ciexyz(double r, double g, double b, double *x, double *y, double *z)
+{
+#define MULTIPLY(CR, CG, CB) ((CR) * r + (CG) * g + (CB) * b)
+ *x = MULTIPLY(0.412457445582367576708548995157, 0.357575865245515878143578447634, 0.180437247826399665973085006954);
+ *y = MULTIPLY(0.212673370378408277403536885686, 0.715151730491031756287156895269, 0.072174899130559869164791564344);
+ *z = MULTIPLY(0.019333942761673460208893260415, 0.119191955081838593666354597644, 0.950302838552371742508739771438);
+#undef MULTIPLY
+}
diff --git a/src/util/efflush.h b/src/util/efflush.h
new file mode 100644
index 0000000..001f2af
--- /dev/null
+++ b/src/util/efflush.h
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+
+#define efflush(...) enfflush(1, __VA_ARGS__)
+
+static inline void
+enfflush(int status, FILE *fp, const char *fname)
+{
+ fflush(fp);
+ if (ferror(fp))
+ enprintf(status, "%s:", fname);
+}
diff --git a/src/util/emalloc.h b/src/util/emalloc.h
new file mode 100644
index 0000000..7c4266e
--- /dev/null
+++ b/src/util/emalloc.h
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdlib.h>
+
+#define emalloc(...) enmalloc(1, __VA_ARGS__)
+#define ecalloc(...) encalloc(1, __VA_ARGS__)
+
+static inline void *
+enmalloc(int status, size_t n)
+{
+ void *ptr = malloc(n);
+ if (!ptr)
+ enprintf(status, "malloc: out of memory\n");
+ return ptr;
+}
+
+static inline void *
+encalloc(int status, size_t n, size_t m)
+{
+ void *ptr = calloc(n, m);
+ if (!ptr)
+ enprintf(status, "malloc: out of memory\n");
+ return ptr;
+}
diff --git a/src/util/eopen.h b/src/util/eopen.h
new file mode 100644
index 0000000..42e8c5d
--- /dev/null
+++ b/src/util/eopen.h
@@ -0,0 +1,14 @@
+/* See LICENSE file for copyright and license details. */
+#include <fcntl.h>
+
+#define eopen(...) enopen(1, __VA_ARGS__)
+#define enopen(...) xenopen(__VA_ARGS__, 0)
+
+static inline int
+xenopen(int status, const char *path, int flags, int mode, ...)
+{
+ int fd = open(path, flags, mode);
+ if (fd < 0)
+ enprintf(status, "open %s:", path);
+ return fd;
+}
diff --git a/src/util/eprintf.h b/src/util/eprintf.h
new file mode 100644
index 0000000..a9b342f
--- /dev/null
+++ b/src/util/eprintf.h
@@ -0,0 +1,10 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdlib.h>
+
+void weprintf(const char *fmt, ...);
+
+#define eprintf(...)\
+ (weprintf(__VA_ARGS__), exit(1))
+
+#define enprintf(status, ...)\
+ (weprintf(__VA_ARGS__), exit(status))
diff --git a/src/util/fshut.h b/src/util/fshut.h
new file mode 100644
index 0000000..4c91179
--- /dev/null
+++ b/src/util/fshut.h
@@ -0,0 +1,36 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+
+#define efshut(...) enfshut(1, __VA_ARGS__)
+
+static inline int
+fshut(FILE *fp, const char *fname)
+{
+ int ret = 0;
+
+ /* fflush() is undefined for input streams by ISO C,
+ * but not POSIX 2008 if you ignore ISO C overrides.
+ * Leave it unchecked and rely on the following
+ * functions to detect errors.
+ */
+ fflush(fp);
+
+ if (ferror(fp) && !ret) {
+ weprintf("ferror %s:", fname);
+ ret = 1;
+ }
+
+ if (fclose(fp) && !ret) {
+ weprintf("fclose %s:", fname);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static inline void
+enfshut(int status, FILE *fp, const char *fname)
+{
+ if (fshut(fp, fname))
+ exit(status);
+}
diff --git a/src/util/io.h b/src/util/io.h
new file mode 100644
index 0000000..25f360c
--- /dev/null
+++ b/src/util/io.h
@@ -0,0 +1,12 @@
+/* See LICENSE file for copyright and license details. */
+
+#define ewriteall(...) enwriteall(1, __VA_ARGS__)
+
+int writeall(int fd, void *buf, size_t n);
+
+static inline void
+enwriteall(int status, int fd, void *buf, size_t n, const char *fname)
+{
+ if (writeall(fd, buf, n))
+ enprintf(status, "write %s:", fname);
+}
diff --git a/src/util/to.h b/src/util/to.h
new file mode 100644
index 0000000..7bb08c7
--- /dev/null
+++ b/src/util/to.h
@@ -0,0 +1,135 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdlib.h>
+
+int tollu(const char *s, unsigned long long int min, unsigned long long int max, unsigned long long int *out);
+int tolli(const char *s, long long int min, long long int max, long long int *out);
+#define DEF_STR_TO_INT(FNAME, INTTYPE, INTER_FNAME, INTER_INTTYPE, PRI)\
+ static inline int\
+ FNAME(const char *s, INTTYPE min, INTTYPE max, INTTYPE *out)\
+ {\
+ INTER_INTTYPE inter;\
+ if (INTER_FNAME(s, (INTER_INTTYPE)min, (INTER_INTTYPE)max, &inter))\
+ return -1;\
+ *out = (INTTYPE)inter;\
+ return 0;\
+ }
+DEF_STR_TO_INT(tolu, unsigned long int, tollu, unsigned long long int, "lu")
+DEF_STR_TO_INT(tou, unsigned int, tollu, unsigned long long int, "u")
+DEF_STR_TO_INT(toli, long int, tolli, long long int, "li")
+DEF_STR_TO_INT(toi, int, tolli, long long int, "i")
+#undef DEF_STR_TO_INT
+#define tozu tolu
+#define tozi toli
+#define toju tollu
+#define toji tolli
+
+#define DEF_STR_TO_INT(FNAME, TYPE, PRI)\
+ static inline TYPE\
+ en##FNAME##_flag(int status, int flag, const char *s, TYPE min, TYPE max)\
+ {\
+ TYPE ret = 0;\
+ if (!FNAME(s, min, max, &ret))\
+ enprintf(status,\
+ "argument of -%c must be an integer in [%"PRI", %"PRI"]\n",\
+ flag, min, max);\
+ return ret;\
+ }\
+ \
+ static inline TYPE\
+ e##FNAME##_flag(int flag, const char *s, TYPE min, TYPE max)\
+ {\
+ return en##FNAME##_flag(1, flag, s, min, max);\
+ }\
+ \
+ static inline TYPE\
+ en##FNAME##_arg(int status, const char *name, const char *s, TYPE min, TYPE max)\
+ {\
+ TYPE ret = 0;\
+ if (!FNAME(s, min, max, &ret))\
+ enprintf(status,\
+ "%s must be an integer in [%"PRI", %"PRI"]\n",\
+ name, min, max);\
+ return ret;\
+ }\
+ \
+ static inline TYPE\
+ e##FNAME##_arg(const char *name, const char *s, TYPE min, TYPE max)\
+ {\
+ return en##FNAME##_arg(1, name, s, min, max);\
+ }
+DEF_STR_TO_INT(tollu, unsigned long long int, "llu")
+DEF_STR_TO_INT(tolu, unsigned long int, "lu")
+DEF_STR_TO_INT(tou, unsigned int, "u")
+DEF_STR_TO_INT(tolli, long long int, "lli")
+DEF_STR_TO_INT(toli, long int, "li")
+DEF_STR_TO_INT(toi, int, "i")
+#undef DEF_STR_TO_INT
+
+#define etozu_flag etolu_flag
+#define etozi_flag etoli_flag
+#define etoju_flag etollu_flag
+#define etoji_flag etolli_flag
+#define entozu_flag entolu_flag
+#define entozi_flag entoli_flag
+#define entoju_flag entollu_flag
+#define entoji_flag entolli_flag
+
+#define etozu_arg etolu_arg
+#define etozi_arg etoli_arg
+#define etoju_arg etollu_arg
+#define etoji_arg etolli_arg
+#define entozu_arg entolu_arg
+#define entozi_arg entoli_arg
+#define entoju_arg entollu_arg
+#define entoji_arg entolli_arg
+
+#define DEF_STR_TO_FLOAT(FNAME, TYPE, FUN)\
+ static inline int\
+ FNAME(const char *s, TYPE *out)\
+ {\
+ char *end;\
+ errno = 0;\
+ *out = FUN(s, &end);\
+ if (errno) {\
+ return -1;\
+ } else if (*end) {\
+ errno = EINVAL;\
+ return -1;\
+ }\
+ return 0;\
+ }\
+ \
+ static inline TYPE\
+ en##FNAME##_flag(int status, int flag, const char *s)\
+ {\
+ TYPE ret = 0;\
+ if (!FNAME(s, &ret))\
+ enprintf(status, "argument of -%c must be floating-point value\n", flag);\
+ return ret;\
+ }\
+ \
+ static inline TYPE\
+ e##FNAME##_flag(int flag, const char *s)\
+ {\
+ return en##FNAME##_flag(1, flag, s);\
+ }\
+ \
+ static inline TYPE\
+ en##FNAME##_arg(int status, const char *name, const char *s)\
+ {\
+ TYPE ret = 0;\
+ if (!FNAME(s, &ret))\
+ enprintf(status, "%s must be floating-point value\n", name);\
+ return ret;\
+ }\
+ \
+ static inline TYPE\
+ e##FNAME##_arg(const char *name, const char *s)\
+ {\
+ return en##FNAME##_arg(1, name, s);\
+ }
+DEF_STR_TO_FLOAT(tof, float, strtof)
+DEF_STR_TO_FLOAT(tolf, double, strtod)
+DEF_STR_TO_FLOAT(tollf, long double, strtold)
+#undef DEF_STR_TO_FLOAT