Пример #1
0
/**
 * gimp_drawable_get:
 * @drawable_ID: the ID of the drawable
 *
 * This function creates a #GimpDrawable structure for the core
 * drawable identified by @drawable_ID. The returned structure
 * contains some basic information about the drawable and can also
 * hold tile data for transfer to and from the core.
 *
 * Note that the name of this function is somewhat misleading, because
 * it suggests that it simply returns a handle.  This is not the case:
 * if the function is called multiple times, it creates separate tile
 * lists each time, which will usually produce undesired results.
 *
 * When a plug-in has finished working with a drawable, before exiting
 * it should call gimp_drawable_detach() to make sure that all tile data is
 * transferred back to the core.
 *
 * Return value: a new #GimpDrawable wrapper
 **/
GimpDrawable *
gimp_drawable_get (gint32 drawable_ID)
{
  GimpDrawable *drawable;
  gint          width;
  gint          height;
  gint          bpp;

  width  = gimp_drawable_width  (drawable_ID);
  height = gimp_drawable_height (drawable_ID);
  bpp    = gimp_drawable_bpp    (drawable_ID);

  g_return_val_if_fail (width > 0 && height > 0 && bpp > 0, NULL);

  drawable = g_slice_new0 (GimpDrawable);

  drawable->drawable_id  = drawable_ID;
  drawable->width        = width;
  drawable->height       = height;
  drawable->bpp          = bpp;
  drawable->ntile_rows   = (height + TILE_HEIGHT - 1) / TILE_HEIGHT;
  drawable->ntile_cols   = (width  + TILE_WIDTH  - 1) / TILE_WIDTH;

  return drawable;
}
Пример #2
0
static void
preview_update (GtkWidget *widget)
{
  GimpPixelRgn  src_rgn;        /* Source image region */
  guchar       *dst;            /* Output image */
  GimpPreview  *preview;        /* The preview widget */
  guchar       *src;            /* Source pixel rows */
  gint          img_bpp;
  gint          x1,y1;
  gint          width, height;

  preview = GIMP_PREVIEW (widget);

  img_bpp = gimp_drawable_bpp (drawable->drawable_id);

  width  = preview->width;
  height = preview->height;

  gimp_preview_get_position (preview, &x1, &y1);

  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE);

  dst = g_new (guchar, width * height * img_bpp);
  src = g_new (guchar, width * height * img_bpp);

  gimp_pixel_rgn_get_rect (&src_rgn, src, x1, y1, width, height);

  despeckle_median (src, dst, width, height, img_bpp, despeckle_radius, TRUE);

  gimp_preview_draw_buffer (preview, dst, width * img_bpp);

  g_free (src);
  g_free (dst);
}
Пример #3
0
static gboolean
preview_event_handler (GtkWidget *area,
                       GdkEvent  *event,
                       GtkWidget *preview)
{
  gint            pos;
  guchar         *buf;
  guint32         drawable_id;
  GimpRGB         color;
  GdkEventButton *button_event = (GdkEventButton *)event;

  buf = GIMP_PREVIEW_AREA (area)->buf;
  drawable_id = GIMP_DRAWABLE_PREVIEW (preview)->drawable->drawable_id;

  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
      if (button_event->button == 2)
        {
          pos = event->button.x * gimp_drawable_bpp (drawable_id) +
                event->button.y * GIMP_PREVIEW_AREA (area)->rowstride;

          gimp_rgb_set_uchar (&color, buf[pos], buf[pos + 1], buf[pos + 2]);
          gimp_color_button_set_color (GIMP_COLOR_BUTTON (from_colorbutton),
                                       &color);
        }
      break;

   default:
      break;
    }

  return FALSE;
}
Пример #4
0
static void getrange  (GimpDrawable     *drawable, guchar *mintab, guchar *maxtab,  gint x1, gint y1, gint x2, gint y2)
{
    gint         i, j, k, channels;
    GimpPixelRgn rgn_in;
    guchar      *inrow;

  channels = gimp_drawable_bpp (drawable->drawable_id);

  gimp_pixel_rgn_init (&rgn_in,   drawable,   x1, y1,   x2 - x1, y2 - y1,  FALSE, FALSE);  

   inrow = g_new (guchar, channels * (x2 - x1));
 
  for (j = 0; j < 4; j++){
	mintab[j]=255;
	maxtab[j]=0;
  }
  for (i = y1; i < y2; i++)
     {
         /* Get row i */
         gimp_pixel_rgn_get_row (&rgn_in, inrow, x1, i, x2 - x1);
         for (j = x1; j < x2; j++)
           {
              for (k = 0; k < channels; k++){
                  mintab[k]=MIN ( inrow[channels * (j - x1) + k], mintab[k] ) ;
                  maxtab[k]=MAX ( inrow[channels * (j - x1) + k], maxtab[k] ) ;
              }
	   }
     }
  g_free (inrow);
}
Пример #5
0
void
precompute_init (gint w,
                 gint h)
{
  gint n;
  gint bpp=1;

  xstep = 1.0 / (gdouble) width;
  ystep = 1.0 / (gdouble) height;

  pre_w = w;
  pre_h = h;

  for (n = 0; n < 3; n++)
    {
      if (vertex_normals[n] != NULL)
        g_free (vertex_normals[n]);
      if (heights[n] != NULL)
        g_free (heights[n]);

      heights[n] = g_new (gdouble, w);
      vertex_normals[n] = g_new (GimpVector3, w);
    }

  for (n = 0; n < 2; n++)
    if (triangle_normals[n] != NULL)
      g_free (triangle_normals[n]);

  if (bumprow != NULL)
    {
      g_free (bumprow);
      bumprow = NULL;
    }
  if (mapvals.bumpmap_id != -1)
    {
      bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
    }

  bumprow = g_new (guchar, w * bpp);

  triangle_normals[0] = g_new (GimpVector3, (w << 1) + 2);
  triangle_normals[1] = g_new (GimpVector3, (w << 1) + 2);

  for (n = 0; n < (w << 1) + 1; n++)
    {
      gimp_vector3_set (&triangle_normals[0][n], 0.0, 0.0, 1.0);
      gimp_vector3_set (&triangle_normals[1][n], 0.0, 0.0, 1.0);
    }

  for (n = 0; n < w; n++)
    {
      gimp_vector3_set (&vertex_normals[0][n], 0.0, 0.0, 1.0);
      gimp_vector3_set (&vertex_normals[1][n], 0.0, 0.0, 1.0);
      gimp_vector3_set (&vertex_normals[2][n], 0.0, 0.0, 1.0);
      heights[0][n] = 0.0;
      heights[1][n] = 0.0;
      heights[2][n] = 0.0;
    }
}
Пример #6
0
static void
preview_update_preview (GimpPreview  *preview,
                        GimpDrawable *drawable)
{
  gint          x1, y1;
  gint          width, height;
  gint          bpp;
  guchar       *buffer;
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  preview_rgn;
  gint32        image_id, src_image_id;
  gint32        preview_id;
  GimpDrawable *preview_drawable;

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  buffer = g_new (guchar, width * height * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_get_rect (&src_rgn, buffer,
                           x1, y1, width, height);

  /* set up gimp drawable for rendering preview into */
  src_image_id = gimp_drawable_get_image (drawable->drawable_id);
  image_id = gimp_image_new (width, height,
                             gimp_image_base_type (src_image_id));
  preview_id = gimp_layer_new (image_id, "preview", width, height,
                               gimp_drawable_type (drawable->drawable_id),
                               100,
                               GIMP_NORMAL_MODE);
  preview_drawable = gimp_drawable_get (preview_id);
  gimp_image_add_layer (image_id, preview_id, 0);
  gimp_layer_set_offsets (preview_id, 0, 0);
  gimp_pixel_rgn_init (&preview_rgn, preview_drawable,
                       0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&preview_rgn, buffer,
                           0, 0, width, height);
  gimp_drawable_flush (preview_drawable);
  gimp_drawable_merge_shadow (preview_id, TRUE);
  gimp_drawable_update (preview_id, 0, 0, width, height);

  dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE);

  gimp_pixel_rgn_get_rect (&preview_rgn, buffer,
                           0, 0, width, height);

  gimp_preview_draw_buffer (preview, buffer, width * bpp);

  gimp_image_delete (image_id);
  g_free (buffer);
}
static gboolean
sel2path (gint32 image_ID)
{
  gint32                   selection_ID;
  GimpDrawable            *sel_drawable;
  pixel_outline_list_type  olt;
  spline_list_array_type   splines;

  gimp_selection_bounds (image_ID, &has_sel,
                         &sel_x1, &sel_y1, &sel_x2, &sel_y2);

  sel_width  = sel_x2 - sel_x1;
  sel_height = sel_y2 - sel_y1;

  /* Now get the selection channel */

  selection_ID = gimp_image_get_selection (image_ID);

  if (selection_ID < 0)
    return FALSE;

  sel_drawable = gimp_drawable_get (selection_ID);

  if (gimp_drawable_bpp (selection_ID) != 1)
    {
      g_warning ("Internal error. Selection bpp > 1");
      return FALSE;
    }

  gimp_pixel_rgn_init (&selection_rgn, sel_drawable,
                       sel_x1, sel_y1, sel_width, sel_height,
                       FALSE, FALSE);

  gimp_tile_cache_ntiles (2 * (sel_drawable->width + gimp_tile_width () - 1) /
                          gimp_tile_width ());

  olt = find_outline_pixels ();

  splines = fitted_splines (olt);

  do_points (splines, image_ID);

  gimp_drawable_detach (sel_drawable);

  gimp_displays_flush ();

  return TRUE;
}
static gint32 load_raw(
    char*            filename,
    FILE*            file,
    enum             pix_fmt fmt,
    struct raw_data* img_data,
    const gchar*     plugin_name
) {
    gint nr_chls;
    gint x, y;
    gint32 img;
    gint32 layer;
    GimpDrawable* drawable;
    GimpPixelRgn pixel_rgn;
    guchar *pix_row;

    guint width = img_data->size[0];
    guint height = img_data->size[1];
    if (width <= 0 || height <= 0) {
	return ERROR;
    }
    img = create_new_image(filename, NULL, width, height, GIMP_RGB, &layer,
						    &drawable, &pixel_rgn);
    nr_chls = gimp_drawable_bpp(drawable->drawable_id);
    pix_row = g_new(guchar, nr_chls * width);
    x = 0;
    y = 0;
    while (1) {
        guchar rgb[3];
	if (read_rgb_pixel(file, fmt, rgb) == ERROR)
	    return ERROR;
	pix_row[nr_chls * x]     = rgb[IDX_RED];
	pix_row[nr_chls * x + 1] = rgb[IDX_GREEN];
	pix_row[nr_chls * x + 2] = rgb[IDX_BLUE];
	x++;
	if (x == width) {
	    gimp_pixel_rgn_set_row(&pixel_rgn, pix_row, 0, y, width);
	    x = 0;
	    y++;
	}
	if (y == height) break;
    }
    if (fgetc(file) != EOF) {
	printf("%s: warning: file contains more data\n", plugin_name);
    }

    return img;
}
Пример #9
0
/*
  Returns NGRADSAMPLES samples of active gradient.
  Each sample has (gimp_drawable_bpp (drawable_id)) bytes.
  "ripped" from gradmap.c.
 */
static guchar *
get_gradient_samples (gint32    drawable_id,
                      gboolean  reverse)
{
  gchar   *gradient_name;
  gint     n_f_samples;
  gdouble *f_samples, *f_samp;    /* float samples */
  guchar  *b_samples, *b_samp;    /* byte samples */
  gint     bpp, color, has_alpha, alpha;
  gint     i, j;

  gradient_name = gimp_context_get_gradient ();

  gimp_gradient_get_uniform_samples (gradient_name, NGRADSAMPLES, reverse,
                                     &n_f_samples, &f_samples);

  g_free (gradient_name);

  bpp       = gimp_drawable_bpp (drawable_id);
  color     = gimp_drawable_is_rgb (drawable_id);
  has_alpha = gimp_drawable_has_alpha (drawable_id);
  alpha     = (has_alpha ? bpp - 1 : bpp);

  b_samples = g_new (guchar, NGRADSAMPLES * bpp);

  for (i = 0; i < NGRADSAMPLES; i++)
    {
      b_samp = &b_samples[i * bpp];
      f_samp = &f_samples[i * 4];

      if (color)
        for (j = 0; j < 3; j++)
          b_samp[j] = f_samp[j] * 255;
      else
        b_samp[0] = GIMP_RGB_LUMINANCE (f_samp[0], f_samp[1], f_samp[2]) * 255;

      if (has_alpha)
        b_samp[alpha] = f_samp[3] * 255;
    }

  g_free (f_samples);

  return b_samples;
}
Пример #10
0
static void blur (GimpDrawable *drawable) {
	gint i, j, k, channels;
	gint x1, y1, x2, y2;
	GimpPixelRgn rgn_in, rgn_out;
	guchar *row1, *row2, *row3;
	guchar *outrow;

	gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
	channels = gimp_drawable_bpp (drawable->drawable_id);

	gimp_pixel_rgn_init (&rgn_in, drawable, x1, y1, x2 - x1, y2 - y1, FALSE, FALSE);
	gimp_pixel_rgn_init (&rgn_out, drawable, x1, y1, x2 - x1, y2 - y1, TRUE, TRUE);

	/* Initialise enough memory for row1, row2, row3, outrow */
	row1 = g_new (guchar, channels * (x2 - x1));
	outrow = g_new (guchar, channels * (x2 - x1));

	for (i = y1; i < y2; i++) {
		/* Get row i-1, i, i+1 */
		gimp_pixel_rgn_get_row (&rgn_in, row1, x1, MAX (y1, i - 1), x2 - x1);

		for (j = x1; j < x2; j++) {
			/* For each layer, compute the average of the nine pixels */
			for (k = 0; k < channels; k++) {
				int in = row1[channels * (j - x1) + k];
				int a = (1.0 - (in / 255.0)) * 100.0;
				int r = rand() % 100;
				outrow[channels * (j - x1) + k] = r < a ? 0 : 255;
			}
		}

		gimp_pixel_rgn_set_row (&rgn_out, outrow, x1, i, x2 - x1);

		if (i % 10 == 0)
			gimp_progress_update ((gdouble) (i - y1) / (gdouble) (y2 - y1));
	}

	g_free (row1);
	g_free (outrow);

	gimp_drawable_flush (drawable);
	gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
	gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1);
}
Пример #11
0
static int
pf_init(PyGimpPixelFetcher *self, PyObject *args, PyObject *kwargs)
{
    PyGimpDrawable *drw;
    gboolean shadow = FALSE;
    GimpRGB bg_color = { 0.0, 0.0, 0.0, 1.0 };
    GimpPixelFetcherEdgeMode edge_mode = GIMP_PIXEL_FETCHER_EDGE_NONE;
    static char *kwlist[] = { "drawable", "shadow", "bg_color", "edge_mode",
	                      NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O!|iO&i:gimp.PixelFetcher.__init__",
                                     kwlist,
                                     &PyGimpDrawable_Type, &drw, &shadow,
                                     pygimp_rgb_from_pyobject, &bg_color,
                                     &edge_mode))
        return -1;

    if(!drw->drawable)
        drw->drawable = gimp_drawable_get(drw->ID);

    self->pf = gimp_pixel_fetcher_new(drw->drawable, shadow);

    Py_INCREF(drw);
    self->drawable = drw;

    self->shadow = shadow;
    self->bg_color = bg_color;
    self->edge_mode = edge_mode;

    self->bpp = gimp_drawable_bpp(drw->drawable->drawable_id);

    gimp_pixel_fetcher_set_bg_color(self->pf, &bg_color);
    gimp_pixel_fetcher_set_edge_mode(self->pf, edge_mode);

    return 0;
}
Пример #12
0
static void
despeckle (void)
{
  GimpPixelRgn  src_rgn;        /* Source image region */
  GimpPixelRgn  dst_rgn;
  guchar       *src;
  guchar       *dst;
  gint          img_bpp;
  gint          x, y;
  gint          width, height;

  img_bpp = gimp_drawable_bpp (drawable->drawable_id);

  if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                      &x, &y, &width, &height))
    return;

  gimp_pixel_rgn_init (&src_rgn, drawable, x, y, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dst_rgn, drawable, x, y, width, height, TRUE, TRUE);

  src = g_new (guchar, width * height * img_bpp);
  dst = g_new (guchar, width * height * img_bpp);

  gimp_pixel_rgn_get_rect (&src_rgn, src, x, y, width, height);

  despeckle_median (src, dst, width, height, img_bpp, despeckle_radius, FALSE);

  gimp_pixel_rgn_set_rect (&dst_rgn, dst, x, y, width, height);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x, y, width, height);

  g_free (dst);
  g_free (src);
}
Пример #13
0
static void
exponential (GimpDrawable *drawable)
{
  gint         i, j, k, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;
  guchar       output[4];

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       TRUE, TRUE);

  /*
  guchar minp[4],maxp[4];
  for (j = 0; j < 4; j++){
	minp[j]=255;
	maxp[j]=0;
  }
  for (i = x1; i < x2; i++){
      for (j = y1; j < y2; j++){
          guchar pixel[4];
          gimp_pixel_rgn_get_pixel (&rgn_in, pixel, i, j);
          for (k = 0; k < channels; k++){
		if(minp[k]>pixel[k]) minp[k]=pixel[k];
		if(maxp[k]<pixel[k]) maxp[k]=pixel[k];
          }
  } }
  */

  for (i = x1; i < x2; i++)
    {
      for (j = y1; j < y2; j++)
        {
/*          guchar pixel[9][4];   */
          guchar pixel[4];

          /* Get ONE pixel */
       /* gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[0],
                                    MAX (i - 1, x1), MAX (j - 1, y1));
          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[1],
                                    MAX (i - 1, x1), j);
          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[2],
                                    MAX (i - 1, x1), MIN (j + 1, y2 - 1));

          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[3],
                                    i, MAX (j - 1, y1));  */
          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel, /*[4]*/
                                    i, j);
       /*  gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[5],
                                    i, MIN (j + 1, y2 - 1));

          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[6],
                                    MIN (i + 1, x2 - 1), MAX (j - 1, y1));
          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[7],
                                    MIN (i + 1, x2 - 1), j);
          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel[8],
                                    MIN (i + 1, x2 - 1), MIN (j + 1, y2 - 1));
        */
          /* For each layer, compute the exponential color code
		 (255*(-1 +exp(code))/(-1 +exp(255)) ) */

          for (k = 0; k < channels; k++)
            {
                double ex = exp(pixel[k])-1, max=exp(255)-1;
                output[k] = (guchar)(255 *(ex/max));
            }

          gimp_pixel_rgn_set_pixel (&rgn_out,
                                    output,
                                    i, j);
        } /*end for j*/

      if (i % 10 == 0)
        gimp_progress_update ((gdouble) (i - x1) / (gdouble) (x2 - x1));

    } /*end for i*/

  /* Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        x2 - x1, y2 - y1);
}
static void
compose_row (gint          frame_num,
             DisposeType   dispose,
             gint          row_num,
             guchar       *dest,
             gint          dest_width,
             GimpDrawable *drawable,
             gboolean      cleanup)
{
  static guchar *line_buf = NULL;
  guchar        *srcptr;
  GimpPixelRgn   pixel_rgn;
  gint           rawx, rawy, rawbpp, rawwidth, rawheight;
  gint           i;
  gboolean       has_alpha;

  if (cleanup)
    {
      if (line_buf)
        {
          g_free (line_buf);
          line_buf = NULL;
        }

      return;
    }

  if (dispose == DISPOSE_REPLACE)
    {
      total_alpha (dest, dest_width, pixelstep);
    }

  gimp_drawable_offsets (drawable->drawable_id,
                         &rawx,
                         &rawy);

  rawheight = gimp_drawable_height (drawable->drawable_id);

  /* this frame has nothing to give us for this row; return */
  if (row_num >= rawheight + rawy ||
      row_num < rawy)
    return;

  rawbpp = gimp_drawable_bpp (drawable->drawable_id);
  rawwidth = gimp_drawable_width (drawable->drawable_id);
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  if (line_buf)
    {
      g_free (line_buf);
      line_buf = NULL;
    }
  line_buf = g_malloc (rawwidth * rawbpp);

  /* Initialise and fetch the raw new frame row */

  gimp_pixel_rgn_init (&pixel_rgn,
                       drawable,
                       0, row_num - rawy,
                       rawwidth, 1,
                       FALSE,
                       FALSE);
  gimp_pixel_rgn_get_rect (&pixel_rgn,
                           line_buf,
                           0, row_num - rawy,
                           rawwidth, 1);

  /* render... */

  srcptr = line_buf;

  for (i=rawx; i<rawwidth+rawx; i++)
    {
      if (i>=0 && i<dest_width)
        {
          if ((!has_alpha) || ((*(srcptr+rawbpp-1))&128))
            {
              gint pi;

              for (pi = 0; pi < pixelstep-1; pi++)
                {
                  dest[i*pixelstep +pi] = *(srcptr + pi);
                }
              dest[i*pixelstep + pixelstep - 1] = 255;
            }
        }

      srcptr += rawbpp;
    }

}
Пример #15
0
static void
ripple (GimpDrawable *drawable,
        GimpPreview  *preview)
{
  RippleParam_t param;
  gint          edges;
  gint          period;

  param.pft       = gimp_pixel_fetcher_new (drawable, FALSE);
  param.has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  param.width     = drawable->width;
  param.height    = drawable->height;

  edges  = rvals.edges;
  period = rvals.period;

  if (rvals.tile)
    {
      rvals.edges = WRAP;
      rvals.period = (param.width / (param.width / rvals.period) *
                      (rvals.orientation == GIMP_ORIENTATION_HORIZONTAL) +
                      param.height / (param.height / rvals.period) *
                      (rvals.orientation == GIMP_ORIENTATION_VERTICAL));
    }

  if (preview)
    {
      guchar *buffer, *d;
      gint    bpp = gimp_drawable_bpp (drawable->drawable_id);
      gint    width, height;
      gint    x, y;
      gint    x1, y1;

      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);

      d = buffer = g_new (guchar, width * height * bpp);

      for (y = 0; y < height ; y++)
        for (x = 0; x < width ; x++)
          {
            if (rvals.orientation == GIMP_ORIENTATION_VERTICAL)
              ripple_vertical (x1 + x, y1 + y, d, bpp, &param);
            else
              ripple_horizontal (x1 + x, y1 + y, d, bpp, &param);

            d += bpp;
          }

      gimp_preview_draw_buffer (preview, buffer, width * bpp);
      g_free (buffer);
    }
  else
    {
      GimpRgnIterator *iter;

      iter = gimp_rgn_iterator_new (drawable, 0);

      gimp_rgn_iterator_dest (iter,
                              rvals.orientation == GIMP_ORIENTATION_VERTICAL ?
                              ripple_vertical :
                              ripple_horizontal,
                              &param);

      gimp_rgn_iterator_free (iter);
    }

  rvals.edges  = edges;
  rvals.period = period;

  gimp_pixel_fetcher_destroy (param.pft);
}
Пример #16
0
static void
symmetry (GimpDrawable *drawable)
{
  gint         i, j, k, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;
  guchar       output[4];

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       TRUE, TRUE);

  for (i = x1; i < x2; i++)
    {
      for (j = y1; j < y2; j++)
        {
          guchar pixel[4];

          /* Get ONE pixel */
          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel,
                                    i, j);
          /* For each layer */
          for (k = 0; k < channels; k++)
            {
              output[k] = 255 - pixel[k];
            }

          gimp_pixel_rgn_set_pixel (&rgn_out,
                                    output,
                                    i, j);
        } /*end for j*/

      if (i % 10 == 0)
        gimp_progress_update ((gdouble) (i - x1) / (gdouble) (x2 - x1));

    } /*end for i*/

  /* Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        x2 - x1, y2 - y1);
}
Пример #17
0
static void sinusrow (GimpDrawable *drawable)
{
  gint         i, j, k, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;

   guchar      *inrow;
   guchar      *outrow;
 /* guchar       output[4];  */

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       TRUE, TRUE);

 /* Initialise enough memory for inrow, outrow */
        inrow = g_new (guchar, channels * (x2 - x1));
        outrow = g_new (guchar, channels * (x2 - x1));

  guchar minp[4],maxp[4];
  getrange(drawable, minp, maxp, x1, x2, y1, y2);
  
  for (i = y1; i < y2; i++)
     {
         /* Get row i */
         gimp_pixel_rgn_get_row (&rgn_in, inrow, x1, i, x2 - x1);

         for (j = x1; j < x2; j++)
              {
                /* For each layer, compute the average of the nine
                 * pixels */
                for (k = 0; k < channels; k++) 
            {
                double angle = inrow[channels * (j - x1) + k], max=255;
                angle = M_2_PI * (angle / max ) ;
                outrow[channels * (j - x1) + k] = (guchar)(255*(1+sin(angle))/2);
            }

        } /*end for j each pixel of the row*/

      gimp_pixel_rgn_set_row (&rgn_out, outrow, x1, i, x2 - x1);

      if (i % 10 == 0)
        gimp_progress_update ((gdouble) (i - x1) / (gdouble) (x2 - x1));

    } /*end for i each row*/

  g_free (inrow);
  g_free (outrow);

  /* Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        x2 - x1, y2 - y1);
}
Пример #18
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[1];
  GimpRunMode        run_mode;
  GimpPDBStatusType  status;
  GimpDrawable      *drawable;
  gint               x1, y1, x2, y2;

  INIT_I18N ();

  status   = GIMP_PDB_SUCCESS;
  run_mode = param[0].data.d_int32;

  *nreturn_vals = 1;
  *return_vals  = values;

  values[0].type          = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  /* Get the active drawable info */

  drawable = gimp_drawable_get (param[2].data.d_drawable);

  img_width  = gimp_drawable_width (drawable->drawable_id);
  img_height = gimp_drawable_height (drawable->drawable_id);
  img_bpp    = gimp_drawable_bpp (drawable->drawable_id);

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  mbvals.center_x = (gdouble) (x1 + x2 - 1) / 2.0;
  mbvals.center_y = (gdouble) (y1 + y2 - 1) / 2.0;

  /* Set the tile cache size */
  gimp_tile_cache_ntiles (2 * drawable->ntile_cols);

  switch (run_mode)
    {
    case GIMP_RUN_INTERACTIVE:
      /* Possibly retrieve data */
      gimp_get_data (PLUG_IN_PROC, &mbvals);

      /* Get information from the dialog */
      if (! mblur_dialog (param[1].data.d_image, drawable))
        return;
      break;

    case GIMP_RUN_NONINTERACTIVE:
      if (strcmp (name, PLUG_IN_PROC_INWARD) == 0)
        mbvals.blur_outward = FALSE;

      if (nparams == 8)
        {
          mbvals.center_x = param[6].data.d_float;
          mbvals.center_y = param[7].data.d_float;
        }
      else if (nparams != 6)
        {
          status = GIMP_PDB_CALLING_ERROR;
        }

      if (status == GIMP_PDB_SUCCESS)
        {
          mbvals.mblur_type = param[3].data.d_int32;
          mbvals.length     = param[4].data.d_int32;
          mbvals.angle      = param[5].data.d_int32;
        }

    if ((mbvals.mblur_type < 0) || (mbvals.mblur_type > MBLUR_MAX))
      status= GIMP_PDB_CALLING_ERROR;
    break;

    case GIMP_RUN_WITH_LAST_VALS:
      /* Possibly retrieve data */
      gimp_get_data (PLUG_IN_PROC, &mbvals);
      break;

    default:
      break;
    }

  /* Blur the image */

  if ((status == GIMP_PDB_SUCCESS) &&
      (gimp_drawable_is_rgb(drawable->drawable_id) ||
       gimp_drawable_is_gray(drawable->drawable_id)))
    {

      /* Run! */
      has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
      mblur (drawable, NULL);

      /* If run mode is interactive, flush displays */
      if (run_mode != GIMP_RUN_NONINTERACTIVE)
        gimp_displays_flush ();

      /* Store data */
      if (run_mode == GIMP_RUN_INTERACTIVE)
        gimp_set_data (PLUG_IN_PROC, &mbvals, sizeof (mblur_vals_t));
    }
  else if (status == GIMP_PDB_SUCCESS)
    status = GIMP_PDB_EXECUTION_ERROR;

  values[0].data.d_status = status;

  gimp_drawable_detach (drawable);
}
Пример #19
0
void
precompute_normals (gint x1,
                    gint x2,
                    gint y)
{
  GimpVector3 *tmpv, p1, p2, p3, normal;
  gdouble     *tmpd;
  gint         n, i, nv;
  guchar      *map = NULL;
  gint bpp = 1;
  guchar mapval;


  /* First, compute the heights */
  /* ========================== */

  tmpv                = triangle_normals[0];
  triangle_normals[0] = triangle_normals[1];
  triangle_normals[1] = tmpv;

  tmpv              = vertex_normals[0];
  vertex_normals[0] = vertex_normals[1];
  vertex_normals[1] = vertex_normals[2];
  vertex_normals[2] = tmpv;

  tmpd       = heights[0];
  heights[0] = heights[1];
  heights[1] = heights[2];
  heights[2] = tmpd;

  if (mapvals.bumpmap_id != -1)
    {
      bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
    }

  gimp_pixel_rgn_get_row (&bump_region, bumprow, x1, y, x2 - x1);

  if (mapvals.bumpmaptype > 0)
    {
      switch (mapvals.bumpmaptype)
        {
          case 1:
            map = logmap;
            break;
          case 2:
            map = sinemap;
            break;
          default:
            map = spheremap;
            break;
        }

      for (n = 0; n < (x2 - x1); n++)
        {
          if (bpp>1)
            {
              mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ;
            }
          else
            {
              mapval = bumprow[n * bpp];
            }

          heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) map[mapval] / 255.0;
        }
    }
  else
    {
      for (n = 0; n < (x2 - x1); n++)
        {
          if (bpp>1)
            {
              mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ;
            }
          else
            {
              mapval = bumprow[n * bpp];
            }
          heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) mapval / 255.0;
        }
    }

  /* Compute triangle normals */
  /* ======================== */

  i = 0;
  for (n = 0; n < (x2 - x1 - 1); n++)
    {
      p1.x = 0.0;
      p1.y = ystep;
      p1.z = heights[2][n] - heights[1][n];

      p2.x = xstep;
      p2.y = ystep;
      p2.z = heights[2][n+1] - heights[1][n];

      p3.x = xstep;
      p3.y = 0.0;
      p3.z = heights[1][n+1] - heights[1][n];

      triangle_normals[1][i] = gimp_vector3_cross_product (&p2, &p1);
      triangle_normals[1][i+1] = gimp_vector3_cross_product (&p3, &p2);

      gimp_vector3_normalize (&triangle_normals[1][i]);
      gimp_vector3_normalize (&triangle_normals[1][i+1]);

      i += 2;
    }

  /* Compute vertex normals */
  /* ====================== */

  i = 0;
  gimp_vector3_set (&normal, 0.0, 0.0, 0.0);

  for (n = 0; n < (x2 - x1 - 1); n++)
    {
      nv = 0;

      if (n > 0)
        {
          if (y > 0)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i-1]);
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i-2]);
              nv += 2;
            }

          if (y < pre_h)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[1][i-1]);
              nv++;
            }
        }

      if (n <pre_w)
        {
          if (y > 0)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i]);
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i+1]);
              nv += 2;
            }

          if (y < pre_h)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[1][i]);
              gimp_vector3_add (&normal, &normal, &triangle_normals[1][i+1]);
              nv += 2;
            }
        }

      gimp_vector3_mul (&normal, 1.0 / (gdouble) nv);
      gimp_vector3_normalize (&normal);
      vertex_normals[1][n] = normal;

      i += 2;
    }
}
Пример #20
0
static void
brushdmenuselect (GtkWidget *widget,
                  gpointer   data)
{
  GimpPixelRgn  src_rgn;
  guchar       *src_row;
  guchar       *src;
  gint          id;
  gint          bpp;
  gint          x, y;
  ppm_t        *p;
  gint          x1, y1, x2, y2;
  gint          row;
  GimpDrawable *drawable;
  gint          rowstride;

  gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &id);

  if (id == -1)
    return;

  if (brush_from_file == 2)
    return; /* Not finished GUI-building yet */

  if (brush_from_file)
    {
#if 0
      unselectall (brush_list);
#endif
      preset_save_button_set_sensitive (FALSE);
    }

  gtk_adjustment_set_value (brush_gamma_adjust, 1.0);
  gtk_adjustment_set_value (brush_aspect_adjust, 0.0);

  drawable = gimp_drawable_get (id);

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  ppm_kill (&brushppm);
  ppm_new (&brushppm, x2 - x1, y2 - y1);
  p = &brushppm;

  rowstride = p->width * 3;

  src_row = g_new (guchar, (x2 - x1) * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       0, 0, x2 - x1, y2 - y1,
                       FALSE, FALSE);

  if (bpp == 3)
    { /* RGB */
      int bpr = (x2 - x1) * 3;

      for (row = 0, y = y1; y < y2; row++, y++)
        {
          gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
          memcpy (p->col + row*rowstride, src_row, bpr);
        }
    }
  else
    { /* RGBA (bpp > 3) GrayA (bpp == 2) or Gray */
      gboolean is_gray = ((bpp > 3) ? TRUE : FALSE);

      for (row = 0, y = y1; y < y2; row++, y++)
        {
          guchar *tmprow = p->col + row * rowstride;
          guchar *tmprow_ptr;

          gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
          src = src_row;
          tmprow_ptr = tmprow;
          /* Possible micro-optimization here:
           * src_end = src + src_rgn.bpp * (x2-x1);
           * for ( ; src < src_end ; src += src_rgn.bpp)
           */
          for (x = x1; x < x2; x++)
            {
              *(tmprow_ptr++) = src[0];
              *(tmprow_ptr++) = src[is_gray ? 1 : 0];
              *(tmprow_ptr++) = src[is_gray ? 2 : 0];
              src += src_rgn.bpp;
            }
        }
    }
  g_free (src_row);

  if (bpp >= 3)
    pcvals.color_brushes = 1;
  else
    pcvals.color_brushes = 0;

  brush_from_file = 0;
  update_brush_preview (NULL);
}
Пример #21
0
static void
displace (GimpDrawable *drawable,
          GimpPreview  *preview)
{
  GimpDrawable     *map_x = NULL;
  GimpDrawable     *map_y = NULL;
  GimpPixelRgn      dest_rgn;
  GimpPixelRgn      map_x_rgn;
  GimpPixelRgn      map_y_rgn;
  gpointer          pr;
  GimpPixelFetcher *pft;

  gint              width;
  gint              height;
  gint              bytes;
  guchar           *destrow, *dest;
  guchar           *mxrow, *mx;
  guchar           *myrow, *my;
  guchar            pixel[4][4];
  gint              x1, y1, x2, y2;
  gint              x, y;
  gdouble           cx, cy;
  gint              progress, max_progress;

  gdouble           amnt;
  gdouble           needx, needy;
  gdouble           radius, d_alpha;
  gint              xi, yi;

  guchar            values[4];
  guchar            val;

  gint              k;

  gdouble           xm_val, ym_val;
  gint              xm_alpha = 0;
  gint              ym_alpha = 0;
  gint              xm_bytes = 1;
  gint              ym_bytes = 1;
  guchar           *buffer   = NULL;
  gdouble           pi;

  /* initialize */

  /* get rid of uninitialized warnings */
  cx = cy = needx = needy = radius = d_alpha = 0.0;

  pi = 4 * atan (1);

  mxrow = NULL;
  myrow = NULL;

  pft = gimp_pixel_fetcher_new (drawable, FALSE);
  gimp_pixel_fetcher_set_edge_mode (pft, dvals.displace_type);

  bytes  = drawable->bpp;

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
  width  = x2 - x1;
  height = y2 - y1;

  if (dvals.mode == POLAR_MODE)
    {
      cx = x1 + width / 2.0;
      cy = y1 + height / 2.0;
    }

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
      x2 = x1 + width;
      y2 = y1 + height;
      buffer = g_new (guchar, width * height * bytes);
    }

  progress     = 0;
  max_progress = width * height;

  /*
   * The algorithm used here is simple - see
   * http://the-tech.mit.edu/KPT/Tips/KPT7/KPT7.html for a description.
   */

  /* Get the drawables  */
  if (dvals.displace_map_x != -1 && dvals.do_x)
    {
      map_x = gimp_drawable_get (dvals.displace_map_x);
      gimp_pixel_rgn_init (&map_x_rgn, map_x,
                           x1, y1, width, height, FALSE, FALSE);

      if (gimp_drawable_has_alpha (map_x->drawable_id))
        xm_alpha = 1;

      xm_bytes = gimp_drawable_bpp (map_x->drawable_id);
    }

  if (dvals.displace_map_y != -1 && dvals.do_y)
    {
      map_y = gimp_drawable_get (dvals.displace_map_y);
      gimp_pixel_rgn_init (&map_y_rgn, map_y,
                           x1, y1, width, height, FALSE, FALSE);

      if (gimp_drawable_has_alpha (map_y->drawable_id))
        ym_alpha = 1;

      ym_bytes = gimp_drawable_bpp (map_y->drawable_id);
    }

  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height,
                       preview == NULL, preview == NULL);

  /*  Register the pixel regions  */
  if (dvals.do_x && dvals.do_y)
    pr = gimp_pixel_rgns_register (3, &dest_rgn, &map_x_rgn, &map_y_rgn);
  else if (dvals.do_x)
    pr = gimp_pixel_rgns_register (2, &dest_rgn, &map_x_rgn);
  else if (dvals.do_y)
    pr = gimp_pixel_rgns_register (2, &dest_rgn, &map_y_rgn);
  else
    pr = NULL;

  for (pr = pr; pr != NULL; pr = gimp_pixel_rgns_process (pr))
    {
      destrow = dest_rgn.data;
      if (dvals.do_x)
        mxrow = map_x_rgn.data;
      if (dvals.do_y)
        myrow = map_y_rgn.data;

      for (y = dest_rgn.y; y < (dest_rgn.y + dest_rgn.h); y++)
        {
          if (preview)
            dest = buffer + ((y - y1) * width + (dest_rgn.x - x1)) * bytes;
          else
            dest = destrow;
          mx = mxrow;
          my = myrow;

          /*
           * We could move the displacement image address calculation
           * out of here, but when we can have different sized
           * displacement and destination images we'd have to move it
           * back anyway.
           */

          for (x = dest_rgn.x; x < (dest_rgn.x + dest_rgn.w); x++)
            {
              if (dvals.do_x)
                {
                  xm_val = displace_map_give_value(mx, xm_alpha, xm_bytes);
                  amnt = dvals.amount_x * (xm_val - 127.5) / 127.5;
                  /* CARTESIAN_MODE == 0 - performance important here */
                  if (! dvals.mode)
                    {
                      needx = x + amnt;
                    }
                  else
                    {
                      radius = sqrt (SQR (x - cx) + SQR (y - cy)) + amnt;
                    }
                  mx += xm_bytes;
                }
              else
                {
                  if (! dvals.mode)
                    needx = x;
                  else
                    radius = sqrt ((x - cx) * (x - cx) + (y - cy) * (y - cy));
                }


              if (dvals.do_y)
                {
                  ym_val = displace_map_give_value(my, ym_alpha, ym_bytes);
                  amnt = dvals.amount_y * (ym_val - 127.5) / 127.5;
                  if (! dvals.mode)
                    {
                      needy = y + amnt;
                    }
                  else
                    {
                      d_alpha = atan2 (x - cx, y - cy) + (dvals.amount_y / 180)
                                * pi * (ym_val - 127.5) / 127.5;
                    }
                  my += ym_bytes;
                }
              else
                {
                  if (! dvals.mode)
                    needy = y;
                  else
                    d_alpha = atan2 (x - cx, y - cy);
                }
              if (dvals.mode)
                {
                   needx = cx + radius * sin (d_alpha);
                   needy = cy + radius * cos (d_alpha);
                }
              /* Calculations complete; now copy the proper pixel */

              if (needx >= 0.0)
                xi = (int) needx;
              else
                xi = -((int) -needx + 1);

              if (needy >= 0.0)
                yi = (int) needy;
              else
                yi = -((int) -needy + 1);

              gimp_pixel_fetcher_get_pixel (pft, xi, yi, pixel[0]);
              gimp_pixel_fetcher_get_pixel (pft, xi + 1, yi, pixel[1]);
              gimp_pixel_fetcher_get_pixel (pft, xi, yi + 1, pixel[2]);
              gimp_pixel_fetcher_get_pixel (pft, xi + 1, yi + 1, pixel[3]);

              for (k = 0; k < bytes; k++)
                {
                  values[0] = pixel[0][k];
                  values[1] = pixel[1][k];
                  values[2] = pixel[2][k];
                  values[3] = pixel[3][k];
                  val = gimp_bilinear_8 (needx, needy, values);

                  *dest++ = val;
                } /* for */
            }

          destrow += dest_rgn.rowstride;

          if (dvals.do_x)
            mxrow += map_x_rgn.rowstride;
          if (dvals.do_y)
            myrow += map_y_rgn.rowstride;
        }

      if (!preview)
        {
          progress += dest_rgn.w * dest_rgn.h;
          gimp_progress_update ((double) progress / (double) max_progress);
        }
    } /* for */

  gimp_pixel_fetcher_destroy (pft);

  /*  detach from the map drawables  */
  if (dvals.do_x)
    gimp_drawable_detach (map_x);
  if (dvals.do_y)
    gimp_drawable_detach (map_y);

  if (preview)
    {
/*      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &dest_rgn);*/
      gimp_preview_draw_buffer (preview, buffer, width * bytes);
      g_free (buffer);
    }
  else
    {
      /*  update the region  */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }
}
Пример #22
0
static void
edge (GimpDrawable *drawable)
{
  GimpPixelRgn      src_rgn, dest_rgn;
  gpointer          pr;
  GimpPixelFetcher *pft;
  guchar           *srcrow, *src;
  guchar           *destrow, *dest;
  guchar            pix00[4], pix01[4], pix02[4];
  guchar            pix10[4], pix11[4], pix12[4];
  guchar            pix20[4], pix21[4], pix22[4];
  glong             width, height;
  gint              alpha;
  gboolean          has_alpha;
  gint              chan;
  gint              x, y;
  gint              x1, y1, x2, y2;
  gint              maxval;
  gint              cur_progress;
  gint              max_progress;
  gdouble           per_progress;

  if (evals.amount < 1.0)
    evals.amount = 1.0;

  pft = gimp_pixel_fetcher_new (drawable, FALSE);
  gimp_pixel_fetcher_set_edge_mode (pft, evals.wrapmode);

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  width     = gimp_drawable_width (drawable->drawable_id);
  height    = gimp_drawable_height (drawable->drawable_id);
  alpha     = gimp_drawable_bpp (drawable->drawable_id);
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  if (has_alpha)
    alpha--;

  maxval = 255;

  cur_progress = 0;
  per_progress = 0.0;
  max_progress = (x2 - x1) * (y2 - y1) / 100;

  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, x2-x1, y2-y1, FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2-x1, y2-y1, TRUE, TRUE);

  for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      srcrow  = src_rgn.data;
      destrow = dest_rgn.data;

      for (y = dest_rgn.y;
           y < (dest_rgn.y + dest_rgn.h);
           y++, srcrow += src_rgn.rowstride, destrow += dest_rgn.rowstride)
        {
          src  = srcrow;
          dest = destrow;

          for (x = dest_rgn.x;
               x < (dest_rgn.x + dest_rgn.w);
               x++,  src += src_rgn.bpp, dest += dest_rgn.bpp)
            {
              if (dest_rgn.x < x &&  x < dest_rgn.x + dest_rgn.w - 2 &&
                  dest_rgn.y < y &&  y < dest_rgn.y + dest_rgn.h - 2)
                {
                  /*
                   * 3x3 kernel is inside of the tile -- do fast
                   * version
                   */
                  for (chan = 0; chan < alpha; chan++)
                    {
                      /* get the 3x3 kernel into a guchar array,
                       * and send it to edge_detect */
                      guchar kernel[9];
                      gint   i,j;

#define PIX(X,Y)  src[ (Y-1)*(int)src_rgn.rowstride + (X-1)*(int)src_rgn.bpp + chan ]
                      /* make convolution */
                      for(i = 0; i < 3; i++)
                        for(j = 0; j < 3; j++)
                          kernel[3*i + j] = PIX(i,j);

#undef  PIX

                      dest[chan] = edge_detect (kernel);
                    }
                }
              else
                {
                  /*
                   * The kernel is not inside of the tile -- do slow
                   * version
                   */

                  gimp_pixel_fetcher_get_pixel (pft, x-1, y-1, pix00);
                  gimp_pixel_fetcher_get_pixel (pft, x  , y-1, pix10);
                  gimp_pixel_fetcher_get_pixel (pft, x+1, y-1, pix20);
                  gimp_pixel_fetcher_get_pixel (pft, x-1, y  , pix01);
                  gimp_pixel_fetcher_get_pixel (pft, x  , y  , pix11);
                  gimp_pixel_fetcher_get_pixel (pft, x+1, y  , pix21);
                  gimp_pixel_fetcher_get_pixel (pft, x-1, y+1, pix02);
                  gimp_pixel_fetcher_get_pixel (pft, x  , y+1, pix12);
                  gimp_pixel_fetcher_get_pixel (pft, x+1, y+1, pix22);

                  for (chan = 0; chan < alpha; chan++)
                    {
                      guchar kernel[9];

                      kernel[0] = pix00[chan];
                      kernel[1] = pix01[chan];
                      kernel[2] = pix02[chan];
                      kernel[3] = pix10[chan];
                      kernel[4] = pix11[chan];
                      kernel[5] = pix12[chan];
                      kernel[6] = pix20[chan];
                      kernel[7] = pix21[chan];
                      kernel[8] = pix22[chan];

                      dest[chan] = edge_detect (kernel);
                    }
                }
              if (has_alpha)
                dest[alpha] = src[alpha];
            }
        }
      cur_progress += dest_rgn.w * dest_rgn.h;

      if (cur_progress > max_progress)
        {
          cur_progress = cur_progress - max_progress;
          per_progress = per_progress + 0.01;
          gimp_progress_update (per_progress);
        }
    }

  gimp_progress_update (1.0);

  gimp_pixel_fetcher_destroy (pft);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));
}
Пример #23
0
// Run the plugin
static void
run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals)
{
	// Return values
  static GimpParam values[1];

  gint sel_x1, sel_y1, sel_x2, sel_y2, w, h, padding;
	PluginData         pd;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;

  *nreturn_vals = 1;
  *return_vals  = values;

  if (param[0].type!= GIMP_PDB_INT32) 
	  status=GIMP_PDB_CALLING_ERROR;
  if (param[2].type!=GIMP_PDB_DRAWABLE)
	  status=GIMP_PDB_CALLING_ERROR;

  run_mode = (GimpRunMode) param[0].data.d_int32;
	
	pd.drawable = gimp_drawable_get(param[2].data.d_drawable);
	gimp_drawable_mask_bounds(pd.drawable->drawable_id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
	pd.selection_width = sel_x2 - sel_x1;
  pd.selection_height = sel_y2 - sel_y1;
  pd.selection_offset_x = sel_x1;
  pd.selection_offset_y = sel_y1;
  pd.image_width = gimp_drawable_width(pd.drawable->drawable_id);
  pd.image_height = gimp_drawable_height(pd.drawable->drawable_id);
  pd.channel_count = gimp_drawable_bpp(pd.drawable->drawable_id);

  pd.point_grabbed = -1;

	if (run_mode == GIMP_RUN_INTERACTIVE)
	{
		// Interactive call with dialog
		dialog(&pd);
		if (pd.curve_user.count > 0)
		{
			gimp_set_data (PLUG_IN_BINARY, pd.curve_user.user_points, sizeof (GdkPoint) * pd.curve_user.count);
		}
	}
	else if (run_mode == GIMP_RUN_WITH_LAST_VALS)
	{
		// Read a saved curve and apply it
		fft_prepare(&pd);
		gimp_get_data(PLUG_IN_BINARY, pd.curve_user.user_points);
		pd.curve_user.count = gimp_get_data_size(PLUG_IN_BINARY) / sizeof (GdkPoint);
		gimp_pixel_rgn_init(&pd.region, pd.drawable, 0, 0, pd.image_width, pd.image_height, TRUE, TRUE);
		fft_apply(&pd);
		gimp_pixel_rgn_set_rect(&pd.region, pd.img_pixels, 0, 0, pd.image_width, pd.image_height);
		gimp_drawable_flush(pd.drawable);
		gimp_drawable_merge_shadow(pd.drawable->drawable_id, TRUE);
		gimp_drawable_update(pd.drawable->drawable_id, pd.selection_offset_x, pd.selection_offset_y, pd.selection_width, pd.selection_height);
		fft_destroy(&pd);
		gimp_displays_flush();
	}
	else
	{
	  status = GIMP_PDB_CALLING_ERROR;	
	}
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;
  gimp_drawable_detach(pd.drawable);
}
Пример #24
0
static void
blur (GimpDrawable *drawable)
{
  gint         i, ii, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;
  guchar     **row;
  guchar      *outrow;
  gint         width, height;

  gimp_progress_init ("My Blur...");

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  width  = x2 - x1;
  height = y2 - y1;

  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Allocate a big enough tile cache */
  gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       width, height,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       width, height,
                       TRUE, TRUE);

  /* Allocate memory for input and output tile rows */
  init_mem (&row, &outrow, width * channels);

  for (ii = -radius; ii <= radius; ii++)
    {
      gimp_pixel_rgn_get_row (&rgn_in,
                              row[radius + ii],
                              x1, y1 + CLAMP (ii, 0, height - 1),
                              width);
    }

  for (i = 0; i < height; i++)
    {
      /* To be done for each tile row */
      process_row (row,
                   outrow,
                   x1, y1,
                   width, height,
                   channels,
                   i);
      gimp_pixel_rgn_set_row (&rgn_out,
                              outrow,
                              x1, i + y1,
                              width);
      /* shift tile rows to insert the new one at the end */
      shuffle (&rgn_in,
               row,
               x1, y1,
               width, height,
               i);
      if (i % 10 == 0)
        gimp_progress_update ((gdouble) i / (gdouble) height);
    }

  /* We could also put that in a separate function but it's
   * rather simple */
  for (ii = 0; ii < 2 * radius + 1; ii++)
    g_free (row[ii]);

  g_free (row);
  g_free (outrow);

  /*  Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        width, height);
}
Пример #25
0
static void
exponentialrange (GimpDrawable *drawable)
{
  gint         i, j, k, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;
  guchar       output[4];

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       TRUE, TRUE);

  /* find the range [minp,maxp] */
  guchar minp[4],maxp[4];
  /* initial values are high for minp, low for maxp*/
  for (j = 0; j < 4; j++){
	minp[j]=255; // default for guchar 0..255
	maxp[j]=0;
  }
  /* get the right range */
  for (i = x1; i < x2; i++){
      for (j = y1; j < y2; j++){
          guchar pixel[4];
          gimp_pixel_rgn_get_pixel (&rgn_in, pixel, i, j);
          for (k = 0; k < channels; k++){
		if(minp[k]>pixel[k]) minp[k]=pixel[k];
		if(maxp[k]<pixel[k]) maxp[k]=pixel[k];
          }
      }
  }


  for (i = x1; i < x2; i++)
    {
      for (j = y1; j < y2; j++)
        {
          guchar pixel[4];

          gimp_pixel_rgn_get_pixel (&rgn_in,
                                    pixel, /*[4]*/
                                    i, j);
          /* For each layer, compute the exponential in the same range */
          for (k = 0; k < channels; k++)
            {
              	double ex =   exp(pixel[k])- exp(minp[k]);
                double ran=exp(maxp[k])-exp(minp[k]);
                output[k] = (guchar)( minp[k] + (maxp[k]-minp[k]) * (ex/ran) );

            }

          gimp_pixel_rgn_set_pixel (&rgn_out,
                                    output,
                                    i, j);
        } /*end for j*/

      if (i % 10 == 0)
        gimp_progress_update ((gdouble) (i - x1) / (gdouble) (x2 - x1));

    } /*end for i*/

  /* Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        x2 - x1, y2 - y1);
}
Пример #26
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam values[1];
  gint sel_x1, sel_y1, sel_x2, sel_y2;
  gint img_height, img_width, img_bpp, img_has_alpha;

  GimpDrawable      *drawable;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status;

  *nreturn_vals = 1;
  *return_vals  = values;

  status = GIMP_PDB_SUCCESS;

  if (param[0].type != GIMP_PDB_INT32)
    status = GIMP_PDB_CALLING_ERROR;
  run_mode = param[0].data.d_int32;

  INIT_I18N ();

  if (param[2].type != GIMP_PDB_DRAWABLE)
    status = GIMP_PDB_CALLING_ERROR;

  drawable = gimp_drawable_get (param[2].data.d_drawable);

  img_width = gimp_drawable_width (drawable->drawable_id);
  img_height = gimp_drawable_height (drawable->drawable_id);
  img_bpp = gimp_drawable_bpp (drawable->drawable_id);
  img_has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);

  if (!gimp_drawable_is_rgb (drawable->drawable_id))
    status = GIMP_PDB_CALLING_ERROR;

  if (status == GIMP_PDB_SUCCESS)
    {
      gr = g_rand_new ();

      memset (&qbist_info, 0, sizeof (qbist_info));
      create_info (&qbist_info.info);
      qbist_info.oversampling = 4;

      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
          /* Possibly retrieve data */
          gimp_get_data (PLUG_IN_PROC, &qbist_info);

          /* Get information from the dialog */
          if (dialog_run ())
            {
              status = GIMP_PDB_SUCCESS;
              gimp_set_data (PLUG_IN_PROC, &qbist_info, sizeof (QbistInfo));
            }
          else
            status = GIMP_PDB_EXECUTION_ERROR;
          break;

        case GIMP_RUN_NONINTERACTIVE:
          status = GIMP_PDB_CALLING_ERROR;
          break;

        case GIMP_RUN_WITH_LAST_VALS:
          /* Possibly retrieve data */
          gimp_get_data (PLUG_IN_PROC, &qbist_info);
          status = GIMP_PDB_SUCCESS;
          break;

        default:
          status = GIMP_PDB_CALLING_ERROR;
          break;
        }

      if (status == GIMP_PDB_SUCCESS)
        {
          GimpPixelRgn imagePR;
          gpointer     pr;

          gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
                                  gimp_tile_width ());
          gimp_pixel_rgn_init (&imagePR, drawable,
                               0, 0, img_width, img_height, TRUE, TRUE);

          optimize (&qbist_info.info);

          gimp_progress_init (_("Qbist"));

          for (pr = gimp_pixel_rgns_register (1, &imagePR);
               pr != NULL;
               pr = gimp_pixel_rgns_process (pr))
            {
              gint row;

              for (row = 0; row < imagePR.h; row++)
                {
                  qbist (&qbist_info.info,
                         imagePR.data + row * imagePR.rowstride,
                         imagePR.x,
                         imagePR.y + row,
                         imagePR.w,
                         sel_x2 - sel_x1,
                         sel_y2 - sel_y1,
                         imagePR.bpp,
                         qbist_info.oversampling);
                }

              gimp_progress_update ((gfloat) (imagePR.y - sel_y1) /
                                    (gfloat) (sel_y2 - sel_y1));
            }

          gimp_drawable_flush (drawable);
          gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
          gimp_drawable_update (drawable->drawable_id,
                                sel_x1, sel_y1,
                                (sel_x2 - sel_x1), (sel_y2 - sel_y1));

          gimp_displays_flush ();
        }

      g_rand_free (gr);
    }

  values[0].type          = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  gimp_drawable_detach (drawable);
}
Пример #27
0
static void
edge_preview_update (GimpPreview *preview)
{
  /* drawable */
  GimpDrawable *drawable;
  glong         bytes;
  gint          alpha;
  gboolean      has_alpha;

  /* preview */
  guchar       *src           = NULL; /* Buffer to hold source image */
  guchar       *render_buffer = NULL; /* Buffer to hold rendered image */
  guchar       *dest;
  gint          width;                /* Width of preview widget */
  gint          height;               /* Height of preview widget */
  gint          x1;                   /* Upper-left X of preview */
  gint          y1;                   /* Upper-left Y of preview */
  GimpPixelRgn  srcPR;                /* Pixel regions */

  /* algorithm */
  gint x, y;

  /* Get drawable info */
  drawable =
    gimp_drawable_preview_get_drawable (GIMP_DRAWABLE_PREVIEW (preview));
  bytes  = gimp_drawable_bpp (drawable->drawable_id);
  alpha  = bytes;
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  if (has_alpha)
    alpha--;

  /*
   * Setup for filter...
   */
  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  /* initialize pixel regions */
  gimp_pixel_rgn_init (&srcPR, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  src = g_new (guchar, width * height * bytes);
  render_buffer = g_new (guchar, width * height * bytes);

  /* render image */
  gimp_pixel_rgn_get_rect(&srcPR, src, x1, y1, width, height);
  dest = render_buffer;

  /* render algorithm */
  for (y = 0 ; y < height ; y++)
    for (x = 0 ; x < width ; x++)
      {
        gint chan;
        for (chan = 0; chan < alpha; chan++)
          {
            guchar kernel[9];

#define SRC(X,Y) src[bytes * (CLAMP((X), 0, width-1) + \
                              width * CLAMP((Y), 0, height-1)) + chan]

            kernel[0] = SRC (x - 1, y - 1);
            kernel[1] = SRC (x - 1, y    );
            kernel[2] = SRC (x - 1, y + 1);
            kernel[3] = SRC (x    , y - 1);
            kernel[4] = SRC (x    , y    );
            kernel[5] = SRC (x    , y + 1);
            kernel[6] = SRC (x + 1, y - 1);
            kernel[7] = SRC (x + 1, y    );
            kernel[8] = SRC (x + 1, y + 1);

#undef SRC
            dest[chan] = edge_detect (kernel);
          }
        if (has_alpha)
          dest[alpha] = src[bytes * (x + width * y) + alpha];
        dest += bytes;
      }
  /*
   * Draw the preview image on the screen...
   */
  gimp_preview_draw_buffer (preview, render_buffer, width * bytes);

  g_free (render_buffer);
  g_free (src);
}
Пример #28
0
static void
nova (GimpDrawable *drawable,
      GimpPreview  *preview)
{
   GimpPixelRgn  src_rgn;
   GimpPixelRgn  dest_rgn;
   gpointer      pr;
   guchar       *src_row, *dest_row, *save_src;
   guchar       *src, *dest;
   gint          x1, y1, x2, y2, x, y;
   gint          row, col;
   gint          alpha, bpp;
   gint          progress, max_progress;
   gboolean      has_alpha;
   gint          xc, yc; /* center of nova */
   gdouble       u, v, l, w, w1, c, t;
   gdouble      *spoke;
   gdouble       nova_alpha, src_alpha, new_alpha = 0.0;
   gdouble       compl_ratio, ratio;
   GimpRGB       color;
   GimpRGB      *spokecolor;
   GimpHSV       hsv;
   gdouble       spokecol;
   gint          i;
   GRand        *gr;
   guchar       *cache = NULL;
   gint          width, height;
   gdouble       zoom = 0.0;

   gr = g_rand_new ();

   /* initialize */
   has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

   spoke = g_new (gdouble, pvals.nspoke);
   spokecolor = g_new (GimpRGB, pvals.nspoke);

   gimp_rgb_set_alpha (&pvals.color, 1.0);
   gimp_rgb_to_hsv (&pvals.color, &hsv);

   for (i = 0; i < pvals.nspoke; i++)
     {
       spoke[i] = gauss (gr);

       hsv.h += ((gdouble) pvals.randomhue / 360.0) *
                g_rand_double_range (gr, -0.5, 0.5);

       if (hsv.h < 0)
         hsv.h += 1.0;
       else if (hsv.h >= 1.0)
         hsv.h -= 1.0;

       gimp_hsv_to_rgb (&hsv, spokecolor + i);
     }

   if (preview)
     {
       cache = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
                                             &width, &height, &bpp);

       zoom = gimp_zoom_preview_get_factor (GIMP_ZOOM_PREVIEW (preview));

       gimp_preview_transform (preview,
                               pvals.xcenter, pvals.ycenter, &xc, &yc);

       x1 = 0;
       y1 = 0;
       x2 = width;
       y2 = height;
     }
   else
     {
       gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
       bpp = gimp_drawable_bpp (drawable->drawable_id);
       xc = pvals.xcenter;
       yc = pvals.ycenter;

       gimp_pixel_rgn_init (&src_rgn, drawable,
                            x1, y1, x2-x1, y2-y1, FALSE, FALSE);
       gimp_pixel_rgn_init (&dest_rgn, drawable,
                            x1, y1, x2-x1, y2-y1, TRUE, TRUE);
     }

   alpha = (has_alpha) ? bpp - 1 : bpp;

   /* Initialize progress */
   progress     = 0;
   max_progress = (x2 - x1) * (y2 - y1);

   if (preview)
     {
       save_src = src_row  = g_new (guchar, y2 * width * bpp);
       memcpy (src_row, cache, y2 * width * bpp);

       dest_row = g_new (guchar, y2 * width * bpp);
       dest = dest_row;
       src  = src_row;

       for (row = 0, y = 0; row < y2; row++, y++)
         {

           for (col = 0, x = 0; col < x2; col++, x++)
             {
               u = ((gdouble) (x - xc) /
                    ((gdouble) pvals.radius * width /
                     drawable->width * zoom));
               v = ((gdouble) (y - yc) /
                    ((gdouble) pvals.radius * height /
                     drawable->height * zoom));

               l = sqrt (SQR (u) + SQR (v));

               /* This algorithm is still under construction. */
               t = (atan2 (u, v) / (2 * G_PI) + .51) * pvals.nspoke;
               i = (gint) floor (t);
               t -= i;
               i %= pvals.nspoke;
               w1 = spoke[i] * (1 - t) + spoke[(i + 1) % pvals.nspoke] * t;
               w1 = w1 * w1;

               w = 1.0 / (l + 0.001) * 0.9;

               nova_alpha = CLAMP (w, 0.0, 1.0);

               if (has_alpha)
               {
                 src_alpha = (gdouble) src[alpha] / 255.0;
                 new_alpha = src_alpha + (1.0 - src_alpha) * nova_alpha;
                 if (new_alpha != 0.0)
                   ratio = nova_alpha / new_alpha;
                 else
                   ratio = 0.0;
               }
               else
                 ratio = nova_alpha;

               compl_ratio = 1.0 - ratio;

               /* red or gray */
               spokecol = (gdouble)spokecolor[i                   ].r * (1.0-t) +
                          (gdouble)spokecolor[(i+1) % pvals.nspoke].r * t;

               if (w>1.0)
                 color.r = CLAMP (spokecol * w, 0.0, 1.0);
               else
                 color.r = src[0]/255.0 * compl_ratio + spokecol * ratio;
               c = CLAMP (w1 * w, 0.0, 1.0);
               color.r += c;
               dest[0] = CLAMP (color.r*255.0, 0, 255);

               if (bpp>2)
               {
                 /* green */
                 spokecol = (gdouble)spokecolor[i                   ].g * (1.0-t) +
                            (gdouble)spokecolor[(i+1) % pvals.nspoke].g * t;

                 if (w>1.0)
                   color.g = CLAMP (spokecol * w, 0.0, 1.0);
                 else
                   color.g = src[1]/255.0 * compl_ratio + spokecol * ratio;
                 c = CLAMP (w1 * w, 0.0, 1.0);
                 color.g += c;
                 dest[1] = CLAMP (color.g*255.0, 0, 255);

                 /* blue */
                 spokecol = (gdouble)spokecolor[i                   ].b * (1.0-t) +
                            (gdouble)spokecolor[(i+1) % pvals.nspoke].b * t;

                 if (w>1.0)
                   color.b = CLAMP (spokecol * w, 0.0, 1.0);
                 else
                   color.b = src[2]/255.0 * compl_ratio + spokecol * ratio;
                 c = CLAMP (w1 * w, 0.0, 1.0);
                 color.b += c;
                 dest[2] = CLAMP (color.b*255.0, 0, 255);
               }

               /* alpha */
               if (has_alpha)
                 dest[alpha] = new_alpha * 255.0;

               src  += bpp;
               dest += bpp;
             }
         }

       gimp_preview_draw_buffer (preview, dest_row, bpp * width);

       g_free (cache);
       g_free (save_src);
       g_free (dest_row);
     }
   else
     { /* normal mode */
       for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
            pr != NULL ;
            pr = gimp_pixel_rgns_process (pr))
         {
           src_row = src_rgn.data;
           dest_row = dest_rgn.data;

           for (row = 0, y = src_rgn.y; row < src_rgn.h; row++, y++)
             {
               src = src_row;
               dest = dest_row;

               for (col = 0, x = src_rgn.x; col < src_rgn.w; col++, x++)
                 {
                   u = (gdouble) (x-xc) / pvals.radius;
                   v = (gdouble) (y-yc) / pvals.radius;
                   l = sqrt(u*u + v*v);

                   /* This algorithm is still under construction. */
                   t = (atan2 (u, v) / (2 * G_PI) + .51) * pvals.nspoke;
                   i = (gint) floor (t);
                   t -= i;
                   i %= pvals.nspoke;
                   w1 = spoke[i] * (1 - t) + spoke[(i + 1) % pvals.nspoke] * t;
                   w1 = w1 * w1;

                   w = 1/(l+0.001)*0.9;

                   nova_alpha = CLAMP (w, 0.0, 1.0);

                   if (has_alpha)
                     {
                       src_alpha = (gdouble) src[alpha] / 255.0;
                       new_alpha = src_alpha + (1.0 - src_alpha) * nova_alpha;

                       if (new_alpha != 0.0)
                         ratio = nova_alpha / new_alpha;
                       else
                         ratio = 0.0;
                     }
                   else
                     ratio = nova_alpha;

                   compl_ratio = 1.0 - ratio;

                   switch (bpp)
                     {
                     case 1:
                     case 2:
                       /* gray */
                       spokecol = (gdouble)spokecolor[i                   ].r * (1.0-t) +
                                  (gdouble)spokecolor[(i+1) % pvals.nspoke].r * t;
                       if (w>1.0)
                         color.r = CLAMP (spokecol * w, 0.0, 1.0);
                       else
                         color.r = src[0]/255.0 * compl_ratio + spokecol * ratio;
                       c = CLAMP (w1 * w, 0.0, 1.0);
                       color.r += c;
                       dest[0] = CLAMP (color.r*255.0, 0, 255);
                       break;

                     case 3:
                     case 4:
                       /* red */
                       spokecol = (gdouble)spokecolor[i                   ].r * (1.0-t) +
                                  (gdouble)spokecolor[(i+1) % pvals.nspoke].r * t;
                       if (w>1.0)
                         color.r = CLAMP (spokecol * w, 0.0, 1.0);
                       else
                         color.r = src[0]/255.0 * compl_ratio + spokecol * ratio;
                       c = CLAMP (w1 * w, 0.0, 1.0);
                       color.r += c;
                       dest[0] = CLAMP (color.r*255.0, 0, 255);
                       /* green */
                       spokecol = (gdouble)spokecolor[i                   ].g * (1.0-t) +
                                  (gdouble)spokecolor[(i+1) % pvals.nspoke].g * t;
                       if (w>1.0)
                         color.g = CLAMP (spokecol * w, 0.0, 1.0);
                       else
                         color.g = src[1]/255.0 * compl_ratio + spokecol * ratio;
                       c = CLAMP (w1 * w, 0.0, 1.0);
                       color.g += c;
                       dest[1] = CLAMP (color.g*255.0, 0, 255);
                       /* blue */
                       spokecol = (gdouble)spokecolor[i                   ].b * (1.0-t) +
                                  (gdouble)spokecolor[(i+1) % pvals.nspoke].b * t;
                       if (w>1.0)
                         color.b = CLAMP (spokecol * w, 0.0, 1.0);
                       else
                         color.b = src[2]/255.0 * compl_ratio + spokecol * ratio;
                       c = CLAMP (w1 * w, 0.0, 1.0);
                       color.b += c;
                       dest[2] = CLAMP (color.b*255.0, 0, 255);
                       break;
                     }

                   if (has_alpha)
                     dest[alpha] = new_alpha * 255.0;

                   src += src_rgn.bpp;
                   dest += dest_rgn.bpp;
                 }

               src_row += src_rgn.rowstride;
               dest_row += dest_rgn.rowstride;
             }

           /* Update progress */
           progress += src_rgn.w * src_rgn.h;
           gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
         }

       gimp_progress_update (1.0);

       gimp_drawable_flush (drawable);
       gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
       gimp_drawable_update (drawable->drawable_id,
                             x1, y1, (x2 - x1), (y2 - y1));
     }

   g_free (spoke);
   g_free (spokecolor);
   g_rand_free (gr);
}
Пример #29
0
/*
  This function operates on the image when pixelwidth >= tile_width.
  It simply sets the size of GimpPixelRgn as pixelwidth and proceeds.
 */
static void
pixelize_large (GimpDrawable *drawable,
                gint          pixelwidth,
                gint          pixelheight,
                GimpPreview  *preview)
{
  GimpPixelRgn  src_rgn, dest_rgn;
  guchar       *src_row, *dest_row;
  guchar       *src, *dest = NULL, *d;
  gulong        average[4];
  gint          row, col, b, bpp, has_alpha;
  gint          x, y, x_step, y_step;
  gint          i, j;
  gulong        count;
  gint          x1, y1, x2, y2;
  gint          width, height;
  gint          progress = 0, max_progress = 1;
  gpointer      pr;

  bpp = gimp_drawable_bpp (drawable->drawable_id);
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);

      x2 = x1 + width;
      y2 = y1 + height;
      dest = g_new (guchar, width * height * bpp);
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id,
                                 &x1, &y1, &x2, &y2);
      width  = x2 - x1;
      height = y2 - y1;

      /* Initialize progress */
      progress = 0;
      max_progress = 2 * width * height;
    }

  for (y = y1; y < y2; y += pixelheight - (y % pixelheight))
    {
      for (x = x1; x < x2; x += pixelwidth - (x % pixelwidth))
        {
          x_step = pixelwidth  - (x % pixelwidth);
          y_step = pixelheight - (y % pixelheight);
          x_step = MIN (x_step, x2 - x);
          y_step = MIN (y_step, y2 - y);

          gimp_pixel_rgn_init (&src_rgn, drawable,
                               x, y, x_step, y_step, FALSE, FALSE);
          for (b = 0; b < bpp; b++)
            average[b] = 0;
          count = 0;

          for (pr = gimp_pixel_rgns_register (1, &src_rgn);
               pr != NULL;
               pr = gimp_pixel_rgns_process (pr))
            {
              src_row = src_rgn.data;
              for (row = 0; row < src_rgn.h; row++)
                {
                  src = src_row;
                  if (has_alpha)
                    {
                      for (col = 0; col < src_rgn.w; col++)
                        {
                          gulong alpha = src[bpp - 1];

                          average[bpp - 1] += alpha;
                          for (b = 0; b < bpp - 1; b++)
                            average[b] += src[b] * alpha;
                          src += src_rgn.bpp;
                        }
                    }
                  else
                    {
                      for (col = 0; col < src_rgn.w; col++)
                        {
                          for (b = 0; b < bpp; b++)
                            average[b] += src[b];
                          src += src_rgn.bpp;
                        }
                    }
                  src_row += src_rgn.rowstride;
                }
              count += src_rgn.w * src_rgn.h;
              if (!preview)
                {
                  /* Update progress */
                  progress += src_rgn.w * src_rgn.h;
                  gimp_progress_update ((double) progress / (double) max_progress);
                }
            }

          if (count > 0)
            {
              if (has_alpha)
                {
                  gulong alpha = average[bpp - 1];

                  if ((average[bpp - 1] = alpha / count))
                    for (b = 0; b < bpp - 1; b++)
                      average[b] /= alpha;
                }
              else
                {
                  for (b = 0; b < bpp; b++)
                    average[b] /= count;
                }
            }

          if (preview)
            {
              dest_row = dest + ((y - y1) * width + (x - x1)) * bpp;
              for (j = 0; j < y_step; j++)
                {
                  d = dest_row;
                  for (i = 0; i < x_step; i++)
                    for (b = 0; b < bpp; b++)
                      *d++ = average[b];
                  dest_row += width * bpp;
                }
            }
          else
            {
              gimp_pixel_rgn_init (&dest_rgn, drawable,
                                   x, y, x_step, y_step,
                                   TRUE, TRUE);
              for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
                   pr != NULL;
                   pr = gimp_pixel_rgns_process (pr))
                {
                  dest_row = dest_rgn.data;
                  for (row = 0; row < dest_rgn.h; row++)
                    {
                    dest = dest_row;
                    for (col = 0; col < dest_rgn.w; col++)
                      {
                        for (b = 0; b < bpp; b++)
                          dest[b] = average[b];

                        dest  += dest_rgn.bpp;
                      }
                    dest_row += dest_rgn.rowstride;
                  }
                /* Update progress */
                progress += dest_rgn.w * dest_rgn.h;
                gimp_progress_update ((double) progress / (double) max_progress);
              }
            }
        }
    }

  if (preview)
    {
      gimp_preview_draw_buffer (preview, dest, width * bpp);
      g_free (dest);
    }
  else
    {
      /*  update the blurred region	 */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }
}
Пример #30
0
gint
guess_new_size (GtkWidget * button, PreviewData * p_data, GuessDir direction)
{
  gint32 disc_layer_ID;
  GimpDrawable *drawable;
  gint z1, z2, k;
  gint z1min, z1max, z2max;
  gint width, height;
  gint lw, lh;
  gint x_off, y_off;
  gint bpp, c_bpp;
  GimpPixelRgn rgn_in;
  guchar *line;
  gboolean has_alpha;
  gdouble sum;
  gint mask_size;
  gint max_mask_size = 0;
  gint old_size;
  gint new_size;

  disc_layer_ID = p_data->vals->disc_layer_ID;
  switch (direction)
    {
      case GUESS_DIR_HOR:
        old_size = p_data->old_width;
        break;
      case GUESS_DIR_VERT:
        old_size = p_data->old_height;
        break;
      default:
        g_message("You just found a bug");
        return 0;
    }

  LAYER_CHECK_ACTION(disc_layer_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_REFRESH), old_size);

  width = gimp_drawable_width (disc_layer_ID);
  height = gimp_drawable_height (disc_layer_ID);
  has_alpha = gimp_drawable_has_alpha (disc_layer_ID);
  bpp = gimp_drawable_bpp (disc_layer_ID);
  c_bpp = bpp - (has_alpha ? 1 : 0);

  drawable = gimp_drawable_get (disc_layer_ID);
  gimp_pixel_rgn_init (&rgn_in, drawable, 0, 0, width, height, FALSE, FALSE);


  gimp_drawable_offsets (disc_layer_ID, &x_off, &y_off);

  x_off -= p_data->x_off;
  y_off -= p_data->y_off;

  lw = (MIN (p_data->old_width, width + x_off) - MAX (0, x_off));
  lh = (MIN (p_data->old_height, height + y_off) - MAX (0, y_off));

  switch (direction)
    {
      case GUESS_DIR_HOR:
        z1min = MAX (0, y_off);
        z1max = MIN (p_data->old_height, height + y_off);
        z2max = lw;
        break;
      case GUESS_DIR_VERT:
        z1min = MAX (0, x_off);
        z1max = MIN (p_data->old_width, width + x_off);
        z2max = lh;
        break;
      default:
        g_message("You just found a bug");
        return 0;
    }

  line = g_try_new (guchar, bpp * z2max);

  for (z1 = z1min; z1 < z1max; z1++)
    {
      switch (direction)
        {
          case GUESS_DIR_HOR:
            gimp_pixel_rgn_get_row (&rgn_in, line, MAX (0, -x_off), z1 - y_off, z2max);
            break;
          case GUESS_DIR_VERT:
            gimp_pixel_rgn_get_col (&rgn_in, line, z1 - x_off, MAX (0, -y_off), z2max);
            break;
        }

      mask_size = 0;
      for (z2 = 0; z2 < z2max; z2++)
	{
	  sum = 0;
	  for (k = 0; k < c_bpp; k++)
	    {
	      sum += line[bpp * z2 + k];
	    }

	  sum /= (255 * c_bpp);
	  if (has_alpha)
	    {
	      sum *= (gdouble) line[bpp * (z2 + 1) - 1] / 255;
	    }

	  if (sum >= (0.5 / c_bpp))
	    {
	      mask_size++;
	    }
	}
      if (mask_size > max_mask_size)
	{
	  max_mask_size = mask_size;
	}

    }

  new_size = old_size - max_mask_size;

  g_free (line);
  gimp_drawable_detach (drawable);

  return new_size;
}