Commit 3914e047 authored by Michael Natterer's avatar Michael Natterer 😴

plug-ins: port gimpressionist to GEGL, stupid 8-bit port only

parent b7cf8506
......@@ -79,6 +79,7 @@ LDADD = \
$(libgimpmath) \
$(libgimpbase) \
$(GTK_LIBS) \
$(GEGL_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(gimpressionist_RC)
......
......@@ -92,25 +92,44 @@ set_colorbrushes (const gchar *fn)
pcvals.color_brushes = file_is_color (fn);
}
static const Babl *
get_u8_format (gint32 drawable_id)
{
if (gimp_drawable_is_rgb (drawable_id))
{
if (gimp_drawable_has_alpha (drawable_id))
return babl_format ("R'G'B'A u8");
else
return babl_format ("R'G'B' u8");
}
else
{
if (gimp_drawable_has_alpha (drawable_id))
return babl_format ("Y'A u8");
else
return babl_format ("Y' u8");
}
}
static void
brushdmenuselect (GtkWidget *widget,
gpointer data)
{
GimpPixelRgn src_rgn;
guchar *src_row;
guchar *src;
gint id;
gint bpp;
gint x, y;
ppm_t *p;
gint x1, y1, w, h;
gint row;
GimpDrawable *drawable;
gint rowstride;
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &id);
if (id == -1)
GeglBuffer *src_buffer;
const Babl *format;
guchar *src_row;
guchar *src;
gint bpp;
gint x, y;
ppm_t *p;
gint x1, y1, w, h;
gint row;
gint32 drawable_id;
gint rowstride;
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &drawable_id);
if (drawable_id == -1)
return;
if (brush_from_file == 2)
......@@ -127,12 +146,11 @@ brushdmenuselect (GtkWidget *widget,
gtk_adjustment_set_value (brush_gamma_adjust, 1.0);
gtk_adjustment_set_value (brush_aspect_adjust, 0.0);
drawable = gimp_drawable_get (id);
if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x1, &y1, &w, &h))
if (! gimp_drawable_mask_intersect (drawable_id, &x1, &y1, &w, &h))
return;
bpp = gimp_drawable_bpp (drawable->drawable_id);
format = get_u8_format (drawable_id);
bpp = babl_format_get_bytes_per_pixel (format);
ppm_kill (&brushppm);
ppm_new (&brushppm, w, h);
......@@ -142,8 +160,7 @@ brushdmenuselect (GtkWidget *widget,
src_row = g_new (guchar, w * bpp);
gimp_pixel_rgn_init (&src_rgn, drawable,
0, 0, w, h, FALSE, FALSE);
src_buffer = gimp_drawable_get_buffer (drawable_id);
if (bpp == 3)
{ /* RGB */
......@@ -152,7 +169,10 @@ brushdmenuselect (GtkWidget *widget,
for (row = 0, y = y1; y < y2; row++, y++)
{
gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, w);
gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y, w, 1), 1.0,
format, src_row,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
memcpy (p->col + row*rowstride, src_row, bpr);
}
}
......@@ -167,8 +187,10 @@ brushdmenuselect (GtkWidget *widget,
guchar *tmprow_ptr;
gint x2 = x1 + w;
gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y, w, 1), 1.0,
format, src_row,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, w);
src = src_row;
tmprow_ptr = tmprow;
/* Possible micro-optimization here:
......@@ -180,10 +202,13 @@ brushdmenuselect (GtkWidget *widget,
*(tmprow_ptr++) = src[0];
*(tmprow_ptr++) = src[is_gray ? 1 : 0];
*(tmprow_ptr++) = src[is_gray ? 2 : 0];
src += src_rgn.bpp;
src += bpp;
}
}
}
g_object_unref (src_buffer);
g_free (src_row);
if (bpp >= 3)
......
......@@ -52,9 +52,9 @@ const GimpPlugInInfo PLUG_IN_INFO = {
run /* run_proc */
}; /* PLUG_IN_INFO */
static GimpDrawable *drawable;
static ppm_t infile = {0, 0, NULL};
static ppm_t inalpha = {0, 0, NULL};
static gint32 drawable_id;
static ppm_t infile = {0, 0, NULL};
static ppm_t inalpha = {0, 0, NULL};
void
......@@ -140,11 +140,12 @@ run (const gchar *name,
*return_vals = values;
INIT_I18N ();
gegl_init (NULL, NULL);
/* Get the active drawable info */
drawable = gimp_drawable_get (param[2].data.d_drawable);
img_has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
drawable_id = param[2].data.d_drawable;
img_has_alpha = gimp_drawable_has_alpha (drawable_id);
random_generator = g_rand_new ();
......@@ -155,7 +156,7 @@ run (const gchar *name,
{
gint x1, y1, width, height; /* Not used. */
if (! gimp_drawable_mask_intersect (drawable->drawable_id,
if (! gimp_drawable_mask_intersect (drawable_id,
&x1, &y1, &width, &height))
{
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
......@@ -164,8 +165,6 @@ run (const gchar *name,
values[1].data.d_string = _("The selection does not intersect "
"the active layer or mask.");
gimp_drawable_detach (drawable);
return;
}
}
......@@ -193,8 +192,8 @@ run (const gchar *name,
break;
}
if ((status == GIMP_PDB_SUCCESS) &&
(gimp_drawable_is_rgb (drawable->drawable_id) ||
gimp_drawable_is_gray (drawable->drawable_id)))
(gimp_drawable_is_rgb (drawable_id) ||
gimp_drawable_is_gray (drawable_id)))
{
if (with_specified_preset)
......@@ -247,52 +246,77 @@ run (const gchar *name,
size_map_free_resources ();
values[0].data.d_status = status;
}
gimp_drawable_detach (drawable);
static const Babl *
get_u8_format (gint32 drawable_id)
{
if (gimp_drawable_is_rgb (drawable_id))
{
if (gimp_drawable_has_alpha (drawable_id))
return babl_format ("R'G'B'A u8");
else
return babl_format ("R'G'B' u8");
}
else
{
if (gimp_drawable_has_alpha (drawable_id))
return babl_format ("Y'A u8");
else
return babl_format ("Y' u8");
}
}
void
grabarea (void)
{
GimpPixelRgn src_rgn;
ppm_t *p;
gint x1, y1;
gint x, y;
gint width, height;
gint row, col;
gint rowstride;
gpointer pr;
if (! gimp_drawable_mask_intersect (drawable->drawable_id,
GeglBuffer *src_buffer;
GeglBufferIterator *iter;
const Babl *format;
gint bpp;
ppm_t *p;
gint x1, y1;
gint x, y;
gint width, height;
gint row, col;
gint rowstride;
if (! gimp_drawable_mask_intersect (drawable_id,
&x1, &y1, &width, &height))
return;
ppm_new (&infile, width, height);
p = &infile;
if (gimp_drawable_has_alpha (drawable->drawable_id))
format = get_u8_format (drawable_id);
bpp = babl_format_get_bytes_per_pixel (format);
if (gimp_drawable_has_alpha (drawable_id))
ppm_new (&inalpha, width, height);
rowstride = p->width * 3;
gimp_pixel_rgn_init (&src_rgn,
drawable, x1, y1, width, height, FALSE, FALSE);
src_buffer = gimp_drawable_get_buffer (drawable_id);
iter = gegl_buffer_iterator_new (src_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
for (pr = gimp_pixel_rgns_register (1, &src_rgn);
pr != NULL;
pr = gimp_pixel_rgns_process (pr))
while (gegl_buffer_iterator_next (iter))
{
const guchar *src = src_rgn.data;
GeglRectangle roi = iter->items[0].roi;
const guchar *src = iter->items[0].data;
switch (src_rgn.bpp)
switch (bpp)
{
case 1:
for (y = 0, row = src_rgn.y - y1; y < src_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
const guchar *s = src;
guchar *tmprow = p->col + row * rowstride;
for (x = 0, col = src_rgn.x - x1; x < src_rgn.w; x++, col++)
for (x = 0, col = roi.x - x1; x < roi.width; x++, col++)
{
gint k = col * 3;
......@@ -303,18 +327,18 @@ grabarea (void)
s++;
}
src += src_rgn.rowstride;
src += bpp * roi.width;
}
break;
case 2:
for (y = 0, row = src_rgn.y - y1; y < src_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
const guchar *s = src;
guchar *tmprow = p->col + row * rowstride;
guchar *tmparow = inalpha.col + row * rowstride;
for (x = 0, col = src_rgn.x - x1; x < src_rgn.w; x++, col++)
for (x = 0, col = roi.x - x1; x < roi.width; x++, col++)
{
gint k = col * 3;
......@@ -326,29 +350,29 @@ grabarea (void)
s += 2;
}
src += src_rgn.rowstride;
src += bpp * roi.width;
}
break;
case 3:
col = src_rgn.x - x1;
col = roi.x - x1;
for (y = 0, row = src_rgn.y - y1; y < src_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
memcpy (p->col + row * rowstride + col * 3, src, src_rgn.w * 3);
memcpy (p->col + row * rowstride + col * 3, src, roi.width * 3);
src += src_rgn.rowstride;
src += bpp * roi.width;
}
break;
case 4:
for (y = 0, row = src_rgn.y - y1; y < src_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
const guchar *s = src;
guchar *tmprow = p->col + row * rowstride;
guchar *tmparow = inalpha.col + row * rowstride;
for (x = 0, col = src_rgn.x - x1; x < src_rgn.w; x++, col++)
for (x = 0, col = roi.x - x1; x < roi.width; x++, col++)
{
gint k = col * 3;
......@@ -360,34 +384,40 @@ grabarea (void)
s += 4;
}
src += src_rgn.rowstride;
src += bpp * roi.width;
}
break;
}
}
g_object_unref (src_buffer);
}
static void
gimpressionist_main (void)
{
GimpPixelRgn dest_rgn;
ppm_t *p;
gint x1, y1;
gint x, y;
gint width, height;
gint row, col;
gint rowstride;
gint count;
glong done;
glong total;
gpointer pr;
if (! gimp_drawable_mask_intersect (drawable->drawable_id,
GeglBuffer *dest_buffer;
GeglBufferIterator *iter;
const Babl *format;
gint bpp;
ppm_t *p;
gint x1, y1;
gint x, y;
gint width, height;
gint row, col;
gint rowstride;
glong done = 0;
glong total;
if (! gimp_drawable_mask_intersect (drawable_id,
&x1, &y1, &width, &height))
return;
total = width * height;
format = get_u8_format (drawable_id);
bpp = babl_format_get_bytes_per_pixel (format);
gimp_progress_init (_("Painting"));
if (! PPM_IS_INITED (&infile))
......@@ -399,24 +429,27 @@ gimpressionist_main (void)
rowstride = p->width * 3;
gimp_pixel_rgn_init (&dest_rgn,
drawable, x1, y1, width, height, TRUE, TRUE);
dest_buffer = gimp_drawable_get_shadow_buffer (drawable_id);
for (pr = gimp_pixel_rgns_register (1, &dest_rgn), count = 0, done = 0;
pr != NULL;
pr = gimp_pixel_rgns_process (pr), count++)
iter = gegl_buffer_iterator_new (dest_buffer,
GEGL_RECTANGLE (x1, y1, width, height), 0,
format,
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE, 1);
while (gegl_buffer_iterator_next (iter))
{
guchar *dest = dest_rgn.data;
GeglRectangle roi = iter->items[0].roi;
guchar *dest = iter->items[0].data;
switch (dest_rgn.bpp)
switch (bpp)
{
case 1:
for (y = 0, row = dest_rgn.y - y1; y < dest_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
guchar *d = dest;
const guchar *tmprow = p->col + row * rowstride;
for (x = 0, col = dest_rgn.x - x1; x < dest_rgn.w; x++, col++)
for (x = 0, col = roi.x - x1; x < roi.width; x++, col++)
{
gint k = col * 3;
......@@ -425,18 +458,18 @@ gimpressionist_main (void)
tmprow[k + 2]);
}
dest += dest_rgn.rowstride;
dest += bpp * roi.width;
}
break;
case 2:
for (y = 0, row = dest_rgn.y - y1; y < dest_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
guchar *d = dest;
const guchar *tmprow = p->col + row * rowstride;
const guchar *tmparow = inalpha.col + row * rowstride;
for (x = 0, col = dest_rgn.x - x1; x < dest_rgn.w; x++, col++)
for (x = 0, col = roi.x - x1; x < roi.width; x++, col++)
{
gint k = col * 3;
gint value = GIMP_RGB_LUMINANCE (tmprow[k + 0],
......@@ -449,29 +482,29 @@ gimpressionist_main (void)
d += 2;
}
dest += dest_rgn.rowstride;
dest += bpp * roi.width;
}
break;
case 3:
col = dest_rgn.x - x1;
col = roi.x - x1;
for (y = 0, row = dest_rgn.y - y1; y < dest_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
memcpy (dest, p->col + row * rowstride + col * 3, dest_rgn.w * 3);
memcpy (dest, p->col + row * rowstride + col * 3, roi.width * 3);
dest += dest_rgn.rowstride;
dest += bpp * roi.width;
}
break;
case 4:
for (y = 0, row = dest_rgn.y - y1; y < dest_rgn.h; y++, row++)
for (y = 0, row = roi.y - y1; y < roi.height; y++, row++)
{
guchar *d = dest;
const guchar *tmprow = p->col + row * rowstride;
const guchar *tmparow = inalpha.col + row * rowstride;
for (x = 0, col = dest_rgn.x - x1; x < dest_rgn.w; x++, col++)
for (x = 0, col = roi.x - x1; x < roi.width; x++, col++)
{
gint k = col * 3;
......@@ -483,19 +516,20 @@ gimpressionist_main (void)
d += 4;
}
dest += dest_rgn.rowstride;
dest += bpp * roi.width;
}
break;
}
done += dest_rgn.w * dest_rgn.h;
done += roi.width * roi.height;
if (count % 16 == 0)
gimp_progress_update (0.8 + 0.2 * done / total);
gimp_progress_update (0.8 + 0.2 * done / total);
}
g_object_unref (dest_buffer);
gimp_progress_update (1.0);
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
gimp_drawable_merge_shadow (drawable_id, TRUE);
gimp_drawable_update (drawable_id, x1, y1, width, height);
}
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