aboutsummaryrefslogtreecommitdiffstats
path: root/en_masse-template.c
diff options
context:
space:
mode:
Diffstat (limited to 'en_masse-template.c')
-rw-r--r--en_masse-template.c693
1 files changed, 647 insertions, 46 deletions
diff --git a/en_masse-template.c b/en_masse-template.c
index 9a9f17f..b539328 100644
--- a/en_masse-template.c
+++ b/en_masse-template.c
@@ -1,5 +1,620 @@
/* See LICENSE file for copyright and license details. */
+#define XPARAMETERS\
+ size_t n, size_t width, TYPE *ch1, TYPE *ch2, TYPE *ch3
+
+#define XARGUMENTS\
+ (n), (width), (ch1), (ch2), (ch3)
+
+#define PARAMETERS(FROM_SPACE, TO_SPACE)\
+ const libcolour_##FROM_SPACE##_t *from, const libcolour_##TO_SPACE##_t *to, XPARAMETERS
+
+#define ARGUMENTS(FROM, TO)\
+ (FROM), (TO), XARGUMENTS
+
+
+#define SIMPLE_LOOP(CH, INSTRUCTIONS)\
+ do {\
+ TYPE *ch = (CH);\
+ size_t i__;\
+ for (i__ = 0; i__ < n; i__++) {\
+ INSTRUCTIONS;\
+ (CH) += width;\
+ }\
+ (CH) = ch;\
+ } while (0)
+
+#define LOOP(INSTRUCTIONS)\
+ do {\
+ TYPE *c1 = ch1, *c2 = ch2, *c3 = ch3;\
+ size_t i__;\
+ for (i__ = 0; i__ < n; i__++) {\
+ INSTRUCTIONS;\
+ ch1 += width;\
+ ch2 += width;\
+ ch3 += width;\
+ }\
+ ch1 = c1;\
+ ch2 = c2;\
+ ch3 = c3;\
+ } while (0)
+
+#define CONV_0(MACRO)\
+ LOOP(MACRO(*ch1, *ch2, *ch3, *ch1, *ch2, *ch3))
+
+#define CONV_N(MACRO, ...)\
+ LOOP(MACRO(*ch1, *ch2, *ch3, *ch1, *ch2, *ch3, __VA_ARGS__))
+
+
+#define LINEAR_SRGB\
+ do {\
+ if (from->srgb.with_transfer) {\
+ libcolour_srgb_t srgb__ = from->srgb;\
+ srgb__.with_transfer = 0;\
+ to_srgb(ARGUMENTS(from, &srgb__));\
+ }\
+ } while (0)
+
+
+
+#define X(C, T, N) static void to_##N(const libcolour_colour_t *from, const T *to, XPARAMETERS);
+LIST_MODELS(X)
+#undef X
+
+
+
+static void
+conversion_by_matrix(XPARAMETERS, TYPE m11, TYPE m12, TYPE m13, TYPE m21, TYPE m22, TYPE m23, TYPE m31, TYPE m32, TYPE m33)
+{
+ TYPE c1, c2, c3;
+ while (n--) {
+ c1 = *ch1;
+ c2 = *ch2;
+ c3 = *ch3;
+ *ch1 = m11 * c1 + m12 * c2 + m13 * c3;
+ *ch2 = m21 * c1 + m22 * c2 + m23 * c3;
+ *ch3 = m31 * c1 + m32 * c2 + m33 * c3;
+ ch1 += width;
+ ch2 += width;
+ ch3 += width;
+ }
+}
+
+
+static void
+rgb_encode(XPARAMETERS, const libcolour_rgb_t *restrict space)
+{
+ TYPE r_sign, g_sign, b_sign;
+ switch (space->encoding_type) {
+ case LIBCOLOUR_ENCODING_TYPE_LINEAR:
+ break;
+ case LIBCOLOUR_ENCODING_TYPE_SIMPLE:
+ case LIBCOLOUR_ENCODING_TYPE_REGULAR:
+ LOOP(do {
+ (r_sign = 1, g_sign = 1, b_sign = 1);
+ if (*ch1 < 0) (r_sign = -1, *ch1 = -*ch1);
+ if (*ch2 < 0) (g_sign = -1, *ch2 = -*ch2);
+ if (*ch3 < 0) (b_sign = -1, *ch3 = -*ch3);
+ if (space->encoding_type == LIBCOLOUR_ENCODING_TYPE_SIMPLE) {
+ *ch1 = xpow(*ch1, 1 / space->GAMMA);
+ *ch2 = xpow(*ch2, 1 / space->GAMMA);
+ *ch3 = xpow(*ch3, 1 / space->GAMMA);
+ } else {
+ *ch1 = REGULAR(space, *ch1);
+ *ch2 = REGULAR(space, *ch2);
+ *ch3 = REGULAR(space, *ch3);
+ }
+ *ch1 *= r_sign;
+ *ch2 *= g_sign;
+ *ch3 *= b_sign;
+ } while (0));
+ break;
+ case LIBCOLOUR_ENCODING_TYPE_CUSTOM:
+ LOOP((*ch1 = (space->TO_ENCODED_RED)(*ch1),
+ *ch2 = (space->TO_ENCODED_GREEN)(*ch2),
+ *ch3 = (space->TO_ENCODED_BLUE)(*ch3)));
+ break;
+ default:
+ fprintf(stderr, "libcolour: invalid encoding type\n");
+ abort();
+ }
+}
+
+static void
+rgb_decode(XPARAMETERS, const libcolour_rgb_t *restrict space)
+{
+ TYPE r_sign, g_sign, b_sign;
+ switch (space->encoding_type) {
+ case LIBCOLOUR_ENCODING_TYPE_LINEAR:
+ break;
+ case LIBCOLOUR_ENCODING_TYPE_SIMPLE:
+ case LIBCOLOUR_ENCODING_TYPE_REGULAR:
+ LOOP(do {
+ (r_sign = 1, g_sign = 1, b_sign = 1);
+ if (*ch1 < 0) (r_sign = -1, *ch1 = -*ch1);
+ if (*ch2 < 0) (g_sign = -1, *ch2 = -*ch2);
+ if (*ch3 < 0) (b_sign = -1, *ch3 = -*ch3);
+ if (space->encoding_type == LIBCOLOUR_ENCODING_TYPE_SIMPLE) {
+ *ch1 = xpow(*ch1, space->GAMMA);
+ *ch2 = xpow(*ch2, space->GAMMA);
+ *ch3 = xpow(*ch3, space->GAMMA);
+ } else {
+ *ch1 = INVREGULAR(space, *ch1);
+ *ch2 = INVREGULAR(space, *ch2);
+ *ch3 = INVREGULAR(space, *ch3);
+ }
+ *ch1 *= r_sign;
+ *ch2 *= g_sign;
+ *ch3 *= b_sign;
+ } while (0));
+ break;
+ case LIBCOLOUR_ENCODING_TYPE_CUSTOM:
+ LOOP((*ch1 = (space->TO_DECODED_RED)(*ch1),
+ *ch2 = (space->TO_DECODED_GREEN)(*ch2),
+ *ch3 = (space->TO_DECODED_BLUE)(*ch3)));
+ break;
+ default:
+ fprintf(stderr, "libcolour: invalid encoding type\n");
+ abort();
+ }
+}
+
+static int
+rgb_same_transfer(const libcolour_rgb_t *a, const libcolour_rgb_t *b)
+{
+ if (a->encoding_type != b->encoding_type)
+ return 0;
+ switch (a->encoding_type) {
+ case LIBCOLOUR_ENCODING_TYPE_SIMPLE:
+ return a->GAMMA == b->GAMMA;
+ case LIBCOLOUR_ENCODING_TYPE_REGULAR:
+ return a->GAMMA == b->GAMMA &&
+ a->OFFSET == b->OFFSET &&
+ a->SLOPE == b->SLOPE &&
+ a->TRANSITION == b->TRANSITION;
+ case LIBCOLOUR_ENCODING_TYPE_CUSTOM:
+ return a->TO_ENCODED_RED == b->TO_ENCODED_RED &&
+ a->TO_ENCODED_GREEN == b->TO_ENCODED_GREEN &&
+ a->TO_ENCODED_BLUE == b->TO_ENCODED_BLUE &&
+ a->TO_DECODED_RED == b->TO_DECODED_RED &&
+ a->TO_DECODED_GREEN == b->TO_DECODED_GREEN &&
+ a->TO_DECODED_BLUE == b->TO_DECODED_BLUE;
+ default:
+ return 1;
+ }
+}
+
+static void
+to_rgb(PARAMETERS(colour, rgb))
+{
+ int have_transfer = 0, with_transfer = to->with_transfer;
+ switch (from->model) {
+ case LIBCOLOUR_RGB:
+ if (!memcmp(from->rgb.M, to->M, sizeof(TYPE[3][3]))) {
+ have_transfer = from->rgb.with_transfer;
+ if (have_transfer && with_transfer && !rgb_same_transfer(&from->rgb, to)) {
+ rgb_decode(XARGUMENTS, &from->rgb);
+ have_transfer = 0;
+ }
+ break;
+ }
+ /* fall through */
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_RGB(to->Minv));
+ break;
+ }
+
+ if (have_transfer != with_transfer) {
+ if (with_transfer)
+ rgb_encode(XARGUMENTS, to);
+ else
+ rgb_decode(XARGUMENTS, &from->rgb);
+ }
+}
+
+
+static void
+to_srgb(PARAMETERS(colour, srgb))
+{
+ libcolour_srgb_t tmp;
+ switch (from->model) {
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_SRGB);
+ break;
+ case LIBCOLOUR_SRGB:
+ srgb_to_srgb:
+ if (from->srgb.with_transfer != to->with_transfer) {
+ if (to->with_transfer) {
+ LOOP((*ch1 = srgb_encode(*ch1),
+ *ch2 = srgb_encode(*ch2),
+ *ch3 = srgb_encode(*ch3)));
+ } else {
+ LOOP((*ch1 = srgb_decode(*ch1),
+ *ch2 = srgb_decode(*ch2),
+ *ch3 = srgb_decode(*ch3)));
+ }
+ }
+ return;
+ case LIBCOLOUR_YIQ:
+ conversion_by_matrix(XARGUMENTS, YIQ_TO_SRGB);
+ break;
+ case LIBCOLOUR_YDBDR:
+ conversion_by_matrix(XARGUMENTS, YDBDR_TO_SRGB);
+ break;
+ case LIBCOLOUR_YPBPR:
+ CONV_0(YPBPR_TO_SRGB);
+ break;
+ case LIBCOLOUR_YUV:
+ conversion_by_matrix(XARGUMENTS, YUV_TO_SRGB);
+ break;
+ case LIBCOLOUR_YCGCO:
+ conversion_by_matrix(XARGUMENTS, YCGCO_TO_SRGB);
+ break;
+ }
+ if (to->with_transfer) {
+ tmp = *to;
+ tmp.with_transfer = 0;
+ from = (const void *)&tmp;
+ goto srgb_to_srgb;
+ }
+}
+
+
+static void
+to_ciexyy(PARAMETERS(colour, ciexyy))
+{
+ libcolour_srgb_t tmp;
+ size_t m, old_n;
+beginning:
+ m = old_n = n;
+ switch (from->model) {
+ case LIBCOLOUR_CIEXYY:
+ break;
+ case LIBCOLOUR_SRGB:
+ tmp.model = LIBCOLOUR_SRGB;
+ tmp.with_transfer = 0;
+ if (from->srgb.with_transfer)
+ to_srgb(ARGUMENTS((const libcolour_colour_t *)from, &tmp));
+ if (!*ch1 && !*ch2 && !*ch3) {
+ for (m = 1; m < n && !ch1[m * width] && !ch2[m * width] && !ch3[m * width]; m++);
+ n = m;
+ LOOP((*ch1 = D(0.31272660439158),
+ *ch2 = D(0.32902315240275),
+ *ch3 = 0));
+ n = old_n;
+ break;
+ } else {
+ for (m = 1; m < n && (ch1[m * width] || ch2[m * width] || ch3[m * width]); m++);
+ n = m;
+ from = (const void *)&tmp;
+ }
+ /* fall through */
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ CONV_0(CIEXYZ_TO_CIEXYY);
+ break;
+ }
+ if (m != old_n) {
+ n = old_n - m;
+ ch1 += m * width;
+ ch2 += m * width;
+ ch3 += m * width;
+ goto beginning;
+ }
+}
+
+
+static void
+to_ciexyz(PARAMETERS(colour, ciexyz))
+{
+ libcolour_colour_t tmp;
+ switch (from->model) {
+ case LIBCOLOUR_RGB:
+ if (from->rgb.with_transfer) {
+ tmp.rgb = from->rgb;
+ tmp.rgb.with_transfer = 0;
+ to_rgb(ARGUMENTS(from, &tmp.rgb));
+ }
+ conversion_by_matrix(XARGUMENTS, RGB_TO_CIEXYZ(from->rgb.M));
+ break;
+ default:
+ tmp.srgb.model = LIBCOLOUR_SRGB;
+ tmp.srgb.with_transfer = 0;
+ to_srgb(ARGUMENTS(from, &tmp.srgb));
+ from = (const void *)&tmp.srgb;
+ /* fall through */
+ case LIBCOLOUR_SRGB:
+ LINEAR_SRGB;
+ conversion_by_matrix(XARGUMENTS, SRGB_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_CIEXYY:
+ CONV_0(CIEXYY_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_CIEXYZ:
+ break;
+ case LIBCOLOUR_CIELAB:
+ CONV_0(CIELAB_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_CIELCHUV:
+ tmp.cieluv.model = LIBCOLOUR_CIELUV;
+ tmp.cieluv.white = from->cielchuv.white;
+ to_cieluv(ARGUMENTS(from, &tmp.cieluv));
+ from = (const void *)&tmp.cieluv;
+ /* fall through */
+ case LIBCOLOUR_CIELUV:
+ CONV_N(CIELUV_TO_CIEXYZ, from->cieluv.white.X, from->cieluv.white.Y, from->cieluv.white.Z);
+ break;
+ case LIBCOLOUR_YIQ:
+ conversion_by_matrix(XARGUMENTS, YIQ_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_YDBDR:
+ conversion_by_matrix(XARGUMENTS, YDBDR_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_YUV:
+ conversion_by_matrix(XARGUMENTS, YUV_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_YPBPR:
+ conversion_by_matrix(XARGUMENTS, YPBPR_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_YCGCO:
+ conversion_by_matrix(XARGUMENTS, YCGCO_TO_CIEXYZ);
+ break;
+ case LIBCOLOUR_CIEUVW:
+ tmp.cie1960ucs.model = LIBCOLOUR_CIE1960UCS;
+ to_cie1960ucs(ARGUMENTS(from, &tmp.cie1960ucs));
+ from = (const void *)&tmp.cie1960ucs;
+ /* fall through */
+ case LIBCOLOUR_CIE1960UCS:
+ CONV_0(CIE1960UCS_TO_CIEXYZ);
+ break;
+ }
+}
+
+
+static void
+to_cielab(PARAMETERS(colour, cielab))
+{
+ switch (from->model) {
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ CONV_0(CIEXYZ_TO_CIELAB);
+ break;
+ case LIBCOLOUR_CIELAB:
+ break;
+ }
+}
+
+
+static void
+to_cieluv(PARAMETERS(colour, cieluv))
+{
+ libcolour_ciexyz_t tmp;
+ libcolour_cielchuv_t tmp2;
+ TYPE m;
+ switch (from->model) {
+ case LIBCOLOUR_CIELCHUV:
+ if (to->white.X != from->cielchuv.white.X ||
+ to->white.Y != from->cielchuv.white.Y ||
+ to->white.Z != from->cielchuv.white.Z) {
+ tmp.model = LIBCOLOUR_CIEXYZ;
+ tmp2.model = LIBCOLOUR_CIELCHUV;
+ tmp2.white = to->white;
+ tmp2.one_revolution = PI2;
+ to_ciexyz(ARGUMENTS(from, &tmp));
+ to_cielchuv(ARGUMENTS((const libcolour_colour_t *)&tmp, &tmp2));
+ } else if (from->cielchuv.one_revolution != PI2) {
+ m = PI2 / from->cielchuv.one_revolution;
+ SIMPLE_LOOP(ch3, *ch3 *= m);
+ }
+ CONV_0(CIELCHUV_TO_CIELUV);
+ break;
+ case LIBCOLOUR_CIELUV:
+ if (to->white.X == from->cieluv.white.X &&
+ to->white.Y == from->cieluv.white.Y &&
+ to->white.Z == from->cieluv.white.Z)
+ break;
+ /* fall through */
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ CONV_N(CIEXYZ_TO_CIELUV, to->white.X, to->white.Y, to->white.Z);
+ break;
+ }
+}
+
+
+static void
+to_cielchuv(PARAMETERS(colour, cielchuv))
+{
+ libcolour_cieluv_t tmp1, tmp2;
+ TYPE m;
+ switch (from->model) {
+ case LIBCOLOUR_CIELCHUV:
+ if (to->white.X == from->cielchuv.white.X &&
+ to->white.Y == from->cielchuv.white.Y &&
+ to->white.Z == from->cielchuv.white.Z) {
+ if (to->one_revolution != from->cielchuv.one_revolution) {
+ m = to->one_revolution;
+ m /= from->cielchuv.one_revolution;
+ SIMPLE_LOOP(ch3, *ch3 *= m);
+ }
+ break;
+ }
+ /* fall through */
+ default:
+ tmp1.model = LIBCOLOUR_CIELUV;
+ tmp1.white = to->white;
+ to_cieluv(ARGUMENTS(from, &tmp1));
+ from = (const void *)&tmp1;
+ /* fall through */
+ case LIBCOLOUR_CIELUV:
+ if (to->white.X != from->cieluv.white.X ||
+ to->white.Y != from->cieluv.white.Y ||
+ to->white.Z != from->cieluv.white.Z) {
+ tmp2.model = LIBCOLOUR_CIELUV;
+ tmp2.white = to->white;
+ to_cieluv(ARGUMENTS(from, &tmp2));
+ from = (const void *)&tmp2;
+ }
+ CONV_N(CIELUV_TO_CIELCHUV, to->one_revolution);
+ break;
+ }
+}
+
+
+static void
+to_yiq(PARAMETERS(colour, yiq))
+{
+ switch (from->model) {
+ case LIBCOLOUR_YIQ:
+ break;
+ case LIBCOLOUR_SRGB:
+ LINEAR_SRGB;
+ conversion_by_matrix(XARGUMENTS, SRGB_TO_YIQ);
+ break;
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_YIQ);
+ break;
+ }
+}
+
+
+static void
+to_ydbdr(PARAMETERS(colour, ydbdr))
+{
+ switch (from->model) {
+ case LIBCOLOUR_YDBDR:
+ break;
+ case LIBCOLOUR_SRGB:
+ LINEAR_SRGB;
+ conversion_by_matrix(XARGUMENTS, SRGB_TO_YDBDR);
+ break;
+ case LIBCOLOUR_YUV:
+ CONV_0(YUV_TO_YDBDR);
+ break;
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_YDBDR);
+ break;
+ }
+}
+
+
+static void
+to_yuv(PARAMETERS(colour, yuv))
+{
+ switch (from->model) {
+ case LIBCOLOUR_YUV:
+ break;
+ case LIBCOLOUR_YDBDR:
+ CONV_0(YDBDR_TO_YUV);
+ break;
+ case LIBCOLOUR_SRGB:
+ LINEAR_SRGB;
+ conversion_by_matrix(XARGUMENTS, SRGB_TO_YUV);
+ break;
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_YUV);
+ break;
+ }
+}
+
+
+static void
+to_ypbpr(PARAMETERS(colour, ypbpr))
+{
+ switch (from->model) {
+ case LIBCOLOUR_YPBPR:
+ break;
+ case LIBCOLOUR_SRGB:
+ LINEAR_SRGB;
+ CONV_0(SRGB_TO_YPBPR);
+ break;
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_YPBPR);
+ break;
+ }
+}
+
+
+static void
+to_ycgco(PARAMETERS(colour, ycgco))
+{
+ switch (from->model) {
+ case LIBCOLOUR_YCGCO:
+ break;
+ case LIBCOLOUR_SRGB:
+ LINEAR_SRGB;
+ conversion_by_matrix(XARGUMENTS, SRGB_TO_YCGCO);
+ break;
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ conversion_by_matrix(XARGUMENTS, CIEXYZ_TO_YCGCO);
+ break;
+ }
+}
+
+
+static void
+to_cie1960ucs(PARAMETERS(colour, cie1960ucs))
+{
+ switch (from->model) {
+ case LIBCOLOUR_CIE1960UCS:
+ break;
+ case LIBCOLOUR_CIEUVW:
+ CONV_N(CIEUVW_TO_CIE1960UCS, from->cieuvw.u0, from->cieuvw.v0);
+ break;
+ default:
+ to_ciexyz(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIEXYZ:
+ CONV_0(CIEXYZ_TO_CIE1960UCS);
+ break;
+ }
+}
+
+
+static void
+to_cieuvw(PARAMETERS(colour, cieuvw))
+{
+ switch (from->model) {
+ case LIBCOLOUR_CIEUVW:
+ CONV_N(CIEUVW_TO_CIEUVW, from->cieuvw.u0, from->cieuvw.v0, to->u0, to->v0);
+ break;
+ default:
+ to_cie1960ucs(ARGUMENTS(from, NULL));
+ /* fall through */
+ case LIBCOLOUR_CIE1960UCS:
+ CONV_N(CIE1960UCS_TO_CIEUVW, to->u0, to->v0);
+ break;
+ }
+}
+
+
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, ...)
@@ -10,8 +625,8 @@ libcolour_convert_en_masse(const libcolour_colour_t *from, const libcolour_colou
int no_override = mode & LIBCOLOUR_CONVERT_EN_MASSE_NO_OVERRIDE;
va_list args;
TYPE *in1, *in2, *in3, *in_alpha = NULL;
- TYPE *out1, *out2, *out3, *out_alpha = NULL;
- size_t width, i;
+ TYPE *ch1, *ch2, *ch3, *ch_alpha = NULL;
+ size_t width;
if ((unsigned int)mode > 15U) {
errno = EINVAL;
@@ -49,28 +664,34 @@ libcolour_convert_en_masse(const libcolour_colour_t *from, const libcolour_colou
}
if (!no_override) {
- out1 = in1;
- out2 = in2;
- out3 = in3;
- out_alpha = in_alpha;
+ ch1 = in1;
+ ch2 = in2;
+ ch3 = in3;
+ ch_alpha = in_alpha;
} else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_NO_ALPHA) {
- out1 = va_arg(args, TYPE *);
- out2 = out1 + 1;
- out3 = out1 + 2;
+ ch1 = va_arg(args, TYPE *);
+ ch2 = ch1 + 1;
+ ch3 = ch1 + 2;
+ memcpy(ch1, in1, n * 3 * sizeof(TYPE));
} else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_FIRST) {
- out_alpha = va_arg(args, TYPE *);
- out1 = out_alpha + 1;
- out2 = out_alpha + 2;
- out3 = out_alpha + 3;
+ ch_alpha = va_arg(args, TYPE *);
+ ch1 = ch_alpha + 1;
+ ch2 = ch_alpha + 2;
+ ch3 = ch_alpha + 3;
+ memcpy(ch_alpha, in_alpha, n * 4 * sizeof(TYPE));
} else if (alpha_mode == LIBCOLOUR_CONVERT_EN_MASSE_ALPHA_LAST) {
- out1 = va_arg(args, TYPE *);
- out2 = out1 + 1;
- out3 = out1 + 2;
- out_alpha = out1 + 3;
+ ch1 = va_arg(args, TYPE *);
+ ch2 = ch1 + 1;
+ ch3 = ch1 + 2;
+ ch_alpha = ch1 + 3;
+ memcpy(ch1, in1, n * 4 * sizeof(TYPE));
} else {
- out1 = va_arg(args, TYPE *);
- out2 = va_arg(args, TYPE *);
- out3 = va_arg(args, TYPE *);
+ ch1 = va_arg(args, TYPE *);
+ ch2 = va_arg(args, TYPE *);
+ ch3 = va_arg(args, TYPE *);
+ memcpy(ch1, in1, n * sizeof(TYPE));
+ memcpy(ch2, in2, n * sizeof(TYPE));
+ memcpy(ch3, in3, n * sizeof(TYPE));
}
va_end(args);
@@ -85,38 +706,18 @@ libcolour_convert_en_masse(const libcolour_colour_t *from, const libcolour_colou
}
switch (to->model) {
-#define X(C, T, N) case C: memcpy(&tto, to, sizeof(T)); break;
- LIST_MODELS(X)
+#define X(C, T, N)\
+ case C:\
+ memcpy(&tto, to, sizeof(T));\
+ to_##N(ARGUMENTS(&tfrom, &tto.N));\
+ break;
+ LIST_MODELS(X)
#undef X
default:
errno = EINVAL;
return -1;
}
- if (in_alpha != out_alpha) {
- for (i = 0; i < n; i++) {
- *out_alpha = *in_alpha;
- in_alpha += width;
- out_alpha += width;
- }
- }
-
- while (n--) {
- tfrom.rgb.R = *in1;
- tfrom.rgb.G = *in2;
- tfrom.rgb.B = *in3;
- libcolour_convert(&tfrom, &tto);
- *out1 = tto.rgb.R;
- *out2 = tto.rgb.G;
- *out3 = tto.rgb.B;
- in1 += width;
- in2 += width;
- in3 += width;
- out1 += width;
- out2 += width;
- out3 += width;
- }
-
(void) on_cpu;
return 0;
}