gegl_buffer_get() and gegl_buffer_set()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm trying to write a simple plugin and I'm stuck at the combo functions  gegl_buffer_get(), gegl_buffer_set(). When I _get() a buffer to a malloced memmory, the memory seems to be garbage. And when I try to _set() from the memory to a shadow buffer and merge, all I get is a black result.

Here's a (not)working example:

```
#include <libgimp/gimp.h>

static void query(void);
static void run(const gchar     *name,
        gint             nparams,
        const GimpParam *param,
        gint            *nreturn_vals,
        GimpParam      **return_vals);

GimpPlugInInfo PLUG_IN_INFO = {
    NULL,
    NULL,
    query,
    run
};

MAIN();

static void gegl_copy (gint drawable)
{
    GeglBuffer *buffer;
    GeglBuffer *shadow;

    printf("Plugin: Drawable ID %i\n", drawable);
    buffer = gimp_drawable_get_buffer(drawable);
    shadow = gimp_drawable_get_shadow_buffer(drawable);

    printf("Plugin: gegl_copy()\n");
    guint x      = gegl_buffer_get_x(buffer);
    guint y      = gegl_buffer_get_y(buffer);
    guint width  = gegl_buffer_get_width(buffer);
    guint height = gegl_buffer_get_height(buffer);

    printf("Gegl buffer x: %d\n", x);
    printf("Gegl buffer y: %d\n", y);
    printf("Gegl buffer width: %d\n", width);
    printf("Gegl buffer height: %d\n", height);

    gfloat *in;
    gfloat *out;

    gint sel_x, sel_y;
    gint sel_width, sel_height;
    if (! gimp_drawable_mask_intersect (drawable,
                        &sel_x, &sel_y,
                        &sel_width, &sel_height))
        return;

    guint index = 0;

    const Babl *format;
    format = gegl_buffer_get_format(buffer);

    const gint nc = babl_format_get_n_components(format);

    in  = gegl_malloc (sizeof(gfloat) * width * height * nc);
    out = gegl_malloc (sizeof(gfloat) * width * height * nc);

    gegl_buffer_get(buffer,
            GEGL_RECTANGLE(sel_x, sel_y, sel_width, sel_height),
            1,
            format,
            in,
            GEGL_AUTO_ROWSTRIDE,
            GEGL_ABYSS_NONE);

    for (gint i = sel_x; i < sel_width; ++i)
    {
        for (gint j = sel_y; j < sel_height; ++j)
        {
/*
 *                        GeglRectangle point = {i, j, 1, 1};
 *                        GeglColor     *color = gegl_color_new(NULL);
 *
 *                        gegl_color_set_rgba(color, 0.5, 0.5, 0.5, 1.0);
 *
 *                        gegl_buffer_set_color(buffer, &point, color);
 *                        
 */
            for (gint k = 0; k < nc; ++k)
            {
                index = k + nc * (i + sel_width * j);
                
                // out[index] = (gfloat)in[index] / 2;
                out[index] = 0.5;
                /*
                 *printf("%.2f ", (gfloat)out[index]);
                 */
            }
            /*
             *printf("|");
             */
        }
        /*
         *printf("\n");
         */
        if (i % 10 == 0)
            gimp_progress_update((gdouble) i / (gdouble) sel_width);
    }

    gegl_buffer_set(shadow,
            GEGL_RECTANGLE(sel_x, sel_y, sel_width, sel_height),
            1,
            format,
            out,
            GEGL_AUTO_ROWSTRIDE);

    gegl_free(in);
    gegl_free(out);

    g_object_unref(buffer);
    g_object_unref(shadow);

    /*
     *printf("Plugin: Flushing gegl buffer\n");
     *gegl_buffer_flush(shadow);    
     */

    printf("Plugin: Updating gimp drawable\n");
    gimp_drawable_merge_shadow(drawable, TRUE);
    gimp_drawable_update(drawable,
                 x, y, width, height);
}

static void run(const gchar     *name,
        gint             nparams,
        const GimpParam *param,
        gint            *nreturn_vals,
        GimpParam      **return_vals)
{
    printf("Plugin: run()\n");
    babl_init();

    static GimpParam  values[1];
    GimpPDBStatusType status = GIMP_PDB_SUCCESS;
    GimpRunMode       run_mode;
    gint          drawable = param[2].data.d_drawable;
    
    *nreturn_vals = 1;
    *return_vals  = values;

    values[0].type = GIMP_PDB_STATUS;
    values[0].data.d_status = status;

    run_mode = param[0].data.d_int32;


    gimp_progress_init("Test conversion...");

    // Start image procedure
    gegl_copy(drawable);

    printf("Plugin: Flushing gimp displays\n");
    gimp_displays_flush();
}

static void query(void)
{
    printf("Plugin: query()\n");
    static GimpParamDef args[] = {
    {
        GIMP_PDB_INT32,
        "run-mode",
        "Run mode"
    },
    {
        GIMP_PDB_IMAGE,
        "image",
        "Input image"
    },
    {
        GIMP_PDB_DRAWABLE,
        "drawable",
        "Input drawable"
    }};

    gimp_install_procedure(
        "plug-in-test",
        "Test plugin",
        "Test plugin description",
        "JonnyRobbie",
        "Copyright JonnyRobbie",
        "2020",
        "_Test conversion...",
        "RGB*, GRAY*",
        GIMP_PLUGIN,
        G_N_ELEMENTS (args), 0,
        args, NULL
    );

    gimp_plugin_menu_register(
        "plug-in-test",
        "<Image>/Filters/Enhance"
    ); 
}
```

Built with gimptool. It simply tries to fill the drawable with mid grey (or - if you comment the relevant lines in the for cycle - halve the input data). I was trying to follow the plugin tutorial from developer.gimp.org/writing_a_plugin, but that one is painfully out of date without gegl and I got a ton of deprecated warnings. So I tried to rewrite the logic using gegl buffers, but I failed. Well, I managed to do it in the cycle with gegl_buffer_set_color() (commented out in the cycle), but that one's painfully slow, so I thought that _get(), _set() might be faster.

At the end of the day, I want to have a plugin, which takes every pixel separately one by one and does some mathematical operation on that pixel, without the need to access multiple pixels at once.

If you could point me to my mistakes with buffer functions, I'd be grateful.

Thanks, Marek

_______________________________________________
gimp-developer-list mailing list
List address:    gimp-developer-list@xxxxxxxxx
List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
List archives:   https://mail.gnome.org/archives/gimp-developer-list




[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux