Example #1
0
static void
file_open_handle_color_profile (GimpImage    *image,
                                GimpContext  *context,
                                GimpProgress *progress,
                                GimpRunMode   run_mode)
{
  if (gimp_image_get_icc_parasite (image))
    {
      gimp_image_undo_disable (image);

      switch (image->gimp->config->color_profile_policy)
        {
        case GIMP_COLOR_PROFILE_POLICY_ASK:
          if (run_mode == GIMP_RUN_INTERACTIVE)
            file_open_profile_apply_rgb (image, context, progress,
                                         GIMP_RUN_INTERACTIVE);
          break;

        case GIMP_COLOR_PROFILE_POLICY_KEEP:
          break;

        case GIMP_COLOR_PROFILE_POLICY_CONVERT:
          file_open_profile_apply_rgb (image, context, progress,
                                       GIMP_RUN_NONINTERACTIVE);
          break;
        }

      gimp_image_clean_all (image);
      gimp_image_undo_enable (image);
    }
}
Example #2
0
/* ============================================================================
 * gap_image_delete_immediate
 *    delete image (with workaround to ensure that most of the
 *    allocatd memory is freed)
 * ============================================================================
 * The workaround disables undo and scales the image down to miniumum size
 * before calling the gimp_image_delete procedure.
 * this way memory resources for big layers will be freed up immediate.
 */
void
gap_image_delete_immediate (gint32 image_id)
{
  gboolean imageDeleteWorkaroundDefault = TRUE;
  if(gap_base_get_gimprc_gboolean_value("gap-image-delete-workaround"
         , imageDeleteWorkaroundDefault))
  {
    if(gap_debug)
    {
      printf("gap_image_delete_immediate: SCALED down to 2x2 id = %d (workaround for gimp_image-delete problem)\n"
              , (int)image_id
              );
    }

    gimp_image_undo_disable(image_id);
    
    //gimp_image_scale_full(image_id, 2, 2, 0 /*INTERPOLATION_NONE*/);

    gimp_context_push();
    gimp_context_set_interpolation(0);
    gimp_image_scale(image_id, 2, 2);
    gimp_context_pop();


    gimp_image_undo_enable(image_id); /* clear undo stack */
  }

  gimp_image_delete(image_id);
}       /* end  gap_image_delete_immediate */
Example #3
0
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
static gint32
create_new_image (const gchar        *filename,
                  const gchar        *layername,
                  guint               width,
                  guint               height,
                  GimpImageBaseType   type,
                  gdouble             xres,
                  gdouble             yres,
                  gint32             *layer_ID,
                  GimpDrawable      **drawable,
                  GimpPixelRgn       *pixel_rgn)
{
  gint32 image_ID;

  image_ID = gimp_image_new (width, height, type);

  gimp_image_undo_disable (image_ID);
  gimp_image_set_filename (image_ID, filename);
  gimp_image_set_resolution (image_ID, xres, yres);

  *layer_ID = create_new_layer (image_ID, 0,
                                layername, width, height, type,
                                drawable, pixel_rgn);

  return image_ID;
}
Example #4
0
static gint32
create_image (GdkPixbuf   *pixbuf,
              GdkRegion   *shape,
              const gchar *name)
{
  gint32     image;
  gint32     layer;
  gdouble    xres, yres;
  gchar     *comment;
  gint       width, height;
  gboolean   status;

  status = gimp_progress_init (_("Importing screenshot"));

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

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_undo_disable (image);

  gimp_get_monitor_resolution (&xres, &yres);
  gimp_image_set_resolution (image, xres, yres);

  comment = gimp_get_default_comment ();
  if (comment)
    {
      GimpParasite *parasite;

      parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT,
                                    strlen (comment) + 1, comment);

      gimp_image_parasite_attach (image, parasite);
      gimp_parasite_free (parasite);

      g_free (comment);
    }

  layer = gimp_layer_new_from_pixbuf (image,
                                      name ? name : _("Screenshot"),
                                      pixbuf,
                                      100, GIMP_NORMAL_MODE, 0.0, 1.0);
  gimp_image_add_layer (image, layer, 0);

  if (shape && ! gdk_region_empty (shape))
    {
      image_select_shape (image, shape);

      if (! gimp_selection_is_empty (image))
        {
          gimp_layer_add_alpha (layer);
          gimp_edit_clear (layer);
          gimp_selection_none (image);
        }
    }

  gimp_image_undo_enable (image);

  return image;
}
Example #5
0
static gint32
load_image (const gchar  *filename,
            GError      **load_error)
{
  gint32        image;
  gint32        layer;
  GdkPixbuf    *pixbuf;
  gint          width;
  gint          height;
  GError       *error = NULL;

  pixbuf = load_rsvg_pixbuf (filename, &load_vals, &error);

  if (! pixbuf)
    {
      /*  Do not rely on librsvg setting GError on failure!  */
      g_set_error (load_error,
                   error ? error->domain : 0, error ? error->code : 0,
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename),
                   error ? error->message : _("Unknown reason"));
      g_clear_error (&error);

      return -1;
    }

  gimp_progress_init (_("Rendering SVG"));

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

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_undo_disable (image);

  gimp_image_set_filename (image, filename);
  gimp_image_set_resolution (image,
                             load_vals.resolution, load_vals.resolution);

  layer = gimp_layer_new_from_pixbuf (image, _("Rendered SVG"), pixbuf,
                                      100, GIMP_NORMAL_MODE, 0.0, 1.0);
  gimp_image_insert_layer (image, layer, -1, 0);

  gimp_image_undo_enable (image);

  return image;
}
Example #6
0
static gint32
create_gimp_image (PSDimage    *img_a,
                   const gchar *filename)
{
  gint32 image_id = -1;

  img_a->base_type = GIMP_RGB;

  /* Create gimp image */
  IFDBG(2) g_debug ("Create image");
  image_id = gimp_image_new (img_a->columns, img_a->rows, img_a->base_type);

  gimp_image_set_filename (image_id, filename);
  gimp_image_undo_disable (image_id);

  return image_id;
}
Example #7
0
/* ---------------------------------------
 * gap_pview_render_f_from_image_duplicate
 * ---------------------------------------
 * render preview widget from image.
 * This procedure creates a temorary copy of the image
 * for rendering of the preview.
 * NOTE: if the caller wants to render a temporary image
 *       that is not needed anymore after the rendering,
 *       the procedure gap_pview_render_f_from_image should be used
 *       to avoid duplicating of the image.
 *
 * hint: call gtk_widget_queue_draw(pv_ptr->da_widget);
 * after this procedure to make the changes appear on screen.
 */
void
gap_pview_render_f_from_image_duplicate (GapPView *pv_ptr
  , gint32 image_id
  , gint32 flip_request
  , gint32 flip_status
  )
{
  gint32 dup_image_id;
  
  dup_image_id = gimp_image_duplicate(image_id);
  gimp_image_undo_disable (dup_image_id); 
  gap_pview_render_f_from_image(pv_ptr
                 , dup_image_id
                 , flip_request
                 , flip_status
                 );
  gimp_image_delete(dup_image_id);
  
}  /* end gap_pview_render_f_from_image_duplicate */
Example #8
0
static void
webx_pipeline_create_background (WebxPipeline *pipeline)
{
  g_return_if_fail (WEBX_IS_PIPELINE (pipeline));

  if (gimp_drawable_is_rgb (pipeline->rgb_layer))
    {
      pipeline->background = webx_drawable_to_pixbuf (pipeline->rgb_layer);
    }
  else
    {
      /* pipeline->rgb_image is still original image, which can be
         non rgb (as we create background early in pipeline). */
      gint duplicate = gimp_image_duplicate (pipeline->rgb_image);
      gimp_image_undo_disable (duplicate);
      pipeline->background = webx_image_to_pixbuf (duplicate);
      gimp_image_delete (duplicate);
    }
}
/* ---------------------------------------
 * gap_track_detail_on_top_layers_lastvals
 * ---------------------------------------
 * processing based on last values used in the same gimp session.
 * (uses defaults when called the 1.st time)
 * Intended for use in the player
 */
gint32
gap_track_detail_on_top_layers_lastvals(gint32 imageId)
{
    gint32       rc;
    gboolean     doProgress;
    FilterValues fiVals;

    /* clear undo stack */
    if (gimp_image_undo_is_enabled(imageId))
    {
        gimp_image_undo_disable(imageId);
    }

    doProgress = FALSE;
    gap_detail_tracking_get_values(&fiVals);
    rc = gap_track_detail_on_top_layers(imageId, doProgress, &fiVals);

    gimp_image_undo_enable(imageId); /* clear undo stack */

    return(rc);

}  /* end gap_track_detail_on_top_layers_lastvals */
Example #10
0
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
static gint32
create_new_image (const gchar    *filename,
                  guint           width,
                  guint           height,
                  GimpImageType   gdtype,
                  gint32         *layer_ID,
                  GimpDrawable  **drawable,
                  GimpPixelRgn   *pixel_rgn)
{
  gint32            image_ID;
  GimpImageBaseType gitype;

  if ((gdtype == GIMP_GRAY_IMAGE) || (gdtype == GIMP_GRAYA_IMAGE))
    gitype = GIMP_GRAY;
  else if ((gdtype == GIMP_INDEXED_IMAGE) || (gdtype == GIMP_INDEXEDA_IMAGE))
    gitype = GIMP_INDEXED;
  else
    gitype = GIMP_RGB;

  image_ID = gimp_image_new (width, height, gitype);
  gimp_image_set_filename (image_ID, filename);

  gimp_image_undo_disable (image_ID);
  *layer_ID = gimp_layer_new (image_ID, _("Background"), width, height,
                              gdtype, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer (image_ID, *layer_ID, -1, 0);

  if (drawable)
    {
      *drawable = gimp_drawable_get (*layer_ID);
      if (pixel_rgn != NULL)
        gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
                             (*drawable)->height, TRUE, FALSE);
    }

  return image_ID;
}
Example #11
0
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
static gint32
create_new_image (const gchar        *filename,
                  const gchar        *layername,
                  guint               width,
                  guint               height,
                  GimpImageBaseType   type,
                  GimpPrecision       precision,
                  gdouble             xres,
                  gdouble             yres,
                  gint32             *layer_ID)
{
  gint32 image_ID;

  image_ID = gimp_image_new_with_precision (width, height, type, precision);

  gimp_image_undo_disable (image_ID);
  gimp_image_set_filename (image_ID, filename);
  gimp_image_set_resolution (image_ID, xres, yres);

  *layer_ID = create_new_layer (image_ID, 0,
                                layername, width, height, type);

  return image_ID;
}
Example #12
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 #13
0
static GValueArray *
image_undo_disable_invoker (GimpProcedure      *procedure,
                            Gimp               *gimp,
                            GimpContext        *context,
                            GimpProgress       *progress,
                            const GValueArray  *args,
                            GError            **error)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  GimpImage *image;
  gboolean disabled = FALSE;

  image = gimp_value_get_image (&args->values[0], gimp);

  if (success)
    {
    #if 0
      GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;

      if (plug_in)
        success = gimp_plug_in_cleanup_undo_disable (plug_in, image);
    #endif

      if (success)
        disabled = gimp_image_undo_disable (image);
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_boolean (&return_vals->values[1], disabled);

  return return_vals;
}
Example #14
0
gint32
load_image (const gchar  *filename,
            GimpRunMode   runmode,
            gboolean      preview,
            gboolean     *resolution_loaded,
            GError      **error)
{
  gint32 volatile  image_ID;
  gint32           layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  jpeg_saved_marker_ptr         marker;
  FILE            *infile;
  guchar          *buf;
  guchar         **rowbuf;
  GimpImageBaseType image_type;
  GimpImageType    layer_type;
  GeglBuffer      *buffer = NULL;
  const Babl      *format;
  gint             tile_height;
  gint             scanlines;
  gint             i, start, end;
  cmsHTRANSFORM    cmyk_transform = NULL;

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  if (!preview)
    {
      jerr.pub.output_message = my_output_message;

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

  if ((infile = g_fopen (filename, "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return -1;
    }

  image_ID = -1;

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
        fclose (infile);

      if (image_ID != -1 && !preview)
        gimp_image_delete (image_ID);

      if (preview)
        destroy_preview ();

      if (buffer)
        g_object_unref (buffer);

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  if (! preview)
    {
      /* - step 2.1: tell the lib to save the comments */
      jpeg_save_markers (&cinfo, JPEG_COM, 0xffff);

      /* - step 2.2: tell the lib to save APP1 data (Exif or XMP) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xffff);

      /* - step 2.3: tell the lib to save APP2 data (ICC profiles) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 2, 0xffff);
    }

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   */

  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar,
               tile_height * cinfo.output_width * cinfo.output_components);

  rowbuf = g_new (guchar *, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  switch (cinfo.output_components)
    {
    case 1:
      image_type = GIMP_GRAY;
      layer_type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      image_type = GIMP_RGB;
      layer_type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          image_type = GIMP_RGB;
          layer_type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);
      return -1;
      break;
    }

  if (preview)
    {
      image_ID = preview_image_ID;
    }
  else
    {
      image_ID = gimp_image_new_with_precision (cinfo.output_width,
                                                cinfo.output_height,
                                                image_type,
                                                GIMP_PRECISION_U8_GAMMA);

      gimp_image_undo_disable (image_ID);
      gimp_image_set_filename (image_ID, filename);
    }

  if (preview)
    {
      preview_layer_ID = gimp_layer_new (preview_image_ID, _("JPEG preview"),
                                         cinfo.output_width,
                                         cinfo.output_height,
                                         layer_type, 100, GIMP_NORMAL_MODE);
      layer_ID = preview_layer_ID;
    }
  else
    {
      layer_ID = gimp_layer_new (image_ID, _("Background"),
                                 cinfo.output_width,
                                 cinfo.output_height,
                                 layer_type, 100, GIMP_NORMAL_MODE);
    }

  if (! preview)
    {
      GString  *comment_buffer = NULL;
      guint8   *profile        = NULL;
      guint     profile_size   = 0;

      /* Step 5.0: save the original JPEG settings in a parasite */
      jpeg_detect_original_settings (&cinfo, image_ID);

      /* Step 5.1: check for comments, or Exif metadata in APP1 markers */
      for (marker = cinfo.marker_list; marker; marker = marker->next)
        {
          const gchar *data = (const gchar *) marker->data;
          gsize        len  = marker->data_length;

          if (marker->marker == JPEG_COM)
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found image comment (%d bytes)\n",
                       marker->data_length);
#endif

              if (! comment_buffer)
                {
                  comment_buffer = g_string_new_len (data, len);
                }
              else
                {
                  /* concatenate multiple comments, separate them with LF */
                  g_string_append_c (comment_buffer, '\n');
                  g_string_append_len (comment_buffer, data, len);
                }
            }
          else if ((marker->marker == JPEG_APP0 + 1)
                   && (len > sizeof (JPEG_APP_HEADER_EXIF) + 8)
                   && ! strcmp (JPEG_APP_HEADER_EXIF, data))
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found Exif block (%d bytes)\n",
                       (gint) (len - sizeof (JPEG_APP_HEADER_EXIF)));
#endif
            }
        }

      if (jpeg_load_resolution (image_ID, &cinfo))
        {
          if (resolution_loaded)
            *resolution_loaded = TRUE;
        }

      /* if we found any comments, then make a parasite for them */
      if (comment_buffer && comment_buffer->len)
        {
          GimpParasite *parasite;

          jpeg_load_sanitize_comment (comment_buffer->str);
          parasite = gimp_parasite_new ("gimp-comment",
                                        GIMP_PARASITE_PERSISTENT,
                                        strlen (comment_buffer->str) + 1,
                                        comment_buffer->str);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);

          g_string_free (comment_buffer, TRUE);
        }

      /* Step 5.3: check for an embedded ICC profile in APP2 markers */
      jpeg_icc_read_profile (&cinfo, &profile, &profile_size);

      if (cinfo.out_color_space == JCS_CMYK)
        {
          cmyk_transform = jpeg_load_cmyk_transform (profile, profile_size);
        }
      else if (profile) /* don't attach the profile if we are transforming */
        {
          GimpParasite *parasite;

          parasite = gimp_parasite_new ("icc-profile",
                                        GIMP_PARASITE_PERSISTENT |
                                        GIMP_PARASITE_UNDOABLE,
                                        profile_size, profile);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);
        }

      g_free (profile);

      /* Do not attach the "jpeg-save-options" parasite to the image
       * because this conflicts with the global defaults (bug #75398).
       */
    }

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */

  buffer = gimp_drawable_get_buffer (layer_ID);
  format = babl_format (image_type == GIMP_RGB ? "R'G'B' u8" : "Y' u8");

  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end   = cinfo.output_scanline + tile_height;
      end   = MIN (end, cinfo.output_height);

      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      if (cinfo.out_color_space == JCS_CMYK)
        jpeg_load_cmyk_to_rgb (buf, cinfo.output_width * scanlines,
                               cmyk_transform);

      gegl_buffer_set (buffer,
                       GEGL_RECTANGLE (0, start, cinfo.output_width, scanlines),
                       0,
                       format,
                       buf,
                       GEGL_AUTO_ROWSTRIDE);

      if (! preview && (cinfo.output_scanline % 32) == 0)
        gimp_progress_update ((gdouble) cinfo.output_scanline /
                              (gdouble) cinfo.output_height);
    }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  if (cmyk_transform)
    cmsDeleteTransform (cmyk_transform);

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  g_object_unref (buffer);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */

  /* Detach from the drawable and add it to the image.
   */
  if (! preview)
    {
      gimp_progress_update (1.0);
    }

  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);

  return image_ID;
}
static gint32
do_optimizations (GimpRunMode run_mode,
                  gboolean    diff_only)
{
  GimpPixelRgn   pixel_rgn;
  static guchar *rawframe = NULL;
  guchar        *srcptr;
  guchar        *destptr;
  gint           row, this_frame_num;
  guint32        frame_sizebytes;
  gint32         new_layer_id;
  DisposeType    dispose;
  guchar        *this_frame = NULL;
  guchar        *last_frame = NULL;
  guchar        *opti_frame = NULL;
  guchar        *back_frame = NULL;

  gint           this_delay;
  gint           cumulated_delay = 0;
  gint           last_true_frame = -1;
  gint           buflen;

  gchar         *oldlayer_name;
  gchar         *newlayer_name;

  gboolean       can_combine;

  gint32         bbox_top, bbox_bottom, bbox_left, bbox_right;
  gint32         rbox_top, rbox_bottom, rbox_left, rbox_right;

  switch (opmode)
    {
    case OPUNOPTIMIZE:
      gimp_progress_init (_("Unoptimizing animation"));
      break;
    case OPFOREGROUND:
      gimp_progress_init (_("Removing animation background"));
      break;
    case OPBACKGROUND:
      gimp_progress_init (_("Finding animation background"));
      break;
    case OPOPTIMIZE:
    default:
      gimp_progress_init (_("Optimizing animation"));
      break;
    }

  width     = gimp_image_width (image_id);
  height    = gimp_image_height (image_id);
  layers    = gimp_image_get_layers (image_id, &total_frames);
  imagetype = gimp_image_base_type (image_id);
  pixelstep = (imagetype == GIMP_RGB) ? 4 : 2;

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


  drawabletype_alpha = (imagetype == GIMP_RGB) ? GIMP_RGBA_IMAGE :
    ((imagetype == GIMP_INDEXED) ? GIMP_INDEXEDA_IMAGE : GIMP_GRAYA_IMAGE);

  frame_sizebytes = width * height * pixelstep;

  this_frame = g_malloc (frame_sizebytes);
  last_frame = g_malloc (frame_sizebytes);
  opti_frame = g_malloc (frame_sizebytes);

  if (opmode == OPBACKGROUND ||
      opmode == OPFOREGROUND)
    back_frame = g_malloc (frame_sizebytes);

  total_alpha (this_frame, width*height, pixelstep);
  total_alpha (last_frame, width*height, pixelstep);

  new_image_id = gimp_image_new(width, height, imagetype);
  gimp_image_undo_disable (new_image_id);

  if (imagetype == GIMP_INDEXED)
    {
      palette = gimp_image_get_colormap (image_id, &ncolours);
      gimp_image_set_colormap (new_image_id, palette, ncolours);
    }

#if 1
  if (opmode == OPBACKGROUND ||
      opmode == OPFOREGROUND)
    {
      /* iterate through all rows of all frames, find statistical
         mode for each pixel position. */
      gint     i,j;
      guchar **these_rows;
      guchar **red;
      guchar **green;
      guchar **blue;
      guint  **count;
      guint   *num_colours;

      these_rows = g_new (guchar *, total_frames);
      red =        g_new (guchar *, total_frames);
      green =      g_new (guchar *, total_frames);
      blue =       g_new (guchar *, total_frames);
      count =      g_new (guint *, total_frames);

      num_colours = g_new (guint, width);

      for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
        {
          these_rows[this_frame_num] = g_malloc(width * pixelstep);

          red[this_frame_num]   = g_new (guchar, width);
          green[this_frame_num] = g_new (guchar, width);
          blue[this_frame_num]  = g_new (guchar, width);

          count[this_frame_num] = g_new0(guint, width);
        }

      for (row = 0; row < height; row++)
        {
          memset(num_colours, 0, width * sizeof(guint));

          for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
            {
              drawable =
                gimp_drawable_get (layers[total_frames-(this_frame_num+1)]);

              dispose = get_frame_disposal (this_frame_num);

              compose_row(this_frame_num,
                          dispose,
                          row,
                          these_rows[this_frame_num],
                          width,
                          drawable,
                          FALSE
                          );

              gimp_drawable_detach(drawable);
            }

          for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
            {
              for (i=0; i<width; i++)
                {
                  if (these_rows[this_frame_num][i * pixelstep + pixelstep -1]
                      >= 128)
                    {
                      for (j=0; j<num_colours[i]; j++)
                        {

                          switch (pixelstep)
                            {
                            case 4:
                              if (these_rows[this_frame_num][i * 4 +0] ==
                                  red[j][i] &&
                                  these_rows[this_frame_num][i * 4 +1] ==
                                  green[j][i] &&
                                  these_rows[this_frame_num][i * 4 +2] ==
                                  blue[j][i])
                                {
                                  (count[j][i])++;
                                  goto same;
                                }
                              break;
                            case 2:
                              if (these_rows[this_frame_num][i * 2 +0] ==
                                  red[j][i])
                                {
                                  (count[j][i])++;
                                  goto same;
                                }
                              break;
                            default:
                              g_error ("Eeep!");
                              break;
                            }
                        }

                      count[num_colours[i]][i] = 1;
                      red[num_colours[i]][i] =
                        these_rows[this_frame_num][i * pixelstep];
                      if (pixelstep == 4)
                        {
                          green[num_colours[i]][i] =
                            these_rows[this_frame_num][i * 4 +1];
                          blue[num_colours[i]][i] =
                            these_rows[this_frame_num][i * 4 +2];
                        }
                      num_colours[i]++;
                    }
                same:
                  /* nop */;
                }
            }

          for (i=0; i<width; i++)
            {
              guint  best_count = 0;
              guchar best_r = 255, best_g = 0, best_b = 255;

              for (j=0; j<num_colours[i]; j++)
                {
                  if (count[j][i] > best_count)
                    {
                      best_count = count[j][i];
                      best_r = red[j][i];
                      best_g = green[j][i];
                      best_b = blue[j][i];
                    }
                }

              back_frame[width * pixelstep * row +i*pixelstep + 0] = best_r;
              if (pixelstep == 4)
                {
                  back_frame[width * pixelstep * row +i*pixelstep + 1] =
                    best_g;
                  back_frame[width * pixelstep * row +i*pixelstep + 2] =
                    best_b;
                }
              back_frame[width * pixelstep * row +i*pixelstep +pixelstep-1] =
                (best_count == 0) ? 0 : 255;

              if (best_count == 0)
                g_warning("yayyyy!");
            }
          /*      memcpy(&back_frame[width * pixelstep * row],
                  these_rows[0],
                  width * pixelstep);*/
        }

      for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
        {
          g_free (these_rows[this_frame_num]);
          g_free (red[this_frame_num]);
          g_free (green[this_frame_num]);
          g_free (blue[this_frame_num]);
          g_free (count[this_frame_num]);
        }

      g_free (these_rows);
      g_free (red);
      g_free (green);
      g_free (blue);
      g_free (count);
      g_free (num_colours);
    }
Example #16
0
GimpImage *
gimp_image_duplicate (GimpImage *image)
{
  GimpImage    *new_image;
  GimpLayer    *floating_layer;
  GList        *list;
  GimpLayer    *active_layer              = NULL;
  GimpChannel  *active_channel            = NULL;
  GimpVectors  *active_vectors            = NULL;
  GimpDrawable *new_floating_sel_drawable = NULL;
  GimpDrawable *floating_sel_drawable     = NULL;
  gchar        *filename;
  gint          count;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  gimp_set_busy_until_idle (image->gimp);

  /*  Create a new image  */
  new_image = gimp_create_image (image->gimp,
                                 image->width, image->height,
                                 image->base_type,
                                 FALSE);
  gimp_image_undo_disable (new_image);

  /*  Store the folder to be used by the save dialog  */
  filename = gimp_image_get_filename (image);
  if (filename)
    {
      g_object_set_data_full (G_OBJECT (new_image), "gimp-image-dirname",
                              g_path_get_dirname (filename),
                              (GDestroyNotify) g_free);
      g_free (filename);
    }

  /*  Copy the colormap if necessary  */
  if (new_image->base_type == GIMP_INDEXED)
    gimp_image_set_colormap (new_image,
                             gimp_image_get_colormap (image),
                             gimp_image_get_colormap_size (image),
                             FALSE);

  /*  Copy resolution information  */
  new_image->xresolution     = image->xresolution;
  new_image->yresolution     = image->yresolution;
  new_image->resolution_unit = image->resolution_unit;

  /*  Copy floating layer  */
  floating_layer = gimp_image_floating_sel (image);
  if (floating_layer)
    {
      floating_sel_relax (floating_layer, FALSE);

      floating_sel_drawable = floating_layer->fs.drawable;
      floating_layer = NULL;
    }

  /*  Copy the layers  */
  for (list = GIMP_LIST (image->layers)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpLayer *layer = list->data;
      GimpLayer *new_layer;

      new_layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
                                                 new_image,
                                                 G_TYPE_FROM_INSTANCE (layer),
                                                 FALSE));

      /*  Make sure the copied layer doesn't say: "<old layer> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_layer),
                            gimp_object_get_name (GIMP_OBJECT (layer)));

      /*  Make sure that if the layer has a layer mask,
       *  its name isn't screwed up
       */
      if (new_layer->mask)
        gimp_object_set_name (GIMP_OBJECT (new_layer->mask),
                              gimp_object_get_name (GIMP_OBJECT (layer->mask)));

      if (gimp_image_get_active_layer (image) == layer)
        active_layer = new_layer;

      if (image->floating_sel == layer)
        floating_layer = new_layer;

      if (floating_sel_drawable == GIMP_DRAWABLE (layer))
        new_floating_sel_drawable = GIMP_DRAWABLE (new_layer);

      if (floating_layer != new_layer)
        gimp_image_add_layer (new_image, new_layer, count++);
    }

  /*  Copy the channels  */
  for (list = GIMP_LIST (image->channels)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpChannel *channel = list->data;
      GimpChannel *new_channel;

      new_channel =
        GIMP_CHANNEL (gimp_item_convert (GIMP_ITEM (channel),
                                         new_image,
                                         G_TYPE_FROM_INSTANCE (channel),
                                         FALSE));

      /*  Make sure the copied channel doesn't say: "<old channel> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_channel),
                            gimp_object_get_name (GIMP_OBJECT (channel)));

      if (gimp_image_get_active_channel (image) == channel)
        active_channel = (new_channel);

      if (floating_sel_drawable == GIMP_DRAWABLE (channel))
        new_floating_sel_drawable = GIMP_DRAWABLE (new_channel);

      gimp_image_add_channel (new_image, new_channel, count++);
    }

  /*  Copy any vectors  */
  for (list = GIMP_LIST (image->vectors)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpVectors *vectors = list->data;
      GimpVectors *new_vectors;

      new_vectors =
        GIMP_VECTORS (gimp_item_convert (GIMP_ITEM (vectors),
                                         new_image,
                                         G_TYPE_FROM_INSTANCE (vectors),
                                         FALSE));

      /*  Make sure the copied vectors doesn't say: "<old vectors> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_vectors),
                            gimp_object_get_name (GIMP_OBJECT (vectors)));

      if (gimp_image_get_active_vectors (image) == vectors)
        active_vectors = new_vectors;

      gimp_image_add_vectors (new_image, new_vectors, count++);
    }

  /*  Copy the selection mask  */
  {
    TileManager *src_tiles;
    TileManager *dest_tiles;
    PixelRegion  srcPR, destPR;

    src_tiles  =
      gimp_drawable_get_tiles (GIMP_DRAWABLE (image->selection_mask));
    dest_tiles =
      gimp_drawable_get_tiles (GIMP_DRAWABLE (new_image->selection_mask));

    pixel_region_init (&srcPR, src_tiles,
                       0, 0, image->width, image->height, FALSE);
    pixel_region_init (&destPR, dest_tiles,
                       0, 0, image->width, image->height, TRUE);

    copy_region (&srcPR, &destPR);

    new_image->selection_mask->bounds_known   = FALSE;
    new_image->selection_mask->boundary_known = FALSE;
  }

  if (floating_layer)
    floating_sel_attach (floating_layer, new_floating_sel_drawable);

  /*  Set active layer, active channel, active vectors  */
  if (active_layer)
    gimp_image_set_active_layer (new_image, active_layer);

  if (active_channel)
    gimp_image_set_active_channel (new_image, active_channel);

  if (active_vectors)
    gimp_image_set_active_vectors (new_image, active_vectors);

  /*  Copy state of all color channels  */
  for (count = 0; count < MAX_CHANNELS; count++)
    {
      new_image->visible[count] = image->visible[count];
      new_image->active[count]  = image->active[count];
    }

  /*  Copy any guides  */
  for (list = image->guides; list; list = g_list_next (list))
    {
      GimpGuide *guide    = list->data;
      gint       position = gimp_guide_get_position (guide);

      switch (gimp_guide_get_orientation (guide))
        {
        case GIMP_ORIENTATION_HORIZONTAL:
          gimp_image_add_hguide (new_image, position, FALSE);
          break;

        case GIMP_ORIENTATION_VERTICAL:
          gimp_image_add_vguide (new_image, position, FALSE);
          break;

        default:
          g_error ("Unknown guide orientation.\n");
        }
    }

  /*  Copy any sample points  */
  for (list = image->sample_points; list; list = g_list_next (list))
    {
      GimpSamplePoint *sample_point = list->data;

      gimp_image_add_sample_point_at_pos (new_image,
                                          sample_point->x,
                                          sample_point->y,
                                          FALSE);
    }

  /*  Copy the grid  */
  if (image->grid)
    gimp_image_set_grid (new_image, image->grid, FALSE);

  /*  Copy the quick mask info  */
  new_image->quick_mask_state    = image->quick_mask_state;
  new_image->quick_mask_inverted = image->quick_mask_inverted;
  new_image->quick_mask_color    = image->quick_mask_color;

  /*  Copy parasites  */
  if (image->parasites)
    {
      g_object_unref (new_image->parasites);
      new_image->parasites = gimp_parasite_list_copy (image->parasites);
    }

  gimp_image_undo_enable (new_image);

  return new_image;
}
Example #17
0
static void
ico_image_get_reduced_buf (guint32   layer,
                           gint      bpp,
                           gint     *num_colors,
                           guchar  **cmap_out,
                           guchar  **buf_out)
{
  gint32      tmp_image;
  gint32      tmp_layer;
  gint        w, h;
  guchar     *buf;
  guchar     *cmap   = NULL;
  GeglBuffer *buffer = gimp_drawable_get_buffer (layer);
  const Babl *format;

  w = gegl_buffer_get_width  (buffer);
  h = gegl_buffer_get_height (buffer);

  switch (gimp_drawable_type (layer))
    {
    case GIMP_RGB_IMAGE:
      format = babl_format ("R'G'B' u8");
      break;

    case GIMP_RGBA_IMAGE:
      format = babl_format ("R'G'B'A u8");
      break;

    case GIMP_GRAY_IMAGE:
      format = babl_format ("Y' u8");
      break;

    case GIMP_GRAYA_IMAGE:
      format = babl_format ("Y'A u8");
      break;

    case GIMP_INDEXED_IMAGE:
    case GIMP_INDEXEDA_IMAGE:
      format = gegl_buffer_get_format (buffer);

    default:
      g_return_if_reached ();
    }

  *num_colors = 0;

  buf = g_new (guchar, w * h * 4);

  if (bpp <= 8 || bpp == 24 || babl_format_get_bytes_per_pixel (format) != 4)
    {
      gint32      image = gimp_item_get_image (layer);
      GeglBuffer *tmp;

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "tmp", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      tmp = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, tmp, NULL);

      g_object_unref (tmp);

      if (! gimp_drawable_is_rgb (tmp_layer))
        gimp_image_convert_rgb (tmp_image);

      if (bpp <= 8)
        {
          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      1 << bpp, TRUE, FALSE, "dummy");

          cmap = gimp_image_get_colormap (tmp_image, num_colors);

          if (*num_colors == (1 << bpp) &&
              ! ico_cmap_contains_black (cmap, *num_colors))
            {
              /* Windows icons with color maps need the color black.
               * We need to eliminate one more color to make room for black.
               */

              if (gimp_drawable_is_indexed (layer))
                {
                  g_free (cmap);
                  cmap = gimp_image_get_colormap (image, num_colors);
                  gimp_image_set_colormap (tmp_image, cmap, *num_colors);
                }
              else if (gimp_drawable_is_gray (layer))
                {
                  gimp_image_convert_grayscale (tmp_image);
                }
              else
                {
                  gimp_image_convert_rgb (tmp_image);
                }

              tmp = gimp_drawable_get_buffer (tmp_layer);

              gegl_buffer_set (tmp, GEGL_RECTANGLE (0, 0, w, h), 0,
                               format, buf, GEGL_AUTO_ROWSTRIDE);

              g_object_unref (tmp);

              if (! gimp_drawable_is_rgb (layer))
                gimp_image_convert_rgb (tmp_image);

              gimp_image_convert_indexed (tmp_image,
                                          GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                          (1<<bpp) - 1, TRUE, FALSE, "dummy");
              g_free (cmap);
              cmap = gimp_image_get_colormap (tmp_image, num_colors);
            }

          gimp_image_convert_rgb (tmp_image);
        }
      else if (bpp == 24)
        {
          GimpParam    *return_vals;
          gint          n_return_vals;

          return_vals =
            gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                                GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                                GIMP_PDB_IMAGE, tmp_image,
                                GIMP_PDB_DRAWABLE, tmp_layer,
                                GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                                GIMP_PDB_END);
          gimp_destroy_params (return_vals, n_return_vals);
        }

      gimp_layer_add_alpha (tmp_layer);

      tmp = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_get (tmp, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       NULL, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      g_object_unref (tmp);

      gimp_image_delete (tmp_image);
    }
  else
    {
      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
    }

  g_object_unref (buffer);

  *cmap_out = cmap;
  *buf_out = buf;
}
Example #18
0
GimpImage *
file_open_image (Gimp                *gimp,
                 GimpContext         *context,
                 GimpProgress        *progress,
                 GFile               *file,
                 GFile               *entered_file,
                 gboolean             as_new,
                 GimpPlugInProcedure *file_proc,
                 GimpRunMode          run_mode,
                 GimpPDBStatusType   *status,
                 const gchar        **mime_type,
                 GError             **error)
{
  GimpValueArray *return_vals;
  GimpImage      *image       = NULL;
  GFile          *local_file  = NULL;
  gchar          *path        = NULL;
  gchar          *entered_uri = NULL;
  GError         *my_error    = NULL;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
  g_return_val_if_fail (G_IS_FILE (file), NULL);
  g_return_val_if_fail (G_IS_FILE (entered_file), NULL);
  g_return_val_if_fail (status != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  *status = GIMP_PDB_EXECUTION_ERROR;

  /* FIXME enable these tests for remote files again, needs testing */
  if (g_file_is_native (file) &&
      g_file_query_exists (file, NULL))
    {
      GFileInfo *info;

      info = g_file_query_info (file,
                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
                                G_FILE_QUERY_INFO_NONE,
                                NULL, error);
      if (! info)
        return NULL;

      if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Not a regular file"));
          g_object_unref (info);
          return NULL;
        }

      if (! g_file_info_get_attribute_boolean (info,
                                               G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Permission denied"));
          g_object_unref (info);
          return NULL;
        }

      g_object_unref (info);
    }

  if (! file_proc)
    file_proc = gimp_plug_in_manager_file_procedure_find (gimp->plug_in_manager,
                                                          GIMP_FILE_PROCEDURE_GROUP_OPEN,
                                                          file, error);

  if (! file_proc)
    {
      /*  don't bail out on remote files, they might need to be
       *  downloaded for magic matching
       */
      if (g_file_is_native (file))
        return NULL;

      g_clear_error (error);
    }

  if (! g_file_is_native (file) &&
      ! file_remote_mount_file (gimp, file, progress, &my_error))
    {
      if (my_error)
        g_propagate_error (error, my_error);
      else
        *status = GIMP_PDB_CANCEL;

      return NULL;
    }

  if (! file_proc || ! file_proc->handles_uri)
    {
      path = g_file_get_path (file);

      if (! path)
        {
          local_file = file_remote_download_image (gimp, file, progress,
                                                   &my_error);

          if (! local_file)
            {
              if (my_error)
                g_propagate_error (error, my_error);
              else
                *status = GIMP_PDB_CANCEL;

              return NULL;
            }

          /*  if we don't have a file proc yet, try again on the local
           *  file
           */
          if (! file_proc)
            file_proc = gimp_plug_in_manager_file_procedure_find (gimp->plug_in_manager,
                                                                  GIMP_FILE_PROCEDURE_GROUP_OPEN,
                                                                  local_file, error);

          if (! file_proc)
            {
              g_file_delete (local_file, NULL, NULL);
              g_object_unref (local_file);

              return NULL;
            }

          path = g_file_get_path (local_file);
        }
    }

  if (! path)
    path = g_file_get_uri (file);

  entered_uri = g_file_get_uri (entered_file);

  if (! entered_uri)
    entered_uri = g_strdup (path);

  if (progress)
    g_object_add_weak_pointer (G_OBJECT (progress), (gpointer) &progress);

  return_vals =
    gimp_pdb_execute_procedure_by_name (gimp->pdb,
                                        context, progress, error,
                                        gimp_object_get_name (file_proc),
                                        GIMP_TYPE_INT32, run_mode,
                                        G_TYPE_STRING,   path,
                                        G_TYPE_STRING,   entered_uri,
                                        G_TYPE_NONE);

  if (progress)
    g_object_remove_weak_pointer (G_OBJECT (progress), (gpointer) &progress);

  g_free (path);
  g_free (entered_uri);

  *status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

  if (*status == GIMP_PDB_SUCCESS)
    image = gimp_value_get_image (gimp_value_array_index (return_vals, 1),
                                  gimp);

  if (local_file)
    {
      if (image)
        gimp_image_set_file (image, file);

      g_file_delete (local_file, NULL, NULL);
      g_object_unref (local_file);
    }

  if (*status == GIMP_PDB_SUCCESS)
    {
      if (image)
        {
          /* Only set the load procedure if it hasn't already been set. */
          if (! gimp_image_get_load_proc (image))
            gimp_image_set_load_proc (image, file_proc);

          file_proc = gimp_image_get_load_proc (image);

          if (mime_type)
            *mime_type = file_proc->mime_type;
        }
      else
        {
          if (error && ! *error)
            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("%s plug-in returned SUCCESS but did not "
                           "return an image"),
                         gimp_procedure_get_label (GIMP_PROCEDURE (file_proc)));

          *status = GIMP_PDB_EXECUTION_ERROR;
        }
    }
  else if (*status != GIMP_PDB_CANCEL)
    {
      if (error && ! *error)
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("%s plug-In could not open image"),
                     gimp_procedure_get_label (GIMP_PROCEDURE (file_proc)));
    }

  gimp_value_array_unref (return_vals);

  if (image)
    {
      gimp_image_undo_disable (image);

      gimp_image_import_color_profile (image, context, progress,
                                       run_mode == GIMP_RUN_INTERACTIVE ?
                                       TRUE : FALSE);

      if (file_open_file_proc_is_import (file_proc))
        {
          /* Remember the import source */
          gimp_image_set_imported_file (image, file);

          /* We shall treat this file as an Untitled file */
          gimp_image_set_file (image, NULL);
        }

      /* Enables undo again */
      file_open_sanitize_image (image, as_new);
    }

  return image;
}
Example #19
0
static void
gimp_display_shell_drop_pixbuf (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                GdkPixbuf *pixbuf,
                                gpointer   data)
{
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image     = shell->display->image;
  GimpLayer        *new_layer;
  GimpImageType     image_type;
  gboolean          new_image = FALSE;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  switch (gdk_pixbuf_get_n_channels (pixbuf))
    {
    case 1: image_type = GIMP_GRAY_IMAGE;  break;
    case 2: image_type = GIMP_GRAYA_IMAGE; break;
    case 3: image_type = GIMP_RGB_IMAGE;   break;
    case 4: image_type = GIMP_RGBA_IMAGE;  break;
      break;

    default:
      g_return_if_reached ();
      break;
    }

  if (! image)
    {
      image = gimp_create_image (shell->display->gimp,
                                 gdk_pixbuf_get_width (pixbuf),
                                 gdk_pixbuf_get_height (pixbuf),
                                 GIMP_IMAGE_TYPE_BASE_TYPE (image_type),
                                 FALSE);

      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
      g_object_unref (image);

      gimp_image_undo_disable (image);

      new_image = TRUE;
    }

  new_layer =
    gimp_layer_new_from_pixbuf (pixbuf, image, image_type,
                                _("Dropped Buffer"),
                                GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

  if (new_layer)
    {
      GimpItem *new_item = GIMP_ITEM (new_layer);

      new_item = GIMP_ITEM (new_layer);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      if (! new_image)
        gimp_display_shell_dnd_position_item (shell, new_item);

      gimp_image_add_layer (image, new_layer, -1);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }

  if (new_image)
    gimp_image_undo_enable (image);
}
Example #20
0
static void
ico_dialog_update_icon_preview (GtkWidget *dialog,
                                gint32     layer,
                                gint       bpp)
{
  GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer);
  GdkPixbuf *pixbuf;
  gint       w       = gimp_drawable_width (layer);
  gint       h       = gimp_drawable_height (layer);

  if (! preview)
    return;

  if (bpp <= 8)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      guchar       *cmap;
      gint          num_colors;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      gimp_image_convert_indexed (tmp_image,
                                  GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                  1 <<bpp, TRUE, FALSE, "dummy");

      cmap = gimp_image_get_colormap (tmp_image, &num_colors);
      if ( num_colors == (1 << bpp) &&
           !ico_cmap_contains_black (cmap, num_colors))
        {
          /* Windows icons with color maps need the color black.
           * We need to eliminate one more color to make room for black.
           */
          if (gimp_drawable_is_indexed (layer))
            {
              g_free (cmap);
              cmap = gimp_image_get_colormap (image, &num_colors);
              gimp_image_set_colormap (tmp_image, cmap, num_colors);
            }
          else if (gimp_drawable_is_gray (layer))
            {
              gimp_image_convert_grayscale (tmp_image);
            }
          else
            {
              gimp_image_convert_rgb (tmp_image);
            }

          tmp = gimp_drawable_get (tmp_layer);
          gimp_pixel_rgn_init (&dst_pixel_rgn,
                               tmp, 0, 0, w, h, TRUE, FALSE);
          gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
          gimp_drawable_detach (tmp);

          if (!gimp_drawable_is_rgb (layer))
            gimp_image_convert_rgb (tmp_image);

          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      (1<<bpp) - 1, TRUE, FALSE, "dummy");
        }
      g_free (cmap);
      g_free (buffer);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else if (bpp == 24)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      GimpParam    *return_vals;
      gint          n_return_vals;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
      g_free (buffer);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      return_vals =
        gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                            GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                            GIMP_PDB_IMAGE, tmp_image,
                            GIMP_PDB_DRAWABLE, tmp_layer,
                            GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                            GIMP_PDB_END);
      gimp_destroy_params (return_vals, n_return_vals);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else
    {
      pixbuf = gimp_drawable_get_thumbnail (layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);
    }

  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  g_object_unref (pixbuf);
}
Example #21
0
static gboolean
webx_pipeline_check_update (WebxPipeline *pipeline)
{
  gint *layers;
  gint  num_layers;
  gint  i;

  g_return_val_if_fail (WEBX_IS_PIPELINE (pipeline), FALSE);

  if (pipeline->rgb_image != -1)
    {
      gimp_image_delete (pipeline->rgb_image);
      pipeline->rgb_image = -1;
    }
  if (pipeline->indexed_image != -1)
    {
      gimp_image_delete (pipeline->indexed_image);
      pipeline->indexed_image = -1;
    }
  if (pipeline->background)
    {
      g_object_unref (pipeline->background);
      pipeline->background = NULL;
    }

  pipeline->rgb_image = gimp_image_duplicate (pipeline->user_image);
  gimp_image_undo_disable (pipeline->rgb_image);
  pipeline->rgb_layer =
    gimp_image_merge_visible_layers (pipeline->rgb_image,
                                     GIMP_CLIP_TO_IMAGE);

  /* make sure there is only one layer, where all visible layers were merged */
  layers = gimp_image_get_layers (pipeline->rgb_image, &num_layers);
  for (i = 0; i < num_layers; i++)
    {
      if (layers[i] != pipeline->rgb_layer)
        gimp_image_remove_layer (pipeline->rgb_image, layers[i]);
    }
  g_free (layers);

  /* we don't want layer to be smaller than image */
  gimp_layer_resize_to_image_size (pipeline->rgb_layer);
  gimp_image_scale (pipeline->rgb_image,
                    pipeline->resize_width, pipeline->resize_height);
  webx_pipeline_create_background (pipeline);

  pipeline->crop_offsx *= pipeline->crop_scale_x;
  pipeline->crop_offsy *= pipeline->crop_scale_y;
  pipeline->crop_width *= pipeline->crop_scale_x;
  pipeline->crop_height *= pipeline->crop_scale_y;
  pipeline->crop_scale_x = 1.0;
  pipeline->crop_scale_y = 1.0;
  webx_pipeline_crop_clip (pipeline);

  if (pipeline->crop_width != pipeline->resize_width
      || pipeline->crop_height != pipeline->resize_height )
    {
      gimp_image_crop (pipeline->rgb_image,
                       pipeline->crop_width, pipeline->crop_height,
                       pipeline->crop_offsx, pipeline->crop_offsy);
    }
    
  if (gimp_drawable_is_indexed (pipeline->rgb_layer))
    {
      pipeline->indexed_image = gimp_image_duplicate (pipeline->rgb_image);
      gimp_image_undo_disable (pipeline->indexed_image);
      pipeline->indexed_layer =
        gimp_image_merge_visible_layers (pipeline->indexed_image,
                                         GIMP_CLIP_TO_IMAGE);
    }
  else
    {
      pipeline->indexed_image = -1;
      pipeline->indexed_layer = -1;
    }

  if ( ! gimp_drawable_is_rgb (pipeline->rgb_layer))
    gimp_image_convert_rgb (pipeline->rgb_image);

  return TRUE;
}
Example #22
0
GList *
file_open_layers (Gimp                *gimp,
                  GimpContext         *context,
                  GimpProgress        *progress,
                  GimpImage           *dest_image,
                  gboolean             merge_visible,
                  GFile               *file,
                  GimpRunMode          run_mode,
                  GimpPlugInProcedure *file_proc,
                  GimpPDBStatusType   *status,
                  GError             **error)
{
  GimpImage   *new_image;
  GList       *layers    = NULL;
  const gchar *mime_type = NULL;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
  g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
  g_return_val_if_fail (G_IS_FILE (file), NULL);
  g_return_val_if_fail (status != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  new_image = file_open_image (gimp, context, progress,
                               file, file, FALSE,
                               file_proc,
                               run_mode,
                               status, &mime_type, error);

  if (new_image)
    {
      gint n_visible = 0;

      gimp_image_undo_disable (new_image);

      layers = file_open_get_layers (new_image, merge_visible, &n_visible);

      if (merge_visible && n_visible > 1)
        {
          GimpLayer *layer;

          g_list_free (layers);

          layer = gimp_image_merge_visible_layers (new_image, context,
                                                   GIMP_CLIP_TO_IMAGE,
                                                   FALSE, FALSE);

          layers = g_list_prepend (NULL, layer);
        }

      if (layers)
        {
          gchar *basename;

          basename = g_path_get_basename (gimp_file_get_utf8_name (file));
          file_open_convert_items (dest_image, basename, layers);
          g_free (basename);

          gimp_document_list_add_file (GIMP_DOCUMENT_LIST (gimp->documents),
                                       file, mime_type);
        }
      else
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
			       _("Image doesn't contain any layers"));
          *status = GIMP_PDB_EXECUTION_ERROR;
        }

      g_object_unref (new_image);
    }

  return g_list_reverse (layers);
}
Example #23
0
static void
gimp_display_shell_drop_drawable (GtkWidget    *widget,
                                  gint          x,
                                  gint          y,
                                  GimpViewable *viewable,
                                  gpointer      data)
{
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image     = shell->display->image;
  GType             new_type;
  GimpItem         *new_item;
  gboolean          new_image = FALSE;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    {
      GimpImage         *src_image = gimp_item_get_image (GIMP_ITEM (viewable));
      GimpDrawable      *drawable  = GIMP_DRAWABLE (viewable);
      GimpImageBaseType  type;
      gdouble            xres;
      gdouble            yres;

      type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));

      image = gimp_create_image (shell->display->gimp,
                                 gimp_item_width (GIMP_ITEM (viewable)),
                                 gimp_item_height (GIMP_ITEM (viewable)),
                                 type, TRUE);
      gimp_image_undo_disable (image);

      if (type == GIMP_INDEXED)
        gimp_image_set_colormap (image,
                                 gimp_image_get_colormap (src_image),
                                 gimp_image_get_colormap_size (src_image),
                                 FALSE);

      gimp_image_get_resolution (src_image, &xres, &yres);
      gimp_image_set_resolution (image, xres, yres);
      gimp_image_set_unit (image, gimp_image_get_unit (src_image));

      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
      g_object_unref (image);

      new_image = TRUE;
    }

  if (GIMP_IS_LAYER (viewable))
    new_type = G_TYPE_FROM_INSTANCE (viewable);
  else
    new_type = GIMP_TYPE_LAYER;

  new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      if (! new_image)
        gimp_display_shell_dnd_position_item (shell, new_item);

      gimp_item_set_visible (new_item, TRUE, FALSE);
      gimp_item_set_linked (new_item, FALSE, FALSE);

      gimp_image_add_layer (image, new_layer, -1);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }

  if (new_image)
    gimp_image_undo_enable (image);
}
Example #24
0
GimpImage *
gimp_image_duplicate (GimpImage *image)
{
  GimpImage    *new_image;
  GimpLayer    *active_layer;
  GimpChannel  *active_channel;
  GimpVectors  *active_vectors;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  gimp_set_busy_until_idle (image->gimp);

  /*  Create a new image  */
  new_image = gimp_create_image (image->gimp,
                                 gimp_image_get_width  (image),
                                 gimp_image_get_height (image),
                                 gimp_image_get_base_type (image),
                                 gimp_image_get_precision (image),
                                 FALSE);
  gimp_image_undo_disable (new_image);

  /*  Store the source uri to be used by the save dialog  */
  gimp_image_duplicate_save_source_uri (image, new_image);


  /*  Copy the colormap if necessary  */
  gimp_image_duplicate_colormap (image, new_image);

  /*  Copy resolution information  */
  gimp_image_duplicate_resolution (image, new_image);

  /*  Copy the layers  */
  active_layer = gimp_image_duplicate_layers (image, new_image);

  /*  Copy the channels  */
  active_channel = gimp_image_duplicate_channels (image, new_image);

  /*  Copy any vectors  */
  active_vectors = gimp_image_duplicate_vectors (image, new_image);

  /*  Copy floating layer  */
  gimp_image_duplicate_floating_sel (image, new_image);

  /*  Copy the selection mask  */
  gimp_image_duplicate_mask (image, new_image);

  /*  Set active layer, active channel, active vectors  */
  if (active_layer)
    gimp_image_set_active_layer (new_image, active_layer);

  if (active_channel)
    gimp_image_set_active_channel (new_image, active_channel);

  if (active_vectors)
    gimp_image_set_active_vectors (new_image, active_vectors);

  /*  Copy state of all color components  */
  gimp_image_duplicate_components (image, new_image);

  /*  Copy any guides  */
  gimp_image_duplicate_guides (image, new_image);

  /*  Copy any sample points  */
  gimp_image_duplicate_sample_points (image, new_image);

  /*  Copy the grid  */
  gimp_image_duplicate_grid (image, new_image);

  /*  Copy the quick mask info  */
  gimp_image_duplicate_quick_mask (image, new_image);

  /*  Copy parasites  */
  gimp_image_duplicate_parasites (image, new_image);

  gimp_image_undo_enable (new_image);

  return new_image;
}
Example #25
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;
}
Example #26
0
void
edit_undo_clear_cmd_callback (GtkAction *action,
                              gpointer   data)
{
  GimpImage     *image;
  GimpUndoStack *undo_stack;
  GimpUndoStack *redo_stack;
  GtkWidget     *widget;
  GtkWidget     *dialog;
  gchar         *size;
  gint64         memsize;
  gint64         guisize;
  return_if_no_image (image, data);
  return_if_no_widget (widget, data);

  dialog = gimp_message_dialog_new (_("Clear Undo History"), GIMP_STOCK_WARNING,
                                    widget,
                                    GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
                                    gimp_standard_help_func,
                                    GIMP_HELP_EDIT_UNDO_CLEAR,

                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    GTK_STOCK_CLEAR,  GTK_RESPONSE_OK,

                                    NULL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  g_signal_connect_object (gtk_widget_get_toplevel (widget), "unmap",
                           G_CALLBACK (gtk_widget_destroy),
                           dialog, G_CONNECT_SWAPPED);

  g_signal_connect_object (image, "disconnect",
                           G_CALLBACK (gtk_widget_destroy),
                           dialog, G_CONNECT_SWAPPED);

  gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
                                     _("Really clear image's undo history?"));

  undo_stack = gimp_image_get_undo_stack (image);
  redo_stack = gimp_image_get_redo_stack (image);

  memsize =  gimp_object_get_memsize (GIMP_OBJECT (undo_stack), &guisize);
  memsize += guisize;
  memsize += gimp_object_get_memsize (GIMP_OBJECT (redo_stack), &guisize);
  memsize += guisize;

  size = g_format_size (memsize);

  gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box,
                             _("Clearing the undo history of this "
                               "image will gain %s of memory."), size);
  g_free (size);

  if (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK)
    {
      gimp_image_undo_disable (image);
      gimp_image_undo_enable (image);
      gimp_image_flush (image);
    }

  gtk_widget_destroy (dialog);
}
Example #27
0
static void
guillotine (gint32 image_ID)
{
  gint      guide;
  gint      image_width;
  gint      image_height;
  gboolean  guides_found = FALSE;
  GList    *hguides, *hg;
  GList    *vguides, *vg;

  image_width  = gimp_image_width (image_ID);
  image_height = gimp_image_height (image_ID);

  hguides = g_list_append (NULL,    GINT_TO_POINTER (0));
  hguides = g_list_append (hguides, GINT_TO_POINTER (image_height));

  vguides = g_list_append (NULL,    GINT_TO_POINTER (0));
  vguides = g_list_append (vguides, GINT_TO_POINTER (image_width));

  for (guide = gimp_image_find_next_guide (image_ID, 0);
       guide > 0;
       guide = gimp_image_find_next_guide (image_ID, guide))
    {
      gint position = gimp_image_get_guide_position (image_ID, guide);

      switch (gimp_image_get_guide_orientation (image_ID, guide))
        {
        case GIMP_ORIENTATION_HORIZONTAL:
          if (! g_list_find (hguides, GINT_TO_POINTER (position)))
            {
              hguides = g_list_insert_sorted (hguides,
                                              GINT_TO_POINTER (position),
                                              guide_sort_func);
              guides_found = TRUE;
            }
          break;

        case GIMP_ORIENTATION_VERTICAL:
          if (! g_list_find (vguides, GINT_TO_POINTER (position)))
            {
              vguides = g_list_insert_sorted (vguides,
                                              GINT_TO_POINTER (position),
                                              guide_sort_func);
              guides_found = TRUE;
            }
          break;

        case GIMP_ORIENTATION_UNKNOWN:
          g_assert_not_reached ();
          break;
        }
    }

  if (guides_found)
    {
      gchar *filename;
      gint   h, v, hpad, vpad;
      gint   x, y;
      gchar *hformat;
      gchar *format;

      filename = gimp_image_get_filename (image_ID);
      if (!filename)
        filename = g_strdup (_("Untitled"));

      /* get the number horizontal and vertical slices */
      h = g_list_length (hguides);
      v = g_list_length (vguides);

      /* need the number of digits of h and v for the padding */
      hpad = log10(h) + 1;
      vpad = log10(v) + 1;

      /* format for the x-y coordinates in the filename */
      hformat = g_strdup_printf ("%%0%i", MAX (hpad, vpad));
      format  = g_strdup_printf ("-%si-%si", hformat, hformat);

      /*  Do the actual dup'ing and cropping... this isn't a too naive a
       *  way to do this since we got copy-on-write tiles, either.
       */
      for (y = 0, hg = hguides; hg && hg->next; y++, hg = hg->next)
        {
          for (x = 0, vg = vguides; vg && vg->next; x++, vg = vg->next)
            {
              gint32   new_image = gimp_image_duplicate (image_ID);
              GString *new_filename;
              gchar   *fileextension;
              gchar   *fileindex;
              gint     pos;

              if (new_image == -1)
                {
                  g_warning ("Couldn't create new image.");
                  return;
                }

              gimp_image_undo_disable (new_image);

              gimp_image_crop (new_image,
                               GPOINTER_TO_INT (vg->next->data) -
                               GPOINTER_TO_INT (vg->data),
                               GPOINTER_TO_INT (hg->next->data) -
                               GPOINTER_TO_INT (hg->data),
                               GPOINTER_TO_INT (vg->data),
                               GPOINTER_TO_INT (hg->data));


              new_filename = g_string_new (filename);

              /* show the rough coordinates of the image in the title */
              fileindex    = g_strdup_printf (format, x, y);

              /* get the position of the file extension - last . in filename */
              fileextension = strrchr (new_filename->str, '.');
              pos           = fileextension - new_filename->str;

              /* insert the coordinates before the extension */
              g_string_insert (new_filename, pos, fileindex);
	      g_free (fileindex);

              gimp_image_set_filename (new_image, new_filename->str);
              g_string_free (new_filename, TRUE);

              while ((guide = gimp_image_find_next_guide (new_image, 0)))
                gimp_image_delete_guide (new_image, guide);

              gimp_image_undo_enable (new_image);

              gimp_display_new (new_image);
            }
        }

      g_free (filename);
      g_free (hformat);
      g_free (format);
    }

  g_list_free (hguides);
  g_list_free (vguides);
}
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
    static GimpParam  values[6];
    GimpRunMode       run_mode;
    GimpPDBStatusType status   = GIMP_PDB_SUCCESS;
    gint32            image_ID = -1;
    PopplerDocument  *doc      = NULL;
    GError           *error    = NULL;

    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 = GIMP_PDB_EXECUTION_ERROR;

    if (! g_thread_supported ())
        g_thread_init (NULL);

    if (strcmp (name, LOAD_PROC) == 0)
    {
        PdfSelectedPages pages = { 0, NULL };

        switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
            /* Possibly retrieve last settings */
            gimp_get_data (LOAD_PROC, &loadvals);

            doc = open_document (param[1].data.d_string, &error);

            if (!doc)
            {
                status = GIMP_PDB_EXECUTION_ERROR;
                break;
            }

            if (load_dialog (doc, &pages))
                gimp_set_data (LOAD_PROC, &loadvals, sizeof(loadvals));
            else
                status = GIMP_PDB_CANCEL;
            break;

        case GIMP_RUN_WITH_LAST_VALS:
            /* FIXME: implement last vals mode */
            status = GIMP_PDB_EXECUTION_ERROR;
            break;

        case GIMP_RUN_NONINTERACTIVE:
            doc = open_document (param[1].data.d_string, &error);

            if (doc)
            {
                PopplerPage *test_page = poppler_document_get_page (doc, 0);

                if (test_page)
                {
                    pages.n_pages = 1;
                    pages.pages = g_new (gint, 1);
                    pages.pages[0] = 0;

                    g_object_unref (test_page);
                }
                else
                {
                    status = GIMP_PDB_EXECUTION_ERROR;
                    g_object_unref (doc);
                }
            }
            else
            {
                status = GIMP_PDB_EXECUTION_ERROR;
            }
            break;
        }

        if (status == GIMP_PDB_SUCCESS)
        {
            image_ID = load_image (doc, param[1].data.d_string,
                                   run_mode,
                                   loadvals.target,
                                   loadvals.resolution,
                                   &pages);

            if (image_ID != -1)
            {
                *nreturn_vals = 2;
                values[1].type         = GIMP_PDB_IMAGE;
                values[1].data.d_image = image_ID;
            }
            else
            {
                status = GIMP_PDB_EXECUTION_ERROR;
            }
        }

        if (doc)
            g_object_unref (doc);

        g_free (pages.pages);
    }
    else if (strcmp (name, LOAD_THUMB_PROC) == 0)
    {
        if (nparams < 2)
        {
            status = GIMP_PDB_CALLING_ERROR;
        }
        else
        {
            gdouble      width     = 0;
            gdouble      height    = 0;
            gdouble      scale;
            gint32       image     = -1;
            gint         num_pages = 0;
            GdkPixbuf   *pixbuf    = NULL;

            /* Possibly retrieve last settings */
            gimp_get_data (LOAD_PROC, &loadvals);

            doc = open_document (param[0].data.d_string, &error);

            if (doc)
            {
                PopplerPage *page = poppler_document_get_page (doc, 0);

                if (page)
                {
                    poppler_page_get_size (page, &width, &height);

                    g_object_unref (page);
                }

                num_pages = poppler_document_get_n_pages (doc);

                pixbuf = get_thumbnail (doc, 0, param[1].data.d_int32);

                g_object_unref (doc);
            }

            if (pixbuf)
            {
                image = gimp_image_new (gdk_pixbuf_get_width  (pixbuf),
                                        gdk_pixbuf_get_height (pixbuf),
                                        GIMP_RGB);

                gimp_image_undo_disable (image);

                layer_from_pixbuf (image, "thumbnail", 0, pixbuf, 0.0, 1.0);
                g_object_unref (pixbuf);

                gimp_image_undo_enable (image);
                gimp_image_clean_all (image);
            }

            scale = loadvals.resolution / gimp_unit_get_factor (GIMP_UNIT_POINT);

            width  *= scale;
            height *= scale;

            if (image != -1)
            {
                *nreturn_vals = 6;

                values[1].type         = GIMP_PDB_IMAGE;
                values[1].data.d_image = image;
                values[2].type         = GIMP_PDB_INT32;
                values[2].data.d_int32 = width;
                values[3].type         = GIMP_PDB_INT32;
                values[3].data.d_int32 = height;
                values[4].type         = GIMP_PDB_INT32;
                values[4].data.d_int32 = GIMP_RGB_IMAGE;
                values[5].type         = GIMP_PDB_INT32;
                values[5].data.d_int32 = num_pages;
            }
            else
            {
                status = GIMP_PDB_EXECUTION_ERROR;
            }
        }

    }
    else
    {
        status = GIMP_PDB_CALLING_ERROR;
    }

    if (status != GIMP_PDB_SUCCESS && error)
    {
        *nreturn_vals = 2;
        values[1].type          = GIMP_PDB_STRING;
        values[1].data.d_string = error->message;
    }

    values[0].data.d_status = status;
}
void
gimp_image_import_color_profile (GimpImage    *image,
                                 GimpContext  *context,
                                 GimpProgress *progress,
                                 gboolean      interactive)
{
  GimpColorConfig *config = image->gimp->config->color_management;

  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (GIMP_IS_CONTEXT (context));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  config = image->gimp->config->color_management;

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    return;

  if (config->mode == GIMP_COLOR_MANAGEMENT_OFF)
    return;

  if (gimp_image_get_color_profile (image))
    {
      GimpColorProfilePolicy  policy;
      GimpColorProfile       *dest_profile = NULL;

      policy = image->gimp->config->color_profile_policy;

      if (policy == GIMP_COLOR_PROFILE_POLICY_ASK)
        {
          if (interactive)
            {
              gboolean dont_ask = FALSE;

              policy = gimp_query_profile_policy (image->gimp, image, context,
                                                  &dest_profile, &dont_ask);

              if (dont_ask)
                {
                  g_object_set (G_OBJECT (image->gimp->config),
                                "color-profile-policy", policy,
                                NULL);
                }
            }
          else
            {
              policy = GIMP_COLOR_PROFILE_POLICY_KEEP;
            }
        }

      if (policy == GIMP_COLOR_PROFILE_POLICY_CONVERT)
        {
          GimpColorRenderingIntent  intent;
          gboolean                  bpc;

          if (! dest_profile)
            {
              dest_profile = gimp_image_get_builtin_color_profile (image);
              g_object_ref (dest_profile);
            }

          intent = config->display_intent;
          bpc    = (intent == GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC);

          gimp_image_undo_disable (image);

          gimp_image_convert_color_profile (image, dest_profile,
                                            intent, bpc,
                                            progress, NULL);

          gimp_image_clean_all (image);
          gimp_image_undo_enable (image);

          g_object_unref (dest_profile);
        }
    }
}
static gint32
load_image (PopplerDocument        *doc,
            const gchar            *filename,
            GimpRunMode             run_mode,
            GimpPageSelectorTarget  target,
            guint32                 resolution,
            PdfSelectedPages       *pages)
{
    gint32   image_ID = 0;
    gint32  *images   = NULL;
    gint     i;
    gdouble  scale;
    gdouble  doc_progress = 0;

    if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
        images = g_new0 (gint32, pages->n_pages);

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

    scale = resolution / gimp_unit_get_factor (GIMP_UNIT_POINT);

    /* read the file */

    for (i = 0; i < pages->n_pages; i++)
    {
        PopplerPage *page;
        gchar       *page_label;
        gdouble      page_width;
        gdouble      page_height;

        GdkPixbuf   *buf;
        gint         width;
        gint         height;

        page = poppler_document_get_page (doc, pages->pages[i]);

        poppler_page_get_size (page, &page_width, &page_height);
        width  = page_width  * scale;
        height = page_height * scale;

        g_object_get (G_OBJECT (page), "label", &page_label, NULL);

        if (! image_ID)
        {
            gchar *name;

            image_ID = gimp_image_new (width, height, GIMP_RGB);
            gimp_image_undo_disable (image_ID);

            if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
                name = g_strdup_printf (_("%s-%s"), filename, page_label);
            else
                name = g_strdup_printf (_("%s-pages"), filename);

            gimp_image_set_filename (image_ID, name);
            g_free (name);

            gimp_image_set_resolution (image_ID, resolution, resolution);
        }

        buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);

        poppler_page_render_to_pixbuf (page, 0, 0, width, height, scale, 0, buf);

        layer_from_pixbuf (image_ID, page_label, i, buf,
                           doc_progress, 1.0 / pages->n_pages);

        g_free (page_label);
        g_object_unref (buf);

        doc_progress = (double) (i + 1) / pages->n_pages;
        gimp_progress_update (doc_progress);

        if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
        {
            images[i] = image_ID;

            gimp_image_undo_enable (image_ID);
            gimp_image_clean_all (image_ID);

            image_ID = 0;
        }
    }

    if (image_ID)
    {
        gimp_image_undo_enable (image_ID);
        gimp_image_clean_all (image_ID);
    }

    if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
    {
        if (run_mode != GIMP_RUN_NONINTERACTIVE)
        {
            /* Display images in reverse order.  The last will be
             * displayed by GIMP itself
             */
            for (i = pages->n_pages - 1; i > 0; i--)
                gimp_display_new (images[i]);
        }

        image_ID = images[0];

        g_free (images);
    }

    return image_ID;
}