/* ---------------------------------------------------- * p_drop_image_cache * ---------------------------------------------------- * drop the image cache. */ static void p_drop_image_cache(void) { gint32 *images; gint nimages; gint l_idi; if(gap_debug) { printf("p_drop_image_cache START pid:%d\n", (int) gap_base_getpid()); } images = gimp_image_list(&nimages); for(l_idi=0; l_idi < nimages; l_idi++) { GimpParasite *l_parasite; l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_CACHE_PARASITE); if(gap_debug) { printf("FrameFetcher: CHECK (image_id:%d) name:%s pid:%d\n" , (int)images[l_idi] , gimp_image_get_filename(images[l_idi]) , (int)gap_base_getpid() ); } if(l_parasite) { if(gap_debug) { printf("FrameFetcher: DELETE (image_id:%d) name:%s pid:%d\n" , (int)images[l_idi] , gimp_image_get_filename(images[l_idi]) , (int)gap_base_getpid() ); } /* delete image from the duplicates cache */ gap_image_delete_immediate(images[l_idi]); gimp_parasite_free(l_parasite); } } if(images) { g_free(images); } if(gap_debug) { printf("p_drop_image_cache END pid:%d\n", (int)gap_base_getpid()); } } /* end p_drop_image_cache */
/* ------------------------------------------------- * gap_frame_fetch_delete_list_of_duplicated_images * ------------------------------------------------- * deletes all duplicate imageas that wre created by the specified ffetch_user_id * (if ffetch_user_id -1 is specified delte all duplicated images) */ void gap_frame_fetch_delete_list_of_duplicated_images(gint32 ffetch_user_id) { gint32 *images; gint nimages; gint l_idi; images = gimp_image_list(&nimages); for(l_idi=0; l_idi < nimages; l_idi++) { GimpParasite *l_parasite; l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_DUP_CACHE_PARASITE); if(gap_debug) { printf("FrameFetcher: check (image_id:%d) name:%s pid:%d\n" , (int)images[l_idi] , gimp_image_get_filename(images[l_idi]) , (int)gap_base_getpid() ); } if(l_parasite) { gint32 *ffetch_user_id_ptr; ffetch_user_id_ptr = (gint32 *) l_parasite->data; if((*ffetch_user_id_ptr == ffetch_user_id) || (ffetch_user_id < 0)) { if(gap_debug) { printf("FrameFetcher: DELETE duplicate %s (image_id:%d) user_id:%d (%d) name:%s pid:%d\n" , gimp_image_get_filename(images[l_idi]) , (int)images[l_idi] , (int)ffetch_user_id , (int)*ffetch_user_id_ptr , gimp_image_get_filename(images[l_idi]) , (int)gap_base_getpid() ); } /* delete image from the duplicates cache */ gap_image_delete_immediate(images[l_idi]); } gimp_parasite_free(l_parasite); } } if(images) { g_free(images); } } /* end gap_frame_fetch_delete_list_of_duplicated_images */
static void gimp_image_prop_view_label_set_filetype (GtkWidget *label, GimpImage *image) { GimpPlugInManager *manager = image->gimp->plug_in_manager; GimpPlugInProcedure *proc; proc = gimp_image_get_save_proc (image); if (! proc) proc = gimp_image_get_load_proc (image); if (! proc) { gchar *filename = gimp_image_get_filename (image); if (filename) { proc = file_procedure_find (manager->load_procs, filename, NULL); g_free (filename); } } gtk_label_set_text (GTK_LABEL (label), proc ? gimp_plug_in_procedure_get_label (proc) : NULL); }
static void gimp_image_prop_view_label_set_filesize (GtkWidget *label, GimpImage *image) { gchar *filename = gimp_image_get_filename (image); if (filename) { struct stat buf; if (g_stat (filename, &buf) == 0) { gchar *str = g_format_size (buf.st_size); gtk_label_set_text (GTK_LABEL (label), str); g_free (str); } else { gtk_label_set_text (GTK_LABEL (label), NULL); } g_free (filename); } else { gtk_label_set_text (GTK_LABEL (label), NULL); } }
/* Build a filename like <imagename>-<channel>.<extension> */ gchar * generate_filename (guint32 image_ID, guint colorspace, guint channel) { /* Build a filename like <imagename>-<channel>.<extension> */ gchar *fname; gchar *filename; gchar *extension; fname = gimp_image_get_filename (image_ID); if (fname) { extension = fname + strlen (fname) - 1; while (extension >= fname) { if (*extension == '.') break; extension--; } if (extension >= fname) { *(extension++) = '\0'; if (decovals.as_layers) filename = g_strdup_printf ("%s-%s.%s", fname, gettext (extract[colorspace].type), extension); else filename = g_strdup_printf ("%s-%s.%s", fname, gettext (extract[colorspace].component[channel].channel_name), extension); } else { if (decovals.as_layers) filename = g_strdup_printf ("%s-%s", fname, gettext (extract[colorspace].type)); else filename = g_strdup_printf ("%s-%s", fname, gettext (extract[colorspace].component[channel].channel_name)); } } else { filename = g_strdup (gettext (extract[colorspace].component[channel].channel_name)); } g_free (fname); return filename; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[2]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint32 image_ID; gint32 drawable_ID; INIT_I18N (); run_mode = param[0].data.d_int32; image_ID = param[1].data.d_image; drawable_ID = param[2].data.d_drawable; *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; if (strcmp (name, PLUG_IN_PROC) == 0) { switch (run_mode) { case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC, &mail_info); { gchar *filename = gimp_image_get_filename (image_ID); if (filename) { gchar *basename = g_filename_display_basename (filename); g_strlcpy (mail_info.filename, basename, BUFFER_SIZE); g_free (basename); g_free (filename); } } if (! save_dialog ()) status = GIMP_PDB_CANCEL; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams < 8) { status = GIMP_PDB_CALLING_ERROR; } else { g_strlcpy (mail_info.filename, param[3].data.d_string, BUFFER_SIZE); g_strlcpy (mail_info.receipt, param[4].data.d_string, BUFFER_SIZE); g_strlcpy (mail_info.from, param[5].data.d_string, BUFFER_SIZE); g_strlcpy (mail_info.subject, param[6].data.d_string, BUFFER_SIZE); g_strlcpy (mail_info.comment, param[7].data.d_string, BUFFER_SIZE); } break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &mail_info); break; default: break; } if (status == GIMP_PDB_SUCCESS) { status = save_image (mail_info.filename, image_ID, drawable_ID, run_mode); if (status == GIMP_PDB_SUCCESS) { if (mesg_body) g_strlcpy (mail_info.comment, mesg_body, BUFFER_SIZE); gimp_set_data (PLUG_IN_PROC, &mail_info, sizeof (m_info)); } } } else { status = GIMP_PDB_CALLING_ERROR; } values[0].data.d_status = status; }
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 draw_info_header (GtkPrintContext *context, cairo_t *cr, PrintData *data) { PangoLayout *layout; PangoFontDescription *desc; gdouble text_height; gdouble text_width; gdouble fname_text_width; gint layout_height; gint layout_width; gchar date_buffer[100]; GDate *date; const gchar *name_str; GimpParasite *parasite; const gchar *end_ptr; gchar *filename; gdouble cr_width; cairo_save (cr); cr_width = gtk_print_context_get_width (context); cairo_rectangle (cr, 0, 0, cr_width, HEADER_HEIGHT); cairo_set_source_rgb (cr, 0.8, 0.8, 0.8); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 1); cairo_stroke (cr); layout = gtk_print_context_create_pango_layout (context); desc = pango_font_description_from_string ("sans 14"); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_width (layout, -1); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); /* image name */ pango_layout_set_text (layout, gimp_image_get_name (data->image_id), -1); pango_layout_get_size (layout, &layout_width, &layout_height); text_height = (gdouble) layout_height / PANGO_SCALE; cairo_move_to (cr, 0.02 * cr_width, (HEADER_HEIGHT - text_height) / 5); pango_cairo_show_layout (cr, layout); /* user name */ name_str = g_get_real_name (); if (name_str && g_utf8_validate (name_str, -1, &end_ptr)) { pango_layout_set_text (layout, name_str, -1); pango_layout_get_size (layout, &layout_width, &layout_height); text_height = (gdouble) layout_height / PANGO_SCALE; text_width = (gdouble) layout_width / PANGO_SCALE; cairo_move_to (cr, 0.5 * cr_width - 0.5 * text_width, (HEADER_HEIGHT - text_height) / 5); pango_cairo_show_layout (cr, layout); } /* date */ date = g_date_new (); g_date_set_time_t (date, time (NULL)); g_date_strftime (date_buffer, 100, "%x", date); g_date_free (date); pango_layout_set_text (layout, date_buffer, -1); pango_layout_get_size (layout, &layout_width, &layout_height); text_height = (gdouble) layout_height / PANGO_SCALE; text_width = (gdouble) layout_width / PANGO_SCALE; cairo_move_to (cr, 0.98 * cr_width - text_width, (HEADER_HEIGHT - text_height) / 5); pango_cairo_show_layout (cr, layout); /* file name if any */ filename = gimp_image_get_filename (data->image_id); if (filename) { pango_layout_set_text (layout, gimp_filename_to_utf8 (filename), -1); g_free (filename); pango_layout_get_size (layout, &layout_width, &layout_height); text_height = (gdouble) layout_height / PANGO_SCALE; fname_text_width = (gdouble) layout_width / PANGO_SCALE; cairo_move_to (cr, 0.02 * cr_width, 4 * (HEADER_HEIGHT - text_height) / 5); pango_cairo_show_layout (cr, layout); } else { fname_text_width = 0; } /* image comment if it is short */ parasite = gimp_image_parasite_find (data->image_id, "gimp-comment"); if (parasite) { pango_layout_set_text (layout, gimp_parasite_data (parasite), -1); pango_layout_get_size (layout, &layout_width, &layout_height); text_height = (gdouble) layout_height / PANGO_SCALE; text_width = (gdouble) layout_width / PANGO_SCALE; if (fname_text_width + text_width < 0.8 * cr_width && text_height < 0.5 * HEADER_HEIGHT) { cairo_move_to (cr, 0.98 * cr_width - text_width, 4 * (HEADER_HEIGHT - text_height) / 5); pango_cairo_show_layout (cr, layout); } gimp_parasite_free (parasite); } g_object_unref (layout); cairo_restore (cr); }
/* Decompose an image. It returns the number of new (gray) images. The image IDs for the new images are returned in image_ID_dst. On failure, -1 is returned. */ static gint32 decompose (gint32 image_ID, gint32 drawable_ID, const gchar *extract_type, gint32 *image_ID_dst, gint32 *nlayers, gint32 *layer_ID_dst) { const gchar *layername; gint i, j, extract_idx, scan_lines; gint height, width, tile_height, num_layers; gchar *filename; guchar *src; guchar *dst[MAX_EXTRACT_IMAGES]; GimpDrawable *drawable_src; GimpDrawable *drawable_dst[MAX_EXTRACT_IMAGES]; GimpPixelRgn pixel_rgn_src; GimpPixelRgn pixel_rgn_dst[MAX_EXTRACT_IMAGES]; extract_idx = -1; /* Search extract type */ for (j = 0; j < G_N_ELEMENTS (extract); j++) { if (g_ascii_strcasecmp (extract_type, extract[j].type) == 0) { extract_idx = j; break; } } if (extract_idx < 0) return -1; /* Check structure of source image */ drawable_src = gimp_drawable_get (drawable_ID); if (drawable_src->bpp < 3) { g_message ("Not an RGB image."); return -1; } if ((extract[extract_idx].extract_fun == extract_alpha || extract[extract_idx].extract_fun == extract_rgba) && (!gimp_drawable_has_alpha (drawable_ID))) { g_message ("No alpha channel available."); return -1; } width = drawable_src->width; height = drawable_src->height; tile_height = gimp_tile_height (); gimp_pixel_rgn_init (&pixel_rgn_src, drawable_src, 0, 0, width, height, FALSE, FALSE); /* allocate a buffer for retrieving information from the src pixel region */ src = g_new (guchar, tile_height * width * drawable_src->bpp); /* Create all new gray images */ num_layers = extract[extract_idx].num_images; if (num_layers > MAX_EXTRACT_IMAGES) num_layers = MAX_EXTRACT_IMAGES; for (j = 0; j < num_layers; j++) { /* Build a filename like <imagename>-<channel>.<extension> */ gchar *fname; gchar *extension; gdouble xres, yres; fname = gimp_image_get_filename (image_ID); if (fname) { extension = fname + strlen (fname) - 1; while (extension >= fname) { if (*extension == '.') break; extension--; } if (extension >= fname) { *(extension++) = '\0'; if (decovals.as_layers) filename = g_strdup_printf ("%s-%s.%s", fname, gettext (extract[extract_idx].type), extension); else filename = g_strdup_printf ("%s-%s.%s", fname, gettext (extract[extract_idx].channel_name[j]), extension); } else { if (decovals.as_layers) filename = g_strdup_printf ("%s-%s", fname, gettext (extract[extract_idx].type)); else filename = g_strdup_printf ("%s-%s", fname, gettext (extract[extract_idx].channel_name[j])); } } else { filename = g_strdup (gettext (extract[extract_idx].channel_name[j])); } gimp_image_get_resolution (image_ID, &xres, &yres); if (decovals.as_layers) { layername = gettext (extract[extract_idx].channel_name[j]); if (j == 0) image_ID_dst[j] = create_new_image (filename, layername, width, height, GIMP_GRAY, xres, yres, layer_ID_dst + j, drawable_dst + j, pixel_rgn_dst + j); else layer_ID_dst[j] = create_new_layer (image_ID_dst[0], j, layername, width, height, GIMP_GRAY, drawable_dst + j, pixel_rgn_dst + j); } else { image_ID_dst[j] = create_new_image (filename, NULL, width, height, GIMP_GRAY, xres, yres, layer_ID_dst + j, drawable_dst + j, pixel_rgn_dst + j); } g_free (filename); g_free (fname); dst[j] = g_new (guchar, tile_height * width); } i = 0; while (i < height) { /* Get source pixel region */ scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); gimp_pixel_rgn_get_rect (&pixel_rgn_src, src, 0, i, width, scan_lines); /* Extract the channel information */ extract[extract_idx].extract_fun (src, drawable_src->bpp, scan_lines*width, dst); /* Transfer the registration color */ if (decovals.use_registration) transfer_registration_color (src, drawable_src->bpp, scan_lines*width, dst, extract[extract_idx].num_images); /* Set destination pixel regions */ for (j = 0; j < num_layers; j++) gimp_pixel_rgn_set_rect (&(pixel_rgn_dst[j]), dst[j], 0, i, width, scan_lines); i += scan_lines; gimp_progress_update ((gdouble) i / (gdouble) height); } g_free (src); for (j = 0; j < num_layers; j++) { gimp_drawable_detach (drawable_dst[j]); gimp_drawable_update (layer_ID_dst[j], 0, 0, gimp_drawable_width (layer_ID_dst[j]), gimp_drawable_height (layer_ID_dst[j])); gimp_layer_add_alpha (layer_ID_dst[j]); g_free (dst[j]); } gimp_drawable_detach (drawable_src); *nlayers = num_layers; return (decovals.as_layers ? 1 : num_layers); }
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; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[4]; gint32 image_ID; XMPModel *xmp_model; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpParasite *parasite = NULL; *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; INIT_I18N(); if (! strcmp (name, EDITOR_PROC)) image_ID = param[1].data.d_image; else image_ID = param[0].data.d_image; xmp_model = xmp_model_new (); /* if there is already a metadata parasite, load it */ parasite = gimp_image_get_parasite (image_ID, METADATA_PARASITE); if (parasite) { GError *error = NULL; if (!! strncmp (gimp_parasite_data (parasite), METADATA_MARKER, METADATA_MARKER_LEN) || ! xmp_model_parse_buffer (xmp_model, (const gchar *) gimp_parasite_data (parasite) + METADATA_MARKER_LEN, gimp_parasite_data_size (parasite) - METADATA_MARKER_LEN, TRUE, &error)) { g_printerr ("\nMetadata parasite seems to be corrupt\n"); /* continue anyway, we will attach a clean parasite later */ } gimp_parasite_free (parasite); } /* If we have no metadata yet, try to find an XMP packet in the file * (but ignore errors if nothing is found). * * FIXME: This is a workaround until all file plug-ins do the right * thing when loading their files. */ if (xmp_model_is_empty (xmp_model) && !! strcmp (name, DECODE_XMP_PROC)) { const gchar *filename; GError *error = NULL; filename = gimp_image_get_filename (image_ID); if (filename != NULL) if (xmp_model_parse_file (xmp_model, filename, &error)) /* g_message ("XMP loaded from file '%s'\n", filename) */; } /* Now check what we are supposed to do */ if (! strcmp (name, DECODE_XMP_PROC)) { const gchar *buffer; GError *error = NULL; buffer = param[1].data.d_string; if (! xmp_model_parse_buffer (xmp_model, buffer, strlen (buffer), FALSE, &error)) status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, ENCODE_XMP_PROC)) { /* done below together with the parasite */ } else if (! strcmp (name, DECODE_EXIF_PROC)) { GError *error = NULL; if (! xmp_merge_from_exifbuffer (xmp_model, image_ID, &error)) { status = GIMP_PDB_EXECUTION_ERROR; g_printerr ("\nExif to XMP merge failed.\n"); } } else if (! strcmp (name, GET_PROC)) { g_printerr ("Not implemented yet (GET_PROC)\n"); /* FIXME */ status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, SET_PROC)) { g_printerr ("Not implemented yet (SET_PROC)\n"); /* FIXME */ status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, GET_SIMPLE_PROC)) { const gchar *schema_name; const gchar *property_name; const gchar *value; schema_name = param[1].data.d_string; property_name = param[2].data.d_string; value = xmp_model_get_scalar_property (xmp_model, schema_name, property_name); if (value) { *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = g_strdup (value); } else status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, SET_SIMPLE_PROC)) { const gchar *schema_name; const gchar *property_name; const gchar *property_value; schema_name = param[1].data.d_string; property_name = param[2].data.d_string; property_value = param[3].data.d_string; if (! xmp_model_set_scalar_property (xmp_model, schema_name, property_name, property_value)) status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, IMPORT_PROC)) { const gchar *filename; gchar *buffer; gsize buffer_length; GError *error = NULL; filename = param[1].data.d_string; if (! g_file_get_contents (filename, &buffer, &buffer_length, &error)) { g_error_free (error); status = GIMP_PDB_EXECUTION_ERROR; } else if (! xmp_model_parse_buffer (xmp_model, buffer, buffer_length, TRUE, &error)) { g_error_free (error); status = GIMP_PDB_EXECUTION_ERROR; } g_free (buffer); } else if (! strcmp (name, EXPORT_PROC)) { /* FIXME: this is easy to implement, but the first thing to do is */ /* to improve the code of export_dialog_response() in interface.c */ g_printerr ("Not implemented yet (EXPORT_PROC)\n"); status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, EDITOR_PROC)) { GimpRunMode run_mode; run_mode = param[0].data.d_int32; if (run_mode == GIMP_RUN_INTERACTIVE) { if (! metadata_dialog (image_ID, xmp_model)) status = GIMP_PDB_CANCEL; } g_printerr ("Not implemented yet (EDITOR_PROC)\n"); status = GIMP_PDB_EXECUTION_ERROR; } else { status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { GString *buffer; /* Generate the updated parasite and attach it to the image */ buffer = g_string_new (METADATA_MARKER); xmp_generate_packet (xmp_model, buffer); parasite = gimp_parasite_new (METADATA_PARASITE, GIMP_PARASITE_PERSISTENT, buffer->len, (gpointer) buffer->str); gimp_image_attach_parasite (image_ID, parasite); if (! strcmp (name, ENCODE_XMP_PROC)) { *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = g_strdup (buffer->str + METADATA_MARKER_LEN); } g_string_free (buffer, TRUE); } g_object_unref (xmp_model); values[0].data.d_status = status; }
static void run (char *name, /* I - Name of print program. */ int nparams, /* I - Number of parameters passed in */ GimpParam *param, /* I - Parameter values */ int *nreturn_vals, /* O - Number of return values */ GimpParam **return_vals) /* O - Return values */ { GimpDrawable *drawable; /* Drawable for image */ GimpRunModeType run_mode; /* Current run mode */ GimpParam *values; /* Return values */ gint32 drawable_ID; /* drawable ID */ GimpExportReturnType export = GIMP_EXPORT_CANCEL; /* return value of gimp_export_image() */ gdouble xres, yres; char *image_filename; char *image_basename; stpui_image_t *image; gint32 image_ID; gint32 base_type; if (getenv("STP_DEBUG_STARTUP")) while (SDEBUG) ; /* * Initialise libgimpprint */ stp_init(); #ifdef INIT_I18N_UI INIT_I18N_UI(); #else /* * With GCC and glib 1.2, there will be a warning here about braces in * expressions. Getting rid of it causes more problems than it solves. * In particular, turning on -ansi on the command line causes a number of * other useful things, such as strcasecmp, popen, and snprintf to go away */ INIT_LOCALE (PACKAGE); #endif stpui_printer_initialize(&gimp_vars); /* * Initialize parameter data... */ run_mode = (GimpRunModeType)param[0].data.d_int32; values = g_new (GimpParam, 1); values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_SUCCESS; *nreturn_vals = 1; *return_vals = values; image_ID = param[1].data.d_int32; drawable_ID = param[2].data.d_int32; image_filename = gimp_image_get_filename (image_ID); image_basename = image_filename; if (strchr(image_filename, '/')) image_basename = strrchr(image_filename, '/') + 1; stpui_set_image_filename(image_basename); g_free(image_filename); /* eventually export the image */ switch (run_mode) { case GIMP_RUN_INTERACTIVE: case GIMP_RUN_WITH_LAST_VALS: gimp_ui_init ("print", TRUE); export = gimp_export_image (&image_ID, &drawable_ID, "Print", (GIMP_EXPORT_CAN_HANDLE_RGB | GIMP_EXPORT_CAN_HANDLE_GRAY | GIMP_EXPORT_CAN_HANDLE_INDEXED | GIMP_EXPORT_CAN_HANDLE_ALPHA)); if (export == GIMP_EXPORT_CANCEL) { *nreturn_vals = 1; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; return; } break; default: break; }
/* ---------------------------------------------------- * p_load_cache_image * ---------------------------------------------------- * load an image from cache or from file (in case image is not already cached) * in case the flag addToCache is TRUE the image will be automatically added * to the cache after read from file operation. */ static gint32 p_load_cache_image(const char* filename, gint32 ffetch_user_id, gboolean addToCache) { gint32 l_image_id; char *l_filename; gint32 *images; gint nimages; gint l_idi; gint l_number_of_cached_images; gint32 l_first_cached_image_id; GimpParasite *l_parasite; if(filename == NULL) { printf("p_load_cache_image: ** ERROR cant load filename == NULL! pid:%d\n", (int)gap_base_getpid()); return -1; } l_image_id = -1; l_first_cached_image_id = -1; l_number_of_cached_images = 0; images = gimp_image_list(&nimages); for(l_idi=0; l_idi < nimages; l_idi++) { l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_CACHE_PARASITE); if(l_parasite) { gint32 *mtime_ptr; gint32 *ffetch_id_ptr; gchar *filename_ptr; mtime_ptr = (gint32 *) l_parasite->data; ffetch_id_ptr = (gint32 *)&l_parasite->data[sizeof(gint32)]; filename_ptr = (gchar *)&l_parasite->data[sizeof(gint32) + sizeof(gint32)]; l_number_of_cached_images++; if (l_first_cached_image_id < 0) { l_first_cached_image_id = images[l_idi]; } if(strcmp(filename, filename_ptr) == 0) { gint32 mtimefile; mtimefile = gap_file_get_mtime(filename); if(mtimefile == *mtime_ptr) { /* image found in cache */ l_image_id = images[l_idi]; } else { /* image found in cache, but has changed modification timestamp * (delete from cache and reload) */ if(gap_debug) { printf("FrameFetcher: DELETE because mtime changed : (image_id:%d) ffetchId:%d name:%s mtimefile:%d mtimecache:%d pid:%d\n" , (int)images[l_idi] , (int)*ffetch_id_ptr , gimp_image_get_filename(images[l_idi]) , (int)mtimefile , (int)*mtime_ptr , (int)gap_base_getpid() ); } gap_image_delete_immediate(images[l_idi]); } l_idi = nimages -1; /* force break at next loop iteration */ } gimp_parasite_free(l_parasite); } } if(images) { g_free(images); } if (l_image_id >= 0) { if(gap_debug) { printf("FrameFetcher: p_load_cache_image CACHE-HIT :%s (image_id:%d) pid:%d\n" , filename, (int)l_image_id, (int)gap_base_getpid()); } return(l_image_id); } l_filename = g_strdup(filename); l_image_id = gap_lib_load_image(l_filename); if(gap_debug) { printf("FrameFetcher: loaded image from disk:%s (image_id:%d) pid:%d\n" , l_filename, (int)l_image_id, (int)gap_base_getpid()); } if((l_image_id >= 0) && (addToCache == TRUE)) { guchar *parasite_data; gint32 parasite_size; gint32 *parasite_mtime_ptr; gint32 *parasite_ffetch_id_ptr; gchar *parasite_filename_ptr; gint32 len_filename0; /* filename length including the terminating 0 */ if (l_number_of_cached_images > p_get_ffetch_max_img_cache_elements()) { /* the image cache already has more elements than desired, * drop the 1st cached image */ if(gap_debug) { printf("FrameFetcher: DELETE because cache is full: (image_id:%d) name:%s number_of_cached_images:%d pid:%d\n" , (int)l_first_cached_image_id , gimp_image_get_filename(l_first_cached_image_id) , (int)l_number_of_cached_images , (int)gap_base_getpid() ); } gap_image_delete_immediate(l_first_cached_image_id); } /* build parasite data including mtime and full filename with terminating 0 byte */ len_filename0 = strlen(filename) + 1; parasite_size = sizeof(gint32) + sizeof(gint32) + len_filename0; parasite_data = g_malloc0(parasite_size); parasite_mtime_ptr = (gint32 *)parasite_data; parasite_ffetch_id_ptr = (gint32 *)¶site_data[sizeof(gint32)]; parasite_filename_ptr = (gchar *)¶site_data[sizeof(gint32) + sizeof(gint32)]; *parasite_mtime_ptr = gap_file_get_mtime(filename); *parasite_ffetch_id_ptr = ffetch_user_id; memcpy(parasite_filename_ptr, filename, len_filename0); /* attach a parasite to mark the image as part of the gap image cache */ l_parasite = gimp_parasite_new(GAP_IMAGE_CACHE_PARASITE ,0 /* GIMP_PARASITE_PERSISTENT 0 for non persistent */ ,parasite_size ,parasite_data ); if(l_parasite) { gimp_image_parasite_attach(l_image_id, l_parasite); gimp_parasite_free(l_parasite); } g_free(parasite_data); } g_free(l_filename); return(l_image_id); } /* end p_load_cache_image */
/* ---------------------------------------------------- * gap_frame_fetch_dump_resources * ---------------------------------------------------- * print current resource usage to stdout * this includes information about * - ALL images currently loaded * - all video filehandles with memory cache sizes * */ void gap_frame_fetch_dump_resources() { gint32 *images; gint nimages; gint l_idi; gint l_number_of_cached_images; printf("gap_frame_fetch_dump_resources: START pid:%d\n", (int)gap_base_getpid()); l_number_of_cached_images = 0; images = gimp_image_list(&nimages); for(l_idi=0; l_idi < nimages; l_idi++) { GimpParasite *l_parasite; char *l_filename; char *l_cacheInfoString; gint32 image_id; image_id = images[l_idi]; l_filename = gimp_image_get_filename(image_id); l_parasite = gimp_image_parasite_find(image_id, GAP_IMAGE_CACHE_PARASITE); if(l_parasite) { gint32 *mtime_ptr; gint32 *ffetch_id_ptr; gchar *filename_ptr; mtime_ptr = (gint32 *) l_parasite->data; ffetch_id_ptr = (gint32 *)&l_parasite->data[sizeof(gint32)]; filename_ptr = (gchar *)&l_parasite->data[sizeof(gint32) + sizeof(gint32)]; l_number_of_cached_images++; l_cacheInfoString = g_strdup_printf("Cache member: mtime:%d ffetchId:%d %s" ,*mtime_ptr ,*ffetch_id_ptr ,filename_ptr ); gimp_parasite_free(l_parasite); } else { l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_DUP_CACHE_PARASITE); if(l_parasite) { gint32 *ffetch_user_id_ptr; ffetch_user_id_ptr = (gint32 *) l_parasite->data; l_number_of_cached_images++; l_cacheInfoString = g_strdup_printf("Cache member (merged duplicate): ffetchId:%d" ,*ffetch_user_id_ptr ); gimp_parasite_free(l_parasite); } else { l_cacheInfoString = g_strdup_printf("Not cached"); } } printf(" FrameFetcher ImgId:%d (%d x %d) %s %s\n" ,(int)image_id ,(int)gimp_image_width(image_id) ,(int)gimp_image_height(image_id) ,l_filename ,l_cacheInfoString ); g_free(l_cacheInfoString); if(l_filename != NULL) { g_free(l_filename); } l_parasite = NULL; } if(images) { g_free(images); } printf(" Number of images currently loaded in gimp total: %d gap_ffetch_max_img_cache_elements:%d marked as cache member:%d\n" ,(int)nimages ,(int)p_get_ffetch_max_img_cache_elements() ,(int)l_number_of_cached_images ); p_dump_resources_gvahand(); p_dump_process_resource_usage(); } /* end gap_frame_fetch_dump_resources */