[gimp] app: fix up dissolve mode
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: fix up dissolve mode
- Date: Wed, 2 May 2012 16:27:05 +0000 (UTC)
commit 77f7b31fa30bbfe0c911c46f0a9c95d5ee0316df
Author: Ãyvind KolÃs <pippin gimp org>
Date: Sat Mar 31 21:13:49 2012 +0100
app: fix up dissolve mode
It produces some garbage, but it is 99.5% compliant with the output of legacy
gimp dissolve mode now.
app/gegl/gimpoperationdissolvemode.c | 247 +++++++++-------------------------
app/gegl/gimpoperationdissolvemode.h | 7 +-
2 files changed, 66 insertions(+), 188 deletions(-)
---
diff --git a/app/gegl/gimpoperationdissolvemode.c b/app/gegl/gimpoperationdissolvemode.c
index 47827a4..32e03cf 100644
--- a/app/gegl/gimpoperationdissolvemode.c
+++ b/app/gegl/gimpoperationdissolvemode.c
@@ -3,6 +3,7 @@
*
* gimpoperationdissolvemode.c
* Copyright (C) 2012 Ville Sokk <ville sokk gmail com>
+ * 2012 Ãyvind KolÃs <pippin gimp org>
*
* 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
@@ -30,35 +31,17 @@
#define RANDOM_TABLE_SIZE 4096
-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);
-
+static void gimp_operation_dissolve_mode_prepare (GeglOperation *operation);
+static gboolean gimp_operation_dissolve_mode_process (GeglOperation *operation,
+ void *in_buf,
+ void *aux_buf,
+ void *out_buf,
+ glong samples,
+ const GeglRectangle *result,
+ gint level);
G_DEFINE_TYPE (GimpOperationDissolveMode, gimp_operation_dissolve_mode,
- GEGL_TYPE_OPERATION_COMPOSER)
+ GIMP_TYPE_OPERATION_POINT_LAYER_MODE)
static gint32 random_table[RANDOM_TABLE_SIZE];
@@ -66,14 +49,14 @@ static gint32 random_table[RANDOM_TABLE_SIZE];
static void
gimp_operation_dissolve_mode_class_init (GimpOperationDissolveModeClass *klass)
{
- 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;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposerClass *point_composer_class;
+ GRand *gr;
+ gint i;
+ static gboolean table_initialized = FALSE;
- object_class->set_property = gimp_operation_dissolve_mode_set_property;
- object_class->get_property = gimp_operation_dissolve_mode_get_property;
+ operation_class = GEGL_OPERATION_CLASS (klass);
+ point_composer_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:dissolve-mode",
@@ -81,195 +64,91 @@ gimp_operation_dissolve_mode_class_init (GimpOperationDissolveModeClass *klass)
"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));
+ operation_class->prepare = gimp_operation_dissolve_mode_prepare;
+ point_composer_class->process = gimp_operation_dissolve_mode_process;
#define RANDOM_SEED 314159265
- /* generate a table of random seeds */
- gr = g_rand_new_with_seed (RANDOM_SEED);
-
- for (i = 0; i < RANDOM_TABLE_SIZE; i++)
+ if (!table_initialized)
{
- random_table[i] = g_rand_int (gr);
- }
-
- g_rand_free (gr);
-}
-
-static void
-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);
+ /* generate a table of random seeds */
+ gr = g_rand_new_with_seed (RANDOM_SEED);
- switch (property_id)
- {
- case PROP_PREMULTIPLIED:
- self->premultiplied = g_value_get_boolean (value);
- break;
+ for (i = 0; i < RANDOM_TABLE_SIZE; i++)
+ {
+ random_table[i] = g_rand_int (gr);
+ }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
+ g_rand_free (gr);
+ table_initialized = TRUE;
}
}
static void
-gimp_operation_dissolve_mode_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+gimp_operation_dissolve_mode_init (GimpOperationDissolveMode *self)
{
- 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");
+ format = babl_format ("R'G'B'A 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,
- GeglBuffer *input,
- GeglBuffer *aux,
- GeglBuffer *output,
+ void *in_buf,
+ void *aux_buf,
+ void *out_buf,
+ glong samples,
const GeglRectangle *result,
gint level)
{
- 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))
+ gint x, y, i;
+ gfloat *in = in_buf;
+ gfloat *out = out_buf;
+ gfloat *aux = aux_buf;
+
+ for (i = 0, y = result->y; y < result->y + result->height; y++)
{
- 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];
+ GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
- for (row = 0; row < height; row++)
+ /* fast forward through this 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++, i++)
{
- 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]);
+ gdouble rand_val;
+ /* dissolve if random value is >= opacity */
+ rand_val = g_rand_int_range (gr, 0, 255);
- for (i = 0; i < x; i++)
+ if (aux[3] * 255 >= rand_val)
{
- g_rand_double_range (gr, 0.0, 0.1);
+ out[0] = aux[0];
+ out[1] = aux[1];
+ out[2] = aux[2];
+ out[3] = 1.0;
}
-
- for (pixel = 0; pixel < width; pixel++)
+ else
{
- gdouble rand_val;
-
- /* dissolve if random value is >= opacity */
- rand_val = g_rand_double_range (gr, 0.0, 1.0);
-
- if (layer[ALPHA] >= rand_val)
- {
- 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++)
- {
- out[i] = in[i];
- }
- }
-
- in += 4;
- layer += 4;
- out += 4;
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
}
- g_rand_free (gr);
+ in+=4;
+ out+=4;
+ aux+=4;
}
+ g_rand_free (gr);
}
return TRUE;
diff --git a/app/gegl/gimpoperationdissolvemode.h b/app/gegl/gimpoperationdissolvemode.h
index ee5fe2b..ad9dbf5 100644
--- a/app/gegl/gimpoperationdissolvemode.h
+++ b/app/gegl/gimpoperationdissolvemode.h
@@ -29,19 +29,18 @@
#define GIMP_IS_OPERATION_DISSOLVE_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OPERATION_DISSOLVE_MODE))
#define GIMP_OPERATION_DISSOLVE_MODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OPERATION_DISSOLVE_MODE, GimpOperationDissolveModeClass))
+#include "gimpoperationpointlayermode.h"
typedef struct _GimpOperationDissolveModeClass GimpOperationDissolveModeClass;
struct _GimpOperationDissolveModeClass
{
- GeglOperationComposerClass parent_class;
+ GimpOperationPointLayerModeClass parent_class;
};
struct _GimpOperationDissolveMode
{
- GeglOperationComposer parent_instance;
-
- gboolean premultiplied;
+ GimpOperationPointLayerMode parent_instance;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]