diff options
Diffstat (limited to 'en_masse-template.c')
-rw-r--r-- | en_masse-template.c | 122 |
1 files changed, 122 insertions, 0 deletions
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; +} |