GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

Commit 4bdbff08 authored by Øyvind "pippin" Kolås's avatar Øyvind "pippin" Kolås Committed by Michael Natterer

libgimp: add a GeglBuffer backend for plug-ins

Also added an API to get GeglBuffers for drawables, you choose whether you
get.
parent 153f5665
......@@ -62,8 +62,9 @@ AM_CPPFLAGS = \
-DGIMP_COMPILATION
INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
$(GEGL_CFLAGS) \
-I$(includedir)
lib_LTLIBRARIES = libgimp-2.0.la libgimpui-2.0.la
......@@ -229,6 +230,8 @@ libgimp_2_0_la_sources = \
gimpselection.h \
gimptile.c \
gimptile.h \
gimptilebackendplugin.c \
gimptilebackendplugin.h \
gimpunitcache.c \
gimpunitcache.h \
gimpvectors.c \
......@@ -368,6 +371,7 @@ libgimp_2_0_la_LIBADD = \
$(libgimpcolor) \
$(libgimpbase) \
$(CAIRO_LIBS) \
$(GEGL_LIBS) \
$(GDK_PIXBUF_LIBS) \
$(RT_LIBS)
......
......@@ -22,6 +22,7 @@
#define __GIMP_H__
#include <cairo.h>
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libgimpbase/gimpbase.h>
......
......@@ -23,6 +23,7 @@
#undef GIMP_DISABLE_DEPRECATED
#include "gimp.h"
#include "gimptilebackendplugin.h"
#define TILE_WIDTH gimp_tile_width()
#define TILE_HEIGHT gimp_tile_height()
......@@ -645,3 +646,31 @@ gimp_drawable_attach_new_parasite (gint32 drawable_ID,
return success;
}
GeglBuffer *
gimp_drawable_get_buffer (gint32 drawable_ID)
{
GeglBuffer *buffer;
GimpDrawable *drawable;
GeglTileBackend *backend;
drawable = gimp_drawable_get (drawable_ID);
backend = gimp_tile_backend_plugin_new (drawable, FALSE);
buffer = gegl_buffer_new_for_backend (NULL, backend);
g_object_unref (backend);
return buffer;
}
GeglBuffer *
gimp_drawable_get_shadow_buffer (gint32 drawable_ID)
{
GeglBuffer *buffer;
GimpDrawable *drawable;
GeglTileBackend *backend;
drawable = gimp_drawable_get (drawable_ID);
backend = gimp_tile_backend_plugin_new (drawable, TRUE);
buffer = gegl_buffer_new_for_backend (NULL, backend);
g_object_unref (backend);
return buffer;
}
......@@ -29,7 +29,6 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
struct _GimpDrawable
{
gint32 drawable_id; /* drawable ID */
......@@ -43,6 +42,10 @@ struct _GimpDrawable
};
GeglBuffer * gimp_drawable_get_buffer (gint32 drawable_ID);
GeglBuffer * gimp_drawable_get_shadow_buffer (gint32 drawable_ID);
GimpDrawable * gimp_drawable_get (gint32 drawable_ID);
void gimp_drawable_detach (GimpDrawable *drawable);
void gimp_drawable_flush (GimpDrawable *drawable);
......
/* gimptilebackendtilemanager.c
* Copyright (C) 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
* 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 <stdlib.h>
#include <string.h>
#include <gegl.h>
#include "gimp.h"
#include "gimptilebackendplugin.h"
#define TILE_WIDTH gimp_tile_width()
#define TILE_HEIGHT gimp_tile_width()
struct _GimpTileBackendPluginPrivate
{
GimpDrawable *drawable;
gboolean shadow;
int mul;
};
static int gimp_gegl_tile_mul (void)
{
static int mul = 2;
static gboolean inited = 0;
if (G_LIKELY (inited))
return mul;
inited = 1;
if (g_getenv ("GIMP_GEGL_TILE_MUL"))
mul = atoi (g_getenv ("GIMP_GEGL_TILE_MUL"));
if (mul < 1)
mul = 1;
return mul;
}
static const Babl *get_format (gint32 drawable_ID);
static const Babl *get_format (gint32 drawable_ID)
{
gint32 image_ID = gimp_item_get_image (drawable_ID);
switch (gimp_drawable_type (drawable_ID))
{
case GIMP_RGB_IMAGE: return babl_format ("RGB u8");
case GIMP_RGBA_IMAGE: return babl_format ("RGBA u8");
case GIMP_GRAY_IMAGE: return babl_format ("Y u8");
case GIMP_GRAYA_IMAGE: return babl_format ("YA u8");
case GIMP_INDEXED_IMAGE:
case GIMP_INDEXEDA_IMAGE:
{
const Babl *pala, *pal;
gint ncols;
guchar *cmap = gimp_image_get_colormap (image_ID, &ncols);
babl_new_palette (NULL, &pal, &pala);
babl_palette_set_palette (pal, babl_format ("RGB u8"),
cmap, ncols);
g_free (cmap);
if (gimp_drawable_type (drawable_ID) == GIMP_INDEXEDA_IMAGE)
return pala;
return pal;
}
}
return NULL;
}
static void gimp_tile_backend_plugin_finalize (GObject *object);
static gpointer gimp_tile_backend_plugin_command (GeglTileSource *tile_store,
GeglTileCommand command,
gint x,
gint y,
gint z,
gpointer data);
static void gimp_tile_write_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
gint y,
guchar *source);
static GeglTile * gimp_tile_read_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
gint y);
G_DEFINE_TYPE (GimpTileBackendPlugin, gimp_tile_backend_plugin,
GEGL_TYPE_TILE_BACKEND)
#define parent_class gimp_tile_backend_plugin_parent_class
static void
gimp_tile_backend_plugin_class_init (GimpTileBackendPluginClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gimp_tile_backend_plugin_finalize;
g_type_class_add_private (klass, sizeof (GimpTileBackendPluginPrivate));
gimp_tile_cache_size (1024);
}
static void
gimp_tile_backend_plugin_init (GimpTileBackendPlugin *backend)
{
GeglTileSource *source = GEGL_TILE_SOURCE (backend);
backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend,
GIMP_TYPE_TILE_BACKEND_PLUGIN,
GimpTileBackendPluginPrivate);
source->command = gimp_tile_backend_plugin_command;
}
static void
gimp_tile_backend_plugin_finalize (GObject *object)
{
GimpTileBackendPlugin *backend = GIMP_TILE_BACKEND_PLUGIN (object);
if (backend->priv->drawable) /* This also causes a flush */
gimp_drawable_detach (backend->priv->drawable);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gpointer
gimp_tile_backend_plugin_command (GeglTileSource *tile_store,
GeglTileCommand command,
gint x,
gint y,
gint z,
gpointer data)
{
GimpTileBackendPlugin *backend_plugin;
backend_plugin = GIMP_TILE_BACKEND_PLUGIN (tile_store);
switch (command)
{
case GEGL_TILE_GET:
return gimp_tile_read_mul (backend_plugin, x, y);
case GEGL_TILE_SET:
gimp_tile_write_mul (backend_plugin, x, y, gegl_tile_get_data (data));
gegl_tile_mark_as_stored (data);
return NULL;
default:
g_assert (command < GEGL_TILE_LAST_COMMAND && command >= 0);
}
return NULL;
}
static GeglTile *
gimp_tile_read_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
gint y)
{
GimpTileBackendPluginPrivate *priv = backend_plugin->priv;
GeglTileBackend *backend;
GeglTile *tile;
gint tile_size;
int u, v;
int mul = priv->mul;
unsigned char *tile_data;
x *= mul;
y *= mul;
backend = GEGL_TILE_BACKEND (backend_plugin);
tile_size = gegl_tile_backend_get_tile_size (backend);
tile = gegl_tile_new (tile_size);
tile_data = gegl_tile_get_data (tile);
for (u = 0; u < mul; u++)
for (v = 0; v < mul; v++)
{
GimpTile *gimp_tile;
if (x + u >= priv->drawable->ntile_cols ||
y + v >= priv->drawable->ntile_rows)
continue;
gimp_tile = gimp_drawable_get_tile (priv->drawable,
priv->shadow,
y+v, x+u);
gimp_tile_ref (gimp_tile);
{
gint ewidth = gimp_tile->ewidth;
gint eheight = gimp_tile->eheight;
gint bpp = gimp_tile->bpp;
gint tile_stride = mul * TILE_WIDTH * bpp;
gint gimp_tile_stride = ewidth * bpp;
gint row;
for (row = 0; row < eheight; row++)
{
memcpy (tile_data + (row + TILE_HEIGHT * v) *
tile_stride + u * TILE_WIDTH * bpp,
((char*)gimp_tile->data) + row * gimp_tile_stride,
gimp_tile_stride);
}
}
gimp_tile_unref (gimp_tile, FALSE);
}
return tile;
}
static void
gimp_tile_write_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
gint y,
guchar *source)
{
GimpTileBackendPluginPrivate *priv = backend_plugin->priv;
int u, v;
int mul = priv->mul;
if (!priv->shadow)
return;
x *= mul;
y *= mul;
for (v = 0; v < mul; v++)
for (u = 0; u < mul; u++)
{
GimpTile *gimp_tile;
if (x + u >= priv->drawable->ntile_cols ||
y + v >= priv->drawable->ntile_rows)
continue;
gimp_tile = gimp_drawable_get_tile (priv->drawable,
priv->shadow,
y+v, x+u);
gimp_tile_ref (gimp_tile);
{
gint ewidth = gimp_tile->ewidth;
gint eheight = gimp_tile->eheight;
gint bpp = gimp_tile->bpp;
gint tile_stride = mul * TILE_WIDTH * bpp;
gint gimp_tile_stride = ewidth * bpp;
gint row;
for (row = 0; row < eheight; row++)
memcpy (((char*)gimp_tile->data) + row * gimp_tile_stride,
source + (row + v * TILE_HEIGHT) *
tile_stride + u * TILE_WIDTH * bpp,
gimp_tile_stride);
}
gimp_tile_unref (gimp_tile, TRUE);
}
}
GeglTileBackend *
gimp_tile_backend_plugin_new (GimpDrawable *drawable,
gint shadow)
{
const Babl *format;
GeglTileBackend *ret;
GimpTileBackendPlugin *backend_plugin;
GimpTileBackendPluginPrivate *priv;
gint width = drawable->width;
gint height = drawable->height;
gint mul = gimp_gegl_tile_mul ();
GeglRectangle rect = { 0, 0, width, height};
format = get_format (drawable->drawable_id);
ret = g_object_new (GIMP_TYPE_TILE_BACKEND_PLUGIN,
"tile-width", TILE_WIDTH * mul,
"tile-height", TILE_HEIGHT * mul,
"format", format,
NULL);
backend_plugin = GIMP_TILE_BACKEND_PLUGIN (ret);
priv = backend_plugin->priv;
priv->drawable = drawable;
priv->mul = mul;
priv->shadow = shadow;
gegl_tile_backend_set_extent (ret, &rect);
return ret;
}
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimptilebackendtilemanager.h
* Copyright (C) 2011 Ø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
* 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_TILE_BACKEND_PLUGIN_H__
#define __GIMP_TILE_BACKEND_PLUGIN_H__
#include <gegl-buffer-backend.h>
G_BEGIN_DECLS
#define GIMP_TYPE_TILE_BACKEND_PLUGIN (gimp_tile_backend_plugin_get_type ())
#define GIMP_TILE_BACKEND_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TILE_BACKEND_PLUGIN, GimpTileBackendPlugin))
#define GIMP_TILE_BACKEND_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TILE_BACKEND_PLUGIN, GimpTileBackendPluginClass))
#define GIMP_IS_TILE_BACKEND_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TILE_BACKEND_PLUGIN))
#define GIMP_IS_TILE_BACKEND_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TILE_BACKEND_PLUGIN))
#define GIMP_TILE_BACKEND_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TILE_BACKEND_PLUGIN, GimpTileBackendPluginClass))
typedef struct _GimpTileBackendPluginClass GimpTileBackendPluginClass;
typedef struct _GimpTileBackendPluginPrivate GimpTileBackendPluginPrivate;
struct _GimpTileBackendPlugin
{
GeglTileBackend parent_instance;
GimpTileBackendPluginPrivate *priv;
};
struct _GimpTileBackendPluginClass
{
GeglTileBackendClass parent_class;
};
GType gimp_tile_backend_plugin_get_type (void) G_GNUC_CONST;
GeglTileBackend * gimp_tile_backend_plugin_new (GimpDrawable *drawable,
gint shadow);
G_END_DECLS
#endif /* __GIMP_TILE_BACKEND_plugin_H__ */
......@@ -28,15 +28,15 @@ G_BEGIN_DECLS
/* For information look into the html documentation */
typedef struct _GimpPlugInInfo GimpPlugInInfo;
typedef struct _GimpTile GimpTile;
typedef struct _GimpDrawable GimpDrawable;
typedef struct _GimpPixelRgn GimpPixelRgn;
typedef struct _GimpParamDef GimpParamDef;
typedef struct _GimpParamRegion GimpParamRegion;
typedef union _GimpParamData GimpParamData;
typedef struct _GimpParam GimpParam;
typedef struct _GimpPlugInInfo GimpPlugInInfo;
typedef struct _GimpTile GimpTile;
typedef struct _GimpDrawable GimpDrawable;
typedef struct _GimpPixelRgn GimpPixelRgn;
typedef struct _GimpParamDef GimpParamDef;
typedef struct _GimpParamRegion GimpParamRegion;
typedef union _GimpParamData GimpParamData;
typedef struct _GimpParam GimpParam;
typedef struct _GimpTileBackendPlugin GimpTileBackendPlugin;
G_END_DECLS
......
......@@ -40,6 +40,7 @@ EXTRA_DIST = \
INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
$(GEGL_CFLAGS) \
-I$(includedir)
libexec_PROGRAMS = \
......@@ -127,6 +128,7 @@ libexec_PROGRAMS = \
film \
filter-pack \
fractal-trace \
goat-exercise \
gradient-map \
grid \
guillotine \
......@@ -2263,6 +2265,22 @@ semi_flatten_LDADD = \
$(INTLLIBS) \
$(semi_flatten_RC)
goat_exercise_SOURCES = \
goat-exercise.c
goat_exercise_LDADD = \
$(libgimp) \
$(libgimpmath) \
$(libgimpconfig) \
$(libgimpcolor) \
$(libgimpbase) \
$(CAIRO_LIBS) \
$(GDK_PIXBUF_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(goat_excercise_RC)
sharpen_SOURCES = \
sharpen.c
......
/*
* Goat exercise plug-in by Ø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
* 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 <libgimp/gimp.h>
#include "libgimp/stdplugins-intl.h"
#define PLUG_IN_PROC "plug-in-goat-exercise"
/* Declare local functions.
*/
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
const GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
MAIN ()
static void
query (void)
{
static const GimpParamDef args[] =
{
{ GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
{ GIMP_PDB_IMAGE, "image", "Input image (unused)" },
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }
};
gimp_install_procedure (PLUG_IN_PROC,
N_("Exercise a goat"),
"takes a goat for a walk",
"Øyvind KOlås <pippinp@gimp.org>",
"Øyvind KOlås <pippinp@gimp.org>",
"21march 2012",
N_("Goat-exercise"),
"RGB*, INDEXED*, GRAY*",
GIMP_PLUGIN,
G_N_ELEMENTS (args), 0,
args, NULL);
gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/");
}
static void commit_shadow (gint32 drawable_id)
{
GimpDrawable *drawable = gimp_drawable_get (drawable_id);
gimp_drawable_merge_shadow (drawable_id, TRUE);
gimp_drawable_update (drawable_id, 0, 0, drawable->width, drawable->height);
gimp_drawable_detach (drawable);
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gint32 drawable_id;
GeglBuffer *buffer;
GeglBuffer *shadow_buffer;
*nreturn_vals = 1;
*return_vals = values;
gegl_init (NULL, NULL);
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
INIT_I18N();
drawable_id = param[2].data.d_drawable;
buffer = gimp_drawable_get_buffer (drawable_id);
shadow_buffer = gimp_drawable_get_shadow_buffer (drawable_id);
gegl_render_op (buffer, shadow_buffer, "gegl:unsharp-mask", NULL);
g_object_unref (shadow_buffer);
g_object_unref (buffer);
commit_shadow (drawable_id); /* the buffer first needs to be unreffed, so it is
in a detached state */
gimp_displays_flush ();
values[0].data.d_status = status;
gegl_exit ();
}
......@@ -83,6 +83,7 @@
'film' => { ui => 1 },
'filter-pack' => { ui => 1 },
'fractal-trace' => { ui => 1 },
'goat-exercise' => {},
'gradient-map' => {},
'grid' => { ui => 1 },
'guillotine' => {},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment