[gimp] app: implement the different composite modes for normal mode
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: implement the different composite modes for normal mode
- Date: Fri, 17 Feb 2017 23:22:00 +0000 (UTC)
commit d1a0c253c24dc2748fbe4951ecb5055647c17612
Author: Ell <ell_se yahoo com>
Date: Fri Feb 17 11:58:18 2017 -0500
app: implement the different composite modes for normal mode
.../layer-modes/gimpoperationnormal-sse2.c | 214 ++++++++++++++++----
.../layer-modes/gimpoperationnormal-sse4.c | 209 ++++++++++++++++----
app/operations/layer-modes/gimpoperationnormal.c | 165 +++++++++++++--
3 files changed, 496 insertions(+), 92 deletions(-)
---
diff --git a/app/operations/layer-modes/gimpoperationnormal-sse2.c
b/app/operations/layer-modes/gimpoperationnormal-sse2.c
index b6ab493..1adbd90 100644
--- a/app/operations/layer-modes/gimpoperationnormal-sse2.c
+++ b/app/operations/layer-modes/gimpoperationnormal-sse2.c
@@ -51,67 +51,209 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
}
else
{
- gfloat opacity = ((GimpOperationLayerMode *)(operation))->opacity;
- gfloat *mask = mask_p;
- const __v4sf *v_in = (const __v4sf*) in;
- const __v4sf *v_aux = (const __v4sf*) aux;
- __v4sf *v_out = ( __v4sf*) out;
+ GimpOperationLayerMode *layer_mode = (GimpOperationLayerMode *) operation;
+ gfloat opacity = layer_mode->opacity;
+ gfloat *mask = mask_p;
+ const __v4sf *v_in = (const __v4sf*) in;
+ const __v4sf *v_aux = (const __v4sf*) aux;
+ __v4sf *v_out = ( __v4sf*) out;
- const __v4sf one = _mm_set1_ps (1.0f);
+ const __v4sf one = _mm_set1_ps (1.0f);
const __v4sf v_opacity = _mm_set1_ps (opacity);
- while (samples--)
+ switch (layer_mode->composite_mode)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ case GIMP_LAYER_COMPOSITE_SRC_OVER:
+ case GIMP_LAYER_COMPOSITE_AUTO:
+ while (samples--)
+ {
+ __v4sf rgba_in, rgba_aux, alpha;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
- /* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
- _MM_SHUFFLE (3, 3, 3, 3));
+ /* expand alpha */
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
- if (mask)
- {
- __v4sf mask_alpha;
+ if (mask)
+ {
+ __v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
- mask_alpha = _mm_set1_ps (*mask++);
- alpha = alpha * mask_alpha;
- }
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
+
+ alpha = alpha * v_opacity;
+
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ __v4sf dst_alpha, a_term, out_pixel, out_alpha, out_pixel_rbaa;
+
+ /* expand alpha */
+ dst_alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ /* a_term = dst_a * (1.0 - src_a) */
+ a_term = dst_alpha * (one - alpha);
+
+ /* out(color) = src * src_a + dst * a_term */
+ out_pixel = rgba_aux * alpha + rgba_in * a_term;
+
+ /* out(alpha) = 1.0 * src_a + 1.0 * a_term */
+ out_alpha = alpha + a_term;
+
+ /* un-premultiply */
+ out_pixel = out_pixel / out_alpha;
- alpha = alpha * v_opacity;
+ /* swap in the real alpha */
+ out_pixel_rbaa = _mm_shuffle_ps (out_pixel, out_alpha, _MM_SHUFFLE (3, 3, 2, 0));
+ out_pixel = _mm_shuffle_ps (out_pixel, out_pixel_rbaa, _MM_SHUFFLE (2, 1, 1, 0));
- if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ *v_out++ = out_pixel;
+ }
+ else
+ {
+ *v_out++ = rgba_in;
+ }
+ }
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_ATOP:
+ while (samples--)
{
- __v4sf dst_alpha, a_term, out_pixel, out_alpha, out_pixel_rbaa;
+ __v4sf rgba_in, rgba_aux, alpha;
+
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
/* expand alpha */
- dst_alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
- _MM_SHUFFLE (3, 3, 3, 3));
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (mask)
+ {
+ __v4sf mask_alpha;
+
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
- /* a_term = dst_a * (1.0 - src_a) */
- a_term = dst_alpha * (one - alpha);
+ alpha = alpha * v_opacity;
- /* out(color) = src * src_a + dst * a_term */
- out_pixel = rgba_aux * alpha + rgba_in * a_term;
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ __v4sf dst_alpha, out_pixel, out_pixel_rbaa;
- /* out(alpha) = 1.0 * src_a + 1.0 * a_term */
- out_alpha = alpha + a_term;
+ /* expand alpha */
+ dst_alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
+ _MM_SHUFFLE (3, 3, 3, 3));
- /* un-premultiply */
- out_pixel = out_pixel / out_alpha;
+ /* out(color) = dst * (1 - src_a) + src * src_a */
+ out_pixel = rgba_in + (rgba_aux - rgba_in) * alpha;
+
+ /* swap in the real alpha */
+ out_pixel_rbaa = _mm_shuffle_ps (out_pixel, dst_alpha, _MM_SHUFFLE (3, 3, 2, 0));
+ out_pixel = _mm_shuffle_ps (out_pixel, out_pixel_rbaa, _MM_SHUFFLE (2, 1, 1, 0));
+
+ *v_out++ = out_pixel;
+ }
+ else
+ {
+ *v_out++ = rgba_in;
+ }
+ }
+ break;
+
+ case GIMP_LAYER_COMPOSITE_DST_ATOP:
+ while (samples--)
+ {
+ __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf out_pixel, out_pixel_rbaa;
+
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
+
+ /* expand alpha */
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (mask)
+ {
+ __v4sf mask_alpha;
+
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
+
+ alpha = alpha * v_opacity;
+
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ /* out(color) = src */
+ out_pixel = rgba_aux;
+ }
+ else
+ {
+ out_pixel = rgba_in;
+ }
/* swap in the real alpha */
- out_pixel_rbaa = _mm_shuffle_ps (out_pixel, out_alpha, _MM_SHUFFLE (3, 3, 2, 0));
+ out_pixel_rbaa = _mm_shuffle_ps (out_pixel, alpha, _MM_SHUFFLE (3, 3, 2, 0));
out_pixel = _mm_shuffle_ps (out_pixel, out_pixel_rbaa, _MM_SHUFFLE (2, 1, 1, 0));
*v_out++ = out_pixel;
}
- else
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_IN:
+ while (samples--)
{
- *v_out++ = rgba_in;
+ __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf out_pixel, out_pixel_rbaa;
+
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
+
+ /* expand alpha */
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (mask)
+ {
+ __v4sf mask_alpha;
+
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
+
+ alpha = alpha * v_opacity;
+
+ /* multiply the alpha by in's alpha */
+ alpha *= (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ /* out(color) = src */
+ out_pixel = rgba_aux;
+ }
+ else
+ {
+ out_pixel = rgba_in;
+ }
+
+ /* swap in the real alpha */
+ out_pixel_rbaa = _mm_shuffle_ps (out_pixel, alpha, _MM_SHUFFLE (3, 3, 2, 0));
+ out_pixel = _mm_shuffle_ps (out_pixel, out_pixel_rbaa, _MM_SHUFFLE (2, 1, 1, 0));
+
+ *v_out++ = out_pixel;
}
+ break;
}
}
diff --git a/app/operations/layer-modes/gimpoperationnormal-sse4.c
b/app/operations/layer-modes/gimpoperationnormal-sse4.c
index 1e91c06..72825cf 100644
--- a/app/operations/layer-modes/gimpoperationnormal-sse4.c
+++ b/app/operations/layer-modes/gimpoperationnormal-sse4.c
@@ -52,66 +52,205 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
}
else
{
- gfloat opacity = ((GimpOperationLayerMode *)(operation))->opacity;
- gfloat *mask = mask_p;
- const __v4sf *v_in = (const __v4sf*) in;
- const __v4sf *v_aux = (const __v4sf*) aux;
- __v4sf *v_out = ( __v4sf*) out;
+ GimpOperationLayerMode *layer_mode = (GimpOperationLayerMode *) operation;
+ gfloat opacity = layer_mode->opacity;
+ gfloat *mask = mask_p;
+ const __v4sf *v_in = (const __v4sf*) in;
+ const __v4sf *v_aux = (const __v4sf*) aux;
+ __v4sf *v_out = ( __v4sf*) out;
- const __v4sf one = _mm_set1_ps (1.0f);
+ const __v4sf one = _mm_set1_ps (1.0f);
const __v4sf v_opacity = _mm_set1_ps (opacity);
- while (samples--)
+ switch (layer_mode->composite_mode)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ case GIMP_LAYER_COMPOSITE_SRC_OVER:
+ case GIMP_LAYER_COMPOSITE_AUTO:
+ while (samples--)
+ {
+ __v4sf rgba_in, rgba_aux, alpha;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
- /* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
- _MM_SHUFFLE (3, 3, 3, 3));
+ /* expand alpha */
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
- if (mask)
- {
- __v4sf mask_alpha;
+ if (mask)
+ {
+ __v4sf mask_alpha;
+
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
+
+ alpha = alpha * v_opacity;
+
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ __v4sf dst_alpha, a_term, out_pixel, out_alpha;
+
+ /* expand alpha */
+ dst_alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ /* a_term = dst_a * (1.0 - src_a) */
+ a_term = dst_alpha * (one - alpha);
+
+ /* out(color) = src * src_a + dst * a_term */
+ out_pixel = rgba_aux * alpha + rgba_in * a_term;
+
+ /* out(alpha) = 1.0 * src_a + 1.0 * a_term */
+ out_alpha = alpha + a_term;
- /* multiply aux's alpha by the mask */
- mask_alpha = _mm_set1_ps (*mask++);
- alpha = alpha * mask_alpha;
+ /* un-premultiply */
+ out_pixel = out_pixel / out_alpha;
+
+ /* swap in the real alpha */
+ out_pixel = _mm_blend_ps (out_pixel, out_alpha, 0x08);
+
+ *v_out++ = out_pixel;
+ }
+ else
+ {
+ *v_out++ = rgba_in;
+ }
}
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_ATOP:
+ while (samples--)
+ {
+ __v4sf rgba_in, rgba_aux, alpha;
+
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
+
+ /* expand alpha */
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (mask)
+ {
+ __v4sf mask_alpha;
+
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
+
+ alpha = alpha * v_opacity;
- alpha = alpha * v_opacity;
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ __v4sf dst_alpha, out_pixel;
- if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ /* expand alpha */
+ dst_alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ /* out(color) = dst * (1 - src_a) + src * src_a */
+ out_pixel = rgba_in + (rgba_aux - rgba_in) * alpha;
+
+ /* swap in the real alpha */
+ out_pixel = _mm_blend_ps (out_pixel, dst_alpha, 0x08);
+
+ *v_out++ = out_pixel;
+ }
+ else
+ {
+ *v_out++ = rgba_in;
+ }
+ }
+ break;
+
+ case GIMP_LAYER_COMPOSITE_DST_ATOP:
+ while (samples--)
{
- __v4sf dst_alpha, a_term, out_pixel, out_alpha;
+ __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf out_pixel;
+
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
/* expand alpha */
- dst_alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
- _MM_SHUFFLE (3, 3, 3, 3));
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
- /* a_term = dst_a * (1.0 - src_a) */
- a_term = dst_alpha * (one - alpha);
+ if (mask)
+ {
+ __v4sf mask_alpha;
- /* out(color) = src * src_a + dst * a_term */
- out_pixel = rgba_aux * alpha + rgba_in * a_term;
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
- /* out(alpha) = 1.0 * src_a + 1.0 * a_term */
- out_alpha = alpha + a_term;
+ alpha = alpha * v_opacity;
- /* un-premultiply */
- out_pixel = out_pixel / out_alpha;
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ /* out(color) = src */
+ out_pixel = rgba_aux;
+ }
+ else
+ {
+ out_pixel = rgba_in;
+ }
/* swap in the real alpha */
- out_pixel = _mm_blend_ps (out_pixel, out_alpha, 0x08);
+ out_pixel = _mm_blend_ps (out_pixel, alpha, 0x08);
*v_out++ = out_pixel;
}
- else
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_IN:
+ while (samples--)
{
- *v_out++ = rgba_in;
+ __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf out_pixel;
+
+ rgba_in = *v_in++;
+ rgba_aux = *v_aux++;
+
+ /* expand alpha */
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (mask)
+ {
+ __v4sf mask_alpha;
+
+ /* multiply aux's alpha by the mask */
+ mask_alpha = _mm_set1_ps (*mask++);
+ alpha = alpha * mask_alpha;
+ }
+
+ alpha = alpha * v_opacity;
+
+ /* multiply the alpha by in's alpha */
+ alpha *= (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_in,
+ _MM_SHUFFLE (3, 3, 3, 3));
+
+ if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
+ {
+ /* out(color) = src */
+ out_pixel = rgba_aux;
+ }
+ else
+ {
+ out_pixel = rgba_in;
+ }
+
+ /* swap in the real alpha */
+ out_pixel = _mm_blend_ps (out_pixel, alpha, 0x08);
+
+ *v_out++ = out_pixel;
}
+ break;
}
}
diff --git a/app/operations/layer-modes/gimpoperationnormal.c
b/app/operations/layer-modes/gimpoperationnormal.c
index 2e4d5fb..30870a7 100644
--- a/app/operations/layer-modes/gimpoperationnormal.c
+++ b/app/operations/layer-modes/gimpoperationnormal.c
@@ -123,43 +123,166 @@ gimp_operation_normal_process_core (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- while (samples--)
+ switch (layer_mode->composite_mode)
{
- gfloat layer_alpha;
+ case GIMP_LAYER_COMPOSITE_SRC_OVER:
+ case GIMP_LAYER_COMPOSITE_AUTO:
+ while (samples--)
+ {
+ gfloat layer_alpha;
+
+ layer_alpha = layer[ALPHA] * opacity;
+ if (has_mask)
+ layer_alpha *= *mask;
+
+ out[ALPHA] = layer_alpha + in[ALPHA] - layer_alpha * in[ALPHA];
+
+ if (out[ALPHA])
+ {
+ gfloat layer_weight = layer_alpha / out[ALPHA];
+ gfloat in_weight = 1.0f - layer_weight;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = layer[b] * layer_weight + in[b] * in_weight;
+ }
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
- layer_alpha = layer[ALPHA] * opacity;
- if (has_mask)
- layer_alpha *= *mask;
+ in += 4;
+ layer += 4;
+ out += 4;
- out[ALPHA] = layer_alpha + in[ALPHA] - layer_alpha * in[ALPHA];
+ if (has_mask)
+ mask++;
+ }
+ break;
- if (out[ALPHA])
+ case GIMP_LAYER_COMPOSITE_SRC_ATOP:
+ while (samples--)
{
- gfloat layer_weight = layer_alpha / out[ALPHA];
- gfloat in_weight = 1.0f - layer_weight;
- gint b;
+ gfloat layer_alpha;
+
+ layer_alpha = layer[ALPHA] * opacity;
+ if (has_mask)
+ layer_alpha *= *mask;
+
+ out[ALPHA] = in[ALPHA];
+
+ if (out[ALPHA])
+ {
+ gint b;
- for (b = RED; b < ALPHA; b++)
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b] + (layer[b] - in[b]) * layer_alpha;
+ }
+ }
+ else
{
- out[b] = layer[b] * layer_weight + in[b] * in_weight;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
}
+
+ in += 4;
+ layer += 4;
+ out += 4;
+
+ if (has_mask)
+ mask++;
}
- else
+ break;
+
+ case GIMP_LAYER_COMPOSITE_DST_ATOP:
+ while (samples--)
{
- gint b;
+ gfloat layer_alpha;
- for (b = RED; b < ALPHA; b++)
+ layer_alpha = layer[ALPHA] * opacity;
+ if (has_mask)
+ layer_alpha *= *mask;
+
+ out[ALPHA] = layer_alpha;
+
+ if (out[ALPHA])
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = layer[b];
+ }
+ }
+ else
{
- out[b] = in[b];
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
}
+
+ in += 4;
+ layer += 4;
+ out += 4;
+
+ if (has_mask)
+ mask++;
}
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_IN:
+ while (samples--)
+ {
+ gfloat layer_alpha;
- in += 4;
- layer += 4;
- out += 4;
+ layer_alpha = layer[ALPHA] * opacity;
+ if (has_mask)
+ layer_alpha *= *mask;
- if (has_mask)
- mask++;
+ out[ALPHA] = in[ALPHA] * layer_alpha;
+
+ if (out[ALPHA])
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = layer[b];
+ }
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ out += 4;
+
+ if (has_mask)
+ mask++;
+ }
+ break;
}
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]