diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 53 | ||||
-rw-r--r-- | blackbody.c | 186 | ||||
-rw-r--r-- | config.mk | 6 | ||||
-rw-r--r-- | generate-table.c | 43 | ||||
-rw-r--r-- | libred.7 (renamed from man/libred.7) | 4 | ||||
-rw-r--r-- | libred.h | 148 | ||||
-rw-r--r-- | libred.h.0 (renamed from man/libred.h.0) | 24 | ||||
-rw-r--r-- | libred_check_timetravel.3 (renamed from man/libred_check_timetravel.3) | 22 | ||||
-rw-r--r-- | libred_get_colour.3 | 54 | ||||
-rw-r--r-- | libred_solar_elevation.3 | 40 | ||||
-rw-r--r-- | macros.h | 7 | ||||
-rw-r--r-- | man/libred_get_colour.3 | 74 | ||||
-rw-r--r-- | man/libred_init_colour.3 | 41 | ||||
-rw-r--r-- | man/libred_solar_elevation.3 | 48 | ||||
-rw-r--r-- | man/libred_term_colour.3 | 33 | ||||
-rw-r--r-- | parse_10deg.c | 55 | ||||
-rw-r--r-- | solar.c | 144 |
18 files changed, 417 insertions, 567 deletions
@@ -2,6 +2,8 @@ *~ *.o *.a +*.i *.su *.so *.lo +/generate-table diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2a747f0 --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +all: libred.a +solar.o: solar.c libred.h +blackbody.o: blackbody.c 10deg-xy.i 10deg-rgb.i libred.h + +10deg-xy.i: 10deg + sed -e 's/^/{/' -e 's/ /, /' -e 's/$$/},/' < 10deg | sed '$$s/,$$//' > $@ + +generate-table: generate-table.c blackbody.c 10deg-xy.i libred.h + $(CC) -o $@ generate-table.c $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) + +10deg-rgb.i: generate-table 10deg + ./generate-table > $@ + +.c.o: + $(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS) + +libred.a: solar.o blackbody.o + $(AR) rc $@ $? + $(AR) s $@ + +install: libred.a + mkdir -p -- "$(DESTDIR)$(PREFIX)/lib" + mkdir -p -- "$(DESTDIR)$(PREFIX)/include" + mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man0" + mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man3" + mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man7" + cp -- libred.a "$(DESTDIR)$(PREFIX)/lib" + cp -- libred.h "$(DESTDIR)$(PREFIX)/include" + cp -- libred.h.0 "$(DESTDIR)$(MANPREFIX)/man0" + cp -- libred_check_timetravel.3 libred_get_colour.3 libred_solar_elevation.3 "$(DESTDIR)$(MANPREFIX)/man3" + cp -- libred.7 "$(DESTDIR)$(MANPREFIX)/man7" + +uninstall: + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libred.a" + -rm -f -- "$(DESTDIR)$(PREFIX)/include/libred.h" + -rm -f -- "$(DESTDIR)$(MANPREFIX)/man0/libred.h.0" + -rm -f -- "$(DESTDIR)$(MANPREFIX)/man3/libred_check_timetravel.3" + -rm -f -- "$(DESTDIR)$(MANPREFIX)/man3/libred_get_colour.3" + -rm -f -- "$(DESTDIR)$(MANPREFIX)/man3/libred_solar_elevation.3" + -rm -f -- "$(DESTDIR)$(MANPREFIX)/man7/libred.7" + +clean: + -rm -f -- generate-table *.i *.o *.a *.lo *.su *.so + +.SUFFIXES: +.SUFFIXES: .c .o + +.PHONY: all check install uninstall clean diff --git a/blackbody.c b/blackbody.c index 104e7da..9dfe1a8 100644 --- a/blackbody.c +++ b/blackbody.c @@ -4,173 +4,143 @@ # pragma GCC diagnostic ignored "-Wunsuffixed-float-constants" #endif - #ifndef LIBRED_COMPILING_PARSER #include "libred.h" -#include "macros.h" -#include <math.h> #include <errno.h> -#include <fcntl.h> - - - -/** - * The file descriptor to the colour lookup table. - */ -int libred_fd = -1; - +#include <math.h> +#include <stddef.h> -/** - * This function must be called, once, - * before calling `libred_get_colour`. - * - * @return 0 on success, -1 on error. - * - * @throws Any error specified for `open(3)`. - */ -int -libred_init_colour(void) -{ - libred_term_colour(); - libred_fd = open(SYSDEPRESDIR "/" PACKAGE "/10deg", O_RDONLY); - return libred_fd < 0 ? -1 : 0; -} +struct xy {double x, y;}; +struct rgb {double r, g, b;}; +static struct xy xy_table[] = { +#include "10deg-xy.i" +}; -/** - * Call this when the process will not - * longer make calls to `libred_get_colour`. - */ -void -libred_term_colour(void) -{ - if (libred_fd >= 0) - close(libred_fd), libred_fd = -1; -} +static struct rgb rgb_table[] = { +#include "10deg-rgb.i" +}; #endif /** - * Convert from CIE xyY to [0, 1] sRGB. + * Convert from CIE xyY to [0, 1] sRGB * - * @param x The 'x' component. - * @param y The 'y' component. - * @param Y The 'Y' component. - * @param r Output parameter for the “red” value. - * (Seriously, sRGB red is orange, just look at it fullscreen.) - * @param g Output parameter for the green value. - * @param b Output parameter for the blue value. + * @param x The 'x' component + * @param y The 'y' component + * @param Y The 'Y' component + * @param r Output parameter for the “red” value + * (Seriously, sRGB red is orange, just look at it fullscreen) + * @param g Output parameter for the green value + * @param b Output parameter for the blue value */ static void ciexyy_to_srgb(double x, double y, double Y, double *r, double *g, double *b) { #define SRGB(C) (((C) <= 0.0031308) ? (12.92 * (C)) : ((1.0 + 0.055) * pow((C), 1.0 / 2.4) - 0.055)) - double X, Z; + double X, Z, max; #if __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wfloat-equal" #endif - /* Convert CIE xyY to CIE XYZ. */ + /* Convert CIE xyY to CIE XYZ */ X = Y * (y == 0.0 ? 0.0 : (x / y)); Z = Y * (y == 0.0 ? 0.0 : ((1.0 - x - y) / y)); #if __GNUC__ # pragma GCC diagnostic pop #endif - /* Convert CIE XYZ to [0, 1] linear RGB. (ciexyz_to_linear) */ + /* Convert CIE XYZ to [0, 1] linear RGB (ciexyz_to_linear) */ *r = ( 3.240450 * X) + (-1.537140 * Y) + (-0.4985320 * Z); *g = (-0.969266 * X) + ( 1.876010 * Y) + ( 0.0415561 * Z); *b = (0.0556434 * X) + (-0.204026 * Y) + ( 1.0572300 * Z); - /* Convert [0, 1] linear RGB to [0, 1] sRGB. */ + /* Convert [0, 1] linear RGB to [0, 1] sRGB */ SRGB(*r), SRGB(*g), SRGB(*b); + + /* Adjust colours for use */ + max = fmax(fmax(fabs(*r), fabs(*g)), fabs(*b)); +#if __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (max != 0.0) *r /= max, *g /= max, *b /= max; +#if __GNUC__ +# pragma GCC diagnostic pop +#endif + *r = *r > 0.0 ? *r : 0.0; + *g = *g > 0.0 ? *g : 0.0; + *b = *b > 0.0 ? *b : 0.0; } #ifndef LIBRED_COMPILING_PARSER - /** * Perform linear interpolation (considered very good) * between the CIE xyY values for two colour temperatures * and convert the result to sRGB. The two colours should * be the closest below the desired colour temperature, - * and the closest above the desired colour temperature. + * and the closest above the desired colour temperature * - * @param x1 The 'x' component for the low colour. - * @param y1 The 'y' component for the low colour. - * @param x2 The 'x' component for the high colour. - * @param y2 The 'y' component for the high colour. - * @param temp The desired colour temperature. - * @param r Output parameter for the “red” value. - * @param g Output parameter for the green value. - * @param b Output parameter for the blue value. + * @param x1 The 'x' component for the low colour + * @param y1 The 'y' component for the low colour + * @param x2 The 'x' component for the high colour + * @param y2 The 'y' component for the high colour + * @param temp The desired colour temperature + * @param r Output parameter for the “red” value + * @param g Output parameter for the green value + * @param b Output parameter for the blue value */ static void interpolate(double x1, double y1, double x2, double y2, double temp, double *r, double *g, double *b) { - double weight = fmod(temp, (double)LIBRED_DELTA_TEMPERATURE) / (double)LIBRED_DELTA_TEMPERATURE; + double weight = fmod(temp - (LIBRED_LOWEST_TEMPERATURE % LIBRED_DELTA_TEMPERATURE), + (double)LIBRED_DELTA_TEMPERATURE) / (double)LIBRED_DELTA_TEMPERATURE; double x = x1 * (1 - weight) + x2 * weight; double y = y1 * (1 - weight) + y2 * weight; ciexyy_to_srgb(x, y, 1.0, r, g, b); } - /** - * Get the [0, 1] sRGB values of a colour temperature. - * - * @param temp The desired colour temperature. - * @param r Output parameter for the “red” value. - * @param g Output parameter for the green value. - * @param b Output parameter for the blue value. - * @return 0 on succeess, -1 on error. + * Get the [0, 1] sRGB values of a colour temperature * - * @throws EOVERFLOW The file did not have the expected size. - * @throws EDOM The selected temperature is below 1000 K. - * @throws Any error specified for pread(3). + * @param temp The desired colour temperature + * @param r Output parameter for the “red” value + * @param g Output parameter for the green value + * @param b Output parameter for the blue value + * @return 0 on succeess, -1 on error + * @throws EDOM The selected temperature is below 1000 K */ int libred_get_colour(long int temp, double *r, double *g, double *b) { - double values[10]; /* low:x,y,r,g,b + high:x,y,r,g,b */ - off_t offset; - double max; - - /* We do not have any values for above 40 000 K, but - * the differences will be unnoticeable, perhaps even - * unencodeable. */ - if (temp > LIBRED_HIGHEST_TEMPERATURE) temp = LIBRED_HIGHEST_TEMPERATURE; - /* Things do not glow below 1000 K. Yes, fire is hot! */ - if (temp < LIBRED_LOWEST_TEMPERATURE) t ((errno = EDOM)); - - /* Read table. */ - offset = ((off_t)temp - LIBRED_LOWEST_TEMPERATURE) / LIBRED_DELTA_TEMPERATURE; - offset *= (off_t)(sizeof(values) / 2); - errno = EOVERFLOW; xpread(libred_fd, values, sizeof(values), offset); - - /* Get colour. */ - if (temp % LIBRED_DELTA_TEMPERATURE) - interpolate(values[0], values[1], values[6], values[7], (double)temp, r, g, b); - else - *r = values[2], *g = values[3], *b = values[4]; - - /* Adjust colours for use. */ - max = fmax(fmax(fabs(*r), fabs(*g)), fabs(*b)); -#if __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (max != 0.0) *r /= max, *g /= max, *b /= max; -#if __GNUC__ -# pragma GCC diagnostic pop -#endif - *r = *r > 0.0 ? *r : 0.0; - *g = *g > 0.0 ? *g : 0.0; - *b = *b > 0.0 ? *b : 0.0; + double x1, y1, x2, y2; + size_t i; + + if (temp > LIBRED_HIGHEST_TEMPERATURE) + temp = LIBRED_HIGHEST_TEMPERATURE; + + if (temp < LIBRED_LOWEST_TEMPERATURE) { + errno = EDOM; + return -1; + } + + if (temp % LIBRED_DELTA_TEMPERATURE) { /* TODO make optional */ + i = (temp - LIBRED_LOWEST_TEMPERATURE) / LIBRED_DELTA_TEMPERATURE; + x1 = xy_table[i].x; + y1 = xy_table[i].y; + x2 = xy_table[i + 1].x; + y2 = xy_table[i + 1].y; + interpolate(x1, y1, x2, y2, (double)temp, r, g, b); + } else { + i = (temp - LIBRED_LOWEST_TEMPERATURE) / LIBRED_DELTA_TEMPERATURE; + *r = rgb_table[i].r; + *g = rgb_table[i].g; + *b = rgb_table[i].b; + } return 0; -fail: - return -1; } #endif diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..32897e2 --- /dev/null +++ b/config.mk @@ -0,0 +1,6 @@ +PREFIX = /usr +MANPREFIX = $(PREFIX)/share/man + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CFLAGS = -std=c99 -Wall +LDFLAGS = -lm diff --git a/generate-table.c b/generate-table.c new file mode 100644 index 0000000..ac89af7 --- /dev/null +++ b/generate-table.c @@ -0,0 +1,43 @@ +/* See LICENSE file for copyright and license details. */ +#include "libred.h" +#include <errno.h> +#include <math.h> +#include <string.h> +#include <stdio.h> + +#if __GNUC__ +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +struct xy {double x, y;}; + +static struct xy xy_table[] = { +#include "10deg-xy.i" +}; + +/* define ciexyy_to_srgb() and adjust_luma() */ +#define LIBRED_COMPILING_PARSER +#include "blackbody.c" + +int +main(void) +{ + long int temp = LIBRED_LOWEST_TEMPERATURE; + size_t i, n = sizeof(xy_table) / sizeof(*xy_table); + double r, g, b; + + for (i = 0; i < n; i++, temp += LIBRED_DELTA_TEMPERATURE) { + if (temp == 6500) + r = g = b = 1; + else + ciexyy_to_srgb(xy_table[i].x, xy_table[i].y, 1, &r, &g, &b); + printf("{%a, %a, %a}%s\n", r, g, b, i + 1 == n ? "" : ","); + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) { + perror(NULL); + return -1; + } + + return 0; +} @@ -5,9 +5,7 @@ libred \- Solar elevation and blackbody colour calculation .B libred is a C library for calculating the Sun's apparent elevation and colours temperatures. -.SH "FUTURE DIRECTIONS" -None. -.SH "SEE ALSO" +.SH SEE ALSO .BR libred.h (0), .BR solar-python (7), .BR redshift (1), @@ -5,216 +5,186 @@ /** - * Approximate apparent size of the Sun in degrees. + * Approximate apparent size of the Sun in degrees */ #define LIBRED_SOLAR_APPARENT_RADIUS (32.0 / 60.0) /** - * The Sun's elevation at sunset and sunrise, measured in degrees. + * The Sun's elevation at sunset and sunrise, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_SUNSET_SUNRISE (-32.0 / 60.0) /** - * The Sun's elevation at civil dusk and civil dawn, measured in degrees. + * The Sun's elevation at civil dusk and civil dawn, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_CIVIL_DUSK_DAWN (-6.0) /** - * The Sun's elevation at nautical dusk and nautical dawn, measured in degrees. + * The Sun's elevation at nautical dusk and nautical dawn, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN (-12.0) /** - * The Sun's elevation at astronomical dusk and astronomical dawn, measured in degrees. + * The Sun's elevation at astronomical dusk and astronomical dawn, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN (-18.0) /** - * The Sun's elevation at amateur astronomical dusk and amateur astronomical dawn, measured in degrees. + * The Sun's elevation at amateur astronomical dusk and amateur astronomical dawn, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_AMATEUR_ASTRONOMICAL_DUSK_DAWN (-15.0) /** - * The Sun's lowest elevation during the golden hour, measured in degrees. + * The Sun's lowest elevation during the golden hour, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_GOLDEN_HOUR_LOW (-4.0) /** - * The Sun's highest elevation during the golden hour, measured in degrees. + * The Sun's highest elevation during the golden hour, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_GOLDEN_HOUR_HIGH (6.0) /** - * The Sun's lowest elevation during the blue hour, measured in degrees. + * The Sun's lowest elevation during the blue hour, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_BLUE_HOUR_LOW (-6.0) /** - * The Sun's highest elevation during the blue hour, measured in degrees. + * The Sun's highest elevation during the blue hour, measured in degrees */ #define LIBRED_SOLAR_ELEVATION_BLUE_HOUR_HIGH (-4.0) /** - * Test whether it is twilight. + * Test whether it is twilight * - * @param ELEV:double The current elevation. - * @return 1 if is twilight, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is twilight, 0 otherwise */ #define LIBRED_IS_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= -32.0 / 60.0)) /** - * Test whether it is civil twilight. + * Test whether it is civil twilight * - * @param ELEV:double The current elevation. - * @return 1 if is civil twilight, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is civil twilight, 0 otherwise */ #define LIBRED_IS_CIVIL_TWILIGHT(ELEV) ((-6.0 <= (ELEV)) && ((ELEV) <= -32.0 / 60.0)) /** - * Test whether it is nautical twilight. + * Test whether it is nautical twilight * - * @param ELEV:double The current elevation. - * @return 1 if is nautical twilight, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is nautical twilight, 0 otherwise */ #define LIBRED_IS_NAUTICAL_TWILIGHT(ELEV) ((-12.0 <= (ELEV)) && ((ELEV) <= -32.0 / 60.0)) /** - * Test whether it is astronomical twilight. + * Test whether it is astronomical twilight * - * @param ELEV:double The current elevation. - * @return 1 if is astronomical twilight, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is astronomical twilight, 0 otherwise */ #define LIBRED_IS_ASTRONOMICAL_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= -32.0 / 60.0)) /** - * Test whether it is amateur astronomical twilight. + * Test whether it is amateur astronomical twilight * - * @param ELEV:double The current elevation. - * @return 1 if is amatuer astronomical twilight, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is amatuer astronomical twilight, 0 otherwise */ #define LIBRED_IS_AMATEUR_ASTRONOMICAL_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= -15.0)) /** - * Test whether it is nighttime. + * Test whether it is nighttime * - * @param ELEV:double The current elevation. - * @return 1 if is nighttime, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is nighttime, 0 otherwise */ #define LIBRED_IS_NIGHTTIME(ELEV) ((ELEV) < -18.0) /** - * Test whether it is daytime. + * Test whether it is daytime * - * @param ELEV:double The current elevation. - * @return 1 if is daytime, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is daytime, 0 otherwise */ #define LIBRED_IS_DAYTIME(ELEV) ((ELEV) > -32.0 / 60.0) /** - * Test whether it is the golden hour. + * Test whether it is the golden hour * - * @param ELEV:double The current elevation. - * @return 1 if is golden hour, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is golden hour, 0 otherwise */ #define LIBRED_IS_GOLDEN_HOUR(ELEV) ((-4.0 <= (ELEV)) && ((ELEV) <= 6.0)) /** - * Test whether it is the blue hour. + * Test whether it is the blue hour * - * @param ELEV:double The current elevation. - * @return 1 if is blue hour, 0 otherwise. + * @param ELEV:double The current elevation + * @return 1 if is blue hour, 0 otherwise */ #define LIBRED_IS_BLUE_HOUR(ELEV) ((-6.0 <= (ELEV)) && ((ELEV) <= -4.0)) /** * Calculates the Sun's elevation as apparent - * from a geographical position. + * from a geographical position * * @param latitude The latitude in degrees northwards from - * the equator, negative for southwards. + * the equator, negative for southwards * @param longitude The longitude in degrees eastwards from - * Greenwich, negative for westwards. - * @return The Sun's apparent elevation as seen, right now, - * from the specified position, measured in degrees. - * - * @throws 0 On success. - * @throws Any error specified for clock_gettime(3) on error. + * Greenwich, negative for westwards + * @param elevation Output parameter for the Sun's apparent elevation + * as seen, right now, from the specified position, + * measured in degrees + * @return 0 on success, -1 on failure + * @throws Any error specified for clock_gettime(3) on error */ -double libred_solar_elevation(double, double); +double libred_solar_elevation(double, double, double *); /** - * Exit if time the is before year 0 in J2000. + * Exit if time the is before year 0 in J2000 * - * @return 0 on success, -1 on error. + * @return 0 on success, -1 on error */ int libred_check_timetravel(void); /** - * The highest colour temperature in the table. + * The highest colour temperature in the table */ #define LIBRED_HIGHEST_TEMPERATURE 40000 /** - * The lowest colour temperature in the table. + * The lowest colour temperature in the table */ #define LIBRED_LOWEST_TEMPERATURE 1000 /** * The temperature difference between the colours in the table. * Note, `libred_get_colour` will make interpolation for colours - * that are not in the table. + * that are not in the table */ #define LIBRED_DELTA_TEMPERATURE 100 /** - * The file descriptor to the colour lookup table. - * -1 if none is open. - */ -extern int libred_fd; - -/** - * Iff this macro is define `libred_fd` is available. - */ -#define LIBRED_HAVE_FD 1 - - -/** - * This function must be called, once, - * before calling `libred_get_colour`. - * - * @return 0 on success, -1 on error. - * - * @throws Any error specified for `open(3)`. - */ -int libred_init_colour(void); - -/** - * Call this when the process will not - * longer make calls to `libred_get_colour`. - */ -void libred_term_colour(void); - -/** - * Get the [0, 1] sRGB values of a colour temperature. + * Get the [0, 1] sRGB values of a colour temperature * - * @param temp The desired colour temperature. - * @param r Output parameter for the “red” value. - * @param g Output parameter for the green value. - * @param b Output parameter for the blue value. - * @return 0 on succeess, -1 on error. + * @param temp The desired colour temperature + * @param r Output parameter for the “red” value + * @param g Output parameter for the green value + * @param b Output parameter for the blue value + * @return 0 on succeess, -1 on error * - * @throws EOVERFLOW The file did not have the expected size. - * @throws EDOM The selected temperature is below 1000 K. - * @throws Any error specified for pread(3). + * @throws EDOM The selected temperature is below 1000 K */ -int libred_get_colour(long int, double*, double*, double*); +int libred_get_colour(long int, double *, double *, double *); diff --git a/man/libred.h.0 b/libred.h.0 index 95a5144..c3aa853 100644 --- a/man/libred.h.0 +++ b/libred.h.0 @@ -122,31 +122,9 @@ This header defines the following functions: .BR libred_check_timetravel (3) .TP * -.BR libred_init_colour (3) -.TP -* -.BR libred_term_colour (3) -.TP -* .BR libred_get_colour (3) -.PP -This header may define -.B extern int libred_fd -iff it does it also defines the macro -.BR LIBRED_HAVE_FD . -If it does, you want to keep this file descriptor open when you daemonise -your process. It is set by -.BR libred_init_colour (3) -and unset by -.BR libred_term_colour (3). -It value is negative (more precisely it is -1) if no file descriptor has -been opened. -.SH "FUTURE DIRECTIONS" -None. -.SH "SEE ALSO" +.SH SEE ALSO .BR libred (7), .BR libred_solar_elevation (3), .BR libred_check_timetravel (3), -.BR libred_init_colour (3), -.BR libred_term_colour (3), .BR libred_get_colour (3) diff --git a/man/libred_check_timetravel.3 b/libred_check_timetravel.3 index 1d34d39..cf79cd2 100644 --- a/man/libred_check_timetravel.3 +++ b/libred_check_timetravel.3 @@ -11,8 +11,9 @@ int \fBlibred_check_timetravel\fP(void); Link with .IR -lred . .SH DESCRIPTION -.B libred_check_timetravel -exits the process if +The +.BR libred_check_timetravel () +function exits the process if .B libred is not compiled to support the current time, which is the case if it was compiled without @@ -20,19 +21,16 @@ if it was compiled without and the clock is before year 2000.5 in the Julian calendar. Before exiting, the function will print an informative error message to standard error. -.SH "RETURN VALUE" +.SH RETURN VALUE Upon successful completion, without time incompatibility, the function -returns 0. Upon failure, that is, it is unable to read the clock, the -function returns -1. +.BR libred_check_timetravel () +returns 0. On failure, the function returns -1 and sets +.I errno +to indicate the error. .SH ERRORS The function may fail for any reason specified for -.BR clock_gettime (3), -and set the value of -.B errno -to the same values. -.SH "FUTURE DIRECTIONS" -None. -.SH "SEE ALSO" +.BR clock_gettime (3). +.SH SEE ALSO .BR libred.h (0), .BR libred (7), .BR libred_solar_elevation (3) diff --git a/libred_get_colour.3 b/libred_get_colour.3 new file mode 100644 index 0000000..d169a60 --- /dev/null +++ b/libred_get_colour.3 @@ -0,0 +1,54 @@ +.TH LIBRED_GET_COLOUR 3 LIBRED +.SH NAME +libred_get_colour \- Calculate a colour temperature +.SH SYNOPSIS +.nf +#include <libred.h> + +int \fBlibred_get_colour\fP(long int \fItemp\fP, double *\fIr\fP, double *\fIg\fP, double *\fIb\fP); +.fi +.PP +Link with +.IR -lred . +.SH DESCRIPTION +.BR libred_get_colour () +gets or interpolates the colour temperature for +.I temp +kelvins, and returns the colour temperature in sRGB. The values, +between 0.0 and 1.0, for the \(dqred\(dq, green, and blue channels +are stored in +.IR *r , +.IR *g , +and +.IR *b , +respectively. +.PP +At least one of the values will be 1.0, none will be greater than +1.0, and none will be less than 0.0. It is guaranteed (unless the +resources file has been modified) that +.IR *r , +.IR *g , +and +.I *b +all will be 1.0 if +.I temp +is 6500. +.SH RETURN VALUE +Upon successful completion, the +.BR libred_get_colour () +function returns 0. On failure, the function returns -1 and sets +.I errno +to indicate the error. +.SH ERRORS +The function may fail if: +.TP +.B EDOM +If +.I temp +is less than +.B LIBRED_LOWEST_TEMPERATURE +(which is 1000). +.SH SEE ALSO +.BR libred.h (0), +.BR libred (7), +.BR libred_get_solar_elevation (3) diff --git a/libred_solar_elevation.3 b/libred_solar_elevation.3 new file mode 100644 index 0000000..9bb4b0a --- /dev/null +++ b/libred_solar_elevation.3 @@ -0,0 +1,40 @@ +.TH LIBRED_SOLAR_ELEVATION 3 LIBRED +.SH NAME +libred_solar_elevation \- Calculate the Sun's apparent elevation +.SH SYNOPSIS +.nf +#include <libred.h> + +int \fBlibred_solar_elevation\fP(double \fIlatitude\fP, double \fIlongitude\fP, double *\felevation\fP); +.fi +.PP +Link with +.IR -lred . +.SH DESCRIPTION +.BR libred_solar_elevation () +calculates the Sun's elevation, and stores it, measured in degrees, in +.IR *elevation , +as apparent from a selected geographical position, namely from +.I latitude +degrees north of GPS's equator and +.I longitude +degrees east of GPS's prime meridian. The function is only +explicitly defined for values between -90 and +90 for +.I latitude +and values between -180 and +180 for and +.IR longitude . +Other values may or may not work, no error is thrown if used. +.SH RETURN VALUE +Upon successful completion, the +.BR libred_solar_elevation () +return 0, on failure it returns -1 and sets +.I errno +to indicate the error. +.SH ERRORS +The function may fail for any reason specified for +.BR clock_gettime (3). +.SH SEE ALSO +.BR libred.h (0), +.BR libred (7), +.BR libred_check_timetravel (3), +.BR libred_get_colour (3) diff --git a/macros.h b/macros.h deleted file mode 100644 index e760bd0..0000000 --- a/macros.h +++ /dev/null @@ -1,7 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <unistd.h> - - -#define t(...) do { if (__VA_ARGS__) goto fail; } while (0) -#define xpread(fd, buf, len, off) t (pread(fd, buf, len, off) < (ssize_t)(len)) -#define xwrite(fd, buf, len) t (write(fd, buf, len) < (ssize_t)(len)) diff --git a/man/libred_get_colour.3 b/man/libred_get_colour.3 deleted file mode 100644 index fd32eb3..0000000 --- a/man/libred_get_colour.3 +++ /dev/null @@ -1,74 +0,0 @@ -.TH LIBRED_GET_COLOUR 3 LIBRED -.SH NAME -libred_get_colour \- Calculate a colour temperature -.SH SYNOPSIS -.nf -#include <libred.h> - -int \fBlibred_get_colour\fP(long int \fItemp\fP, double* \fIr\fP, double* \fIg\fP, double* \fIb\fP); -.fi -.PP -Link with -.IR -lred . -.SH DESCRIPTION -.B libred_get_colour -gets or interpolates the colour temperature for -.I temp -kelvins, and returns the colour temperature in sRGB. The values, -between 0.0 and 1.0, for the "red", green, and blue channels -are stored in -.IR *r , -.IR *g , -and -.IR *b , -respectively. -.PP -At least one of the values will be 1.0, none will be greater than -1.0, and none will be less than 0.0. It is guaranteed (unless the -resources file has been modified) that -.IR *r , -.IR *g , -and -.I *b -all will be 1.0 if -.I temp -is 6500. -.PP -You must call -.BR libred_init_colour (3) -before the first use of this function, -and you should call -.BR libred_term_colour (3) -after the last use of this function. -.SH "RETURN VALUE" -Upon successful completion, the function returns 0. On failure, -the function returns -1 and sets -.B errno -appropriately. -.SH ERRORS -The function may fail if: -.TP -.B EOVERFLOW -The colour temperature lookup table is smaller than it should be. -.TP -.B EDOM -If -.I temp -is less than -.B LIBRED_LOWEST_TEMPERATURE -(which is 1000.) -.PP -The function may also fail for any reason specified for -.BR pread (3), -and set the value of -.B errno -to the same values. -.SH "FUTURE DIRECTIONS" -It is possible that the behaviour is changed to loading the -colour temperature lookup table rather than just open a -file descriptor to it. -.SH "SEE ALSO" -.BR libred.h (0), -.BR libred (7), -.BR libred_init_colour (3), -.BR libred_term_colour (3) diff --git a/man/libred_init_colour.3 b/man/libred_init_colour.3 deleted file mode 100644 index 9463245..0000000 --- a/man/libred_init_colour.3 +++ /dev/null @@ -1,41 +0,0 @@ -.TH LIBRED_INIT_COLOUR 3 LIBRED -.SH NAME -libred_init_colour \- Prepare for use of libred_get_colour(3) -.SH SYNOPSIS -.nf -#include <libred.h> - -int \fBlibred_init_colour\fP(void); -.fi -.PP -Link with -.IR -lred . -.SH DESCRIPTION -.B libred_init_colour -open a file descriptor, without returning it, to the colour -temperature lookup table, and stores the file descriptor to -.BR libred_fd . -It is necessary to call this function before the first call to -.BR libred_get_colour (3). -.SH "RETURN VALUE" -Upon successful completion, the function returns 0. On failure, -the function returns -1 and sets -.B errno -appropriately. -.SH ERRORS -The function may fail for any reason specified for -.BR open (3), -and set the value of -.B errno -to the same values. -.B errno -is always set to 0 on success. -.SH "FUTURE DIRECTIONS" -It is possible that the behaviour is changed to loading the -colour temperature lookup table rather than just open a -file descriptor to it. -.SH "SEE ALSO" -.BR libred.h (0), -.BR libred (7), -.BR libred_get_colour (3), -.BR libred_term_colour (3) diff --git a/man/libred_solar_elevation.3 b/man/libred_solar_elevation.3 deleted file mode 100644 index 7fd499f..0000000 --- a/man/libred_solar_elevation.3 +++ /dev/null @@ -1,48 +0,0 @@ -.TH LIBRED_SOLAR_ELEVATION 3 LIBRED -.SH NAME -libred_solar_elevation \- Calculate the Sun's apparent elevation -.SH SYNOPSIS -.nf -#include <libred.h> - -double \fBlibred_solar_elevation\fP(double \fIlatitude\fP, double \fIlongitude\fP); -.fi -.PP -Link with -.IR -lred . -.SH DESCRIPTION -.B libred_solar_elevation -calculates the Sun's elevation as apparent from a select geographical position. -Namely from -.I latitude -degrees north of GPS's equator and -.I longitude -degrees east of GPS's prime meridian. The function is only explicitly defined for -values between -90 and +90 for -.I latitude -and values between -180 and +180 for and -.IR longitude . -Other values may or may not work, no error is thrown if used. -.SH "RETURN VALUE" -Upon successful completion, the function sets -.B errno -to 0 and returns the Sun's current apparent elevation, measured in -degrees above the horizon. On failure, the function returns an -arbitrary value (happens to always be 0.0) and sets -.B errno -an a non-zero value. -.SH ERRORS -The function may fail for any reason specified for -.BR clock_gettime (3), -and set the value of -.B errno -to the same values. -.B errno -is always set to 0 on success. -.SH "FUTURE DIRECTIONS" -None. -.SH "SEE ALSO" -.BR libred.h (0), -.BR libred (7), -.BR libred_check_timetravel (3), -.BR libred_init_colour (3) diff --git a/man/libred_term_colour.3 b/man/libred_term_colour.3 deleted file mode 100644 index 6d327c2..0000000 --- a/man/libred_term_colour.3 +++ /dev/null @@ -1,33 +0,0 @@ -.TH LIBRED_TERM_COLOUR 3 LIBRED -.SH NAME -libred_term_colour \- Deallocate resources required by libred_get_colour(3) -.SH SYNOPSIS -.nf -#include <libred.h> - -void \fBlibred_term_colour\fP(void); -.fi -.PP -Link with -.IR -lred . -.SH DESCRIPTION -.B libred_term_colour -deallocates all resources acquired by -.BR libred_init_colour (3). -It is highly recommended to call this function before calling an -.BR exec (3)-function. -If you want to use -.BR libred_get_colour (3) -again after a call to this function has been made, you must first call -.BR libred_init_colour (3). -.SH "RETURN VALUE" -None. -.SH ERRORS -None. -.SH "FUTURE DIRECTIONS" -None. -.SH "SEE ALSO" -.BR libred.h (0), -.BR libred (7), -.BR libred_get_colour (3), -.BR libred_init_colour (3) diff --git a/parse_10deg.c b/parse_10deg.c deleted file mode 100644 index 4cdfd61..0000000 --- a/parse_10deg.c +++ /dev/null @@ -1,55 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "libred.h" -#include "macros.h" -#include <stdio.h> -#include <math.h> -#include <sys/stat.h> - - - -/** - * The number of measured temperatures. - */ -#define TEMPERATURES ((LIBRED_HIGHEST_TEMPERATURE - LIBRED_LOWEST_TEMPERATURE) / LIBRED_DELTA_TEMPERATURE + 1) - - - -#define LIBRED_COMPILING_PARSER -#include "blackbody.c" - - - -/** - * Create the lookup table of temperatures. - * - * Standard input should be the file '10deg', - * standard output should be the table file - * and must be a regular file. - * - * @param argc Should be 1. - * @param argv Should only contain the name of the process. - * @return 0 on success, 1 on error. - */ -int -main(int argc, char *argv[]) -{ -#define x (xyrgb[0]) -#define y (xyrgb[1]) -#define r (xyrgb[2]) -#define g (xyrgb[3]) -#define b (xyrgb[4]) - - double xyrgb[5]; - struct stat attr; - long int temp = LIBRED_LOWEST_TEMPERATURE; - - for (; fscanf(stdin, "%lf %lf\n", &x, &y) == 2; temp += LIBRED_DELTA_TEMPERATURE) { - (temp == 6500) ? (r = g = b = 1.0) : ciexyy_to_srgb(x, y, 1.0, &r, &g, &b); - xwrite(STDOUT_FILENO, xyrgb, sizeof(xyrgb)); - } - xwrite(STDOUT_FILENO, xyrgb, sizeof(xyrgb)); /* sugar */ - t (fstat(STDOUT_FILENO, &attr)); - return ((size_t)(attr.st_size) != (TEMPERATURES + 1) * 5 * sizeof(double)); -fail: - return perror(argc ? *argv : "parse_10deg"), 1; -} @@ -11,8 +11,6 @@ # pragma GCC diagnostic ignored "-Wunsuffixed-float-constants" #endif - - /* Select clock. */ #if defined(DO_NOT_USE_COARSEC_CLOCK) || !defined(CLOCK_REALTIME_COARSE) # ifdef CLOCK_REALTIME_COARSE @@ -21,30 +19,26 @@ # define CLOCK_REALTIME_COARSE CLOCK_REALTIME #endif - - /** - * Get current Julian Centuries time (100 Julian days since J2000.) - * - * @return The current Julian Centuries time. + * Get current Julian Centuries time (100 Julian days since J2000) * - * @throws 0 On success. - * @throws Any error specified for clock_gettime(3) on error. + * @param nowp Output parameter for the current Julian Centuries time + * @return 0 on success, -1 on failure + * @throws Any error specified for clock_gettime(3) on error */ static double -julian_centuries() +julian_centuries(double *nowp) { struct timespec now; - double tm; if (clock_gettime(CLOCK_REALTIME_COARSE, &now)) - return 0.0; - tm = (double)(now.tv_nsec) / 1000000000.0 + (double)(now.tv_sec); - tm = (tm / 86400.0 + 2440587.5 - 2451545.0) / 36525.0; - return errno = 0, tm; + return -1; + *nowp = (double)(now.tv_nsec) / 1000000000.0 + (double)(now.tv_sec); + *nowp = (*nowp / 86400.0 + 2440587.5 - 2451545.0) / 36525.0; + return 0; } /** - * Convert a Julian Centuries timestamp to a Julian Day timestamp. + * Convert a Julian Centuries timestamp to a Julian Day timestamp * * @param tm The time in Julian Centuries * @return The time in Julian Days @@ -57,7 +51,7 @@ julian_centuries_to_julian_day(double tm) /** - * Convert an angle (or otherwise) from degrees to radians. + * Convert an angle (or otherwise) from degrees to radians * * @param deg The angle in degrees. * @param The angle in radians. @@ -69,7 +63,7 @@ radians(double deg) } /** - * Convert an angle (or otherwise) from radians to degrees. + * Convert an angle (or otherwise) from radians to degrees * * @param rad The angle in radians. * @param The angle in degrees. @@ -84,11 +78,11 @@ degrees(double rad) /** * Calculates the Sun's elevation from the solar hour angle * - * @param longitude The longitude in degrees eastwards. - * from Greenwich, negative for westwards. - * @param declination The declination, in radians. - * @param hour_angle The solar hour angle, in radians. - * @return The Sun's elevation, in radians. + * @param longitude The longitude in degrees eastwards + * from Greenwich, negative for westwards + * @param declination The declination, in radians + * @param hour_angle The solar hour angle, in radians + * @return The Sun's elevation, in radians */ static inline double elevation_from_hour_angle(double latitude, double declination, double hour_angle) @@ -100,10 +94,10 @@ elevation_from_hour_angle(double latitude, double declination, double hour_angle } /** - * Calculates the Sun's geometric mean longitude. + * Calculates the Sun's geometric mean longitude * - * @param tm The time in Julian Centuries. - * @return The Sun's geometric mean longitude in radians. + * @param tm The time in Julian Centuries + * @return The Sun's geometric mean longitude in radians */ static inline double sun_geometric_mean_longitude(double tm) @@ -116,10 +110,10 @@ sun_geometric_mean_longitude(double tm) } /** - * Calculates the Sun's geometric mean anomaly. + * Calculates the Sun's geometric mean anomaly * - * @param tm The time in Julian Centuries. - * @return The Sun's geometric mean anomaly in radians. + * @param tm The time in Julian Centuries + * @return The Sun's geometric mean anomaly in radians */ static inline double sun_geometric_mean_anomaly(double tm) @@ -128,10 +122,10 @@ sun_geometric_mean_anomaly(double tm) } /** - * Calculates the Earth's orbit eccentricity. + * Calculates the Earth's orbit eccentricity * - * @param tm The time in Julian Centuries. - * @return The Earth's orbit eccentricity. + * @param tm The time in Julian Centuries + * @return The Earth's orbit eccentricity */ static inline double earth_orbit_eccentricity(double tm) @@ -141,10 +135,10 @@ earth_orbit_eccentricity(double tm) /** * Calculates the Sun's equation of the centre, the difference - * between the true anomaly and the mean anomaly. + * between the true anomaly and the mean anomaly * - * @param tm The time in Julian Centuries. - * @return The Sun's equation of the centre, in radians. + * @param tm The time in Julian Centuries + * @return The Sun's equation of the centre, in radians */ static inline double sun_equation_of_centre(double tm) @@ -157,10 +151,10 @@ sun_equation_of_centre(double tm) } /** - * Calculates the Sun's real longitudinal position. + * Calculates the Sun's real longitudinal position * - * @param tm The time in Julian Centuries. - * @return The longitude, in radians. + * @param tm The time in Julian Centuries + * @return The longitude, in radians */ static inline double sun_real_longitude(double tm) @@ -169,10 +163,10 @@ sun_real_longitude(double tm) } /** - * Calculates the Sun's apparent longitudinal position. + * Calculates the Sun's apparent longitudinal position * - * @param tm The time in Julian Centuries. - * @return The longitude, in radians. + * @param tm The time in Julian Centuries + * @return The longitude, in radians */ static inline double sun_apparent_longitude(double tm) @@ -183,10 +177,10 @@ sun_apparent_longitude(double tm) /** * Calculates the mean ecliptic obliquity of the Sun's - * apparent motion without variation correction. + * apparent motion without variation correction * - * @param tm The time in Julian Centuries. - * @return The uncorrected mean obliquity, in radians. + * @param tm The time in Julian Centuries + * @return The uncorrected mean obliquity, in radians */ static double mean_ecliptic_obliquity(double tm) @@ -197,10 +191,10 @@ mean_ecliptic_obliquity(double tm) /** * Calculates the mean ecliptic obliquity of the Sun's - * parent motion with variation correction. + * parent motion with variation correction * - * @param tm The time in Julian Centuries. - * @return The mean obliquity, in radians. + * @param tm The time in Julian Centuries + * @return The mean obliquity, in radians */ static double corrected_mean_ecliptic_obliquity(double tm) @@ -210,10 +204,10 @@ corrected_mean_ecliptic_obliquity(double tm) } /** - * Calculates the Sun's declination. + * Calculates the Sun's declination * - * @param tm The time in Julian Centuries. - * @return The Sun's declination, in radian. + * @param tm The time in Julian Centuries + * @return The Sun's declination, in radian */ static inline double solar_declination(double tm) @@ -224,10 +218,10 @@ solar_declination(double tm) /** * Calculates the equation of time, the discrepancy - * between apparent and mean solar time. + * between apparent and mean solar time * - * @param tm The time in Julian Centuries. - * @return The equation of time, in degrees. + * @param tm The time in Julian Centuries + * @return The equation of time, in degrees */ static inline double equation_of_time(double tm) @@ -245,15 +239,15 @@ equation_of_time(double tm) /** * Calculates the Sun's elevation as apparent - * from a geographical position. + * from a geographical position * - * @param tm The time in Julian Centuries. + * @param tm The time in Julian Centuries * @param latitude The latitude in degrees northwards from - * the equator, negative for southwards. + * the equator, negative for southwards * @param longitude The longitude in degrees eastwards from - * Greenwich, negative for westwards. + * Greenwich, negative for westwards * @return The Sun's apparent elevation at the specified time as seen - * from the specified position, measured in radians. + * from the specified position, measured in radians */ static inline double solar_elevation_from_time(double tm, double latitude, double longitude) @@ -265,35 +259,37 @@ solar_elevation_from_time(double tm, double latitude, double longitude) return elevation_from_hour_angle(latitude, solar_declination(tm), rc); } - /** * Calculates the Sun's elevation as apparent - * from a geographical position. + * from a geographical position * * @param latitude The latitude in degrees northwards from - * the equator, negative for southwards. + * the equator, negative for southwards * @param longitude The longitude in degrees eastwards from - * Greenwich, negative for westwards. - * @return The Sun's apparent elevation as seen, right now, - * from the specified position, measured in degrees. - * - * @throws 0 On success. - * @throws Any error specified for clock_gettime(3) on error. + * Greenwich, negative for westwards + * @param elevation Output parameter for the Sun's apparent elevation + * as seen, right now, from the specified position, + * measured in degrees + * @return 0 on success, -1 on failure + * @throws Any error specified for clock_gettime(3) on error */ double -libred_solar_elevation(double latitude, double longitude) +libred_solar_elevation(double latitude, double longitude, double *elevation) { - double tm = julian_centuries(); - return errno ? -1 : degrees(solar_elevation_from_time(tm, latitude, longitude)); + double tm; + if (julian_centuries(&tm)) + return -1; + *elevation = degrees(solar_elevation_from_time(tm, latitude, longitude)); + return 0; } - /** - * Exit if time the is before year 0 in J2000. + * Exit if time the is before year 0 in J2000 * - * @return 0 on success, -1 on error. + * @return 0 on success, -1 on error */ -int libred_check_timetravel(void) +int +libred_check_timetravel(void) { #if !defined(TIMETRAVELLER) struct timespec now; |