// Called before any real progress is made
static void
progressStart(gchar * message)
{
  gimp_progress_init(message);
  gimp_progress_update(0.0);
#ifdef DEBUG
  /* To console.  On Windows, it annoyingly opens a console.  
  On Unix it dissappears unless console already open.
  */
  g_printf(message);  
  g_printf("\n");
#endif
}
Example #2
0
static void
notify_progress_cb (WebKitWebView  *view,
                    GParamSpec     *pspec,
                    gpointer        user_data)
{
  static gdouble old_progress = 0.0;
  gdouble progress = webkit_web_view_get_estimated_load_progress (view);

  if ((progress - old_progress) > 0.01)
    {
      gimp_progress_update (progress);
      old_progress = progress;
    }
}
Example #3
0
File: gluas.c Project: jonnor/gegl
static int
l_progress(lua_State * lua)
{
  lua_Number percent;

  if (!lua_gettop(lua))
    return 0;
  percent = lua_tonumber(lua, -1);

#if 0
  g_warning ("progress,.. %f", percent);
  gimp_progress_update((double) percent);
#endif
  return 0;
}
Example #4
0
void
gimp_rgn_iterate2 (GimpDrawable *drawable,
                   GimpRunMode   unused,
                   GimpRgnFunc2  func,
                   gpointer      data)
{
  GimpPixelRgn  srcPR, destPR;
  gint          x1, y1, x2, y2;
  gpointer      pr;
  gint          total_area;
  gint          area_so_far;
  gint          progress_skip;

  g_return_if_fail (drawable != NULL);

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

  total_area = (x2 - x1) * (y2 - y1);

  if (total_area <= 0)
    return;

  area_so_far   = 0;
  progress_skip = 0;

  /* Initialize the pixel regions. */
  gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, (x2 - x1), (y2 - y1),
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable, x1, y1, (x2 - x1), (y2 - y1),
                       TRUE, TRUE);

  for (pr = gimp_pixel_rgns_register (2, &srcPR, &destPR);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      gimp_rgn_render_region (&srcPR, &destPR, func, data);

      area_so_far += srcPR.w * srcPR.h;

      if (((progress_skip++) % 10) == 0)
        gimp_progress_update ((gdouble) area_so_far / (gdouble) total_area);
    }

  /*  update the processed 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));
}
Example #5
0
static void
mblur (GimpDrawable *drawable,
       GimpPreview  *preview)
{
  gint x, y;
  gint width, height;

  if (preview)
    {
      gimp_preview_get_position (preview, &x, &y);
      gimp_preview_get_size (preview, &width, &height);
    }
  else if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                           &x, &y, &width, &height))
    {
      return;
    }

  if (! preview)
    gimp_progress_init (_("Motion blurring"));

  switch (mbvals.mblur_type)
    {
    case MBLUR_LINEAR:
      mblur_linear (drawable, preview, x, y, width, height);
      break;

    case MBLUR_RADIAL:
      mblur_radial (drawable, preview, x, y, width, height);
      break;

    case MBLUR_ZOOM:
      mblur_zoom (drawable, preview, x, y, width, height);
      break;

    default:
      break;
    }

  if (! preview)
    {
      gimp_progress_update (1.0);

      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x, y, width, height);
    }
}
Example #6
0
static void
draw_page (GtkPrintOperation *operation,
           GtkPrintContext   *context,
           gint               page_nr,
           PrintData         *data)
{
  GError *error = NULL;

  if (print_draw_page (context, data, &error))
    {
      gimp_progress_update (1.0);
    }
  else
    {
      print_show_error (error->message);
      g_error_free (error);
    }
}
Example #7
0
static void
notify_progress_cb (WebKitWebView  *view,
                    GParamSpec     *pspec,
                    gpointer        user_data)
{
  static gdouble old_progress = 0.0;
  gdouble progress;

  g_object_get (view,
                "progress", &progress,
                NULL);

  if ((progress - old_progress) > 0.01)
    {
      gimp_progress_update (progress);
      old_progress = progress;
    }
}
Example #8
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);
}
Example #9
0
static void
gimp_rgn_iterator_iter_single (GimpRgnIterator *iter,
                               GimpPixelRgn    *srcPR,
                               GimpRgnFuncSrc   func,
                               gpointer         data)
{
  gpointer  pr;
  gint      total_area;
  gint      area_so_far;

  total_area = (iter->x2 - iter->x1) * (iter->y2 - iter->y1);
  area_so_far   = 0;

  for (pr = gimp_pixel_rgns_register (1, srcPR);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      guchar *src = srcPR->data;
      gint    y;

      for (y = srcPR->y; y < srcPR->y + srcPR->h; y++)
        {
          guchar *s = src;
          gint x;

          for (x = srcPR->x; x < srcPR->x + srcPR->w; x++)
            {
              func (x, y, s, srcPR->bpp, data);
              s += srcPR->bpp;
            }

          src += srcPR->rowstride;
        }

      area_so_far += srcPR->w * srcPR->h;
      gimp_progress_update ((gdouble) area_so_far / (gdouble) total_area);
    }
}
Example #10
0
static gboolean
copy_file (GFile        *src_file,
           GFile        *dest_file,
           Mode          mode,
           GimpRunMode   run_mode,
           GError      **error)
{
  UriProgress progress = { 0, };
  gboolean    success;

  gimp_progress_init (_("Connecting to server"));

  progress.mode = mode;

  success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, NULL,
                         uri_progress_callback, &progress,
                         error);
  gimp_progress_update (1.0);

  if (! success &&
      run_mode == GIMP_RUN_INTERACTIVE &&
      (*error)->domain == G_IO_ERROR   &&
      (*error)->code   == G_IO_ERROR_NOT_MOUNTED)
    {
      g_clear_error (error);

      if (mount_enclosing_volume (mode == DOWNLOAD ? src_file : dest_file,
                                  error))
        {
          success = g_file_copy (src_file, dest_file, 0, NULL,
                                 uri_progress_callback, &progress,
                                 error);

        }
    }

  return success;
}
Example #11
0
static gboolean
load_finished_idle (gpointer data)
{
  static gint count = 0;

  gimp_progress_update ((gdouble) count * 0.025);

  count++;

  if (count < 10)
    return G_SOURCE_CONTINUE;

  webkit_web_view_get_snapshot (WEBKIT_WEB_VIEW (data),
                                WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT,
                                WEBKIT_SNAPSHOT_OPTIONS_NONE,
                                NULL,
                                snapshot_ready,
                                NULL);

  count = 0;

  return G_SOURCE_REMOVE;
}
Example #12
0
gint32
file_vtf_load_image (const gchar *fname, GError **error)
{
    gimp_progress_init_printf ("Opening '%s'", gimp_filename_to_utf8 (fname));

    gint32 image = -1;
    std::auto_ptr<Vtf::File> vtf (new Vtf::File);

    try {
        vtf->load(fname);

        Vtf::HiresImageResource* vres = (Vtf::HiresImageResource*)
                                        vtf->findResource (Vtf::Resource::TypeHires);
        if (!vres)
            throw Vtf::Exception ("Cound not find high-resolution image");

        image = gimp_image_new (vres->width (), vres->height  (), GIMP_RGB);
        gimp_image_set_filename (image, fname);

        guint16 i, frame_count = vres->frameCount ();
        for (i = 0; i < frame_count; i++) {
            if (!file_vtf_load_layer (vres, image, i)) {
                g_set_error (error, 0, 0, "Unsupported format %s",
                             Vtf::formatToString (vres->format()));
                gimp_image_delete (image);
                image = -1;
                break;
            }
        }

        gimp_progress_update (1.0);
    } catch (std::exception& e) {
        g_set_error (error, 0, 0, e.what ());
    }

    return image;
}
Example #13
0
gint32
file_vtf_load_thumbnail_image (const gchar *fname, gint *width, gint *height,
                               GError **error)
{
    gint32 image = -1;
    gimp_progress_init_printf ("Opening thumbnail for '%s'",
                               gimp_filename_to_utf8 (fname));

    Vtf::File *vtf = new Vtf::File;
    try {
        vtf->load(fname);

        Vtf::HiresImageResource* vres = (Vtf::HiresImageResource*)
                                        vtf->findResource(Vtf::Resource::TypeHires);
        if (!vres)
            throw Vtf::Exception ("Cound not find high-resolution image");

        *width = static_cast<gint> (vres->width ());
        *height = static_cast<gint> (vres->height ());

        image = gimp_image_new (*width, *height, GIMP_RGB);
        if (!file_vtf_load_layer (vres, image, 0)) {
            g_set_error (error, 0, 0, "Unsupported format %s",
                         Vtf::formatToString(vres->format()));
            gimp_image_delete (image);
            image = -1;
        }

        gimp_progress_update (1.0);
    } catch (std::exception& e) {
        g_set_error (error, 0, 0, e.what());
    }

    delete vtf;
    return image;
}
Example #14
0
static void
snapshot_ready (GObject      *source_object,
                GAsyncResult *result,
                gpointer      user_data)
{
  WebKitWebView   *view = WEBKIT_WEB_VIEW (source_object);
  cairo_surface_t *surface;

  surface = webkit_web_view_get_snapshot_finish (view, result,
                                                 &webpagevals.error);

  if (surface)
    {
      gint   width;
      gint   height;
      gint32 layer;

      width  = cairo_image_surface_get_width (surface);
      height = cairo_image_surface_get_height (surface);

      webpagevals.image = gimp_image_new (width, height, GIMP_RGB);

      gimp_image_undo_disable (webpagevals.image);
      layer = gimp_layer_new_from_surface (webpagevals.image, _("Webpage"),
                                           surface,
                                           0.25, 1.0);
      gimp_image_insert_layer (webpagevals.image, layer, -1, 0);
      gimp_image_undo_enable (webpagevals.image);

      cairo_surface_destroy (surface);
    }

  gimp_progress_update (1.0);

  gtk_main_quit ();
}
Example #15
0
/*
 * Cartoon algorithm
 * -----------------
 * Mask radius = radius of pixel neighborhood for intensity comparison
 * Threshold   = relative intensity difference which will result in darkening
 * Ramp        = amount of relative intensity difference before total black
 * Blur radius = mask radius / 3.0
 *
 * Algorithm:
 * For each pixel, calculate pixel intensity value to be: avg (blur radius)
 * relative diff = pixel intensity / avg (mask radius)
 * If relative diff < Threshold
 *   intensity mult = (Ramp - MIN (Ramp, (Threshold - relative diff))) / Ramp
 *   pixel intensity *= intensity mult
 */
static void
cartoon (GimpDrawable *drawable,
         GimpPreview  *preview)
{
  GimpPixelRgn  src_rgn, dest_rgn;
  GimpPixelRgn *pr;
  gint          width, height;
  gint          bytes;
  gboolean      has_alpha;
  guchar       *dest1;
  guchar       *dest2;
  guchar       *src;
  guchar       *src1, *sp_p1, *sp_m1;
  guchar       *src2, *sp_p2, *sp_m2;
  gdouble       n_p1[5], n_m1[5];
  gdouble       n_p2[5], n_m2[5];
  gdouble       d_p1[5], d_m1[5];
  gdouble       d_p2[5], d_m2[5];
  gdouble       bd_p1[5], bd_m1[5];
  gdouble       bd_p2[5], bd_m2[5];
  gdouble      *val_p1, *val_m1, *vp1, *vm1;
  gdouble      *val_p2, *val_m2, *vp2, *vm2;
  gint          x1, y1, x2, y2;
  gint          i, j;
  gint          row, col, b;
  gint          terms;
  gint          progress, max_progress;
  gint          initial_p1[4];
  gint          initial_p2[4];
  gint          initial_m1[4];
  gint          initial_m2[4];
  gdouble       radius;
  gdouble       std_dev1;
  gdouble       std_dev2;
  gdouble       ramp;
  guchar       *preview_buffer = NULL;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

      width     = (x2 - x1);
      height    = (y2 - y1);
    }

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

  val_p1 = g_new (gdouble, MAX (width, height) * bytes);
  val_p2 = g_new (gdouble, MAX (width, height) * bytes);
  val_m1 = g_new (gdouble, MAX (width, height) * bytes);
  val_m2 = g_new (gdouble, MAX (width, height) * bytes);

  src   = g_new (guchar, MAX (width, height) * bytes);
  dest1 = g_new0 (guchar, width * height);
  dest2 = g_new0 (guchar, width * height);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       0, 0, drawable->width, drawable->height, FALSE, FALSE);

  progress = 0;
  max_progress = width * height * 2;

  /*  Calculate the standard deviations  */
  radius   = 1.0; /* blur radius */
  radius   = fabs (radius) + 1.0;
  std_dev1 = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

  radius   = cvals.mask_radius;
  radius   = fabs (radius) + 1.0;
  std_dev2 = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

  /*  derive the constants for calculating the gaussian from the std dev  */
  find_constants (n_p1, n_m1, d_p1, d_m1, bd_p1, bd_m1, std_dev1);
  find_constants (n_p2, n_m2, d_p2, d_m2, bd_p2, bd_m2, std_dev2);

  /*  First the vertical pass  */
  for (col = 0; col < width; col++)
    {
      memset (val_p1, 0, height * bytes * sizeof (gdouble));
      memset (val_p2, 0, height * bytes * sizeof (gdouble));
      memset (val_m1, 0, height * bytes * sizeof (gdouble));
      memset (val_m2, 0, height * bytes * sizeof (gdouble));

      gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, height);

      src1  = src;
      sp_p1 = src1;
      sp_m1 = src1 + (height - 1) * bytes;
      vp1   = val_p1;
      vp2   = val_p2;
      vm1   = val_m1 + (height - 1) * bytes;
      vm2   = val_m2 + (height - 1) * bytes;

      /*  Set up the first vals  */
      for (i = 0; i < bytes; i++)
        {
          initial_p1[i] = sp_p1[i];
          initial_m1[i] = sp_m1[i];
        }

      for (row = 0; row < height; row++)
        {
          gdouble *vpptr1, *vmptr1;
          gdouble *vpptr2, *vmptr2;

          terms = (row < 4) ? row : 4;

          for (b = 0; b < bytes; b++)
            {
              vpptr1 = vp1 + b; vmptr1 = vm1 + b;
              vpptr2 = vp2 + b; vmptr2 = vm2 + b;

              for (i = 0; i <= terms; i++)
                {
                  *vpptr1 += n_p1[i] * sp_p1[(-i * bytes) + b] -
                    d_p1[i] * vp1[(-i * bytes) + b];
                  *vmptr1 += n_m1[i] * sp_m1[(i * bytes) + b] -
                    d_m1[i] * vm1[(i * bytes) + b];

                  *vpptr2 += n_p2[i] * sp_p1[(-i * bytes) + b] -
                    d_p2[i] * vp2[(-i * bytes) + b];
                  *vmptr2 += n_m2[i] * sp_m1[(i * bytes) + b] -
                    d_m2[i] * vm2[(i * bytes) + b];
                }

              for (j = i; j <= 4; j++)
                {
                  *vpptr1 += (n_p1[j] - bd_p1[j]) * initial_p1[b];
                  *vmptr1 += (n_m1[j] - bd_m1[j]) * initial_m1[b];

                  *vpptr2 += (n_p2[j] - bd_p2[j]) * initial_p1[b];
                  *vmptr2 += (n_m2[j] - bd_m2[j]) * initial_m1[b];
                }
            }

          sp_p1 += bytes;
          sp_m1 -= bytes;
          vp1   += bytes;
          vp2   += bytes;
          vm1   -= bytes;
          vm2   -= bytes;
        }

      transfer_pixels (val_p1, val_m1, dest1 + col, width, bytes, height);
      transfer_pixels (val_p2, val_m2, dest2 + col, width, bytes, height);

      if (!preview)
        {
          progress += height;
          if ((col % 5) == 0)
            gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }
    }

  for (row = 0; row < height; row++)
    {
      memset (val_p1, 0, width * sizeof (gdouble));
      memset (val_p2, 0, width * sizeof (gdouble));
      memset (val_m1, 0, width * sizeof (gdouble));
      memset (val_m2, 0, width * sizeof (gdouble));

      src1 = dest1 + row * width;
      src2 = dest2 + row * width;

      sp_p1 = src1;
      sp_p2 = src2;
      sp_m1 = src1 + width - 1;
      sp_m2 = src2 + width - 1;
      vp1   = val_p1;
      vp2   = val_p2;
      vm1   = val_m1 + width - 1;
      vm2   = val_m2 + width - 1;

      /*  Set up the first vals  */
      initial_p1[0] = sp_p1[0];
      initial_p2[0] = sp_p2[0];
      initial_m1[0] = sp_m1[0];
      initial_m2[0] = sp_m2[0];

      for (col = 0; col < width; col++)
        {
          gdouble *vpptr1, *vmptr1;
          gdouble *vpptr2, *vmptr2;

          terms = (col < 4) ? col : 4;

          vpptr1 = vp1; vmptr1 = vm1;
          vpptr2 = vp2; vmptr2 = vm2;

          for (i = 0; i <= terms; i++)
            {
              *vpptr1 += n_p1[i] * sp_p1[-i] - d_p1[i] * vp1[-i];
              *vmptr1 += n_m1[i] * sp_m1[i] - d_m1[i] * vm1[i];

              *vpptr2 += n_p2[i] * sp_p2[-i] - d_p2[i] * vp2[-i];
              *vmptr2 += n_m2[i] * sp_m2[i] - d_m2[i] * vm2[i];
            }

          for (j = i; j <= 4; j++)
            {
              *vpptr1 += (n_p1[j] - bd_p1[j]) * initial_p1[0];
              *vmptr1 += (n_m1[j] - bd_m1[j]) * initial_m1[0];

              *vpptr2 += (n_p2[j] - bd_p2[j]) * initial_p2[0];
              *vmptr2 += (n_m2[j] - bd_m2[j]) * initial_m2[0];
            }

          sp_p1 ++;
          sp_p2 ++;
          sp_m1 --;
          sp_m2 --;
          vp1 ++;
          vp2 ++;
          vm1 --;
          vm2 --;
        }

      transfer_pixels (val_p1, val_m1, dest1 + row * width, 1, 1, width);
      transfer_pixels (val_p2, val_m2, dest2 + row * width, 1, 1, width);

      if (!preview)
        {
          progress += width;
          if ((row % 5) == 0)
            gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }
    }

  /* Compute the ramp value which sets 'pct_black' % of the darkened pixels black */
  ramp = compute_ramp (dest1, dest2, width * height, cvals.pct_black);

  /* Initialize the pixel regions. */
  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE);

  if (preview)
    {
      pr = gimp_pixel_rgns_register (1, &src_rgn);
      preview_buffer = g_new (guchar, width * height * bytes);
    }
  else
    {
      gimp_pixel_rgn_init (&dest_rgn, drawable,
                           x1, y1, width, height, TRUE, TRUE);
      pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
    }

  while (pr)
    {
      guchar  *src_ptr  = src_rgn.data;
      guchar  *dest_ptr;
      guchar  *blur_ptr = dest1 + (src_rgn.y - y1) * width + (src_rgn.x - x1);
      guchar  *avg_ptr  = dest2 + (src_rgn.y - y1) * width + (src_rgn.x - x1);
      gdouble  diff;
      gdouble  mult     = 0.0;
      gdouble  lightness;

      if (preview)
        dest_ptr =
          preview_buffer +
          ((src_rgn.y - y1) * width + (src_rgn.x - x1)) * bytes;
      else
        dest_ptr = dest_rgn.data;

      for (row = 0; row < src_rgn.h; row++)
        {
          for (col = 0; col < src_rgn.w; col++)
            {
              if (avg_ptr[col] != 0)
                {
                  diff = (gdouble) blur_ptr[col] / (gdouble) avg_ptr[col];
                  if (diff < cvals.threshold)
                    {
                      if (ramp == 0.0)
                        mult = 0.0;
                      else
                        mult = (ramp - MIN (ramp, (cvals.threshold - diff))) / ramp;
                    }
                  else
                    mult = 1.0;
                }

              lightness = CLAMP (blur_ptr[col] * mult, 0, 255);

              if (bytes < 3)
                {
                  dest_ptr[col * bytes] = (guchar) lightness;
                  if (has_alpha)
                    dest_ptr[col * bytes + 1] = src_ptr[col * src_rgn.bpp + 1];
                }
              else
                {
                  /*  Convert to HLS, set lightness and convert back  */
                  gint r, g, b;

                  r = src_ptr[col * src_rgn.bpp + 0];
                  g = src_ptr[col * src_rgn.bpp + 1];
                  b = src_ptr[col * src_rgn.bpp + 2];

                  gimp_rgb_to_hsl_int (&r, &g, &b);
                  b = lightness;
                  gimp_hsl_to_rgb_int (&r, &g, &b);

                  dest_ptr[col * bytes + 0] = r;
                  dest_ptr[col * bytes + 1] = g;
                  dest_ptr[col * bytes + 2] = b;

                  if (has_alpha)
                    dest_ptr[col * bytes + 3] = src_ptr[col * src_rgn.bpp + 3];
                }
            }

          src_ptr  += src_rgn.rowstride;
          if (preview)
            dest_ptr += width * bytes;
          else
            dest_ptr += dest_rgn.rowstride;
          blur_ptr += width;
          avg_ptr  += width;
        }

      if (!preview)
        {
          progress += src_rgn.w * src_rgn.h;
          gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }

      pr = gimp_pixel_rgns_process (pr);
    }

  if (preview)
    {
      gimp_preview_draw_buffer (preview, preview_buffer, width * bytes);
      g_free (preview_buffer);
    }
  else
    {
      /*  merge the shadow, update the drawable  */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }

  /*  free up buffers  */
  g_free (val_p1);
  g_free (val_p2);
  g_free (val_m1);
  g_free (val_m2);
  g_free (src);
  g_free (dest1);
  g_free (dest2);
}
Example #16
0
static void
mblur_zoom (GimpDrawable *drawable,
            GimpPreview  *preview,
            gint          x1,
            gint          y1,
            gint          width,
            gint          height)
{
  GimpPixelRgn      dest_rgn;
  GimpPixelFetcher *pft;
  gpointer          pr;
  GimpRGB           background;

  gdouble   center_x;
  gdouble   center_y;
  guchar   *dest, *d;
  guchar    pixel[4];
  guchar    p1[4], p2[4], p3[4], p4[4];
  gint32    sum[4];

  gint      progress, max_progress;
  gint      x, y, i, n, p, c;
  gdouble   xx_start, xx_end, yy_start, yy_end;
  gdouble   xx, yy;
  gdouble   dxx, dyy;
  gdouble   dx, dy;
  gint      xy_len;
  gdouble   f, r;
  gint      drawable_x1, drawable_y1;
  gint      drawable_x2, drawable_y2;

  /* initialize */

  xx = 0.0;
  yy = 0.0;
  center_x = mbvals.center_x;
  center_y = mbvals.center_y;

  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &drawable_x1, &drawable_y1,
                             &drawable_x2, &drawable_y2);
  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_pixel_fetcher_set_bg_color (pft, &background);

  progress     = 0;
  max_progress = width * height;

  n = mbvals.length;

  if (n == 0)
    n = 1;

  r = sqrt (SQR (drawable->width / 2) + SQR (drawable->height / 2));
  n = ((gdouble) n * r / MBLUR_LENGTH_MAX);
  f = (r-n)/r;

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn), p = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), p++)
    {
      dest = dest_rgn.data;

      for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
        {
          d = dest;

          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              for (c = 0; c < img_bpp; c++)
                sum[c] = 0;

              xx_start = x;
              yy_start = y;

              if (mbvals.blur_outward)
                {
                  xx_end = center_x + ((gdouble) x - center_x) * f;
                  yy_end = center_y + ((gdouble) y - center_y) * f;
                }
              else
                {
                  xx_end = center_x + ((gdouble) x - center_x) * (1.0/f);
                  yy_end = center_y + ((gdouble) y - center_y) * (1.0/f);
                }

              xy_len = sqrt (SQR (xx_end-xx_start) + SQR (yy_end-yy_start)) + 1;

              if (xy_len < 3)
                xy_len = 3;

              dxx = (xx_end - xx_start) / (gdouble) xy_len;
              dyy = (yy_end - yy_start) / (gdouble) xy_len;

              xx = xx_start;
              yy = yy_start;

              for (i = 0; i < xy_len; i++)
                {
                  if ((yy < drawable_y1) || (yy >= drawable_y2) ||
                      (xx < drawable_x1) || (xx >= drawable_x2))
                    break;

                  if ((xx+1 < drawable_x2) && (yy+1 < drawable_y2))
                    {
                      dx = xx - floor (xx);
                      dy = yy - floor (yy);

                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy,   p1);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy,   p2);
                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy+1, p3);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy+1, p4);

                      for (c = 0; c < img_bpp; c++)
                        {
                          pixel[c] = (((gdouble)p1[c] * (1.0-dx) +
                                       (gdouble)p2[c] * dx) * (1.0-dy) +
                                      ((gdouble)p3[c] * (1.0-dx) +
                                       (gdouble)p4[c] * dx) * dy);
                        }
                    }
                  else
                    {
                      gimp_pixel_fetcher_get_pixel (pft, xx+.5, yy+.5, pixel);
                    }

                  if (has_alpha)
                    {
                      gint32 alpha = pixel[img_bpp-1];

                      sum[img_bpp-1] += alpha;

                      for (c = 0; c < img_bpp-1; c++)
                        sum[c] += pixel[c] * alpha;
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        sum[c] += pixel[c];
                    }

                  xx += dxx;
                  yy += dyy;
                }

              if (i == 0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, d);
                }
              else
                {
                  if (has_alpha)
                    {
                      gint32 alpha = sum[img_bpp-1];

                      if ((d[img_bpp-1] = alpha/i) != 0)
                        {
                          for (c = 0; c < img_bpp-1; c++)
                            d[c] = sum[c] / alpha;
                        }
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        d[c] = sum[c] / i;
                    }
                }

              d += dest_rgn.bpp;
            }

          dest += dest_rgn.rowstride;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;

          if ((p % 8) == 0)
            gimp_progress_update ((gdouble) progress / max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);
}
Example #17
0
/**
 * gimp_layer_new_from_pixbuf:
 * @image_ID: The RGB image to which to add the layer.
 * @name: The layer name.
 * @pixbuf: A GdkPixbuf.
 * @opacity: The layer opacity.
 * @mode: The layer combination mode.
 * @progress_start: start of progress
 * @progress_end: end of progress
 *
 * Create a new layer from a %GdkPixbuf.
 *
 * This procedure creates a new layer from the given %GdkPixbuf.  The
 * image has to be an RGB image and just like with gimp_layer_new()
 * you will still need to add the layer to it.
 *
 * If you pass @progress_end > @progress_start to this function,
 * @gimp_progress_update() will be called for. You have to call
 * @gimp_progress_init() beforehand.
 *
 * Returns: The newly created layer.
 *
 * Since: GIMP 2.4
 */
gint32
gimp_layer_new_from_pixbuf (gint32                image_ID,
                            const gchar          *name,
                            GdkPixbuf            *pixbuf,
                            gdouble               opacity,
                            GimpLayerModeEffects  mode,
                            gdouble               progress_start,
                            gdouble               progress_end)
{
  GimpDrawable *drawable;
  GimpPixelRgn	rgn;
  const guchar *pixels;
  gpointer      pr;
  gint32        layer;
  gint          width;
  gint          height;
  gint          rowstride;
  gint          bpp;
  gdouble       range = progress_end - progress_start;
  guint         count = 0;
  guint         done  = 0;

  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);

  if (gimp_image_base_type (image_ID) != GIMP_RGB)
    {
      g_warning ("gimp_layer_new_from_pixbuf() needs an RGB image");
      return -1;
    }

  if (gdk_pixbuf_get_colorspace (pixbuf) != GDK_COLORSPACE_RGB)
    {
      g_warning ("gimp_layer_new_from_pixbuf() assumes that GdkPixbuf is RGB");
      return -1;
    }

  width  = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);
  bpp    = gdk_pixbuf_get_n_channels (pixbuf);

  layer = gimp_layer_new (image_ID, name, width, height,
                          bpp == 3 ? GIMP_RGB_IMAGE : GIMP_RGBA_IMAGE,
                          opacity, mode);

  if (layer == -1)
    return -1;

  drawable = gimp_drawable_get (layer);

  gimp_pixel_rgn_init (&rgn, drawable, 0, 0, width, height, TRUE, FALSE);

  g_assert (bpp == rgn.bpp);

  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  pixels    = gdk_pixbuf_get_pixels (pixbuf);

  for (pr = gimp_pixel_rgns_register (1, &rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      const guchar *src  = pixels + rgn.y * rowstride + rgn.x * bpp;
      guchar       *dest = rgn.data;
      gint          y;

      for (y = 0; y < rgn.h; y++)
        {
          memcpy (dest, src, rgn.w * rgn.bpp);

          src  += rowstride;
          dest += rgn.rowstride;
        }

      if (range > 0.0)
        {
          done += rgn.h * rgn.w;

          if (count++ % 32 == 0)
            gimp_progress_update (progress_start +
                                  (gdouble) done / (width * height) * range);
        }
    }

  if (range > 0.0)
    gimp_progress_update (progress_end);

  gimp_drawable_detach (drawable);

  return layer;
}
Example #18
0
static void
mblur_linear (GimpDrawable *drawable,
              GimpPreview  *preview,
              gint          x1,
              gint          y1,
              gint          width,
              gint          height)
{
  GimpPixelRgn      dest_rgn;
  GimpPixelFetcher *pft;
  gpointer          pr;
  GimpRGB           background;

  guchar *dest;
  guchar *d;
  guchar  pixel[4];
  gint32  sum[4];
  gint    progress, max_progress;
  gint    c, p;
  gint    x, y, i, xx, yy, n;
  gint    dx, dy, px, py, swapdir, err, e, s1, s2;

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

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_pixel_fetcher_set_bg_color (pft, &background);

  progress     = 0;
  max_progress = width * height;

  n = mbvals.length;
  px = (gdouble) n * cos (mbvals.angle / 180.0 * G_PI);
  py = (gdouble) n * sin (mbvals.angle / 180.0 * G_PI);

  /*
   * Initialization for Bresenham algorithm:
   * dx = abs(x2-x1), s1 = sign(x2-x1)
   * dy = abs(y2-y1), s2 = sign(y2-y1)
   */
  if ((dx = px) != 0)
    {
      if (dx < 0)
        {
          dx = -dx;
          s1 = -1;
        }
      else
        s1 = 1;
    }
  else
    s1 = 0;

  if ((dy = py) != 0)
    {
      if (dy < 0)
        {
          dy = -dy;
          s2 = -1;
        }
      else
        s2 = 1;
    }
  else
    s2 = 0;

  if (dy > dx)
    {
      swapdir = dx;
      dx = dy;
      dy = swapdir;
      swapdir = 1;
    }
  else
    swapdir = 0;

  dy *= 2;
  err = dy - dx;        /* Initial error term   */
  dx *= 2;

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn), p = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), p++)
    {
      dest = dest_rgn.data;

      for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
        {
          d = dest;

          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              xx = x; yy = y; e = err;
              for (c = 0; c < img_bpp; c++)
                sum[c]= 0;

              for (i = 0; i < n; )
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, pixel);

                  if (has_alpha)
                    {
                      gint32 alpha = pixel[img_bpp-1];

                      sum[img_bpp-1] += alpha;
                      for (c = 0; c < img_bpp-1; c++)
                        sum[c] += pixel[c] * alpha;
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        sum[c] += pixel[c];
                    }
                  i++;

                  while (e >= 0 && dx)
                    {
                      if (swapdir)
                        xx += s1;
                      else
                        yy += s2;
                      e -= dx;
                    }

                  if (swapdir)
                    yy += s2;
                  else
                    xx += s1;

                  e += dy;

                  if ((xx < x1) || (xx >= x1 + width) ||
                      (yy < y1) || (yy >= y1 + height))
                    break;
                }

              if (i == 0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, d);
                }
              else
                {
                  if (has_alpha)
                    {
                      gint32 alpha = sum[img_bpp-1];

                      if ((d[img_bpp-1] = alpha/i) != 0)
                        {
                          for (c = 0; c < img_bpp-1; c++)
                            d[c] = sum[c] / alpha;
                        }
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        d[c] = sum[c] / i;
                    }
                }

              d += dest_rgn.bpp;
            }

          dest += dest_rgn.rowstride;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;

          if ((p % 8) == 0)
            gimp_progress_update ((gdouble) progress / max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);
}
Example #19
0
static void
mblur_radial (GimpDrawable *drawable,
              GimpPreview  *preview,
              gint          x1,
              gint          y1,
              gint          width,
              gint          height)
{
  GimpPixelRgn      dest_rgn;
  GimpPixelFetcher *pft;
  gpointer          pr;
  GimpRGB           background;

  gdouble   center_x;
  gdouble   center_y;
  guchar   *dest;
  guchar   *d;
  guchar    pixel[4];
  guchar    p1[4], p2[4], p3[4], p4[4];
  gint32    sum[4];

  gint      progress, max_progress, c;

  gint      x, y, i, p, n, count;
  gdouble   angle, theta, r, xx, yy, xr, yr;
  gdouble   phi, phi_start, s_val, c_val;
  gdouble   dx, dy;

  /* initialize */

  xx = 0.0;
  yy = 0.0;

  center_x = mbvals.center_x;
  center_y = mbvals.center_y;

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

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_pixel_fetcher_set_bg_color (pft, &background);

  progress     = 0;
  max_progress = width * height;

  angle = gimp_deg_to_rad (mbvals.angle);

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn), p = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), p++)
    {
      dest = dest_rgn.data;

      for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
        {
          d = dest;

          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              xr = (gdouble) x - center_x;
              yr = (gdouble) y - center_y;

              r = sqrt (SQR (xr) + SQR (yr));
              n = r * angle;

              if (angle == 0.0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, x, y, d);
                  d += dest_rgn.bpp;
                  continue;
                }

              /* ensure quality with small angles */
              if (n < 3)
                n = 3;  /* always use at least 3 (interpolation) steps */

              /* limit loop count due to performanc reasons */
              if (n > 100)
                n = 100 + sqrt (n-100);

              if (xr != 0.0)
                {
                  phi = atan(yr/xr);
                  if (xr < 0.0)
                    phi = G_PI + phi;

                }
              else
                {
                  if (yr >= 0.0)
                    phi = G_PI_2;
                  else
                    phi = -G_PI_2;
                }

              for (c = 0; c < img_bpp; c++)
                sum[c] = 0;

              if (n == 1)
                phi_start = phi;
              else
                phi_start = phi + angle/2.0;

              theta = angle / (gdouble)n;
              count = 0;

              for (i = 0; i < n; i++)
                {
                  s_val = sin (phi_start - (gdouble) i * theta);
                  c_val = cos (phi_start - (gdouble) i * theta);

                  xx = center_x + r * c_val;
                  yy = center_y + r * s_val;

                  if ((yy < y1) || (yy >= y1 + height) ||
                      (xx < x1) || (xx >= x1 + width))
                    continue;

                  ++count;
                  if ((xx + 1 < x1 + width) && (yy + 1 < y1 + height))
                    {
                      dx = xx - floor (xx);
                      dy = yy - floor (yy);

                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy,   p1);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy,   p2);
                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy+1, p3);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy+1, p4);

                      for (c = 0; c < img_bpp; c++)
                        {
                          pixel[c] = (((gdouble) p1[c] * (1.0-dx) +
                                       (gdouble) p2[c] * dx) * (1.0-dy) +
                                      ((gdouble) p3[c] * (1.0-dx) +
                                       (gdouble) p4[c] * dx) * dy);
                        }
                    }
                  else
                    {
                      gimp_pixel_fetcher_get_pixel (pft, xx+.5, yy+.5, pixel);
                    }

                  if (has_alpha)
                    {
                      gint32 alpha = pixel[img_bpp-1];

                      sum[img_bpp-1] += alpha;

                      for (c = 0; c < img_bpp-1; c++)
                        sum[c] += pixel[c] * alpha;
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        sum[c] += pixel[c];
                    }
                }

              if (count == 0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, d);
                }
              else
                {
                  if (has_alpha)
                    {
                      gint32 alpha = sum[img_bpp-1];

                      if ((d[img_bpp-1] = alpha/count) != 0)
                        {
                          for (c = 0; c < img_bpp-1; c++)
                            d[c] = sum[c] / alpha;
                        }
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        d[c] = sum[c] / count;
                    }
                }

              d += dest_rgn.bpp;
            }

          dest += dest_rgn.rowstride;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;

          if ((p % 8) == 0)
            gimp_progress_update ((gdouble) progress / max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);

}
Example #20
0
gboolean
draw_page_cairo (GtkPrintContext *context,
                 PrintData       *data)
{
  GimpDrawable    *drawable = gimp_drawable_get (data->drawable_id);
  GimpPixelRgn     region;
  cairo_t         *cr;
  cairo_surface_t *surface;
  guchar          *pixels;
  gdouble          cr_width;
  gdouble          cr_height;
  gdouble          cr_dpi_x;
  gdouble          cr_dpi_y;
  gint             width;
  gint             height;
  gint             stride;
  gint             y;
  gdouble          scale_x;
  gdouble          scale_y;

  width  = drawable->width;
  height = drawable->height;

  gimp_tile_cache_ntiles (width / gimp_tile_width () + 1);

  cr = gtk_print_context_get_cairo_context (context);

  cr_width  = gtk_print_context_get_width  (context);
  cr_height = gtk_print_context_get_height (context);
  cr_dpi_x  = gtk_print_context_get_dpi_x  (context);
  cr_dpi_y  = gtk_print_context_get_dpi_y  (context);

  scale_x = cr_dpi_x / data->xres;
  scale_y = cr_dpi_y / data->yres;

#if 0
  /* print header if it is requested */
  if (data->show_info_header)
    {
      draw_info_header (context, cr, data);

/* In points */
#define HEADER_HEIGHT (20 * 72.0 / 25.4)
      cairo_translate (cr, 0, HEADER_HEIGHT);
      cr_height -= HEADER_HEIGHT;
    }
#endif

  cairo_translate (cr,
                   data->offset_x / cr_dpi_x * 72.0,
                   data->offset_y / cr_dpi_y * 72.0);
  cairo_scale (cr, scale_x, scale_y);

  gimp_pixel_rgn_init (&region, drawable, 0, 0, width, height, FALSE, FALSE);

  surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);

  pixels = cairo_image_surface_get_data (surface);
  stride = cairo_image_surface_get_stride (surface);

  for (y = 0; y < height; y++, pixels += stride)
    {
      gimp_pixel_rgn_get_row (&region, pixels, 0, y, width);

      switch (drawable->bpp)
        {
        case 3:
          convert_from_rgb (pixels, width);
          break;
        case 4:
          convert_from_rgba (pixels, width);
          break;
        }

      if (y % 16 == 0)
        gimp_progress_update ((gdouble) y / (gdouble) height);
    }

  cairo_set_source_surface (cr, surface, 0, 0);
  cairo_rectangle (cr, 0, 0, width, height);
  cairo_fill (cr);
  cairo_surface_destroy (surface);

  gimp_progress_update (1.0);

  gimp_drawable_detach (drawable);

  return TRUE;
}
Example #21
0
/*  -  Filter function  -  I wish all filter functions had a pmode :) */
static void
glasstile (GimpDrawable *drawable,
           GimpPreview  *preview)
{
  GimpPixelRgn  srcPR, destPR;
  gint          width, height;
  gint          bytes;
  guchar       *dest, *d;
  guchar       *cur_row;
  gint          row, col, i;
  gint          x1, y1, x2, y2;

  /* Translations of variable names from Maswan
   * rutbredd = grid width
   * ruthojd = grid height
   * ymitt = y middle
   * xmitt = x middle
   */

  gint rutbredd, xpixel1, xpixel2;
  gint ruthojd , ypixel2;
  gint xhalv, xoffs, xmitt, xplus;
  gint yhalv, yoffs, ymitt, yplus;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
      x2 = x1 + width;
      y2 = y1 + height;
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
      width  = x2 - x1;
      height = y2 - y1;
    }
  bytes  = drawable->bpp;

  cur_row = g_new (guchar, width * bytes);
  dest    = g_new (guchar, width * bytes);

  /* initialize the pixel regions, set grid height/width */
  gimp_pixel_rgn_init (&srcPR, drawable,
                        x1, y1, width, height,
                        FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable,
                       x1, y1, width, height,
                       preview == NULL, TRUE);

  rutbredd = gtvals.xblock;
  ruthojd  = gtvals.yblock;

  xhalv = rutbredd / 2;
  yhalv = ruthojd  / 2;

  xplus = rutbredd % 2;
  yplus = ruthojd  % 2;

  ymitt = y1;
  yoffs = 0;

  /*  Loop through the rows */
  for (row = y1; row < y2; row++)
    {
      d = dest;

      ypixel2 = ymitt + yoffs * 2;
      ypixel2 = CLAMP (ypixel2, 0, y2 - 1);

      gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, ypixel2, width);
      yoffs++;

      /* if current offset = half, do a displacement next time around */
      if (yoffs == yhalv)
        {
          ymitt += ruthojd;
          yoffs = - (yhalv + yplus);
        }

      xmitt = 0;
      xoffs = 0;

      for (col = 0; col < x2 - x1; col++) /* one pixel */
        {
          xpixel1 = (xmitt + xoffs) * bytes;
          xpixel2 = (xmitt + xoffs * 2) * bytes;

          if (xpixel2 < (x2 - x1) * bytes)
            {
              if (xpixel2 < 0)
                xpixel2 = 0;
              for (i = 0; i < bytes; i++)
                d[xpixel1 + i] = cur_row[xpixel2 + i];
            }
          else
            {
              for (i = 0; i < bytes; i++)
                d[xpixel1 + i] = cur_row[xpixel1 + i];
            }

          xoffs++;

          if (xoffs == xhalv)
            {
              xmitt += rutbredd;
              xoffs = - (xhalv + xplus);
            }
        }

      /*  Store the dest  */
      gimp_pixel_rgn_set_row (&destPR, dest, x1, row, width);

      if (!preview && ((row % 5) == 0))
        {
          gimp_progress_update ((gdouble) row / (gdouble) height);
        }
    }

  /*  Update region  */
  if (preview)
    {
      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &destPR);
    }
  else
    {
      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, width, height);
    }

  g_free (cur_row);
  g_free (dest);
}
Example #22
0
static void
gauss_rle (GimpDrawable *drawable,
           gdouble       radius,
           gint          pass,
           gboolean      show_progress)
{
  GimpPixelRgn src_rgn, dest_rgn;
  gint     width, height;
  gint     bytes;
  gint     has_alpha;
  guchar  *dest, *dp;
  guchar  *src, *sp;
  gint    *buf, *bb;
  gint     pixels;
  gint     total = 1;
  gint     x1, y1, x2, y2;
  gint     i, row, col, b;
  gint     start, end;
  gdouble  progress, max_progress;
  gint    *curve;
  gint    *sum = NULL;
  gint     val;
  gint     length;
  gint     initial_p, initial_m;
  gdouble  std_dev;

  if (radius <= 0.0)
    return;

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

  width  = (x2 - x1);
  height = (y2 - y1);

  if (width < 1 || height < 1)
    return;

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

  buf = g_new (gint, MAX (width, height) * 2);

  /*  allocate buffers for source and destination pixels  */
  src = g_new (guchar, MAX (width, height) * bytes);
  dest = g_new (guchar, MAX (width, height) * bytes);

  gimp_pixel_rgn_init (&src_rgn,
                       drawable, 0, 0, drawable->width, drawable->height,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn,
                       drawable, 0, 0, drawable->width, drawable->height,
                       TRUE, TRUE);

  progress = 0.0;
  max_progress  = 2 * width * height;

  /*  First the vertical pass  */
  radius = fabs (radius) + 1.0;
  std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

  curve = make_curve (std_dev, &length);
  sum = g_new (gint, 2 * length + 1);

  sum[0] = 0;

  for (i = 1; i <= length*2; i++)
    sum[i] = curve[i-length-1] + sum[i-1];
  sum += length;

  total = sum[length] - sum[-length];

  for (col = 0; col < width; col++)
    {
      gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, (y2 - y1));

      if (has_alpha)
        multiply_alpha (src, height, bytes);

      sp = src;
      dp = dest;

      for (b = 0; b < bytes; b++)
        {
          initial_p = sp[b];
          initial_m = sp[(height-1) * bytes + b];

          /*  Determine a run-length encoded version of the row  */
          run_length_encode (sp + b, buf, bytes, height);

          for (row = 0; row < height; row++)
            {
              start = (row < length) ? -row : -length;
              end = (height <= (row + length) ?
                     (height - row - 1) : length);

              val = 0;
              i = start;
              bb = buf + (row + i) * 2;

              if (start != -length)
                val += initial_p * (sum[start] - sum[-length]);

              while (i < end)
                {
                  pixels = bb[0];
                  i += pixels;

                  if (i > end)
                    i = end;

                  val += bb[1] * (sum[i] - sum[start]);
                  bb += (pixels * 2);
                  start = i;
                }

              if (end != length)
                val += initial_m * (sum[length] - sum[end]);

              dp[row * bytes + b] = val / total;
            }
        }

      if (has_alpha)
        separate_alpha (dest, height, bytes);

      gimp_pixel_rgn_set_col (&dest_rgn, dest, col + x1, y1, (y2 - y1));

      if (show_progress)
        {
          progress += height;

          if ((col % 32) == 0)
            gimp_progress_update (0.5 * (pass + (progress / max_progress)));
        }
    }

  /*  prepare for the horizontal pass  */
  gimp_pixel_rgn_init (&src_rgn,
                       drawable, 0, 0, drawable->width, drawable->height,
                       FALSE, TRUE);

  /*  Now the horizontal pass  */
  for (row = 0; row < height; row++)
    {
      gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, (x2 - x1));
      if (has_alpha)
        multiply_alpha (src, width, bytes);

      sp = src;
      dp = dest;

      for (b = 0; b < bytes; b++)
        {
          initial_p = sp[b];
          initial_m = sp[(width-1) * bytes + b];

          /*  Determine a run-length encoded version of the row  */
          run_length_encode (sp + b, buf, bytes, width);

          for (col = 0; col < width; col++)
            {
              start = (col < length) ? -col : -length;
              end = (width <= (col + length)) ? (width - col - 1) : length;

              val = 0;
              i = start;
              bb = buf + (col + i) * 2;

              if (start != -length)
                val += initial_p * (sum[start] - sum[-length]);

              while (i < end)
                {
                  pixels = bb[0];
                  i += pixels;

                  if (i > end)
                    i = end;

                  val += bb[1] * (sum[i] - sum[start]);
                  bb += (pixels * 2);
                  start = i;
                }

              if (end != length)
                val += initial_m * (sum[length] - sum[end]);

              dp[col * bytes + b] = val / total;
            }
        }

      if (has_alpha)
        separate_alpha (dest, width, bytes);

      gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, (x2 - x1));

      if (show_progress)
        {
          progress += width;

          if ((row % 32) == 0)
            gimp_progress_update (0.5 * (pass + (progress / max_progress)));
        }
    }

  /*  merge the shadow, update the drawable  */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));

  /*  free buffers  */
  g_free (buf);
  g_free (src);
  g_free (dest);
}
Example #23
0
/*
 * 'load_image()' - Load a WMF image into a new image window.
 */
static gint32
load_image (const gchar  *filename,
            GError      **error)
{
  gint32        image;
  gint32        layer;
  GimpDrawable *drawable;
  guchar       *pixels;
  GimpPixelRgn  pixel_rgn;
  guint         width, height;
  guint         rowstride;
  guint         count = 0;
  guint         done  = 0;
  gpointer      pr;

  pixels = wmf_load_file (filename, &width, &height, error);

  if (! pixels)
    return -1;

  rowstride = width * 4;

  gimp_progress_init_printf (_("Opening '%s'"),
                             gimp_filename_to_utf8 (filename));

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_set_filename (image, filename);
  gimp_image_set_resolution (image,
                             load_vals.resolution, load_vals.resolution);

  layer = gimp_layer_new (image,
                          _("Rendered WMF"),
                          width, height,
                          GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);

  drawable = gimp_drawable_get (layer);

  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, TRUE, FALSE);

  for (pr = gimp_pixel_rgns_register (1, &pixel_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      const guchar *src  = pixels + pixel_rgn.y * rowstride + pixel_rgn.x * 4;
      guchar       *dest = pixel_rgn.data;
      gint          y;

      for (y = 0; y < pixel_rgn.h; y++)
        {
          memcpy (dest, src, pixel_rgn.w * pixel_rgn.bpp);

          src  += rowstride;
          dest += pixel_rgn.rowstride;
        }

      done += pixel_rgn.h * pixel_rgn.w;

      if (count++ % 16 == 0)
        gimp_progress_update ((gdouble) done / (width * height));
    }

  g_free (pixels);

  gimp_drawable_detach (drawable);

  gimp_progress_update (1.0);

  /* Tell GIMP to display the image.
   */
  gimp_image_insert_layer (image, layer, -1, 0);
  gimp_drawable_flush (drawable);

  return image;
}
Example #24
0
static inline void
filter (void)
{
  static void (* overlap)(guchar *, const guchar *);
  GimpPixelRgn  src;
  GimpPixelRgn  dst;
  GimpRGB       color;
  guchar     pixel[4];
  gint       division_x;
  gint       division_y;
  gint       offset_x;
  gint       offset_y;
  Tile      *tiles;
  gint       numof_tiles;
  Tile      *t;
  gint       i;
  gint       x;
  gint       y;
  gint       move_max_pixels;
  gint       clear_x0;
  gint       clear_y0;
  gint       clear_x1;
  gint       clear_y1;
  gint       clear_width;
  gint       clear_height;
  guchar    *pixels;
  guchar    *buffer;
  gint       dindex;
  gint       sindex;
  gint       px, py;
  GRand     *gr;

  gr = g_rand_new ();

  /* INITIALIZE */
  gimp_pixel_rgn_init (&src, p.drawable, 0, 0,
                       p.drawable->width, p.drawable->height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dst, p.drawable, 0, 0,
                       p.drawable->width, p.drawable->height, TRUE, TRUE);
  pixels = g_new (guchar,
                  p.drawable->bpp * p.drawable->width * p.drawable->height);
  buffer = g_new (guchar,
                  p.drawable->bpp * p.params.tile_width * p.params.tile_height);

  overlap = p.drawable_has_alpha ? overlap_RGBA : overlap_RGB;

  gimp_progress_init (_("Paper Tile"));

  gimp_drawable_mask_bounds (p.drawable->drawable_id,
                             &p.selection.x0, &p.selection.y0,
                             &p.selection.x1, &p.selection.y1);
  p.selection.width  = p.selection.x1 - p.selection.x0;
  p.selection.height = p.selection.y1 - p.selection.y0;

  gimp_tile_cache_ntiles (2 * (p.selection.width / gimp_tile_width () + 1));

  /* TILES */
  division_x = p.params.division_x;
  division_y = p.params.division_y;
  if (p.params.fractional_type == FRACTIONAL_TYPE_FORCE)
    {
      if (0 < p.drawable->width  % p.params.tile_width) division_x++;
      if (0 < p.drawable->height % p.params.tile_height) division_y++;
      if (p.params.centering)
        {
          if (1 < p.drawable->width % p.params.tile_width)
            {
              division_x++;
              offset_x =
                (p.drawable->width % p.params.tile_width) / 2 -
                p.params.tile_width;
            }
          else
            {
              offset_x = 0;
            }

          if (1 < p.drawable->height % p.params.tile_height)
            {
              division_y++;
              offset_y =
                (p.drawable->height % p.params.tile_height) / 2 -
                p.params.tile_height;
            }
          else
            {
              offset_y = 0;
            }
        }
      else
        {
          offset_x = 0;
          offset_y = 0;
        }
    }
  else
    {
      if (p.params.centering)
        {
          offset_x = (p.drawable->width  % p.params.tile_width) / 2;
          offset_y = (p.drawable->height % p.params.tile_height) / 2;
        }
      else
        {
          offset_x = 0;
          offset_y = 0;
        }
    }

  move_max_pixels = p.params.move_max_rate * p.params.tile_width / 100.0;
  numof_tiles = division_x * division_y;
  t = tiles = g_new(Tile, numof_tiles);

  for (y = 0; y < division_y; y++)
    {
      gint srcy = offset_y + p.params.tile_height * y;

      for (x = 0; x < division_x; x++, t++)
        {
          gint srcx = offset_x + p.params.tile_width * x;

          if (srcx < 0)
            {
              t->x     = 0;
              t->width = srcx + p.params.tile_width;
            }
          else if (srcx + p.params.tile_width < p.drawable->width)
            {
              t->x     = srcx;
              t->width = p.params.tile_width;
            }
          else
            {
              t->x     = srcx;
              t->width = p.drawable->width - srcx;
            }

          if (srcy < 0)
            {
              t->y      = 0;
              t->height = srcy + p.params.tile_height;
            }
          else if (srcy + p.params.tile_height < p.drawable->height)
            {
              t->y      = srcy;
              t->height = p.params.tile_height;
            }
          else
            {
              t->y      = srcy;
              t->height = p.drawable->height - srcy;
            }

          t->z = g_rand_int (gr);
          random_move (&t->move_x, &t->move_y, move_max_pixels);
        }
    }

  qsort (tiles, numof_tiles, sizeof *tiles, tile_compare);

  gimp_pixel_rgn_get_rect (&src, pixels, 0, 0, p.drawable->width,
                           p.drawable->height);

  if (p.params.fractional_type == FRACTIONAL_TYPE_IGNORE)
    {
      clear_x0     = offset_x;
      clear_y0     = offset_y;
      clear_width  = p.params.tile_width * division_x;
      clear_height = p.params.tile_height * division_y;
    }
  else
    {
      clear_x0     = 0;
      clear_y0     = 0;
      clear_width  = p.drawable->width;
      clear_height = p.drawable->height;
    }

  clear_x1 = clear_x0 + clear_width;
  clear_y1 = clear_y0 + clear_height;

  switch (p.params.background_type)
    {
    case BACKGROUND_TYPE_TRANSPARENT:
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for (i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = 0;
                }
            }
        }
      break;

    case BACKGROUND_TYPE_INVERTED:
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              pixels[dindex+0] = 255 - pixels[dindex+0];
              pixels[dindex+1] = 255 - pixels[dindex+1];
              pixels[dindex+2] = 255 - pixels[dindex+2];
            }
        }
      break;

    case BACKGROUND_TYPE_IMAGE:
      break;

    case BACKGROUND_TYPE_FOREGROUND:
      gimp_context_get_foreground (&color);
      gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]);
      pixel[3] = 255;
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for (i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = pixel[i];
                }
            }
        }
      break;

    case BACKGROUND_TYPE_BACKGROUND:
      gimp_context_get_background (&color);
      gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]);
      pixel[3] = 255;
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for(i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = pixel[i];
                }
            }
        }
      break;

    case BACKGROUND_TYPE_COLOR:
      gimp_rgba_get_uchar (&p.params.background_color,
                           pixel, pixel + 1, pixel + 2, pixel + 3);
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for(i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = pixel[i];
                }
            }
        }
      break;
    }

  /* DRAW */
  for (t = tiles, i = 0; i < numof_tiles; i++, t++)
    {
      gint x0 = t->x + t->move_x;
      gint y0 = t->y + t->move_y;

      gimp_pixel_rgn_get_rect (&src, buffer, t->x, t->y, t->width, t->height);

      for (y = 0; y < t->height; y++)
        {
          py = y0 + y;
          for (x = 0; x < t->width; x++)
            {
              px = x0 + x;
              sindex = p.drawable->bpp * (t->width * y + x);
              if (0 <= px && px < p.drawable->width &&
                  0 <= py && py < p.drawable->height)
                {
                  dindex = p.drawable->bpp * (p.drawable->width * py + px);
                  overlap(&pixels[dindex], &buffer[sindex]);
                }
              else if (p.params.wrap_around)
                {
                  px = (px + p.drawable->width)  % p.drawable->width;
                  py = (py + p.drawable->height) % p.drawable->height;
                  dindex = p.drawable->bpp * (p.drawable->width * py + px);
                  overlap(&pixels[dindex], &buffer[sindex]);
                }
            }
        }

      gimp_progress_update ((gdouble) i / (gdouble) numof_tiles);
    }

  gimp_pixel_rgn_set_rect (&dst, pixels, 0, 0, p.drawable->width,
                           p.drawable->height);

  gimp_progress_update (1.0);
  gimp_drawable_flush (p.drawable);
  gimp_drawable_merge_shadow (p.drawable->drawable_id, TRUE);
  gimp_drawable_update (p.drawable->drawable_id,
                        p.selection.x0, p.selection.y0,
                        p.selection.width, p.selection.height);

  g_rand_free (gr);
  g_free (buffer);
  g_free (pixels);
  g_free (tiles);
}
Example #25
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[1];
  gint32             image_ID;
  GimpDrawable      *drawable;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;

  run_mode = param[0].data.d_int32;

  INIT_I18N ();

  *nreturn_vals = 1;
  *return_vals  = values;

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

  /*  Get the specified image and drawable  */
  image_ID = param[1].data.d_image;
  drawable = gimp_drawable_get (param[2].data.d_drawable);

  /*  set the tile cache size so that the gaussian blur works well  */
  gimp_tile_cache_ntiles (2 *
                          (MAX (drawable->width, drawable->height) /
                           gimp_tile_width () + 1));

  if (strcmp (name, PLUG_IN_PROC) == 0)
    {
      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
          /*  Possibly retrieve data  */
          gimp_get_data (PLUG_IN_PROC, &dogvals);

          /*  First acquire information with a dialog  */
          if (! dog_dialog (image_ID, drawable))
            return;
          break;

        case GIMP_RUN_NONINTERACTIVE:
          /*  Make sure all the arguments are there!  */
          if (nparams != 7)
            status = GIMP_PDB_CALLING_ERROR;

          if (status == GIMP_PDB_SUCCESS)
            {
              dogvals.inner     = param[3].data.d_float;
              dogvals.outer     = param[4].data.d_float;
              dogvals.normalize = param[5].data.d_int32;
              dogvals.invert    = param[6].data.d_int32;
            }
          if (status == GIMP_PDB_SUCCESS &&
              (dogvals.inner <= 0.0 && dogvals.outer <= 0.0))
            status = GIMP_PDB_CALLING_ERROR;
          break;

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

        default:
          break;
        }
    }
  else
    {
      status = GIMP_PDB_CALLING_ERROR;
    }

  if (status == GIMP_PDB_SUCCESS)
    {
      /*  Make sure that the drawable is gray or RGB color  */
      if (gimp_drawable_is_rgb (drawable->drawable_id) ||
          gimp_drawable_is_gray (drawable->drawable_id))
        {
          gimp_progress_init (_("DoG Edge Detect"));

          /*  run the Difference of Gaussians  */
          gimp_image_undo_group_start (image_ID);

          dog (image_ID, drawable, dogvals.inner, dogvals.outer, TRUE);

          gimp_image_undo_group_end (image_ID);

          gimp_progress_update (1.0);

          /*  Store data  */
          if (run_mode == GIMP_RUN_INTERACTIVE)
            gimp_set_data (PLUG_IN_PROC, &dogvals, sizeof (DoGValues));

          if (run_mode != GIMP_RUN_NONINTERACTIVE)
            gimp_displays_flush ();
        }
      else
        {
          g_message (_("Cannot operate on indexed color images."));
          status = GIMP_PDB_EXECUTION_ERROR;
        }

      gimp_drawable_detach (drawable);
    }

  values[0].data.d_status = status;
}
Example #26
0
static gboolean
copy_uri (const gchar  *src_uri,
          const gchar  *dest_uri,
          const gchar  *copying_format_str,
          const gchar  *copied_format_str,
          GError      **error)
{
  GnomeVFSHandle   *read_handle;
  GnomeVFSHandle   *write_handle;
  GnomeVFSFileInfo *src_info;
  GnomeVFSFileSize  file_size  = 0;
  GnomeVFSFileSize  bytes_read = 0;
  guchar            buffer[BUFSIZE];
  GnomeVFSResult    result;
  gchar            *memsize;
  GTimeVal          last_time = { 0, 0 };

  gimp_progress_init (_("Connecting to server"));

  src_info = gnome_vfs_file_info_new ();
  result = gnome_vfs_get_file_info (src_uri, src_info, 0);

  /*  ignore errors here, they will be noticed below  */
  if (result == GNOME_VFS_OK &&
      (src_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE))
    {
      file_size = src_info->size;
    }

  gnome_vfs_file_info_unref (src_info);

  result = gnome_vfs_open (&read_handle, src_uri, GNOME_VFS_OPEN_READ);

  if (result != GNOME_VFS_OK)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Could not open '%s' for reading: %s"),
                   src_uri, gnome_vfs_result_to_string (result));
      return FALSE;
    }

  result = gnome_vfs_create (&write_handle, dest_uri,
                             GNOME_VFS_OPEN_WRITE, FALSE, 0644);

  if (result != GNOME_VFS_OK)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Could not open '%s' for writing: %s"),
                   dest_uri, gnome_vfs_result_to_string (result));
      gnome_vfs_close (read_handle);
      return FALSE;
    }

  memsize = g_format_size_for_display (file_size);

  gimp_progress_init_printf (file_size > 0 ?
                             copying_format_str : copied_format_str,
                             memsize);

  g_free (memsize);

  while (TRUE)
    {
      GnomeVFSFileSize  chunk_read;
      GnomeVFSFileSize  chunk_written;
      GTimeVal          now;

      result = gnome_vfs_read (read_handle, buffer, sizeof (buffer),
                               &chunk_read);

      if (chunk_read == 0)
        {
          if (result != GNOME_VFS_ERROR_EOF)
            {
              memsize = g_format_size_for_display (sizeof (buffer));
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("Failed to read %s from '%s': %s"),
                           memsize, src_uri,
                           gnome_vfs_result_to_string (result));
              g_free (memsize);

              gnome_vfs_close (read_handle);
              gnome_vfs_close (write_handle);
              return FALSE;
            }
          else
            {
              gimp_progress_update (1.0);
              break;
            }
        }

      bytes_read += chunk_read;

      /*  update the progress only up to 10 times a second  */

      g_get_current_time (&now);

      if (((now.tv_sec - last_time.tv_sec) * 1000 +
           (now.tv_usec - last_time.tv_usec) / 1000) > 100)
        {
          if (file_size > 0)
            {
              gimp_progress_update ((gdouble) bytes_read / (gdouble) file_size);
            }
          else
            {
              memsize = g_format_size_for_display (bytes_read);

              gimp_progress_set_text_printf (copied_format_str, memsize);
              gimp_progress_pulse ();

              g_free (memsize);
            }

          last_time = now;
        }

      result = gnome_vfs_write (write_handle, buffer, chunk_read,
                                &chunk_written);

      if (chunk_written < chunk_read)
        {
          memsize = g_format_size_for_display (chunk_read);
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("Failed to write %s to '%s': %s"),
                       memsize, dest_uri,
                       gnome_vfs_result_to_string (result));
          g_free (memsize);

          gnome_vfs_close (read_handle);
          gnome_vfs_close (write_handle);
          return FALSE;
        }
    }

  gnome_vfs_close (read_handle);
  gnome_vfs_close (write_handle);

  return TRUE;
}
Example #27
0
static gint32
tile (gint32  image_id,
      gint32  drawable_id,
      gint32 *layer_id)
{
  GimpPixelRgn       src_rgn;
  GimpPixelRgn       dest_rgn;
  GimpDrawable      *drawable;
  GimpDrawable      *new_layer;
  GimpImageBaseType  image_type   = GIMP_RGB;
  gint32             new_image_id = 0;
  gint               old_width;
  gint               old_height;
  gint               i, j;
  gint               progress;
  gint               max_progress;
  gpointer           pr;

  /* sanity check parameters */
  if (tvals.new_width < 1 || tvals.new_height < 1)
    {
      *layer_id = -1;
      return -1;
    }

  /* initialize */
  old_width  = gimp_drawable_width  (drawable_id);
  old_height = gimp_drawable_height (drawable_id);

  if (tvals.new_image)
    {
      /*  create  a new image  */
      switch (gimp_drawable_type (drawable_id))
        {
        case GIMP_RGB_IMAGE:
        case GIMP_RGBA_IMAGE:
          image_type = GIMP_RGB;
          break;

        case GIMP_GRAY_IMAGE:
        case GIMP_GRAYA_IMAGE:
          image_type = GIMP_GRAY;
          break;

        case GIMP_INDEXED_IMAGE:
        case GIMP_INDEXEDA_IMAGE:
          image_type = GIMP_INDEXED;
          break;
        }

      new_image_id = gimp_image_new (tvals.new_width, tvals.new_height,
                                     image_type);
      gimp_image_undo_disable (new_image_id);

      *layer_id = gimp_layer_new (new_image_id, _("Background"),
                                  tvals.new_width, tvals.new_height,
                                  gimp_drawable_type (drawable_id),
                                  100, GIMP_NORMAL_MODE);

      if (*layer_id == -1)
        return -1;

      gimp_image_insert_layer (new_image_id, *layer_id, -1, 0);
      new_layer = gimp_drawable_get (*layer_id);

      /*  Get the source drawable  */
      drawable = gimp_drawable_get (drawable_id);
    }
  else
    {
      gimp_image_undo_group_start (image_id);

      gimp_image_resize (image_id,
                         tvals.new_width, tvals.new_height,
                         0, 0);

      if (gimp_item_is_layer (drawable_id))
        gimp_layer_resize (drawable_id,
                           tvals.new_width, tvals.new_height,
                           0, 0);

      /*  Get the source drawable  */
      drawable = gimp_drawable_get (drawable_id);
      new_layer = drawable;
    }

  /*  progress  */
  progress = 0;
  max_progress = tvals.new_width * tvals.new_height;

  /*  tile...  */
  for (i = 0; i < tvals.new_height; i += old_height)
    {
      gint height = old_height;

      if (height + i > tvals.new_height)
        height = tvals.new_height - i;

      for (j = 0; j < tvals.new_width; j += old_width)
        {
          gint width = old_width;
          gint c;

          if (width + j > tvals.new_width)
            width = tvals.new_width - j;

          gimp_pixel_rgn_init (&src_rgn, drawable,
                               0, 0, width, height, FALSE, FALSE);
          gimp_pixel_rgn_init (&dest_rgn, new_layer,
                               j, i, width, height, TRUE, FALSE);

          for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), c = 0;
               pr != NULL;
               pr = gimp_pixel_rgns_process (pr), c++)
            {
              gint k;

              for (k = 0; k < src_rgn.h; k++)
                memcpy (dest_rgn.data + k * dest_rgn.rowstride,
                        src_rgn.data + k * src_rgn.rowstride,
                        src_rgn.w * src_rgn.bpp);

              progress += src_rgn.w * src_rgn.h;

              if (c % 16 == 0)
                gimp_progress_update ((gdouble) progress /
                                      (gdouble) max_progress);
            }
        }
    }

  gimp_drawable_update (new_layer->drawable_id,
                        0, 0, new_layer->width, new_layer->height);

  gimp_drawable_detach (drawable);

  if (tvals.new_image)
    {
      gimp_drawable_detach (new_layer);

      /*  copy the colormap, if necessary  */
      if (image_type == GIMP_INDEXED)
        {
          guchar *cmap;
          gint    ncols;

          cmap = gimp_image_get_colormap (image_id, &ncols);
          gimp_image_set_colormap (new_image_id, cmap, ncols);
          g_free (cmap);
        }

      gimp_image_undo_enable (new_image_id);
    }
  else
    {
      gimp_image_undo_group_end (image_id);
    }

  return new_image_id;
}
static void
explorer (GimpDrawable * drawable)
{
  GimpPixelRgn  srcPR;
  GimpPixelRgn  destPR;
  gint          width;
  gint          height;
  gint          bpp;
  gint          row;
  gint          x1;
  gint          y1;
  gint          x2;
  gint          y2;
  guchar       *src_row;
  guchar       *dest_row;

  /* Get the input area. This is the bounding box of the selection in
   *  the image (or the entire image if there is no selection). Only
   *  operating on the input area is simply an optimization. It doesn't
   *  need to be done for correct operation. (It simply makes it go
   *  faster, since fewer pixels need to be operated on).
   */
  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  /* Get the size of the input image. (This will/must be the same
   *  as the size of the output image.
   */
  width  = drawable->width;
  height = drawable->height;
  bpp  = drawable->bpp;

  /*  allocate row buffers  */
  src_row  = g_new (guchar, bpp * (x2 - x1));
  dest_row = g_new (guchar, bpp * (x2 - x1));

  /*  initialize the pixel regions  */
  gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);

  xbild = width;
  ybild = height;
  xdiff = (xmax - xmin) / xbild;
  ydiff = (ymax - ymin) / ybild;

  /* for grayscale drawables */
  if (bpp < 3)
    {
      gint     i;
      for (i = 0; i < MAXNCOLORS; i++)
          valuemap[i] = GIMP_RGB_LUMINANCE (colormap[i].r,
                                            colormap[i].g,
                                            colormap[i].b);
    }

  for (row = y1; row < y2; row++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1));

      explorer_render_row (src_row,
                           dest_row,
                           row,
                           (x2 - x1),
                           bpp);

      /*  store the dest  */
      gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1));

      if ((row % 10) == 0)
        gimp_progress_update ((double) row / (double) (y2 - y1));
    }

  /*  update the processed 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));

  g_free (src_row);
  g_free (dest_row);
}
Example #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);
    }
}
Example #30
0
static void
value_propagate_body (GimpDrawable *drawable,
                      GimpPreview  *preview)
{
  GimpImageType  dtype;
  ModeParam      operation;
  GimpPixelRgn   srcRgn, destRgn;
  guchar        *here, *best, *dest;
  guchar        *dest_row, *prev_row, *cur_row, *next_row;
  guchar        *pr, *cr, *nr, *swap;
  gint           width, height, bytes, index;
  gint           begx, begy, endx, endy, x, y, dx;
  gint           left_index, right_index, up_index, down_index;
  gpointer       tmp;
  GimpRGB        foreground;

  /* calculate neighbors' indexes */
  left_index  = (vpvals.direction_mask & (1 << Left2Right)) ? -1 : 0;
  right_index = (vpvals.direction_mask & (1 << Right2Left)) ?  1 : 0;
  up_index    = (vpvals.direction_mask & (1 << Top2Bottom)) ? -1 : 0;
  down_index  = (vpvals.direction_mask & (1 << Bottom2Top)) ?  1 : 0;
  operation   = modes[vpvals.propagate_mode];
  tmp         = NULL;

  dtype = gimp_drawable_type (drawable->drawable_id);
  bytes = drawable->bpp;

  /* Here I use the algorithm of blur.c */
  if (preview)
    {
       gimp_preview_get_position (preview, &begx, &begy);
       gimp_preview_get_size (preview, &width, &height);

       endx = begx + width;
       endy = begy + height;
    }
  else
    {
      if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                          &begx, &begy, &width, &height))
        return;

      endx = begx + width;
      endy = begy + height;
    }

  gimp_tile_cache_ntiles (2 * ((width) / gimp_tile_width () + 1));

  prev_row = g_new (guchar, (width + 2) * bytes);
  cur_row  = g_new (guchar, (width + 2) * bytes);
  next_row = g_new (guchar, (width + 2) * bytes);
  dest_row = g_new (guchar, width * bytes);

  gimp_pixel_rgn_init (&srcRgn, drawable,
                       begx, begy, width, height,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&destRgn, drawable,
                       begx, begy, width, height,
                       (preview == NULL), TRUE);

  pr = prev_row + bytes;
  cr = cur_row + bytes;
  nr = next_row + bytes;

  prepare_row (&srcRgn, pr, begx, (0 < begy) ? begy : begy - 1, endx-begx);
  prepare_row (&srcRgn, cr, begx, begy, endx-begx);

  best = g_new (guchar, bytes);

  if (!preview)
    gimp_progress_init (_("Value Propagate"));

  gimp_context_get_foreground (&foreground);
  gimp_rgb_get_uchar (&foreground, fore+0, fore+1, fore+2);

  /* start real job */
  for (y = begy ; y < endy ; y++)
    {
      prepare_row (&srcRgn, nr, begx, ((y+1) < endy) ? y+1 : endy, endx-begx);

      for (index = 0; index < (endx - begx) * bytes; index++)
        dest_row[index] = cr[index];

      for (x = 0 ; x < endx - begx; x++)
        {
          dest = dest_row + (x * bytes);
          here = cr + (x * bytes);

          /* *** copy source value to best value holder *** */
          memcpy (best, here, bytes);

          if (operation.initializer)
            (* operation.initializer)(dtype, bytes, best, here, &tmp);

          /* *** gather neighbors' values: loop-unfolded version *** */
          if (up_index == -1)
            for (dx = left_index ; dx <= right_index ; dx++)
              (* operation.updater)(dtype, bytes, here, pr+((x+dx)*bytes), best, tmp);
          for (dx = left_index ; dx <= right_index ; dx++)
            if (dx != 0)
              (* operation.updater)(dtype, bytes, here, cr+((x+dx)*bytes), best, tmp);
          if (down_index == 1)
            for (dx = left_index ; dx <= right_index ; dx++)
              (* operation.updater)(dtype, bytes, here, nr+((x+dx)*bytes), best, tmp);
          /* *** store it to dest_row*** */
          (* operation.finalizer)(dtype, bytes, best, here, dest, tmp);
        }

      /* now store destline to destRgn */
      gimp_pixel_rgn_set_row (&destRgn, dest_row, begx, y, endx - begx);

      /* shift the row pointers  */
      swap = pr;
      pr = cr;
      cr = nr;
      nr = swap;


      if (((y % 16) == 0) && !preview)
        gimp_progress_update ((gdouble) y / (gdouble) (endy - begy));
    }

  if (preview)
    {
      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &destRgn);
    }
  else
    {
      /*  update the region  */
      gimp_progress_update (1.0);
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, begx, begy, endx-begx, endy-begy);
    }
}