[Gegl-developer] Making pixel processing color model agnostic

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

 



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



[Index of Archives]     [Yosemite News]     [Yosemite Photos]     [gtk]     [GIMP Users]     [KDE]     [Gimp's Home]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux