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

Making pixel processing color model agnostic

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.

1 of 1 message available
Toggle history

Please log in to manage your subscriptions.

Making pixel processing color model agnostic Øyvind Kolås 18 Sep 17:45
Øyvind Kolås
2004-09-18 17:45:57 UTC (over 19 years ago)

Making pixel processing color model agnostic

GIL is meant to make image processing color- and sample model agnostic, I have my doubts as towards whether such a pre processor is feasible, given the amounts of code that already exist as c code.

The initial approach of GEGL if I understand correctly will be to mandate a floating point version of the image processing, and consider the 8bit version to be an optimization.

I have started moving the processing in some gggl nodes away from the gimp way of implementing color model independence. The gimp model is to check the number of bands.

1 = grayscale 2 = grayscale with alpha
3 = rgb
4 = rgb with alpha

put it in a switch,. and do as appropriate in each case.

In gggl now, I provide a function to calculate a luma_bitmask and an alpha_bitmask for a pixel representation. This allows writing much shorter code.

There are probably other bitmasks that can be extracted in the same manner depending on the components stored in the bands.

The code that follows is the brightness / contrast node currently in gggl, this code shuld work on grayscale, rgb, yuv, lab with and without alpha (it will probably have some slight problems with premultiplied alpha, the easiest solution is to demand only non premultiplied pixel representations for operations like brightness contrast)

--------------------

static inline float op(float in,
float brightness,
float contrast)
{
return ((contrast * (in-0.5)) + 0.5 + brightness); }

static int
process (GgglNodeInstance *ni)
{
Priv *p = ni->priv;
GgglImage *img = ni->in[0];

ni->out[0] = img; if (!img)
return 0;

if (fabs (p->brightness ) < 0.0001 && fabs (1.0-p->contrast) < 0.0001) {

/* just passthrough */

return 0; } else {
/* local variables on stack to avoid extra dereferencing */ float brightness = p->brightness; float contrast = p->contrast; int width = img->width; int height = img->height; int channels = img->channels; unsigned int luma_mask = gggl_pixfmt_luma_bitmask (img->fmt); int y;

for (y = 0; y < height; y++) { int x;
float *pix = (float *) gggl_offset (img, 0, y, 0);

for (x=0; x < width; x++) { int c;
for (c=0; c < channels; c++) {

/* only act if this channel is a lumniosity channel*/ if (luma_mask & (1 << c)) pix[c] = op (pix[c], brightness, contrast);

} pix += channels;
}
}
}
return 0;
}

--------------------

Does anyone have a comment on this approach?

/pippin