static gboolean gimp_operation_dissolve_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *result, gint level) { gdouble opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; gfloat *in = in_buf; gfloat *out = out_buf; gfloat *aux = aux_buf; gfloat *mask = aux2_buf; const gboolean has_mask = mask != NULL; gint x, y; for (y = result->y; y < result->y + result->height; y++) { GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]); /* fast forward through the rows pseudo random sequence */ for (x = 0; x < result->x; x++) g_rand_int (gr); for (x = result->x; x < result->x + result->width; x++) { gfloat value = aux[ALPHA] * opacity * 255; if (has_mask) value *= *mask; if (g_rand_int_range (gr, 0, 255) >= value) { out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = in[3]; } else { out[0] = aux[0]; out[1] = aux[1]; out[2] = aux[2]; out[3] = 1.0; } in += 4; out += 4; aux += 4; if (has_mask) mask ++; } g_rand_free (gr); } return TRUE; }
static gboolean gimp_operation_normal_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation); gdouble opacity = point->opacity; gfloat *in = in_buf; gfloat *aux = aux_buf; gfloat *mask = aux2_buf; gfloat *out = out_buf; const gboolean has_mask = mask != NULL; while (samples--) { gfloat aux_alpha; aux_alpha = aux[ALPHA] * opacity; if (has_mask) aux_alpha *= *mask; out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA]; if (out[ALPHA]) { gint b; for (b = RED; b < ALPHA; b++) { out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0f - aux_alpha)) / out[ALPHA]; } } else { gint b; for (b = RED; b < ALPHA; b++) { out[b] = in[b]; } } in += 4; aux += 4; out += 4; if (has_mask) mask++; } return TRUE; }
static gboolean gimp_operation_softlight_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; return gimp_operation_softlight_mode_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); }
static void gimp_operation_point_layer_mode_prepare (GeglOperation *operation) { GimpOperationPointLayerMode *self = GIMP_OPERATION_POINT_LAYER_MODE (operation); const Babl *format; if (self->premultiplied) format = babl_format ("R'aG'aB'aA float"); else format = babl_format ("R'G'B'A float"); gegl_operation_set_format (operation, "input", format); gegl_operation_set_format (operation, "output", format); gegl_operation_set_format (operation, "aux", format); gegl_operation_set_format (operation, "aux2", babl_format ("Y float")); }
static gboolean gimp_operation_lch_chroma_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { GimpOperationPointLayerMode *gimp_op = GIMP_OPERATION_POINT_LAYER_MODE (operation); gfloat opacity = gimp_op->opacity; gboolean linear = gimp_op->linear; return (linear ? gimp_operation_lch_chroma_mode_process_pixels_linear : gimp_operation_lch_chroma_mode_process_pixels) (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); }
static void gimp_operation_point_layer_mode_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GimpOperationPointLayerMode *self = GIMP_OPERATION_POINT_LAYER_MODE (object); switch (property_id) { case PROP_PREMULTIPLIED: self->premultiplied = g_value_get_boolean (value); break; case PROP_OPACITY: self->opacity = g_value_get_double (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static gboolean gimp_operation_value_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { gdouble opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; gfloat *in = in_buf; gfloat *layer = aux_buf; gfloat *mask = aux2_buf; gfloat *out = out_buf; const gboolean has_mask = mask != NULL; while (samples--) { GimpHSV layer_hsv, out_hsv; GimpRGB layer_rgb = {layer[0], layer[1], layer[2]}; GimpRGB out_rgb = {in[0], in[1], in[2]}; gfloat comp_alpha, new_alpha; comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity; if (has_mask) comp_alpha *= *mask; new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha; if (comp_alpha && new_alpha) { gint b; gfloat ratio = comp_alpha / new_alpha; gimp_rgb_to_hsv (&layer_rgb, &layer_hsv); gimp_rgb_to_hsv (&out_rgb, &out_hsv); out_hsv.v = layer_hsv.v; gimp_hsv_to_rgb (&out_hsv, &out_rgb); out[0] = out_rgb.r; out[1] = out_rgb.g; out[2] = out_rgb.b; for (b = RED; b < ALPHA; b++) { out[b] = out[b] * ratio + in[b] * (1.0 - ratio); } } else { gint b; for (b = RED; b < ALPHA; b++) { out[b] = in[b]; } } out[ALPHA] = in[ALPHA]; in += 4; layer += 4; out += 4; if (has_mask) mask++; } return TRUE; }
static gboolean gimp_operation_behind_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation); gdouble opacity = point->opacity; gfloat *in = in_buf; gfloat *layer = aux_buf; gfloat *mask = aux2_buf; gfloat *out = out_buf; const gboolean has_mask = mask != NULL; if (point->premultiplied) { while (samples--) { gint b; gdouble value = opacity; if (has_mask) value *= *mask; for (b = RED; b <= ALPHA; b++) { out[b] = in[b] + layer[b] * value * (1.0 - in[ALPHA]); } in += 4; layer += 4; out += 4; if (has_mask) mask++; } } else { while (samples--) { gint b; gdouble value = opacity; if (has_mask) value *= *mask; out[ALPHA] = in[ALPHA] + (1.0 - in[ALPHA]) * layer[ALPHA] * value; if (out[ALPHA]) { for (b = RED; b < ALPHA; b++) { out[b] = (in[b] * in[ALPHA] + layer[b] * value * layer[ALPHA] * value * (1.0 - in[ALPHA])) / out[ALPHA]; } } else { for (b = RED; b <= ALPHA; b++) { out[b] = in[b]; } } in += 4; layer += 4; out += 4; if (has_mask) mask++; } } return TRUE; }
static gboolean gimp_operation_hardlight_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { gdouble opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; gfloat *in = in_buf; gfloat *layer = aux_buf; gfloat *mask = aux2_buf; gfloat *out = out_buf; const gboolean has_mask = mask != NULL; while (samples--) { gfloat comp_alpha, new_alpha; comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity; if (has_mask) comp_alpha *= *mask; new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha; if (comp_alpha && new_alpha) { gfloat ratio = comp_alpha / new_alpha; gint b; for (b = RED; b < ALPHA; b++) { gfloat comp; if (layer[b] > 0.5) { comp = (1.0 - in[b]) * (1.0 - (layer[b] - 0.5) * 2.0); comp = MIN (1 - comp, 1); } else { comp = in[b] * (layer[b] * 2.0); comp = MIN (comp, 1.0); } out[b] = comp * ratio + in[b] * (1.0 - ratio); } } else { gint b; for (b = RED; b < ALPHA; b++) { out[b] = in[b]; } } out[ALPHA] = in[ALPHA]; in += 4; layer += 4; out += 4; if (has_mask) mask ++; } return TRUE; }
static gboolean gimp_operation_replace_mode_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation); gfloat opacity = point->opacity; gfloat *in = in_buf; gfloat *layer = aux_buf; gfloat *mask = aux2_buf; gfloat *out = out_buf; while (samples--) { gint b; gfloat new_alpha; if (mask) new_alpha = (layer[ALPHA] - in[ALPHA]) * (*mask) * opacity + in[ALPHA]; else new_alpha = (layer[ALPHA] - in[ALPHA]) * opacity + in[ALPHA]; if (new_alpha) { gfloat ratio; if (mask) ratio = *mask * opacity * layer[ALPHA] / new_alpha; else ratio = opacity * layer[ALPHA] / new_alpha; for (b = RED; b < ALPHA; b++) { gfloat t; if (layer[b] > in[b]) { t = (layer[b] - in[b]) * ratio; out[b] = in[b] + t; } else { t = (in[b] - layer[b]) * ratio; out[b] = in[b] - t; } } } else { for (b = RED; b < ALPHA; b++) out[b] = in[b]; } out[ALPHA] = new_alpha; in += 4; layer += 4; out += 4; if (mask) mask += 1; } return TRUE; }