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

Operations that I require

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.

13 of 13 messages available
Toggle history

Please log in to manage your subscriptions.

Operations that I require Mark Probst 08 May 22:13
Operations that I require Øyvind Kolås 09 May 10:25
Operations that I require Mark Probst 09 May 10:44
Operations that I require Øyvind Kolås 09 May 10:59
Operations that I require Sven Neumann 09 May 11:06
  Operations that I require Mark Probst 09 May 11:10
  Operations that I require Øyvind Kolås 09 May 12:55
Operations that I require Mark Probst 09 May 11:15
Operations that I require Øyvind Kolås 09 May 12:57
Operations that I require Mark Probst 09 May 13:08
Operations that I require Mark Probst 10 May 20:44
Operations that I require Mark Probst 10 May 23:08
Operations that I require Øyvind Kolås 10 May 23:24
Mark Probst
2007-05-08 22:13:21 UTC (almost 17 years ago)

Operations that I require

Hi!

I'm trying to implement a B/W processing application using Gegl, similar to my B/W Photoshop workflow:

http://schani.wordpress.com/2006/05/23/my-digital-bw-workflow/

There are several operations that I need which, as far as I can tell (I'm completely new to Gegl), are not supported, directly or indirectly:

* Channel Mixer. What it does is it generates a B/W image out of a color image by calculating a weighted sum of the color channels.

* Gradient curves. I want to give the user a curve control to modify the contrast of the image, like the "Curve" filter in GIMP/Photoshop.

I'd also like to be able to get a histogram out of the graph at various points.

If those are already possible with Gegl, I'd really appreciate it if somebody could point me to them. If not, I'd be very happy if you could tell me how to best go about implementing them.

Thanks!

Mark

Øyvind Kolås
2007-05-09 10:25:13 UTC (almost 17 years ago)

Operations that I require

On 5/8/07, Mark Probst wrote:

Hi!

I'm trying to implement a B/W processing application using Gegl, similar to my B/W Photoshop workflow:

http://schani.wordpress.com/2006/05/23/my-digital-bw-workflow/

There are several operations that I need which, as far as I can tell (I'm completely new to Gegl), are not supported, directly or indirectly:

* Channel Mixer. What it does is it generates a B/W image out of a color image by calculating a weighted sum of the color channels.

There is no real equivalent to a Channel Mixer operation at the moment.

* Gradient curves. I want to give the user a curve control to modify the contrast of the image, like the "Curve" filter in GIMP/Photoshop.

There is no curves control either, the closest would be levels. Both of these are point operations and would live in the gegl/operations/color/ dir. The Channel Mixer is probably the one that would be easiest to implement.

For a curves operation the main issue is how to pass the curve to the operation, there currently is no operations in GEGL that take an array of values as a parameter; thus you should probably bypass the gegl-chant mechanisms and write all the needed boilerplate yourself gegl/color/remap.c is an example of one operation that does this for other reasons.
When it comes to how an array of values are best expressed, there probably are some examples in GIMP plug-ins.

/Øyvind K.

Mark Probst
2007-05-09 10:44:51 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Øyvind Kolås wrote:

There is no real equivalent to a Channel Mixer operation at the moment.

Does GEGL support single-channel (plus maybe alpha) output/processing?

When it comes to how an array of values are best expressed, there probably are some examples in GIMP plug-ins.

To be honest, I'm not sure if I want to do this with an array of values, for the simple reason that if you're using floats for image processing, your array either has to be pretty big or you're losing precision.

I'd prefer either for GEGL to have some curve data structure that can do linear and spline interpolation, or for the operation to just take a user-implemented function which can compute any curve value. The two approaches can be combined, too - allow the user to pass an arbitrary function, but provide a default one with a curve data structure for people who don't need the flexibility.

Another thing that I'll need sooner or later is brush painting (for dodge/burn functionality). I saw in your FOSDEM talk that that's planned, or at least considered, for the future. Could you give an outline on how that would or could be implemented?

Mark

Øyvind Kolås
2007-05-09 10:59:05 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Mark Probst wrote:

On 5/9/07, Øyvind Kolås wrote:

There is no real equivalent to a Channel Mixer operation at the moment.

Does GEGL support single-channel (plus maybe alpha) output/processing?

Not sure what you mean by this, but it should be possible to rig up a channel mixer using the arithmetic operations + component extraction/muxing nodes.

When it comes to how an array of values are best expressed, there probably are some examples in GIMP plug-ins.

To be honest, I'm not sure if I want to do this with an array of values, for the simple reason that if you're using floats for image processing, your array either has to be pretty big or you're losing precision.

I'd prefer either for GEGL to have some curve data structure that can do linear and spline interpolation, or for the operation to just take a user-implemented function which can compute any curve value. The

One, or two arrays, are that datastructures that would be needed to express a curve. Passing in a function means having an expression parser in-place, in general I feel that doing so is adding unwarranted complexity. I think the curves tool in GIMP is using an array of values + interpolation.

Another thing that I'll need sooner or later is brush painting (for dodge/burn functionality). I saw in your FOSDEM talk that that's planned, or at least considered, for the future. Could you give an outline on how that would or could be implemented?

A brush system is outside the scope of GEGL, the only thing that would be part of GEGL is actual procedural rendering of brushes. The rest of the infrastructure needed to implement a paint-core is already present in GEGL; and there is many (at least two, probably more) ways of implementing such a system. Personally I do not want to start experimenting with such things until after internal refactoring of GEGL is done, since any profiling done before that will provide bogus information.

/Øyvind K.

Sven Neumann
2007-05-09 11:06:00 UTC (almost 17 years ago)

Operations that I require

Hi,

On Wed, 2007-05-09 at 10:59 +0200, Øyvind Kolås wrote:

Passing in a function means having an expression parser in-place, in general I feel that doing so is adding unwarranted complexity.

I don't think Mark suggested to pass in a function literally. He suggested to allow passing a callback function. GEGL would then call this function whenever it needs a curves value. His suggestions make a lot of sense to me and I think you should consider them.

Sven

Mark Probst
2007-05-09 11:10:49 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Sven Neumann wrote:

I don't think Mark suggested to pass in a function literally. He suggested to allow passing a callback function. GEGL would then call this function whenever it needs a curves value.

Yes, that's what I meant. Building and maintaining an expression parser is of course the completely wrong approach.

Mark

Mark Probst
2007-05-09 11:15:38 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Øyvind Kolås wrote:

Not sure what you mean by this, but it should be possible to rig up a channel mixer using the arithmetic operations + component extraction/muxing nodes.

That's what I was thinking, too, but I wonder about the performance of such an approach? Would it be significantly slower than doing it all in one node?

Also: Are there already component extraction/muxing operations?

I guess I just discovered that the operations list on the GEGL homepage is not complete (at least gray, remap and the bilateral filter are missing). Is there a complete operations list somewhere or do I have to go through the source files to learn what's already there?

A brush system is outside the scope of GEGL, the only thing that would be part of GEGL is actual procedural rendering of brushes. The rest of the infrastructure needed to implement a paint-core is already present in GEGL; and there is many (at least two, probably more) ways of implementing such a system.

I see. I'll bug you about this when I'm far enough with my project to worry about it.

Mark

Øyvind Kolås
2007-05-09 12:55:13 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Sven Neumann wrote:

On Wed, 2007-05-09 at 10:59 +0200, Øyvind Kolås wrote:

Passing in a function means having an expression parser in-place, in general I feel that doing so is adding unwarranted complexity.

I don't think Mark suggested to pass in a function literally. He suggested to allow passing a callback function. GEGL would then call this function whenever it needs a curves value. His suggestions make a lot of sense to me and I think you should consider them.

Passing in a pointer to a callback function will work in C, but will not work for XML serialization, C#, Ruby, Python etc.

/Øyvind K.

Øyvind Kolås
2007-05-09 12:57:22 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Mark Probst wrote:

On 5/9/07, Øyvind Kolås wrote:

Not sure what you mean by this, but it should be possible to rig up a channel mixer using the arithmetic operations + component extraction/muxing nodes.

That's what I was thinking, too, but I wonder about the performance of such an approach? Would it be significantly slower than doing it all in one node?

Also: Are there already component extraction/muxing operations?

Component extraction/muxing operations are not already in place, and doing it this way is bound to be significantly slower since it would involve quite a few copies of the data.

I guess I just discovered that the operations list on the GEGL homepage is not complete (at least gray, remap and the bilateral filter are missing). Is there a complete operations list somewhere or do I have to go through the source files to learn what's already there?

The operations on the webpage are the full set of operations compiled and installed by default for the previous release. A website documenting your source tree can be found in docs/operations.html, you can even make that documentation document the work in progress operations in operations/workshop/ by invoking make there, and invoking make in docs/ again.

/Øyvind K.

Mark Probst
2007-05-09 13:08:32 UTC (almost 17 years ago)

Operations that I require

On 5/9/07, Øyvind Kolås wrote:

Component extraction/muxing operations are not already in place, and doing it this way is bound to be significantly slower since it would involve quite a few copies of the data.

Ok, I'll implement a monochrome channel mixer first, then, and bug you again when I'm stuck or done.

and installed by default for the previous release. A website documenting your source tree can be found in docs/operations.html, you can even make that documentation document the work in progress operations in operations/workshop/ by invoking make there, and invoking make in docs/ again.

Thanks a lot!

Mark

Mark Probst
2007-05-10 20:44:41 UTC (almost 17 years ago)

Operations that I require

Hi!

I've already reached the first problem: My operation (the mono channel mixer) takes an RGBA image as input, but produces a YA image. I want to make it a point operation, but I can't use the input buffer as output, so I thought I could set the output buffer using gegl_operation_set_data, but that requires a context id which I don't have. Is there a way to make this a point operation or do I have to implement it as a generic operation?

Mark

Mark Probst
2007-05-10 23:08:42 UTC (almost 17 years ago)

Operations that I require

Ok, so here's my mono mixer, implemented as a generic filter.

Next stop: gradient curves. That'll be a bit more complex...

/* This file is an image processing operation for GEGL *
* GEGL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. *
* GEGL 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 * Lesser General Public License for more details. *
* You should have received a copy of the GNU Lesser General Public * License along with GEGL; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA.
*
* Copyright 2006 Mark Probst
*/

#if GEGL_CHANT_PROPERTIES

gegl_chant_double (red, -10.0, 10.0, 0.5, "Amount of red") gegl_chant_double (green, -10.0, 10.0, 0.25, "Amount of green") gegl_chant_double (blue, -10.0, 10.0, 0.25, "Amount of blue")

#else

#define GEGL_CHANT_FILTER

#define GEGL_CHANT_NAME mono_mixer #define GEGL_CHANT_SELF "mono-mixer.c"

#define GEGL_CHANT_DESCRIPTION "Monochrome channel mixer"

#define GEGL_CHANT_CATEGORIES "color"

#include "gegl-chant.h"

static gboolean process (GeglOperation *operation,
gpointer context_id)
{
GeglChantOperation *self;
GeglBuffer *input;
GeglBuffer *output;
gfloat *in_buf;
gfloat *out_buf;
GeglRectangle *result_rect = gegl_operation_result_rect (operation, context_id);
gfloat red, green, blue;

self = GEGL_CHANT_OPERATION (operation); input = GEGL_BUFFER (gegl_operation_get_data (operation, context_id, "input"));

red = self->red;
green = self->green;
blue = self->blue;

output = g_object_new (GEGL_TYPE_BUFFER, "format", babl_format ("YA float"), "x", result_rect->x,
"y", result_rect->y,
"width", result_rect->width,
"height", result_rect->height,
NULL);

if ((result_rect->width > 0) && (result_rect->height > 0)) {
gint num_pixels = gegl_buffer_pixels (input); gint i;
gfloat *in_pixel, *out_pixel;

in_buf = g_malloc (4 * sizeof (gfloat) * num_pixels); out_buf = g_malloc (2 * sizeof(gfloat) * num_pixels);

gegl_buffer_get (input, result_rect, 1.0, babl_format ("RGBA float"), in_buf);

in_pixel = in_buf; out_pixel = out_buf;
for (i = 0; i < num_pixels; ++i) {
out_pixel[0] = in_pixel[0] * red + in_pixel[1] * green + in_pixel[2] * blue; out_pixel[1] = in_pixel[3];

in_pixel += 4; out_pixel += 2;
}

gegl_buffer_set (output, result_rect, output->format, out_buf);

g_free (in_buf); g_free (out_buf);
}

gegl_operation_set_data (operation, context_id, "output", G_OBJECT (output));

return TRUE; }

#endif

Øyvind Kolås
2007-05-10 23:24:43 UTC (almost 17 years ago)

Operations that I require

On 5/10/07, Mark Probst wrote:

Ok, so here's my mono mixer, implemented as a generic filter.

Looks good, the filter plug-in API headers are not installed yet, this because there will be changes made to it, already there have been changes to the GEGL tree causing your filter not to compile with SVN trunk.

if ((result_rect->width > 0) && (result_rect->height > 0)) {
gint num_pixels = gegl_buffer_pixels (input);

Replace this with:
gint num_pixels = result_rect->width * result_rect->height;

or use: gint num_pixels;
g_object_get (input, "pixels", &num_pixels, NULL);

The function gegl_buffer_pixels was removed as gegl-buffer.h is being prepared to be made more public.

/Øyvind K.