app: remove forward transform preview from cage tool, reverse is actually faster

This commit is contained in:
Alexia Death 2010-10-07 00:37:04 +03:00
parent 1a5bacf649
commit d7492cb528
5 changed files with 90 additions and 407 deletions

View File

@ -55,8 +55,6 @@ libappgegl_a_SOURCES = \
gimpoperationcolorize.h \ gimpoperationcolorize.h \
gimpoperationcagecoefcalc.c \ gimpoperationcagecoefcalc.c \
gimpoperationcagecoefcalc.h \ gimpoperationcagecoefcalc.h \
gimpoperationcagepreview.c \
gimpoperationcagepreview.h \
gimpoperationcagetransform.c \ gimpoperationcagetransform.c \
gimpoperationcagetransform.h \ gimpoperationcagetransform.h \
gimpoperationcurves.c \ gimpoperationcurves.c \

View File

@ -32,7 +32,6 @@
#include "gimp-gegl.h" #include "gimp-gegl.h"
#include "gimpoperationcagecoefcalc.h" #include "gimpoperationcagecoefcalc.h"
#include "gimpoperationcagepreview.h"
#include "gimpoperationcagetransform.h" #include "gimpoperationcagetransform.h"
#include "gimpoperationcolorbalance.h" #include "gimpoperationcolorbalance.h"
#include "gimpoperationcolorize.h" #include "gimpoperationcolorize.h"
@ -99,7 +98,6 @@ gimp_gegl_init (Gimp *gimp)
g_type_class_ref (GIMP_TYPE_OPERATION_TILE_SOURCE); g_type_class_ref (GIMP_TYPE_OPERATION_TILE_SOURCE);
g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_COEF_CALC); g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_COEF_CALC);
g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_PREVIEW);
g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_TRANSFORM); g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_TRANSFORM);
g_type_class_ref (GIMP_TYPE_OPERATION_COLOR_BALANCE); g_type_class_ref (GIMP_TYPE_OPERATION_COLOR_BALANCE);
g_type_class_ref (GIMP_TYPE_OPERATION_COLORIZE); g_type_class_ref (GIMP_TYPE_OPERATION_COLORIZE);

View File

@ -1,282 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
*
* gimpoperationcagepreview.c
* Copyright (C) 2010 Michael Muré <batolettre@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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include "gimp-gegl-types.h"
#include <gegl-buffer-iterator.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "gimpoperationcagepreview.h"
#include "gimpcageconfig.h"
static void gimp_operation_cage_preview_finalize (GObject *object);
static void gimp_operation_cage_preview_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_operation_cage_preview_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_operation_cage_preview_prepare (GeglOperation *operation);
static gboolean gimp_operation_cage_preview_process (GeglOperation *operation,
GeglBuffer *in_buf,
GeglBuffer *aux_buf,
GeglBuffer *out_buf,
const GeglRectangle *roi);
GeglRectangle gimp_operation_cage_preview_get_cached_region (GeglOperation *operation,
const GeglRectangle *roi);
GeglRectangle gimp_operation_cage_preview_get_required_for_output (GeglOperation *operation,
const gchar *input_pad,
const GeglRectangle *roi);
GeglRectangle gimp_operation_cage_preview_get_bounding_box (GeglOperation *operation);
G_DEFINE_TYPE (GimpOperationCagePreview, gimp_operation_cage_preview,
GEGL_TYPE_OPERATION_COMPOSER)
#define parent_class gimp_operation_cage_preview_parent_class
static void
gimp_operation_cage_preview_class_init (GimpOperationCagePreviewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
GeglOperationComposerClass *composer_class = GEGL_OPERATION_COMPOSER_CLASS (klass);
object_class->get_property = gimp_operation_cage_preview_get_property;
object_class->set_property = gimp_operation_cage_preview_set_property;
object_class->finalize = gimp_operation_cage_preview_finalize;
/* FIXME: wrong categories and name, to appears in the gegl tool */
operation_class->name = "gimp:cage_preview";
operation_class->categories = "transform";
operation_class->description = "GIMP cage transform preview";
operation_class->prepare = gimp_operation_cage_preview_prepare;
operation_class->get_required_for_output = gimp_operation_cage_preview_get_required_for_output;
operation_class->get_cached_region = gimp_operation_cage_preview_get_cached_region;
operation_class->no_cache = FALSE;
operation_class->get_bounding_box = gimp_operation_cage_preview_get_bounding_box;
composer_class->process = gimp_operation_cage_preview_process;
g_object_class_install_property (object_class,
GIMP_OPERATION_CAGE_PREVIEW_PROP_CONFIG,
g_param_spec_object ("config", NULL, NULL,
GIMP_TYPE_CAGE_CONFIG,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
}
static void
gimp_operation_cage_preview_init (GimpOperationCagePreview *self)
{
}
static void
gimp_operation_cage_preview_finalize (GObject *object)
{
GimpOperationCagePreview *self = GIMP_OPERATION_CAGE_PREVIEW (object);
if (self->config)
{
g_object_unref (self->config);
self->config = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_operation_cage_preview_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpOperationCagePreview *self = GIMP_OPERATION_CAGE_PREVIEW (object);
switch (property_id)
{
case GIMP_OPERATION_CAGE_PREVIEW_PROP_CONFIG:
g_value_set_object (value, self->config);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_operation_cage_preview_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpOperationCagePreview *self = GIMP_OPERATION_CAGE_PREVIEW (object);
switch (property_id)
{
case GIMP_OPERATION_CAGE_PREVIEW_PROP_CONFIG:
if (self->config)
g_object_unref (self->config);
self->config = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_operation_cage_preview_prepare (GeglOperation *operation)
{
gegl_operation_set_format (operation, "input", babl_format ("RGBA float"));
gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
}
static gboolean
gimp_operation_cage_preview_process (GeglOperation *operation,
GeglBuffer *in_buf,
GeglBuffer *aux_buf,
GeglBuffer *out_buf,
const GeglRectangle *roi)
{
GimpOperationCagePreview *ocp = GIMP_OPERATION_CAGE_PREVIEW (operation);
GimpCageConfig *config = GIMP_CAGE_CONFIG (ocp->config);
Babl *format_io = babl_format ("RGBA float");
Babl *format_coef = babl_format_n (babl_type ("float"), 2 * config->cage_vertice_number);
gint in_index, coef_index;
gint i;
GeglRectangle rect, bb_cage;
GeglBufferIterator *it;
rect.height = 3;
rect.width = 3;
bb_cage = gimp_cage_config_get_bounding_box (config);
it = gegl_buffer_iterator_new (in_buf, &bb_cage, format_io, GEGL_BUFFER_READ);
in_index = 0;
coef_index = gegl_buffer_iterator_add (it, aux_buf, &bb_cage, format_coef, GEGL_BUFFER_READ);
/* pre-copy the input buffer to the out buffer */
gegl_buffer_copy (in_buf, roi, out_buf, roi);
/* iterate on GeglBuffer */
while (gegl_buffer_iterator_next (it))
{
/* iterate inside the roi */
gint n_pixels = it->length;
gint x = it->roi->x; /* initial x */
gint y = it->roi->y; /* and y coordinates */
gint cvn = config->cage_vertice_number;
gfloat *source = it->data[in_index];
gfloat *coef = it->data[coef_index];
while(n_pixels--)
{
if (gimp_cage_config_point_inside(config, x, y))
{
/* computing of the final position of the source pixel */
gdouble pos_x, pos_y;
pos_x = 0;
pos_y = 0;
for(i = 0; i < cvn; i++)
{
pos_x += coef[i] * config->cage_vertices_d[i].x;
pos_y += coef[i] * config->cage_vertices_d[i].y;
}
for(i = 0; i < cvn; i++)
{
pos_x += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].x;
pos_y += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].y;
}
rect.x = (gint) rint(pos_x) - 1;
rect.y = (gint) rint(pos_y) - 1;
/* copy the source pixel in the out buffer */
gegl_buffer_set(out_buf,
&rect,
format_io,
source,
GEGL_AUTO_ROWSTRIDE);
}
source += 4;
coef += 2 * cvn;
/* update x and y coordinates */
x++;
if (x >= (it->roi->x + it->roi->width))
{
x = it->roi->x;
y++;
}
}
}
return TRUE;
}
GeglRectangle
gimp_operation_cage_preview_get_cached_region (GeglOperation *operation,
const GeglRectangle *roi)
{
GeglRectangle result = *gegl_operation_source_get_bounding_box (operation, "input");
return result;
}
GeglRectangle
gimp_operation_cage_preview_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;
}
GeglRectangle
gimp_operation_cage_preview_get_bounding_box (GeglOperation *operation)
{
GeglRectangle result = *gegl_operation_source_get_bounding_box (operation, "input");
return result;
}

View File

@ -1,58 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
*
* gimpoperationcagepreview.h
* Copyright (C) 2010 Michael Muré <batolettre@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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_OPERATION_CAGE_PREVIEW_H__
#define __GIMP_OPERATION_CAGE_PREVIEW_H__
#include <gegl-plugin.h>
#include <operation/gegl-operation-composer.h>
enum
{
GIMP_OPERATION_CAGE_PREVIEW_PROP_0,
GIMP_OPERATION_CAGE_PREVIEW_PROP_CONFIG
};
#define GIMP_TYPE_OPERATION_CAGE_PREVIEW (gimp_operation_cage_preview_get_type ())
#define GIMP_OPERATION_CAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_CAGE_PREVIEW, GimpOperationCagePreview))
#define GIMP_OPERATION_CAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPERATION_CAGE_PREVIEW, GimpOperationCagePreviewClass))
#define GIMP_IS_OPERATION_CAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_CAGE_PREVIEW))
#define GIMP_IS_OPERATION_CAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OPERATION_CAGE_PREVIEW))
#define GIMP_OPERATION_CAGE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OPERATION_CAGE_PREVIEW, GimpOperationCagePreviewClass))
typedef struct _GimpOperationCagePreviewClass GimpOperationCagePreviewClass;
struct _GimpOperationCagePreview
{
GeglOperationComposer parent_instance;
GimpCageConfig *config;
};
struct _GimpOperationCagePreviewClass
{
GeglOperationComposerClass parent_class;
};
GType gimp_operation_cage_preview_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_CAGE_PREVIEW_H__ */

View File

@ -119,6 +119,10 @@ static void gimp_cage_tool_prepare_preview (GimpCageTool *ct
GimpDisplay *display); GimpDisplay *display);
static gboolean gimp_cage_tool_update_preview (GimpTool *tool); static gboolean gimp_cage_tool_update_preview (GimpTool *tool);
static GeglNode* gimp_cage_tool_get_render_node (GimpCageTool *ct,
GeglNode *parent);
G_DEFINE_TYPE (GimpCageTool, gimp_cage_tool, GIMP_TYPE_DRAW_TOOL) G_DEFINE_TYPE (GimpCageTool, gimp_cage_tool, GIMP_TYPE_DRAW_TOOL)
#define parent_class gimp_cage_tool_parent_class #define parent_class gimp_cage_tool_parent_class
@ -695,7 +699,7 @@ gimp_cage_tool_compute_coef (GimpCageTool *ct,
NULL); NULL);
gegl_node_connect_to (input, "output", gegl_node_connect_to (input, "output",
output, "input"); output, "input");
processor = gegl_node_new_processor (output, NULL); processor = gegl_node_new_processor (output, NULL);
@ -711,14 +715,64 @@ gimp_cage_tool_compute_coef (GimpCageTool *ct,
g_object_unref (gegl); g_object_unref (gegl);
} }
static GeglNode*
gimp_cage_tool_get_render_node (GimpCageTool *ct,
GeglNode *parent)
{
GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
GeglNode *cage, *render; /* Render nodes */
GeglNode *input, *output, *aux; /* Proxy nodes*/
GeglNode *node; /* wraper to be returned */
node = gegl_node_new_child (parent,
/* FIXME: Leavin this empty causes compiler warning,
* but adding it causes a hang.
* "operation", "gegl:nop", */
NULL);
input = gegl_node_get_input_proxy (node, "input");
aux = gegl_node_get_input_proxy (node, "aux");
output = gegl_node_get_output_proxy (node, "output");
cage = gegl_node_new_child (parent,
"operation", "gimp:cage_transform",
"config", ct->config,
"fill_plain_color", options->fill_plain_color,
NULL);
render = gegl_node_new_child (parent,
"operation", "gegl:render_mapping",
NULL);
gegl_node_connect_to (input, "output",
cage, "input");
gegl_node_connect_to (aux, "output",
cage, "aux");
gegl_node_connect_to (input, "output",
render, "input");
gegl_node_connect_to (cage, "output",
render, "aux");
gegl_node_connect_to (render, "output",
output, "input");
return node;
}
static void static void
gimp_cage_tool_prepare_preview (GimpCageTool *ct, gimp_cage_tool_prepare_preview (GimpCageTool *ct,
GimpDisplay *display) GimpDisplay *display)
{ {
GimpImage *image = gimp_display_get_image (display); GimpImage *image = gimp_display_get_image (display);
GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpDrawable *drawable = gimp_image_get_active_drawable (image);
GeglNode *coef, *cage;
GeglNode *coef;
GeglNode *node;
if (ct->node_preview) if (ct->node_preview)
{ {
@ -733,17 +787,15 @@ gimp_cage_tool_prepare_preview (GimpCageTool *ct,
"buffer", ct->coef, "buffer", ct->coef,
NULL); NULL);
cage = gegl_node_new_child (ct->node_preview, node = gimp_cage_tool_get_render_node (ct,
"operation", "gimp:cage_preview", ct->node_preview);
"config", ct->config,
NULL);
gegl_node_connect_to (coef, "output", gegl_node_connect_to (coef, "output",
cage, "aux"); node, "aux");
ct->image_map = gimp_image_map_new (drawable, ct->image_map = gimp_image_map_new (drawable,
_("Cage transform"), _("Cage transform"),
cage, node,
NULL, NULL,
NULL); NULL);
} }
@ -780,8 +832,8 @@ static void
gimp_cage_tool_process (GimpCageTool *ct, gimp_cage_tool_process (GimpCageTool *ct,
GimpDisplay *display) GimpDisplay *display)
{ {
GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct); TileManager *new_tiles = NULL;
TileManager *new_tiles; TileManager *old_tiles = NULL;
GeglRectangle rect; GeglRectangle rect;
GimpImage *image = gimp_display_get_image (display); GimpImage *image = gimp_display_get_image (display);
@ -797,15 +849,25 @@ gimp_cage_tool_process (GimpCageTool *ct,
{ {
GeglNode *gegl = gegl_node_new (); GeglNode *gegl = gegl_node_new ();
#ifdef DEBUG_CAGE /* reverse transform */
/* debug coeficient */ GeglNode *coef, *node, *input, *output;
GeglNode *coef, *debug, *output;
old_tiles = gimp_drawable_get_tiles (drawable);
input = gegl_node_new_child (gegl,
"operation", "gimp:tilemanager-source",
"tile-manager", old_tiles,
"linear", TRUE,
NULL);
coef = gegl_node_new_child (gegl, coef = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source", "operation", "gegl:buffer-source",
"buffer", ct->coef, "buffer", ct->coef,
NULL); NULL);
node = gimp_cage_tool_get_render_node (ct,
gegl);
new_tiles = gimp_drawable_get_shadow_tiles (drawable); new_tiles = gimp_drawable_get_shadow_tiles (drawable);
output = gegl_node_new_child (gegl, output = gegl_node_new_child (gegl,
"operation", "gimp:tilemanager-sink", "operation", "gimp:tilemanager-sink",
@ -813,6 +875,18 @@ gimp_cage_tool_process (GimpCageTool *ct,
"linear", TRUE, "linear", TRUE,
NULL); NULL);
gegl_node_connect_to (input, "output",
node, "input");
gegl_node_connect_to (coef, "output",
node, "aux");
gegl_node_connect_to (node, "output",
output, "input");
/* Debug code sample for debugging coef calculation.*/
/*
debug = gegl_node_new_child (gegl, debug = gegl_node_new_child (gegl,
"operation", "gegl:debugit", "operation", "gegl:debugit",
NULL); NULL);
@ -821,54 +895,7 @@ gimp_cage_tool_process (GimpCageTool *ct,
debug, "input"); debug, "input");
gegl_node_connect_to (debug, "output", gegl_node_connect_to (debug, "output",
output, "input"); output, "input");*/
#else
/* reverse transform */
GeglNode *coef, *cage, *render, *input, *output;
input = gegl_node_new_child (gegl,
"operation", "gimp:tilemanager-source",
"tile-manager", gimp_drawable_get_tiles (drawable),
"linear", TRUE,
NULL);
cage = gegl_node_new_child (gegl,
"operation", "gimp:cage_transform",
"config", ct->config,
"fill_plain_color", options->fill_plain_color,
NULL);
coef = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", ct->coef,
NULL);
render = gegl_node_new_child (gegl,
"operation", "gegl:render_mapping",
NULL);
new_tiles = gimp_drawable_get_shadow_tiles (drawable);
output = gegl_node_new_child (gegl,
"operation", "gimp:tilemanager-sink",
"tile-manager", new_tiles,
"linear", TRUE,
NULL);
gegl_node_connect_to (input, "output",
cage, "input");
gegl_node_connect_to (input, "output",
render, "input");
gegl_node_connect_to (coef, "output",
cage, "aux");
gegl_node_connect_to (cage, "output",
render, "aux");
gegl_node_connect_to (render, "output",
output, "input");
#endif
progress = gimp_progress_start (GIMP_PROGRESS (display), progress = gimp_progress_start (GIMP_PROGRESS (display),