RSS/Atom feed Twitter
Site is read-only, email is disabled

basic concepts and usage of gegl in gtk

This discussion is connected to the gegl-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

8 of 8 messages available
Toggle history

Please log in to manage your subscriptions.

basic concepts and usage of gegl in gtk Vincent 28 Dec 22:34
  basic concepts and usage of gegl in gtk Øyvind Kolås 29 Dec 00:17
   basic concepts and usage of gegl in gtk Vincent 05 Jan 01:08
    basic concepts and usage of gegl in gtk Jon Nordby 05 Jan 11:12
    basic concepts and usage of gegl in gtk Øyvind Kolås 05 Jan 13:06
     basic concepts and usage of gegl in gtk Vincent 05 Jan 23:00
  basic concepts and usage of gegl in gtk Jon Nordby 29 Dec 01:29
  basic concepts and usage of gegl in gtk Debarshi Ray 02 Jan 14:04
Vincent
2016-12-28 22:34:25 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

Hello,
I'm evaluating gegl to replace the image display part of siril, a free astronomy image processor [1]. Siril is a GTK+3 application, so I naturally tried gegl-gtk which seems to have be abandonned for some time. I have updated it to compile with gegl 3.10, and examples are apparently working, if someone is interested the code is available [2].

I have a hard time understanding the basic concepts of GEGL, in particular the graph. I could not find a clear documentation for GEGL so my knowledge comes mainly from the gegl-gtk examples, so please tell me if the following is right: some nodes of the graph are data producers, some are data processors, some are data consumers like saving to disk or displaying. In general, there's one data producer and one data consumer in the graph, and there can be many data processors, the image processing operations. The fact that there seems to be a root to all graphs, from which all other nodes are instantiated as children with gegl_node_new_child() is very disturbing because that would mean that it is a tree, not a graph, so I assumed that nodes are automatically connected from parent to child, which doesn't seem to be the case at all.

That being said, I tried to make a simple application that takes a 16-bit integer pixel buffer and display it in gegl-gtk. I figured that would make a graph such as:

gegl:buffer_source -> insert here some -> gegl-gtk widget | brightness mapping buffer| or other operations
|
gegl_buffer --|

The code I'm using is the following, without any operation in the middle: const Babl* format = babl_format("Y u16"); GeglBuffer *buf = gegl_buffer_new(&_rect, format); gegl_buffer_set(buf, &_rect, 1, format, image_buffer, GEGL_AUTO_ROWSTRIDE); /* create the graph that displays this buffer */ GeglNode *bufnode = gegl_node_new_child(gegl, "operation", "gegl:buffer-source", "buffer", buf, NULL); gegl_node_process(bufnode);

// Get the GtkWindow from glade and add gegl-gtk to it GtkWidget *box = lookup_widget("a_window"); view = GTK_WIDGET(gegl_gtk_view_new_for_node(bufnode)); gtk_container_add(GTK_CONTAINER(box), view);

Of course _rect is set to the correct 0,0,width,height of the buffer.

The problem is that all I get from this code is segfaults. What did I miss? Isn't gegl-gtk supposed to display the image data given by the output port of a node? Is something required to transform the gegl buffer data to a format that the gegl-gtk widget can understand?

I will need two types of graphs for image data display: one for grey images channels display with at least a basic brightness/contrast control duplicated for each of the R G and B channels, one that displays colour images recombined from the three greys. Anybody has an idea about how I can recombine the resulting images from the three grey graphs and display it into a new gegl-gtk widget?

Thank you

[1] https://free-astro.org/index.php/Siril [2] https://free-astro.org/svn/siril/trunk/deps/gegl-gtk/

Øyvind Kolås
2016-12-29 00:17:48 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

On Wed, Dec 28, 2016 at 11:34 PM, Vincent wrote:

gegl_buffer_set(buf, &_rect, 1, format, image_buffer, GEGL_AUTO_ROWSTRIDE);

The problem is that all I get from this code is segfaults. What did I miss? Isn't gegl-gtk supposed to display the image data given by the output port of a node? Is something required to transform the gegl buffer data to a format that the gegl-gtk widget can understand?

Without a downloadable buildable code example it is hard to diagnose what is going wrong, based on reading the provided source there is at least one other thing going wrong. You should be providing 0 as the mipmap level/third argument of gegl_buffer_set, if writing directly to mipmap level 1, display at scales

/pippin

Jon Nordby
2016-12-29 01:29:29 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

Can you provide the stack trace? (with debug symbols)

On 28 Dec 2016 11:34 p.m., "Vincent" wrote:

Hello,
I'm evaluating gegl to replace the image display part of siril, a free astronomy image processor [1]. Siril is a GTK+3 application, so I naturally tried gegl-gtk which seems to have be abandonned for some time. I have updated it to compile with gegl 3.10, and examples are apparently working, if someone is interested the code is available [2].

I have a hard time understanding the basic concepts of GEGL, in particular the graph. I could not find a clear documentation for GEGL so my knowledge comes mainly from the gegl-gtk examples, so please tell me if the following is right: some nodes of the graph are data producers, some are data processors, some are data consumers like saving to disk or displaying. In general, there's one data producer and one data consumer in the graph, and there can be many data processors, the image processing operations. The fact that there seems to be a root to all graphs, from which all other nodes are instantiated as children with gegl_node_new_child() is very disturbing because that would mean that it is a tree, not a graph, so I assumed that nodes are automatically connected from parent to child, which doesn't seem to be the case at all.

That being said, I tried to make a simple application that takes a 16-bit integer pixel buffer and display it in gegl-gtk. I figured that would make a graph such as:

gegl:buffer_source -> insert here some -> gegl-gtk widget | brightness mapping buffer| or other operations |
gegl_buffer --|

The code I'm using is the following, without any operation in the middle: const Babl* format = babl_format("Y u16"); GeglBuffer *buf = gegl_buffer_new(&_rect, format); gegl_buffer_set(buf, &_rect, 1, format, image_buffer, GEGL_AUTO_ROWSTRIDE);
/* create the graph that displays this buffer */ GeglNode *bufnode = gegl_node_new_child(gegl, "operation", "gegl:buffer-source", "buffer", buf, NULL);
gegl_node_process(bufnode);

// Get the GtkWindow from glade and add gegl-gtk to it GtkWidget *box = lookup_widget("a_window"); view = GTK_WIDGET(gegl_gtk_view_new_for_node(bufnode)); gtk_container_add(GTK_CONTAINER(box), view);

Of course _rect is set to the correct 0,0,width,height of the buffer.

The problem is that all I get from this code is segfaults. What did I miss? Isn't gegl-gtk supposed to display the image data given by the output port of a node? Is something required to transform the gegl buffer data to a format that the gegl-gtk widget can understand?

I will need two types of graphs for image data display: one for grey images channels display with at least a basic brightness/contrast control duplicated for each of the R G and B channels, one that displays colour images recombined from the three greys. Anybody has an idea about how I can recombine the resulting images from the three grey graphs and display it into a new gegl-gtk widget?

Thank you

[1] https://free-astro.org/index.php/Siril [2] https://free-astro.org/svn/siril/trunk/deps/gegl-gtk/

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

Debarshi Ray
2017-01-02 14:04:03 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

Hey Vincent,

On Wed, Dec 28, 2016 at 11:34:25PM +0100, Vincent wrote:

I'm evaluating gegl to replace the image display part of siril, a free astronomy image processor [1]. Siril is a GTK+3 application, so I naturally tried gegl-gtk which seems to have be abandonned for some time. I have updated it to compile with gegl 3.10, and examples are apparently working, if someone is interested the code is available [2].

I have a hard time understanding the basic concepts of GEGL, in particular the graph. I could not find a clear documentation for GEGL so my knowledge comes mainly from the gegl-gtk examples,

There is some documentation on http://gegl.org/. If you are looking for real world GTK+ applications based on GEGL, you can look at GIMP (https://git.gnome.org/browse/gimp) or GNOME Photos (https://git.gnome.org/browse/gnome-photos).

As for GTK+ widget to render the output of a GEGL graph, GNOME Photos started out by using gegl-gtk (it actually had a copy of the code to avoid depending on a weakly maintained library). Since then the code has evolved a bit and can be found in src/photos-image-view.[ch].

so please tell me
if the following is right: some nodes of the graph are data producers, some are data processors,

Right. GEGL uses 'source' and 'sink' instead of 'producer' and 'consumer'.

some are data consumers like saving to disk or displaying. In general, there's one data producer and one data consumer in the graph, and there can be many data processors, the image processing operations.

It is not that uncommon to have more than one data producer (or source) in a graph. eg., if you want to apply a gradient or vignette to an image.

Similarly, you may have multiple sinks connected to a source.

The fact that there seems to be a root to all graphs,

Note that the root node is optional, but, yes, nodes usually have one.

from which all other nodes are instantiated as children with gegl_node_new_child() is very disturbing because that would mean that it is a tree, not a graph, so I assumed that nodes are automatically connected from parent to child, which doesn't seem to be the case at all.

The root is mainly for convenience. For example:

(a) The root node usually takes over ownership of the other nodes in a graph, so you don't need to destroy them individually.

(b) A node can have a meta-operation constructed from several other operations. As long as the internal nodes are connected to the input/output/... proxies of the parent, it will behave like any other node.

I will need two types of graphs for image data display: one for grey images channels display with at least a basic brightness/contrast control duplicated for each of the R G and B channels, one that displays colour images recombined from the three greys. Anybody has an idea about how I can recombine the resulting images from the three grey graphs and display it into a new gegl-gtk widget?

You will need a composer to re-combine the three channels. Since you have 3 inputs, you will need an operation that sub-classes GeglOperationPointComposer3. There might be something already available in GEGL (grep for GEGL_OP_POINT_COMPOSER3), or you can write your own.

I hope this helps.

Happy hacking, Rishi

Vincent
2017-01-05 01:08:20 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

On Thu, Dec 29, 2016 at 01:17:48AM +0100, yvind Kols wrote:

On Wed, Dec 28, 2016 at 11:34 PM, Vincent wrote:

gegl_buffer_set(buf, &_rect, 1, format, image_buffer, GEGL_AUTO_ROWSTRIDE);

The problem is that all I get from this code is segfaults. What did I miss? Isn't gegl-gtk supposed to display the image data given by the output port of a node? Is something required to transform the gegl buffer data to a format that the gegl-gtk widget can understand?

Without a downloadable buildable code example it is hard to diagnose what is going wrong, based on reading the provided source there is at least one other thing going wrong. You should be providing 0 as the mipmap level/third argument of gegl_buffer_set, if writing directly to mipmap level 1, display at scales

/pippin

Thank you both for your answers. I finally made a sample application that reads a FITS file and tries to display the first channel's grey buffer in a gegl-gtk object.

The code is here: https://free-astro.org/svn/siril/trunk/src/main_gegl_test.c you may also checkout trunk/deps/gegl-gtk. Compilation instructions are given at the top of the file, dependencies are GTK3, GEGL, gegl-gtk and cfitsio.
A sample file is available here:
https://free-astro.org/download/scott.fit

Stack trace for SIGSEV (sorry I don't have all symbols it has too many dependencies to rebuild shortly): #0 0x00007ffff43a6e1e in __memmove_sse2_unaligned_erms () at /usr/lib/libc.so.6
#1 0x00007ffff617b1a1 in gegl_buffer_set () at /usr/lib/libgegl-0.3.so.0
#2 0x000000000040354a in main (argc=2, argv=0x7fffffffe9b8) at main_gegl_test.c:84

Any ideas?

Is there actually a copy of the buffer into GEGL's memory in this function? I would have hoped we could avoid that, to have better performances.

Thank you
Vincent

Jon Nordby
2017-01-05 11:12:06 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

On 5 January 2017 at 02:08, Vincent wrote:

The code is here:
https://free-astro.org/svn/siril/trunk/src/main_gegl_test.c you may also checkout trunk/deps/gegl-gtk. Compilation instructions are given at the top of the file, dependencies are GTK3, GEGL, gegl-gtk and cfitsio.
A sample file is available here:
https://free-astro.org/download/scott.fit

Stack trace for SIGSEV (sorry I don't have all symbols it has too many dependencies to rebuild shortly): #0 0x00007ffff43a6e1e in __memmove_sse2_unaligned_erms () at /usr/lib/libc.so.6
#1 0x00007ffff617b1a1 in gegl_buffer_set () at /usr/lib/libgegl-0.3.so.0
#2 0x000000000040354a in main (argc=2, argv=0x7fffffffe9b8) at main_gegl_test.c:84

Any ideas?

From the stacktrace, it looks like is crashes in gegl_buffer_set(buf, &rect, 0, format, &fit.pdata[0], GEGL_AUTO_ROWSTRIDE);

So probably there is some mismatch between the data in &fit.pdata[0] and the expectations set by the passed parameters to gegl_buffer_set(). Don't see anything obvious in the code on a quick glance, but I would sanity-check
how many bytes are allocated for fit.data

Is there actually a copy of the buffer into GEGL's memory in this function? I would have hoped we could avoid that, to have better performances.

Yes, GeglBuffer is a tiled datastructure, so the data is spread out into tiles.

How many times per second will you be updating the image?

Jon Nordby - www.jonnor.com
Øyvind Kolås
2017-01-05 13:06:52 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

On Thu, Jan 5, 2017 at 2:08 AM, Vincent wrote:

Thank you both for your answers. I finally made a sample application that reads a FITS file and tries to display the first channel's grey buffer in a gegl-gtk object.

The code is here: https://free-astro.org/svn/siril/trunk/src/main_gegl_test.c you may also checkout trunk/deps/gegl-gtk. Compilation instructions are given at the top of the file, dependencies are GTK3, GEGL, gegl-gtk and cfitsio.
A sample file is available here:
https://free-astro.org/download/scott.fit

Changing this line:
gegl_buffer_set(buf, &rect, 0, format, &fit.pdata[0], GEGL_AUTO_ROWSTRIDE); to be:
gegl_buffer_set(buf, &rect, 0, format, fit.pdata[0], GEGL_AUTO_ROWSTRIDE);

results in a window displaying an image rather than a seg fault for me.

Happy hacking :)

Vincent
2017-01-05 23:00:13 UTC (over 7 years ago)

basic concepts and usage of gegl in gtk

On Thu, Jan 05, 2017 at 02:06:52PM +0100, yvind Kols wrote:

On Thu, Jan 5, 2017 at 2:08 AM, Vincent wrote:

Thank you both for your answers. I finally made a sample application that reads a FITS file and tries to display the first channel's grey buffer in a gegl-gtk object.

The code is here: https://free-astro.org/svn/siril/trunk/src/main_gegl_test.c you may also checkout trunk/deps/gegl-gtk. Compilation instructions are given at the top of the file, dependencies are GTK3, GEGL, gegl-gtk and cfitsio.
A sample file is available here:
https://free-astro.org/download/scott.fit

Changing this line:
gegl_buffer_set(buf, &rect, 0, format, &fit.pdata[0], GEGL_AUTO_ROWSTRIDE); to be:
gegl_buffer_set(buf, &rect, 0, format, fit.pdata[0], GEGL_AUTO_ROWSTRIDE);

results in a window displaying an image rather than a seg fault for me.

Happy hacking :)

Sorry everybody for this stupid mistake, I knew it was an easy one... So I confirm that this fix and the previous one that you mentioned, the mipmap level that was supposed to be 0 instead of 1, make my sample work, thanks a lot yvind!

At least I think I had correctly understood the graph part. Now I'll continue my tests in the main application.

Best wishes for 2017. Vincent