From 769d12c6be9e4be2ec776a7f6e69dedefebd9cb2 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 10 Jun 2017 13:50:13 +0200 Subject: Add libcolour_convert_en_masse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 12 +++++- TODO | 23 +--------- config.mk | 2 +- double.c | 4 ++ en_masse-template.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ float.c | 4 ++ libcolour.h | 24 ++++++++++- libcolour_convert.3 | 9 ++-- long-double.c | 4 ++ test.c | 4 +- 10 files changed, 179 insertions(+), 29 deletions(-) create mode 100644 en_masse-template.c diff --git a/Makefile b/Makefile index 0b52b45..5dd9023 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ HDR =\ TEMPLATES =\ convert-template.c\ + en_masse-template.c\ libcolour-template.c MAN7 =\ @@ -42,7 +43,8 @@ MAN3 =\ libcolour_proper.3\ libcolour_get_rgb_colour_space.3\ libcolour_marshal.3\ - libcolour_unmarshal.3 + libcolour_unmarshal.3\ + libcolour_convert_en_masse.3 MAN3_SYMLINKS =\ libcolour_convert_f.3\ @@ -68,7 +70,10 @@ MAN3_SYMLINKS =\ libcolour_marshal_llf.3\ libcolour_unmarshal_f.3\ libcolour_unmarshal_lf.3\ - libcolour_unmarshal_llf.3 + libcolour_unmarshal_llf.3\ + libcolour_convert_en_masse_f.3\ + libcolour_convert_en_masse_lf.3\ + libcolour_convert_en_masse_llf.3 all: libcolour.a libcolour.so.$(SO_VERSION) libcolour.7 test @@ -154,6 +159,9 @@ install: libcolour.a libcolour.so.$(SO_VERSION) libcolour.7 ln -sf -- libcolour_unmarshal.3 "$(DESTDIR)$(MANPREFIX)/man3/libcolour_unmarshal_f.3" ln -sf -- libcolour_unmarshal.3 "$(DESTDIR)$(MANPREFIX)/man3/libcolour_unmarshal_lf.3" ln -sf -- libcolour_unmarshal.3 "$(DESTDIR)$(MANPREFIX)/man3/libcolour_unmarshal_llf.3" + ln -sf -- libcolour_convert_en_masse.3 "$(DESTDIR)$(MANPREFIX)/man3/libcolour_convert_en_masse_f.3" + ln -sf -- libcolour_convert_en_masse.3 "$(DESTDIR)$(MANPREFIX)/man3/libcolour_convert_en_masse_lf.3" + ln -sf -- libcolour_convert_en_masse.3 "$(DESTDIR)$(MANPREFIX)/man3/libcolour_convert_en_masse_llf.3" uninstall: diff --git a/TODO b/TODO index baa0cac..4a19de7 100644 --- a/TODO +++ b/TODO @@ -21,24 +21,5 @@ Colour models and colour spaces: Support for generic additive colour spaces (3 channels and more) Support for generic subtractive colour spaces (3 channels and more) -GPU accelerated functions: - int libcolour_convert_en_masse_f(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `float* ch1, float* ch2, float* ch3`. - int libcolour_convert_en_masse_lf(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `double* ch1, double* ch2, double* ch3`. - int libcolour_convert_en_masse_llf(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `long double* ch1, long double* ch2, long double* ch3`. - - int libcolour_convert_en_masse_3f(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `float* ch123`. - int libcolour_convert_en_masse_3lf(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `double* ch123`. - int libcolour_convert_en_masse_3llf(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `long double* ch123`. - - int libcolour_convert_en_masse_4f(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `float* ch123a`. - int libcolour_convert_en_masse_4lf(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `double* ch123a`. - int libcolour_convert_en_masse_4llf(const libcolour_colour_t* from, const libcolour_colour_t* to, size_t n, ...) - Where `...` normally is `long double* ch123a`. +Improve performance of libcolour_convert_en_masse +GPU accelerate libcolour_convert_en_masse diff --git a/config.mk b/config.mk index c2ee0de..9924d1f 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ VERSION_MAJOR = 2 -VERSION_MINOR = 0 +VERSION_MINOR = 1 PREFIX = /usr/local MANPREFIX = $(PREFIX)/share/man diff --git a/double.c b/double.c index 8bc25de..77a2f70 100644 --- a/double.c +++ b/double.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ #undef libcolour_get_rgb_colour_space #undef libcolour_marshal #undef libcolour_unmarshal +#undef libcolour_convert_en_masse #define libcolour_convert libcolour_convert_lf #define libcolour_srgb_encode libcolour_srgb_encode_lf @@ -77,6 +79,8 @@ #define libcolour_get_rgb_colour_space libcolour_get_rgb_colour_space_lf #define libcolour_marshal libcolour_marshal_lf #define libcolour_unmarshal libcolour_unmarshal_lf +#define libcolour_convert_en_masse libcolour_convert_en_masse_lf #include "convert-template.c" #include "libcolour-template.c" +#include "en_masse-template.c" diff --git a/en_masse-template.c b/en_masse-template.c new file mode 100644 index 0000000..d823026 --- /dev/null +++ b/en_masse-template.c @@ -0,0 +1,122 @@ +/* See LICENSE file for copyright and license details. */ + +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic ignored "-Wfloat-equal" +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wcomma" +# pragma clang diagnostic ignored "-Wfloat-equal" +# pragma clang diagnostic ignored "-Wvla" +# pragma clang diagnostic ignored "-Wtautological-compare" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# pragma clang diagnostic ignored "-Wfloat-conversion" +# pragma clang diagnostic ignored "-Wconversion" +# pragma clang diagnostic ignored "-Wdouble-promotion" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcast-align" +#endif + + + +int +libcolour_convert_en_masse(const libcolour_colour_t *from, const libcolour_colour_t *to, + libcolour_convert_en_masse_mode_t mode, size_t n, ...) +{ + libcolour_colour_t tfrom, tto; + libcolour_convert_en_masse_mode_t alpha_mode = mode & 3; + int on_cpu = mode & LIBCOLOUR_CONVERT_EN_MASSE_ON_CPU; + int no_override = mode & LIBCOLOUR_CONVERT_EN_MASSE_NO_OVERRIDE; + va_list args; + TYPE *in1, *in2, *in3; + TYPE *out1, *out2, *out3; + size_t width; + + if ((unsigned int)mode > 15U) { + errno = EINVAL; + return -1; + } + if (n < 0) { + errno = EINVAL; + return -1; + } + + va_start(args, n); + + if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_NO_ALPHA) { + in1 = va_arg(args, TYPE *); + in2 = in1 + 1; + in3 = in1 + 2; + width = 3; + } else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_FIRST) { + in1 = va_arg(args, TYPE *); + in2 = in1 + 2; + in3 = in1 + 3; + in1 = in1 + 1; + width = 4; + } else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_LAST) { + in1 = va_arg(args, TYPE *); + in2 = in1 + 1; + in3 = in1 + 2; + width = 4; + } else { + in1 = va_arg(args, TYPE *); + in2 = va_arg(args, TYPE *); + in3 = va_arg(args, TYPE *); + width = 1; + } + + if (!no_override) { + out1 = in1; + out2 = in2; + out3 = in3; + } else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_NO_ALPHA) { + out1 = va_arg(args, TYPE *); + out2 = out1 + 1; + out3 = out1 + 2; + } else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_FIRST) { + out1 = va_arg(args, TYPE *); + out2 = out1 + 2; + out3 = out1 + 3; + out1 = out1 + 1; + } else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_LAST) { + out1 = va_arg(args, TYPE *); + out2 = out1 + 1; + out3 = out1 + 2; + } else { + out1 = va_arg(args, TYPE *); + out2 = va_arg(args, TYPE *); + out3 = va_arg(args, TYPE *); + } + + va_end(args); + + switch (from->model) { +#define X(C, T, N) case C: memcpy(&tfrom, from, sizeof(T)); + LIST_MODELS(X) +#undef X + default: + errno = EINVAL; + return -1; + } + + switch (to->model) { +#define X(C, T, N) case C: memcpy(&tto, to, sizeof(T)); + LIST_MODELS(X) +#undef X + default: + errno = EINVAL; + return -1; + } + + while (n--) { + tfrom.rgb.R = in1[n * width]; + tfrom.rgb.G = in2[n * width]; + tfrom.rgb.B = in3[n * width]; + libcolour_convert(&tfrom, &tto); + out1[n * width] = tto.rgb.R; + out2[n * width] = tto.rgb.G; + out3[n * width] = tto.rgb.B; + } + + (void) on_cpu; + return 0; +} diff --git a/float.c b/float.c index 019152c..829003a 100644 --- a/float.c +++ b/float.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ #undef libcolour_get_rgb_colour_space #undef libcolour_marshal #undef libcolour_unmarshal +#undef libcolour_convert_en_masse #define libcolour_convert libcolour_convert_f #define libcolour_srgb_encode libcolour_srgb_encode_f @@ -77,6 +79,8 @@ #define libcolour_get_rgb_colour_space libcolour_get_rgb_colour_space_f #define libcolour_marshal libcolour_marshal_f #define libcolour_unmarshal libcolour_unmarshal_f +#define libcolour_convert_en_masse libcolour_convert_en_masse_f #include "convert-template.c" #include "libcolour-template.c" +#include "en_masse-template.c" diff --git a/libcolour.h b/libcolour.h index d891e80..51dfaa8 100644 --- a/libcolour.h +++ b/libcolour.h @@ -290,6 +290,22 @@ typedef enum libcolour_rgb_colour_space { } libcolour_rgb_colour_space_t; +typedef enum libcolour_convert_en_masse_mode { + LIBCOLOUR_CONVERT_EN_MASSE_NO_ALPHA = 0x0000, +#define LIBCOLOUR_CONVERT_EN_MASSE_NO_ALPHA LIBCOLOUR_CONVERT_EN_MASSE_NO_ALPHA + LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_FIRST = 0x0001, +#define LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_FIRST LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_FIRST + LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_LAST = 0x0002, +#define LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_LAST LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_LAST + LIBCOLOUR_CONVERT_EN_MASSE_SEPARATED = 0x0003, +#define LIBCOLOUR_CONVERT_EN_MASSE_SEPARATED LIBCOLOUR_CONVERT_EN_MASSE_SEPARATED + LIBCOLOUR_CONVERT_EN_MASSE_ON_CPU = 0x0004, +#define LIBCOLOUR_CONVERT_EN_MASSE_ON_CPU LIBCOLOUR_CONVERT_EN_MASSE_ON_CPU + LIBCOLOUR_CONVERT_EN_MASSE_NO_OVERRIDE = 0x0008 +#define LIBCOLOUR_CONVERT_EN_MASSE_NO_OVERRIDE LIBCOLOUR_CONVERT_EN_MASSE_NO_OVERRIDE +} libcolour_convert_en_masse_mode_t; + + #define LIBCOLOUR_X(C, T, N) T N; #define LIBCOLOUR_DEF(TYPE, RES) \ typedef struct libcolour_srgb_##RES {\ @@ -442,7 +458,9 @@ int libcolour_delta_e_##RES(const libcolour_colour_##RES##_t *, const libcolour_ int libcolour_proper_##RES(libcolour_colour_##RES##_t *);\ int libcolour_get_rgb_colour_space_##RES(libcolour_rgb_##RES##_t *, libcolour_rgb_colour_space_t);\ size_t libcolour_marshal_##RES(const libcolour_colour_##RES##_t *, void *);\ -size_t libcolour_unmarshal_##RES(libcolour_colour_##RES##_t *, const void *); +size_t libcolour_unmarshal_##RES(libcolour_colour_##RES##_t *, const void *);\ +int libcolour_convert_en_masse_##RES(const libcolour_colour_##RES##_t *from, const libcolour_colour_##RES##_t *to,\ + libcolour_convert_en_masse_mode_t mode, size_t n, ...); LIBCOLOUR_DEF(float, f) LIBCOLOUR_DEF(double, lf) @@ -494,6 +512,10 @@ LIBCOLOUR_DEF(long double, llf) #define libcolour_unmarshal(COLOUR, BUF)\ LIBCOLOUR_GENERIC(libcolour_unmarshal, (COLOUR), (void *)(COLOUR), (const void *)(BUF)) +#define libcolour_convert_en_masse(FROM, TO, MODE, N, ...)\ + LIBCOLOUR_GENERIC(libcolour_convert_en_masse, (FROM), (const void *)(FROM),\ + (const void *)(TO), (MODE), (N), __VA_ARGS__) + static inline int libcolour_proper_f__(union libcolour_colour_f *colour, enum libcolour_model model) diff --git a/libcolour_convert.3 b/libcolour_convert.3 index 58f133e..1dccc0a 100644 --- a/libcolour_convert.3 +++ b/libcolour_convert.3 @@ -5,9 +5,12 @@ libcolour_convert - Colour space and colour model conversion .nf #include -int \fBlibcolour_convert_f\fP(const libcolour_colour_f_t *\fIfrom\fP, libcolour_colour_f_t *\fIto\fP); -int \fBlibcolour_convert_lf\fP(const libcolour_colour_lf_t *\fIfrom\fP, libcolour_colour_lf_t *\fIto\fP); -int \fBlibcolour_convert_llf\fP(const libcolour_colour_llf_t *\fIfrom\fP, libcolour_colour_llf_t *\fIto\fP); +int \fBlibcolour_convert_f\fP(const libcolour_colour_f_t *restrict \fIfrom\fP, + libcolour_colour_f_t *restrict \fIto\fP); +int \fBlibcolour_convert_lf\fP(const libcolour_colour_lf_t *restrict \fIfrom\fP, + libcolour_colour_lf_t *restrict \fIto\fP); +int \fBlibcolour_convert_llf\fP(const libcolour_colour_llf_t *restrict \fIfrom\fP, + libcolour_colour_llf_t *restrict \fIto\fP); #define \fBlibcolour_convert\fP(\fIfrom\fP, \fIto\fP)\\ (_Generic((\fIfrom\fP),\\ diff --git a/long-double.c b/long-double.c index ec43c96..b91da21 100644 --- a/long-double.c +++ b/long-double.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ #undef libcolour_get_rgb_colour_space #undef libcolour_marshal #undef libcolour_unmarshal +#undef libcolour_convert_en_masse #define libcolour_convert libcolour_convert_llf #define libcolour_srgb_encode libcolour_srgb_encode_llf @@ -77,6 +79,8 @@ #define libcolour_get_rgb_colour_space libcolour_get_rgb_colour_space_llf #define libcolour_marshal libcolour_marshal_llf #define libcolour_unmarshal libcolour_unmarshal_llf +#define libcolour_convert_en_masse libcolour_convert_en_masse_llf #include "convert-template.c" #include "libcolour-template.c" +#include "en_masse-template.c" diff --git a/test.c b/test.c index 5264694..3b04f7c 100644 --- a/test.c +++ b/test.c @@ -665,9 +665,11 @@ colour_spaces_done: } marshal_done: + /* TODO test libcolour_convert_en_masse */ + return rc; fail: perror(*argv); - return 2; (void) argc; + return 2; } -- cgit v1.2.3-70-g09d2