Re: Dissolve blending mode

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

 



Moved to GIMP.

On Sun, Mar 18, 2012 at 9:53 PM, Ville Sokk <ville.sokk@xxxxxxxxx> wrote:
> Dissolve blending mode. The category should be changed, I don't know
> about the compositor categories so I just left it at
> "compositors:math". I tried to follow the way GIMP's dissolve works
> but gegl is obviously different. There's no mask or opacity input like
> in GIMP, I assume masking or gegl:opacity is already done on the
> inputs. Tell me if I need to change something or add those properties.
/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * gimpoperationdissolvemode.c
 * Copyright (C) 2012 Ville Sokk <ville.sokk@xxxxxxxxx>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include <gegl-plugin.h>

#include "gimp-gegl-types.h"

#include "gimpoperationdissolvemode.h"

#include <glib.h>


static gboolean gimp_operation_dissolve_mode_process (GeglOperation       *operation,
                                                      void                *in_buf,
                                                      void                *aux_buf,
                                                      void                *out_buf,
                                                      glong                samples,
                                                      const GeglRectangle *roi);


G_DEFINE_TYPE (GimpOperationDissolveMode, gimp_operation_dissolve_mode,
               GIMP_TYPE_OPERATION_POINT_LAYER_MODE)

#define RANDOM_TABLE_SIZE    4096
static gint32  random_table[RANDOM_TABLE_SIZE];

#define A     (ALPHA)
#define inA   (in[A])
#define inCa  (in[i])
#define layerA  (layer[A])
#define layerC  (layer[A] ? layer[i] / layer[A] : 0.0)
#define outCa (out[i])
#define outA  (out[A])

#define EACH_CHANNEL(expr)            \
        for (i = RED; i < ALPHA; i++) \
          {                           \
            expr;                     \
          }


static void
gimp_operation_dissolve_mode_class_init (GimpOperationDissolveModeClass *klass)
{
  GeglOperationClass              *operation_class;
  GeglOperationPointComposerClass *point_class;

  operation_class = GEGL_OPERATION_CLASS (klass);
  point_class     = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);

  operation_class->name        = "gimp:dissolve-mode";
  operation_class->description = "GIMP dissolve mode operation";

  point_class->process         = gimp_operation_dissolve_mode_process;
}

static void
gimp_operation_dissolve_mode_init (GimpOperationDissolveMode *self)
{
  GRand *gr;
  gint   i;
#define RANDOM_SEED 314159265

    /* generate a table of random seeds */
  gr = g_rand_new_with_seed (RANDOM_SEED);
  for (i = 0; i < RANDOM_TABLE_SIZE; i++)
    {
      random_table[i] = g_rand_int (gr);
    }

  g_rand_free (gr);
}

static gboolean
gimp_operation_dissolve_mode_process (GeglOperation       *operation,
                                      void                *in_buf,
                                      void                *aux_buf,
                                      void                *out_buf,
                                      glong                samples,
                                      const GeglRectangle *roi)
{
  gfloat *in    = in_buf;
  gfloat *layer = aux_buf;
  gfloat *out   = out_buf;
  GRand  *gr = g_rand_new ();
  gint    row, pixel, i;
  gdouble rand_val;
  gint    x = roi->x;
  gint    y = roi->y;
  gint    width = roi->width;
  gint    height = roi->height;

  for (row = 0; row < height; row++)
    {
      gr = g_rand_new_with_seed (random_table[(y + row) % RANDOM_TABLE_SIZE]);
      for (i = 0; i < x; i++)
        {
          g_rand_int (gr);
        }

      for (pixel = 0; pixel < width; pixel++)
        {
          /* dissolve if random value is >= opacity */
          rand_val = g_rand_double_range (gr, 0.0, 1.0);

          if (layerA >= rand_val)
            {
              outA = 1.0;
              EACH_CHANNEL (outCa = layerC);
            }
          else
            {
              outA = inA;
              EACH_CHANNEL (outCa = inCa);
            }

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

      g_rand_free (gr);
    }

  return TRUE;
}
_______________________________________________
gegl-developer-list mailing list
gegl-developer-list@xxxxxxxxx
http://mail.gnome.org/mailman/listinfo/gegl-developer-list

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

  Powered by Linux