static gboolean
gimp_operation_dissolve_mode_process (GeglOperation       *operation,
                                      void                *in_buf,
                                      void                *aux_buf,
                                      void                *aux2_buf,
                                      void                *out_buf,
                                      glong                samples,
                                      const GeglRectangle *result,
                                      gint                 level)
{
  gdouble         opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
  gfloat         *in       = in_buf;
  gfloat         *out      = out_buf;
  gfloat         *aux      = aux_buf;
  gfloat         *mask     = aux2_buf;
  const gboolean  has_mask = mask != NULL;
  gint            x, y;

  for (y = result->y; y < result->y + result->height; y++)
    {
      GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);

      /* fast forward through the rows pseudo random sequence */
      for (x = 0; x < result->x; x++)
        g_rand_int (gr);

      for (x = result->x; x < result->x + result->width; x++)
        {
          gfloat value = aux[ALPHA] * opacity * 255;

          if (has_mask)
            value *= *mask;

          if (g_rand_int_range (gr, 0, 255) >= value)
            {
              out[0] = in[0];
              out[1] = in[1];
              out[2] = in[2];
              out[3] = in[3];
            }
          else
            {
              out[0] = aux[0];
              out[1] = aux[1];
              out[2] = aux[2];
              out[3] = 1.0;
            }

          in   += 4;
          out  += 4;
          aux  += 4;

          if (has_mask)
            mask ++;
        }
      g_rand_free (gr);
    }

  return TRUE;
}
static gboolean
gimp_operation_normal_mode_process (GeglOperation       *operation,
                                    void                *in_buf,
                                    void                *aux_buf,
                                    void                *aux2_buf,
                                    void                *out_buf,
                                    glong                samples,
                                    const GeglRectangle *roi,
                                    gint                 level)
{
  GimpOperationPointLayerMode *point    = GIMP_OPERATION_POINT_LAYER_MODE (operation);
  gdouble                      opacity  = point->opacity;
  gfloat                      *in       = in_buf;
  gfloat                      *aux      = aux_buf;
  gfloat                      *mask     = aux2_buf;
  gfloat                      *out      = out_buf;
  const gboolean               has_mask = mask != NULL;

  while (samples--)
    {
      gfloat aux_alpha;

      aux_alpha = aux[ALPHA] * opacity;
      if (has_mask)
        aux_alpha *= *mask;

      out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];

      if (out[ALPHA])
        {
          gint b;

          for (b = RED; b < ALPHA; b++)
            {
              out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0f - aux_alpha)) / out[ALPHA];
            }
        }
      else
        {
          gint b;

          for (b = RED; b < ALPHA; b++)
            {
              out[b] = in[b];
            }
        }

      in   += 4;
      aux  += 4;
      out  += 4;

      if (has_mask)
        mask++;
    }

  return TRUE;
}
static gboolean
gimp_operation_softlight_mode_process (GeglOperation       *operation,
                                       void                *in_buf,
                                       void                *aux_buf,
                                       void                *aux2_buf,
                                       void                *out_buf,
                                       glong                samples,
                                       const GeglRectangle *roi,
                                       gint                 level)
{
  gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;

  return gimp_operation_softlight_mode_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level);
}
static void
gimp_operation_point_layer_mode_prepare (GeglOperation *operation)
{
  GimpOperationPointLayerMode *self = GIMP_OPERATION_POINT_LAYER_MODE (operation);
  const Babl                  *format;

  if (self->premultiplied)
    format = babl_format ("R'aG'aB'aA float");
  else
    format = babl_format ("R'G'B'A float");

  gegl_operation_set_format (operation, "input",  format);
  gegl_operation_set_format (operation, "output", format);
  gegl_operation_set_format (operation, "aux",    format);
  gegl_operation_set_format (operation, "aux2",   babl_format ("Y float"));
}
static gboolean
gimp_operation_lch_chroma_mode_process (GeglOperation       *operation,
                                        void                *in_buf,
                                        void                *aux_buf,
                                        void                *aux2_buf,
                                        void                *out_buf,
                                        glong                samples,
                                        const GeglRectangle *roi,
                                        gint                 level)
{
  GimpOperationPointLayerMode *gimp_op = GIMP_OPERATION_POINT_LAYER_MODE (operation);
  gfloat                       opacity = gimp_op->opacity;
  gboolean                     linear  = gimp_op->linear;

  return (linear ? gimp_operation_lch_chroma_mode_process_pixels_linear :
                   gimp_operation_lch_chroma_mode_process_pixels)
    (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level);
}
static void
gimp_operation_point_layer_mode_set_property (GObject      *object,
                                              guint         property_id,
                                              const GValue *value,
                                              GParamSpec   *pspec)
{
  GimpOperationPointLayerMode *self = GIMP_OPERATION_POINT_LAYER_MODE (object);

  switch (property_id)
    {
    case PROP_PREMULTIPLIED:
      self->premultiplied = g_value_get_boolean (value);
      break;

    case PROP_OPACITY:
      self->opacity = g_value_get_double (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}
示例#7
0
static gboolean
gimp_operation_value_mode_process (GeglOperation       *operation,
                                   void                *in_buf,
                                   void                *aux_buf,
                                   void                *aux2_buf,
                                   void                *out_buf,
                                   glong                samples,
                                   const GeglRectangle *roi,
                                   gint                 level)
{
  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
  gfloat        *in       = in_buf;
  gfloat        *layer    = aux_buf;
  gfloat        *mask     = aux2_buf;
  gfloat        *out      = out_buf;
  const gboolean has_mask = mask != NULL;

  while (samples--)
    {
      GimpHSV layer_hsv, out_hsv;
      GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
      GimpRGB out_rgb   = {in[0], in[1], in[2]};
      gfloat  comp_alpha, new_alpha;

      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
      if (has_mask)
        comp_alpha *= *mask;

      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;

      if (comp_alpha && new_alpha)
        {
          gint   b;
          gfloat ratio = comp_alpha / new_alpha;

          gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
          gimp_rgb_to_hsv (&out_rgb, &out_hsv);

          out_hsv.v = layer_hsv.v;
          gimp_hsv_to_rgb (&out_hsv, &out_rgb);

          out[0] = out_rgb.r;
          out[1] = out_rgb.g;
          out[2] = out_rgb.b;

          for (b = RED; b < ALPHA; b++)
            {
              out[b] = out[b] * ratio + in[b] * (1.0 - ratio);
            }
        }
      else
        {
          gint b;

          for (b = RED; b < ALPHA; b++)
            {
              out[b] = in[b];
            }
        }

      out[ALPHA] = in[ALPHA];

      in    += 4;
      layer += 4;
      out   += 4;

      if (has_mask)
        mask++;
    }

  return TRUE;
}
示例#8
0
static gboolean
gimp_operation_behind_mode_process (GeglOperation       *operation,
                                    void                *in_buf,
                                    void                *aux_buf,
                                    void                *aux2_buf,
                                    void                *out_buf,
                                    glong                samples,
                                    const GeglRectangle *roi,
                                    gint                 level)
{
  GimpOperationPointLayerMode *point    = GIMP_OPERATION_POINT_LAYER_MODE (operation);
  gdouble                      opacity  = point->opacity;
  gfloat                      *in       = in_buf;
  gfloat                      *layer    = aux_buf;
  gfloat                      *mask     = aux2_buf;
  gfloat                      *out      = out_buf;
  const gboolean               has_mask = mask != NULL;

  if (point->premultiplied)
    {
      while (samples--)
        {
          gint    b;
          gdouble value = opacity;

          if (has_mask)
            value *= *mask;

          for (b = RED; b <= ALPHA; b++)
            {
              out[b] = in[b] + layer[b] * value * (1.0 - in[ALPHA]);
            }

          in    += 4;
          layer += 4;
          out   += 4;

          if (has_mask)
            mask++;
        }
    }
  else
    {
      while (samples--)
        {
          gint    b;
          gdouble value = opacity;

          if (has_mask)
            value *= *mask;

          out[ALPHA] = in[ALPHA] + (1.0 - in[ALPHA]) * layer[ALPHA] * value;

          if (out[ALPHA])
            {
              for (b = RED; b < ALPHA; b++)
                {
                  out[b] = (in[b] * in[ALPHA] + layer[b] * value * layer[ALPHA] * value * (1.0 - in[ALPHA])) / out[ALPHA];
                }
            }
          else
            {
              for (b = RED; b <= ALPHA; b++)
                {
                  out[b] = in[b];
                }
            }

          in    += 4;
          layer += 4;
          out   += 4;

          if (has_mask)
            mask++;
        }
    }

  return TRUE;
}
static gboolean
gimp_operation_hardlight_mode_process (GeglOperation       *operation,
                                       void                *in_buf,
                                       void                *aux_buf,
                                       void                *aux2_buf,
                                       void                *out_buf,
                                       glong                samples,
                                       const GeglRectangle *roi,
                                       gint                 level)
{
  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
  gfloat        *in       = in_buf;
  gfloat        *layer    = aux_buf;
  gfloat        *mask     = aux2_buf;
  gfloat        *out      = out_buf;
  const gboolean has_mask = mask != NULL;

  while (samples--)
    {
      gfloat comp_alpha, new_alpha;

      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
      if (has_mask)
        comp_alpha *= *mask;

      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;

      if (comp_alpha && new_alpha)
        {
          gfloat ratio = comp_alpha / new_alpha;
          gint   b;

          for (b = RED; b < ALPHA; b++)
            {
              gfloat comp;

              if (layer[b] > 0.5)
                {
                  comp = (1.0 - in[b]) * (1.0 - (layer[b] - 0.5) * 2.0);
                  comp = MIN (1 - comp, 1);
                }
              else
                {
                  comp = in[b] * (layer[b] * 2.0);
                  comp = MIN (comp, 1.0);
                }

              out[b] = comp * ratio + in[b] * (1.0 - ratio);
            }
        }
      else
        {
          gint b;

          for (b = RED; b < ALPHA; b++)
            {
              out[b] = in[b];
            }
        }

      out[ALPHA] = in[ALPHA];

      in    += 4;
      layer += 4;
      out   += 4;

      if (has_mask)
        mask ++;
    }

  return TRUE;
}
static gboolean
gimp_operation_replace_mode_process (GeglOperation       *operation,
                                     void                *in_buf,
                                     void                *aux_buf,
                                     void                *aux2_buf,
                                     void                *out_buf,
                                     glong                samples,
                                     const GeglRectangle *roi,
                                     gint                 level)
{
  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
  gfloat                       opacity = point->opacity;
  gfloat                      *in      = in_buf;
  gfloat                      *layer   = aux_buf;
  gfloat                      *mask    = aux2_buf;
  gfloat                      *out     = out_buf;

  while (samples--)
    {
      gint   b;
      gfloat new_alpha;

      if (mask)
        new_alpha = (layer[ALPHA] - in[ALPHA]) * (*mask) * opacity + in[ALPHA];
      else
        new_alpha = (layer[ALPHA] - in[ALPHA]) * opacity + in[ALPHA];

      if (new_alpha)
        {
          gfloat ratio;

          if (mask)
            ratio = *mask * opacity * layer[ALPHA] / new_alpha;
          else
            ratio = opacity * layer[ALPHA] / new_alpha;

          for (b = RED; b < ALPHA; b++)
            {
              gfloat t;

              if (layer[b] > in[b])
                {
                  t = (layer[b] - in[b]) * ratio;
                  out[b] = in[b] + t;
                }
              else
                {
                  t = (in[b] - layer[b]) * ratio;
                  out[b] = in[b] - t;
                }
            }
        }
      else
        {
          for (b = RED; b < ALPHA; b++)
            out[b] = in[b];
        }

      out[ALPHA] = new_alpha;

      in    += 4;
      layer += 4;
      out   += 4;

      if (mask)
        mask += 1;
    }

  return TRUE;
}