[gimp/goat-invasion: 361/401] app: fixed GimpOperationDissolveMode by Ville Sokk
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion: 361/401] app: fixed GimpOperationDissolveMode by Ville Sokk
- Date: Mon, 2 Apr 2012 12:18:28 +0000 (UTC)
commit a0c164b49cbe4ecbdfda382ecbb72839b66d7e50
Author: Michael Natterer <mitch gimp org>
Date: Sat Mar 31 19:50:00 2012 +0200
app: fixed GimpOperationDissolveMode by Ville Sokk
app/gegl/gimpoperationdissolvemode.c | 258 +++++++++++++++++++++++++---------
app/gegl/gimpoperationdissolvemode.h | 16 +--
2 files changed, 199 insertions(+), 75 deletions(-)
---
diff --git a/app/gegl/gimpoperationdissolvemode.c b/app/gegl/gimpoperationdissolvemode.c
index 05636b0..47827a4 100644
--- a/app/gegl/gimpoperationdissolvemode.c
+++ b/app/gegl/gimpoperationdissolvemode.c
@@ -30,39 +30,67 @@
#define RANDOM_TABLE_SIZE 4096
-
-static gboolean gimp_operation_dissolve_mode_process (GeglOperation *operation,
- void *in_buf,
- void *aux_buf,
- void *out_buf,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+enum
+{
+ PROP_0,
+ PROP_PREMULTIPLIED
+};
+
+
+static void gimp_operation_dissolve_mode_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_operation_dissolve_mode_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_operation_dissolve_mode_prepare (GeglOperation *operation);
+static GeglRectangle gimp_operation_dissolve_mode_get_required_for_output (GeglOperation *operation,
+ const gchar *input_pad,
+ const GeglRectangle *roi);
+static gboolean gimp_operation_dissolve_mode_process (GeglOperation *operation,
+ GeglBuffer *input,
+ GeglBuffer *aux,
+ GeglBuffer *output,
+ const GeglRectangle *result,
+ gint level);
G_DEFINE_TYPE (GimpOperationDissolveMode, gimp_operation_dissolve_mode,
- GIMP_TYPE_OPERATION_POINT_LAYER_MODE)
+ GEGL_TYPE_OPERATION_COMPOSER)
-static gint32 random_table[RANDOM_TABLE_SIZE];
+static gint32 random_table[RANDOM_TABLE_SIZE];
static void
gimp_operation_dissolve_mode_class_init (GimpOperationDissolveModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
- GRand *gr;
- gint i;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GeglOperationComposerClass *composer_class = GEGL_OPERATION_COMPOSER_CLASS (klass);
+ GRand *gr;
+ gint i;
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ object_class->set_property = gimp_operation_dissolve_mode_set_property;
+ object_class->get_property = gimp_operation_dissolve_mode_get_property;
gegl_operation_class_set_keys (operation_class,
- "name" , "gimp:dissolve-mode",
- "description", "GIMP dissolve mode operation",
- NULL);
-
- point_class->process = gimp_operation_dissolve_mode_process;
+ "name", "gimp:dissolve-mode",
+ "description", "GIMP dissolve mode operation",
+ "categories", "compositors",
+ NULL);
+
+ operation_class->prepare = gimp_operation_dissolve_mode_prepare;
+ operation_class->get_required_for_output = gimp_operation_dissolve_mode_get_required_for_output;
+ composer_class->process = gimp_operation_dissolve_mode_process;
+
+ g_object_class_install_property (object_class, PROP_PREMULTIPLIED,
+ g_param_spec_boolean ("premultiplied",
+ NULL, NULL,
+ TRUE,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
#define RANDOM_SEED 314159265
@@ -82,68 +110,166 @@ gimp_operation_dissolve_mode_init (GimpOperationDissolveMode *self)
{
}
+static void
+gimp_operation_dissolve_mode_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpOperationDissolveMode *self = GIMP_OPERATION_DISSOLVE_MODE (object);
+
+ switch (property_id)
+ {
+ case PROP_PREMULTIPLIED:
+ self->premultiplied = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_operation_dissolve_mode_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpOperationDissolveMode *self = GIMP_OPERATION_DISSOLVE_MODE (object);
+
+ switch (property_id)
+ {
+ case PROP_PREMULTIPLIED:
+ g_value_set_boolean (value, self->premultiplied);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_operation_dissolve_mode_prepare (GeglOperation *operation)
+{
+ GimpOperationDissolveMode *self = GIMP_OPERATION_DISSOLVE_MODE (operation);
+ const Babl *format;
+
+ if (self->premultiplied)
+ format = babl_format ("RaGaBaA float");
+ else
+ format = babl_format ("RGBA float");
+
+ gegl_operation_set_format (operation, "input", format);
+ gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "output", format);
+}
+
+static GeglRectangle
+gimp_operation_dissolve_mode_get_required_for_output (GeglOperation *operation,
+ const gchar *input_pad,
+ const GeglRectangle *roi)
+{
+ GeglRectangle result = *gegl_operation_source_get_bounding_box (operation,
+ "input");
+
+ return result;
+}
+
static gboolean
gimp_operation_dissolve_mode_process (GeglOperation *operation,
- void *in_buf,
- void *aux_buf,
- void *out_buf,
- glong samples,
- const GeglRectangle *roi,
+ GeglBuffer *input,
+ GeglBuffer *aux,
+ GeglBuffer *output,
+ const GeglRectangle *result,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
- gint x = roi->x;
- gint y = roi->y;
- gint width = roi->width;
- gint height = roi->height;
- gint row;
-
- for (row = 0; row < height; row++)
+ GimpOperationDissolveMode *self = GIMP_OPERATION_DISSOLVE_MODE (operation);
+ GeglBufferIterator *it;
+ const Babl *format;
+ gint index_in, index_out, index_layer;
+
+ if (self->premultiplied)
+ format = babl_format ("RaGaBaA float");
+ else
+ format = babl_format ("RGBA float");
+
+ it = gegl_buffer_iterator_new (output, result, level,
+ format, GEGL_BUFFER_WRITE,
+ GEGL_ABYSS_NONE);
+ index_in = gegl_buffer_iterator_add (it, input, result,
+ level, format, GEGL_BUFFER_READ,
+ GEGL_ABYSS_NONE);
+ index_layer = gegl_buffer_iterator_add (it, aux, result,
+ level, format, GEGL_BUFFER_READ,
+ GEGL_ABYSS_NONE);
+ index_out = 0;
+
+ while (gegl_buffer_iterator_next (it))
{
- GRand *gr;
- gint pixel;
- gint i;
-
- gr = g_rand_new_with_seed (random_table[(y + row) % RANDOM_TABLE_SIZE]);
- for (i = 0; i < x; i++)
+ gint row;
+ gint width = it->roi->width;
+ gint height = it->roi->height;
+ gfloat *in = it->data[index_in];
+ gfloat *out = it->data[index_out];
+ gfloat *layer = it->data[index_layer];
+
+ for (row = 0; row < height; row++)
{
- g_rand_int (gr);
- }
+ gint pixel, i;
+ gint x = gegl_buffer_get_x (aux) + 4096 + it->roi->x;
+ gint y = gegl_buffer_get_y (aux) + 4096 + it->roi->y;
+ GRand *gr = g_rand_new_with_seed (random_table[(y + row) % RANDOM_TABLE_SIZE]);
- for (pixel = 0; pixel < width; pixel++)
- {
- gdouble rand_val;
-
- /* dissolve if random value is >= opacity */
- rand_val = g_rand_double_range (gr, 0.0, 1.0);
+ for (i = 0; i < x; i++)
+ {
+ g_rand_double_range (gr, 0.0, 0.1);
+ }
- if (layer[ALPHA] >= rand_val)
+ for (pixel = 0; pixel < width; pixel++)
{
- out[ALPHA] = 1.0;
+ gdouble rand_val;
- for (i = RED; i < ALPHA; i++)
+ /* dissolve if random value is >= opacity */
+ rand_val = g_rand_double_range (gr, 0.0, 1.0);
+
+ if (layer[ALPHA] >= rand_val)
{
- out[i] = layer[ALPHA] ? layer[i] / layer[ALPHA] : 0.0;
+ out[ALPHA] = 1.0;
+
+ if (self->premultiplied)
+ {
+ for (i = RED; i < ALPHA; i++)
+ {
+ out[i] = layer[i] / layer[ALPHA];
+ }
+ }
+ else
+ {
+ for (i = RED; i < ALPHA; i++)
+ {
+ out[i] = layer[i];
+ }
+ }
}
- }
- else
- {
- out[ALPHA] = in[ALPHA];
-
- for (i = RED; i < ALPHA; i++)
+ else
{
- out[i] = in[i];
+ out[ALPHA] = in[ALPHA];
+
+ for (i = RED; i < ALPHA; i++)
+ {
+ out[i] = in[i];
+ }
}
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
- in += 4;
- layer += 4;
- out += 4;
+ g_rand_free (gr);
}
-
- g_rand_free (gr);
}
return TRUE;
diff --git a/app/gegl/gimpoperationdissolvemode.h b/app/gegl/gimpoperationdissolvemode.h
index 0979f0a..ee5fe2b 100644
--- a/app/gegl/gimpoperationdissolvemode.h
+++ b/app/gegl/gimpoperationdissolvemode.h
@@ -2,7 +2,7 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpoperationdissolvemode.h
- * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2012 Ville Sokk <ville sokk gmail com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,10 +22,6 @@
#ifndef __GIMP_OPERATION_DISSOLVE_MODE_H__
#define __GIMP_OPERATION_DISSOLVE_MODE_H__
-
-#include "gimpoperationpointlayermode.h"
-
-
#define GIMP_TYPE_OPERATION_DISSOLVE_MODE (gimp_operation_dissolve_mode_get_type ())
#define GIMP_OPERATION_DISSOLVE_MODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_DISSOLVE_MODE, GimpOperationDissolveMode))
#define GIMP_OPERATION_DISSOLVE_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPERATION_DISSOLVE_MODE, GimpOperationDissolveModeClass))
@@ -36,14 +32,16 @@
typedef struct _GimpOperationDissolveModeClass GimpOperationDissolveModeClass;
-struct _GimpOperationDissolveMode
+struct _GimpOperationDissolveModeClass
{
- GimpOperationPointLayerMode parent_instance;
+ GeglOperationComposerClass parent_class;
};
-struct _GimpOperationDissolveModeClass
+struct _GimpOperationDissolveMode
{
- GimpOperationPointLayerModeClass parent_class;
+ GeglOperationComposer parent_instance;
+
+ gboolean premultiplied;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]