[gimp] plug-ins: port crop-zealous to GEGL
- From: Thomas Manni <tmanni src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: port crop-zealous to GEGL
- Date: Thu, 11 Dec 2014 09:18:21 +0000 (UTC)
commit f8073e69468d492ebd459943ea8d0cee9cceae43
Author: Thomas Manni <thomas manni free fr>
Date: Thu Dec 11 10:00:00 2014 +0100
plug-ins: port crop-zealous to GEGL
plug-ins/common/Makefile.am | 1 +
plug-ins/common/crop-zealous.c | 197 ++++++++++++++++++++-------------------
2 files changed, 102 insertions(+), 96 deletions(-)
---
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index 1e921e8..d3e648d 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -498,6 +498,7 @@ crop_zealous_LDADD = \
$(libgimpbase) \
$(CAIRO_LIBS) \
$(GDK_PIXBUF_LIBS) \
+ $(GEGL_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(crop_zealous_RC)
diff --git a/plug-ins/common/crop-zealous.c b/plug-ins/common/crop-zealous.c
index d9c2da4..90a7a9c 100644
--- a/plug-ins/common/crop-zealous.c
+++ b/plug-ins/common/crop-zealous.c
@@ -22,9 +22,11 @@
#include "libgimp/stdplugins-intl.h"
-
#define PLUG_IN_PROC "plug-in-zealouscrop"
+#define EPSILON (1e-5)
+#define FLOAT_IS_ZERO(value) (value > -EPSILON && value < EPSILON)
+#define FLOAT_EQUAL(v1, v2) ((v1 - v2) > -EPSILON && (v1 - v2) < EPSILON)
/* Declare local functions. */
@@ -35,13 +37,12 @@ static void run (const gchar *name,
gint *nreturn_vals,
GimpParam **return_vals);
-static inline gboolean colors_equal (const guchar *col1,
- const guchar *col2,
- gint bytes,
+static inline gboolean colors_equal (const gfloat *col1,
+ const gfloat *col2,
+ gint components,
gboolean has_alpha);
-static void do_zcrop (GimpDrawable *drawable,
- gint32 image_id);
-
+static void do_zcrop (gint32 drawable_id,
+ gint32 image_id);
const GimpPlugInInfo PLUG_IN_INFO =
{
@@ -87,12 +88,13 @@ run (const gchar *name,
GimpParam **return_vals)
{
static GimpParam values[1];
- GimpDrawable *drawable;
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
+ gint32 drawable_id;
gint32 image_id;
- INIT_I18N();
+ INIT_I18N ();
+ gegl_init (NULL, NULL);
*nreturn_vals = 1;
*return_vals = values;
@@ -110,27 +112,20 @@ run (const gchar *name,
if (status == GIMP_PDB_SUCCESS)
{
/* Get the specified drawable */
- drawable = gimp_drawable_get(param[2].data.d_drawable);
- image_id = param[1].data.d_image;
+ image_id = param[1].data.d_int32;
+ drawable_id = param[2].data.d_int32;
/* Make sure that the drawable is gray or RGB or indexed */
- if (gimp_drawable_is_rgb (drawable->drawable_id) ||
- gimp_drawable_is_gray (drawable->drawable_id) ||
- gimp_drawable_is_indexed (drawable->drawable_id))
+ if (gimp_drawable_is_rgb (drawable_id) ||
+ gimp_drawable_is_gray (drawable_id) ||
+ gimp_drawable_is_indexed (drawable_id))
{
gimp_progress_init (_("Zealous cropping"));
- gimp_tile_cache_ntiles (1 +
- 2 * (drawable->width > drawable->height ?
- (drawable->width / gimp_tile_width()) :
- (drawable->height / gimp_tile_height())));
-
- do_zcrop(drawable, image_id);
+ do_zcrop (drawable_id, image_id);
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
-
- gimp_drawable_detach (drawable);
}
else
{
@@ -140,17 +135,19 @@ run (const gchar *name,
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
+
+ gegl_exit ();
}
static inline gboolean
-colors_equal (const guchar *col1,
- const guchar *col2,
- gint bytes,
- gboolean has_alpha)
+colors_equal (const gfloat *col1,
+ const gfloat *col2,
+ gint components,
+ gboolean has_alpha)
{
if (has_alpha &&
- col1[bytes - 1] == 0 &&
- col2[bytes - 1] == 0)
+ FLOAT_IS_ZERO (col1[components - 1]) &&
+ FLOAT_IS_ZERO (col2[components - 1]))
{
return TRUE;
}
@@ -158,9 +155,9 @@ colors_equal (const guchar *col1,
{
gint b;
- for (b = 0; b < bytes; b++)
+ for (b = 0; b < components; b++)
{
- if (col1[b] != col2[b])
+ if (! FLOAT_EQUAL (col1[b], col2[b]))
return FALSE;
}
@@ -169,147 +166,155 @@ colors_equal (const guchar *col1,
}
static void
-do_zcrop (GimpDrawable *drawable,
- gint32 image_id)
+do_zcrop (gint32 drawable_id,
+ gint32 image_id)
{
- GimpPixelRgn srcPR, destPR;
- gint width, height, x, y;
- gint bytes;
- guchar *buffer;
- gint8 *killrows;
- gint8 *killcols;
- gint32 livingrows, livingcols, destrow, destcol;
- gint total_area, area;
- gint32 selection_copy;
- gboolean has_alpha;
-
- width = drawable->width;
- height = drawable->height;
- bytes = drawable->bpp;
-
- total_area = width * height * 4;
- area = 0;
+ GeglBuffer *drawable_buffer;
+ GeglBuffer *shadow_buffer;
+ gfloat *linear_buf;
+ const Babl *format;
+
+ gint x, y, width, height;
+ gint components;
+ gint8 *killrows;
+ gint8 *killcols;
+ gint32 livingrows, livingcols, destrow, destcol;
+ gint32 selection_copy_id;
+ gboolean has_alpha;
+
+ drawable_buffer = gimp_drawable_get_buffer (drawable_id);
+ shadow_buffer = gimp_drawable_get_shadow_buffer (drawable_id);
+
+ width = gegl_buffer_get_width (drawable_buffer);
+ height = gegl_buffer_get_height (drawable_buffer);
+ has_alpha = gimp_drawable_has_alpha (drawable_id);
+
+ if (has_alpha)
+ format = babl_format ("R'G'B'A float");
+ else
+ format = babl_format ("R'G'B' float");
+
+ components = babl_format_get_n_components (format);
killrows = g_new (gint8, height);
killcols = g_new (gint8, width);
- buffer = g_malloc ((width > height ? width : height) * bytes);
+ linear_buf = g_new (gfloat, (width > height ? width : height) * components);
- /* initialize the pixel regions */
- gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
- gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
-
- has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
+ /* search which rows to remove */
livingrows = 0;
for (y = 0; y < height; y++)
{
- gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, width);
+ gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (0, y, width, 1),
+ 1.0, format, linear_buf,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
killrows[y] = TRUE;
- for (x = 0; x < width * bytes; x += bytes)
+ for (x = components; x < width * components; x += components)
{
- if (! colors_equal (buffer, &buffer[x], bytes, has_alpha))
+ if (! colors_equal (linear_buf, &linear_buf[x], components, has_alpha))
{
livingrows++;
killrows[y] = FALSE;
break;
}
}
-
- area += width;
- if (y % 20 == 0)
- gimp_progress_update ((double) area / (double) total_area);
}
+ gimp_progress_update (0.25);
+
+ /* search which columns to remove */
livingcols = 0;
for (x = 0; x < width; x++)
{
- gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, height);
+ gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (x, 0, 1, height),
+ 1.0, format, linear_buf,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
killcols[x] = TRUE;
- for (y = 0; y < height * bytes; y += bytes)
+ for (y = components; y < height * components; y += components)
{
- if (! colors_equal (buffer, &buffer[y], bytes, has_alpha))
+ if (! colors_equal (linear_buf, &linear_buf[y], components, has_alpha))
{
livingcols++;
killcols[x] = FALSE;
break;
}
}
-
- area += height;
- if (x % 20 == 0)
- gimp_progress_update ((double) area / (double) total_area);
}
+ gimp_progress_update (0.5);
- if ((livingcols == 0 || livingrows==0) ||
+ if ((livingcols == 0 || livingrows == 0) ||
(livingcols == width && livingrows == height))
{
g_message (_("Nothing to crop."));
+ g_free (linear_buf);
g_free (killrows);
g_free (killcols);
return;
}
- destrow = 0;
+ /* restitute living rows */
+ destrow = 0;
for (y = 0; y < height; y++)
{
if (!killrows[y])
{
- gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, width);
- gimp_pixel_rgn_set_row (&destPR, buffer, 0, destrow, width);
+ gegl_buffer_copy (drawable_buffer,
+ GEGL_RECTANGLE (0, y, width, 1),
+ shadow_buffer,
+ GEGL_RECTANGLE (0, destrow, width, 1));
+
destrow++;
}
-
- area += width;
- if (y % 20 == 0)
- gimp_progress_update ((double) area / (double) total_area);
}
+ gimp_progress_update (0.75);
- destcol = 0;
- gimp_pixel_rgn_init(&srcPR, drawable, 0, 0, width, height, FALSE, TRUE);
+ /* restitute living columns */
+ destcol = 0;
for (x = 0; x < width; x++)
{
if (!killcols[x])
{
- gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, height);
- gimp_pixel_rgn_set_col (&destPR, buffer, destcol, 0, height);
+ gegl_buffer_copy (shadow_buffer,
+ GEGL_RECTANGLE (x, 0, 1, height),
+ shadow_buffer,
+ GEGL_RECTANGLE (destcol, 0, 1, height));
+
destcol++;
}
-
- area += height;
- if (x % 20 == 0)
- gimp_progress_update ((double) area / (double) total_area);
}
- g_free (buffer);
-
- g_free (killrows);
- g_free (killcols);
-
- gimp_drawable_flush (drawable);
+ gimp_progress_update (1.00);
gimp_image_undo_group_start (image_id);
- selection_copy = gimp_selection_save (image_id);
+ selection_copy_id = gimp_selection_save (image_id);
gimp_selection_none (image_id);
- gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
+ gegl_buffer_flush (shadow_buffer);
+ gimp_drawable_merge_shadow (drawable_id, TRUE);
+ gegl_buffer_flush (drawable_buffer);
- gimp_image_select_item (image_id, GIMP_CHANNEL_OP_REPLACE, selection_copy);
- gimp_image_remove_channel (image_id, selection_copy);
+ gimp_image_select_item (image_id, GIMP_CHANNEL_OP_REPLACE, selection_copy_id);
+ gimp_image_remove_channel (image_id, selection_copy_id);
gimp_image_crop (image_id, livingcols, livingrows, 0, 0);
gimp_image_undo_group_end (image_id);
- gimp_progress_update (1.00);
+ g_object_unref (shadow_buffer);
+ g_object_unref (drawable_buffer);
+
+ g_free (linear_buf);
+ g_free (killrows);
+ g_free (killcols);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]