static gboolean
gimp_operation_posterize_process (GeglOperation       *operation,
                                  void                *in_buf,
                                  void                *out_buf,
                                  glong                samples,
                                  const GeglRectangle *roi,
                                  gint                 level)
{
  GimpOperationPointFilter *point  = GIMP_OPERATION_POINT_FILTER (operation);
  GimpPosterizeConfig      *config = GIMP_POSTERIZE_CONFIG (point->config);
  gfloat                   *src    = in_buf;
  gfloat                   *dest   = out_buf;
  gfloat                    levels;

  if (! config)
    return FALSE;

  levels = config->levels - 1.0;

  while (samples--)
    {
      dest[RED]   = RINT (src[RED]   * levels) / levels;
      dest[GREEN] = RINT (src[GREEN] * levels) / levels;
      dest[BLUE]  = RINT (src[BLUE]  * levels) / levels;
      dest[ALPHA] = src[ALPHA];

      src  += 4;
      dest += 4;
    }

  return TRUE;
}
static gboolean
gimp_operation_colorize_process (GeglOperation       *operation,
                                 void                *in_buf,
                                 void                *out_buf,
                                 glong                samples,
                                 const GeglRectangle *roi,
                                 gint                 level)
{
  GimpOperationPointFilter *point  = GIMP_OPERATION_POINT_FILTER (operation);
  GimpColorizeConfig       *config = GIMP_COLORIZE_CONFIG (point->config);
  gfloat                   *src    = in_buf;
  gfloat                   *dest   = out_buf;
  GimpHSL                   hsl;

  if (! config)
    return FALSE;

  hsl.h = config->hue;
  hsl.s = config->saturation;
  hsl.a = src[ALPHA];

  while (samples--)
    {
      GimpRGB rgb;
      gfloat  lum = GIMP_RGB_LUMINANCE (src[RED],
                                        src[GREEN],
                                        src[BLUE]);

      if (config->lightness > 0)
        {
          lum = lum * (1.0 - config->lightness);

          lum += 1.0 - (1.0 - config->lightness);
        }
      else if (config->lightness < 0)
        {
          lum = lum * (config->lightness + 1.0);
        }

      hsl.l = lum;

      gimp_hsl_to_rgb (&hsl, &rgb);

      /*  the code in base/colorize.c would multiply r,b,g with lum,
       *  but this is a bug since it should multiply with 255. We
       *  don't repeat this bug here (this is the reason why the gegl
       *  colorize is brighter than the legacy one).
       */
      dest[RED]   = rgb.r; /* * lum; */
      dest[GREEN] = rgb.g; /* * lum; */
      dest[BLUE]  = rgb.b; /* * lum */;
      dest[ALPHA] = rgb.a;

      src  += 4;
      dest += 4;
    }

  return TRUE;
}
static gboolean
gimp_operation_brightness_contrast_process (GeglOperation       *operation,
        void                *in_buf,
        void                *out_buf,
        glong                samples,
        const GeglRectangle *roi,
        gint                 level)
{
    GimpOperationPointFilter     *point  = GIMP_OPERATION_POINT_FILTER (operation);
    GimpBrightnessContrastConfig *config = GIMP_BRIGHTNESS_CONTRAST_CONFIG (point->config);
    gfloat                       *src    = in_buf;
    gfloat                       *dest   = out_buf;
    gdouble                       brightness;
    gdouble                       slant;

    if (! config)
        return FALSE;

    brightness = config->brightness / 2.0;
    slant = tan ((config->contrast + 1) * G_PI_4);

    while (samples--)
    {
        dest[RED] = gimp_operation_brightness_contrast_map (src[RED],
                    brightness,
                    slant);
        dest[GREEN] = gimp_operation_brightness_contrast_map (src[GREEN],
                      brightness,
                      slant);
        dest[BLUE] = gimp_operation_brightness_contrast_map (src[BLUE],
                     brightness,
                     slant);
        dest[ALPHA] = src[ALPHA];

        src  += 4;
        dest += 4;
    }

    return TRUE;
}
Example #4
0
static gboolean
gimp_operation_curves_process (GeglOperation       *operation,
                               void                *in_buf,
                               void                *out_buf,
                               glong                samples,
                               const GeglRectangle *roi)
{
  GimpOperationPointFilter *point  = GIMP_OPERATION_POINT_FILTER (operation);
  GimpCurvesConfig         *config = GIMP_CURVES_CONFIG (point->config);
  gfloat                   *src    = in_buf;
  gfloat                   *dest   = out_buf;

  if (! config)
    return FALSE;

  gimp_curve_map_pixels (config->curve[0],
                         config->curve[1],
                         config->curve[2],
                         config->curve[3],
                         config->curve[4], src, dest, samples);

  return TRUE;
}
static gboolean
gimp_operation_hue_saturation_process (GeglOperation       *operation,
                                       void                *in_buf,
                                       void                *out_buf,
                                       glong                samples,
                                       const GeglRectangle *roi)
{
  GimpOperationPointFilter *point  = GIMP_OPERATION_POINT_FILTER (operation);
  GimpHueSaturationConfig  *config = GIMP_HUE_SATURATION_CONFIG (point->config);
  gfloat                   *src    = in_buf;
  gfloat                   *dest   = out_buf;
  gfloat                    overlap;

  if (! config)
    return FALSE;

  overlap = config->overlap / 2.0;

  while (samples--)
    {
      GimpRGB  rgb;
      GimpHSL  hsl;
      gdouble  h;
      gint     hue_counter;
      gint     hue                 = 0;
      gint     secondary_hue       = 0;
      gboolean use_secondary_hue   = FALSE;
      gfloat   primary_intensity   = 0.0;
      gfloat   secondary_intensity = 0.0;

      rgb.r = src[RED];
      rgb.g = src[GREEN];
      rgb.b = src[BLUE];

      gimp_rgb_to_hsl (&rgb, &hsl);

      h = hsl.h * 6.0;

      for (hue_counter = 0; hue_counter < 7; hue_counter++)
        {
          gdouble hue_threshold = (gdouble) hue_counter + 0.5;

          if (h < ((gdouble) hue_threshold + overlap))
            {
              hue = hue_counter;

              if (overlap > 0.0 && h > ((gdouble) hue_threshold - overlap))
                {
                  use_secondary_hue = TRUE;

                  secondary_hue = hue_counter + 1;

                  secondary_intensity =
                    (h - (gdouble) hue_threshold + overlap) / (2.0 * overlap);

                  primary_intensity = 1.0 - secondary_intensity;
                }
              else
                {
                  use_secondary_hue = FALSE;
                }

              break;
            }
        }

      if (hue >= 6)
        {
          hue = 0;
          use_secondary_hue = FALSE;
        }

      if (secondary_hue >= 6)
        {
          secondary_hue = 0;
        }

      /*  transform into GimpHueRange values  */
      hue++;
      secondary_hue++;

      if (use_secondary_hue)
        {
          gdouble mapped_primary_hue;
          gdouble mapped_secondary_hue;
          gdouble diff;

          mapped_primary_hue   = map_hue (config, hue,           hsl.h);
          mapped_secondary_hue = map_hue (config, secondary_hue, hsl.h);

          /* Find nearest hue on the circle between primary and
           * secondary hue
           */
          diff = mapped_primary_hue - mapped_secondary_hue;
          if (diff < -0.5)
            {
              mapped_secondary_hue -= 1.0;
            }
          else if (diff >= 0.5)
            {
              mapped_secondary_hue += 1.0;
            }

          hsl.h = (mapped_primary_hue   * primary_intensity +
                   mapped_secondary_hue * secondary_intensity);

          hsl.s = (map_saturation (config, hue,           hsl.s) * primary_intensity +
                   map_saturation (config, secondary_hue, hsl.s) * secondary_intensity);

          hsl.l = (map_lightness (config, hue,           hsl.l) * primary_intensity +
                   map_lightness (config, secondary_hue, hsl.l) * secondary_intensity);
        }
      else
        {
          hsl.h = map_hue        (config, hue, hsl.h);
          hsl.s = map_saturation (config, hue, hsl.s);
          hsl.l = map_lightness  (config, hue, hsl.l);
        }

      gimp_hsl_to_rgb (&hsl, &rgb);

      dest[RED]   = rgb.r;
      dest[GREEN] = rgb.g;
      dest[BLUE]  = rgb.b;
      dest[ALPHA] = src[ALPHA];

      src  += 4;
      dest += 4;
    }

  return TRUE;
}
static gboolean
gimp_operation_color_balance_process (GeglOperation       *operation,
                                      void                *in_buf,
                                      void                *out_buf,
                                      glong                samples,
                                      const GeglRectangle *roi,
                                      gint                 level)
{
  GimpOperationPointFilter *point  = GIMP_OPERATION_POINT_FILTER (operation);
  GimpColorBalanceConfig   *config = GIMP_COLOR_BALANCE_CONFIG (point->config);
  gfloat                   *src    = in_buf;
  gfloat                   *dest   = out_buf;

  if (! config)
    return FALSE;

  while (samples--)
    {
      gfloat r = src[RED];
      gfloat g = src[GREEN];
      gfloat b = src[BLUE];
      gfloat r_n;
      gfloat g_n;
      gfloat b_n;

      GimpRGB rgb = { r, g, b};
      GimpHSL hsl;

      gimp_rgb_to_hsl (&rgb, &hsl);

      r_n = gimp_operation_color_balance_map (r, hsl.l,
                                              config->cyan_red[GIMP_SHADOWS],
                                              config->cyan_red[GIMP_MIDTONES],
                                              config->cyan_red[GIMP_HIGHLIGHTS]);

      g_n = gimp_operation_color_balance_map (g, hsl.l,
                                              config->magenta_green[GIMP_SHADOWS],
                                              config->magenta_green[GIMP_MIDTONES],
                                              config->magenta_green[GIMP_HIGHLIGHTS]);

      b_n = gimp_operation_color_balance_map (b, hsl.l,
                                              config->yellow_blue[GIMP_SHADOWS],
                                              config->yellow_blue[GIMP_MIDTONES],
                                              config->yellow_blue[GIMP_HIGHLIGHTS]);

      if (config->preserve_luminosity)
        {
          GimpHSL hsl2;

          rgb.r = r_n;
          rgb.g = g_n;
          rgb.b = b_n;
          gimp_rgb_to_hsl (&rgb, &hsl);

          rgb.r = r;
          rgb.g = g;
          rgb.b = b;
          gimp_rgb_to_hsl (&rgb, &hsl2);

          hsl.l = hsl2.l;

          gimp_hsl_to_rgb (&hsl, &rgb);

          r_n = rgb.r;
          g_n = rgb.g;
          b_n = rgb.b;
        }

      dest[RED]   = r_n;
      dest[GREEN] = g_n;
      dest[BLUE]  = b_n;
      dest[ALPHA] = src[ALPHA];

      src  += 4;
      dest += 4;
    }

  return TRUE;
}
static gboolean
gimp_operation_desaturate_process (GeglOperation       *operation,
                                   void                *in_buf,
                                   void                *out_buf,
                                   glong                samples,
                                   const GeglRectangle *roi,
                                   gint                 level)
{
  GimpOperationPointFilter *point  = GIMP_OPERATION_POINT_FILTER (operation);
  GimpDesaturateConfig     *config = GIMP_DESATURATE_CONFIG (point->config);
  gfloat                   *src    = in_buf;
  gfloat                   *dest   = out_buf;

  if (! config)
    return FALSE;

  switch (config->mode)
    {
    case GIMP_DESATURATE_LIGHTNESS:
      while (samples--)
        {
          gfloat min, max, value;

          max = MAX (src[0], src[1]);
          max = MAX (max, src[2]);
          min = MIN (src[0], src[1]);
          min = MIN (min, src[2]);

          value = (max + min) / 2;

          dest[0] = value;
          dest[1] = value;
          dest[2] = value;
          dest[3] = src[3];

          src  += 4;
          dest += 4;
        }
      break;

    case GIMP_DESATURATE_LUMINOSITY:
      while (samples--)
        {
          gfloat value = GIMP_RGB_LUMINANCE (src[0], src[1], src[2]);

          dest[0] = value;
          dest[1] = value;
          dest[2] = value;
          dest[3] = src[3];

          src  += 4;
          dest += 4;
        }
      break;

    case GIMP_DESATURATE_AVERAGE:
      while (samples--)
        {
          gfloat value = (src[0] + src[1] + src[2]) / 3;

          dest[0] = value;
          dest[1] = value;
          dest[2] = value;
          dest[3] = src[3];

          src  += 4;
          dest += 4;
        }
      break;
    }

  return TRUE;
}