diff --git a/ChangeLog b/ChangeLog index a22bf4426e..d18a66928a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-10-26 Martin Nordholts + + * app/gegl/gimpoperationpointlayermode.c: Implemented Grain + Extract and Grain Merge. Also corrected the formula for Divide. + + Works the same for 100% opaque layers: + o Grain Extract + o Grain Merge + 2008-10-25 Martin Nordholts * app/gegl/gimpoperationpointlayermode.c: Implement a bunch of diff --git a/app/gegl/gimpoperationpointlayermode.c b/app/gegl/gimpoperationpointlayermode.c index 68f87b52fa..bbf4ccb363 100644 --- a/app/gegl/gimpoperationpointlayermode.c +++ b/app/gegl/gimpoperationpointlayermode.c @@ -173,9 +173,6 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation, while (samples--) { - /* Alpha is treated the same */ - out[A] = lay[A] + in[A] - lay[A] * in[A]; - switch (self->blend_mode) { case GIMP_NORMAL_MODE: @@ -333,33 +330,49 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation, break; case GIMP_SUBTRACT_MODE: - /* Derieved from SVG 1.2 formulas */ + /* Derieved from SVG 1.2 formulas, f(Sc, Dc) = Dc - Sc */ out[R] = in[R] + lay[R] - 2 * lay[R] * in[A]; out[G] = in[G] + lay[G] - 2 * lay[G] * in[A]; out[B] = in[B] + lay[B] - 2 * lay[B] * in[A]; break; + case GIMP_GRAIN_EXTRACT_MODE: + /* Derieved from SVG 1.2 formulas, f(Sc, Dc) = Dc - Sc + 0.5 */ + out[R] = in[R] + lay[R] - 2 * lay[R] * in[A] + 0.5 * in[A] * lay[A]; + out[G] = in[G] + lay[G] - 2 * lay[G] * in[A] + 0.5 * in[A] * lay[A]; + out[B] = in[B] + lay[B] - 2 * lay[B] * in[A] + 0.5 * in[A] * lay[A]; + break; + + case GIMP_GRAIN_MERGE_MODE: + /* Derieved from SVG 1.2 formulas, f(Sc, Dc) = Dc + Sc - 0.5 */ + out[R] = in[R] + lay[R] - 0.5 * in[A] * lay[A]; + out[G] = in[G] + lay[G] - 0.5 * in[A] * lay[A]; + out[B] = in[B] + lay[B] - 0.5 * in[A] * lay[A]; + break; + case GIMP_DIVIDE_MODE: - /* Derieved from SVG 1.2 formulas */ - out[R] = in[R] / lay[R] + lay[R] * (1 - in[A]) + in[R] * (1 - lay[A]); - out[G] = in[G] / lay[G] + lay[G] * (1 - in[A]) + in[G] * (1 - lay[A]); - out[B] = in[B] / lay[B] + lay[B] * (1 - in[A]) + in[B] * (1 - lay[A]); + /* Derieved from SVG 1.2 formulas, f(Sc, Dc) = Dc / Sc */ + out[R] = in[R] * lay[A] * lay[A] / lay[R] + lay[R] * (1 - in[A]) + in[R] * (1 - lay[A]); + out[G] = in[G] * lay[A] * lay[A] / lay[G] + lay[G] * (1 - in[A]) + in[G] * (1 - lay[A]); + out[B] = in[B] * lay[A] * lay[A] / lay[B] + lay[B] * (1 - in[A]) + in[B] * (1 - lay[A]); break; case GIMP_HUE_MODE: case GIMP_SATURATION_MODE: case GIMP_COLOR_MODE: case GIMP_VALUE_MODE: - case GIMP_GRAIN_EXTRACT_MODE: - case GIMP_GRAIN_MERGE_MODE: - case GIMP_COLOR_ERASE_MODE: - case GIMP_ERASE_MODE: - case GIMP_REPLACE_MODE: - case GIMP_ANTI_ERASE_MODE: /* TODO */ break; + case GIMP_ERASE_MODE: + case GIMP_ANTI_ERASE_MODE: + case GIMP_COLOR_ERASE_MODE: + case GIMP_REPLACE_MODE: + /* Icky eraser and paint modes */ + break; + + case GIMP_DISSOLVE_MODE: /* Not a point filter and cannot be implemented here */ /* g_assert_not_reached (); */ @@ -370,6 +383,9 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation, break; } + /* Alpha is treated the same */ + out[A] = lay[A] + in[A] - lay[A] * in[A]; + in += 4; lay += 4; out += 4;