gboolean plug_in_icc_profile_info (GimpImage *image, GimpContext *context, GimpProgress *progress, gchar **name, gchar **desc, gchar **info, GError **error) { Gimp *gimp; GimpProcedure *procedure; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); gimp = image->gimp; procedure = gimp_pdb_lookup_procedure (gimp->pdb, ICC_PROFILE_INFO_PROC); if (procedure && procedure->num_args >= 1 && GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[0])) { GimpValueArray *return_vals; GimpPDBStatusType status; return_vals = gimp_pdb_execute_procedure_by_name (gimp->pdb, context, progress, error, ICC_PROFILE_INFO_PROC, GIMP_TYPE_IMAGE_ID, gimp_image_get_ID (image), G_TYPE_NONE); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); switch (status) { case GIMP_PDB_SUCCESS: plug_in_icc_profile_info_return (return_vals, name, desc, info); break; default: if (error && *error == NULL) g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, _("Error running '%s'"), ICC_PROFILE_INFO_PROC); break; } gimp_value_array_unref (return_vals); return (status == GIMP_PDB_SUCCESS); } g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, _("Plug-In missing (%s)"), ICC_PROFILE_INFO_PROC); return FALSE; }
static GValueArray * gimp_pattern_select_run_callback (GimpPdbDialog *dialog, GimpObject *object, gboolean closing, GError **error) { GimpPattern *pattern = GIMP_PATTERN (object); GimpArray *array; GValueArray *return_vals; array = gimp_array_new (temp_buf_get_data (pattern->mask), temp_buf_get_data_size (pattern->mask), TRUE); return_vals = gimp_pdb_execute_procedure_by_name (dialog->pdb, dialog->caller_context, NULL, error, dialog->callback_name, G_TYPE_STRING, gimp_object_get_name (object), GIMP_TYPE_INT32, pattern->mask->width, GIMP_TYPE_INT32, pattern->mask->height, GIMP_TYPE_INT32, pattern->mask->bytes, GIMP_TYPE_INT32, array->length, GIMP_TYPE_INT8_ARRAY, array, GIMP_TYPE_INT32, closing, G_TYPE_NONE); gimp_array_free (array); return return_vals; }
static GValueArray * gimp_brush_select_run_callback (GimpPdbDialog *dialog, GimpObject *object, gboolean closing) { GimpBrush *brush = GIMP_BRUSH (object); GimpArray *array; GValueArray *return_vals; array = gimp_array_new (temp_buf_data (brush->mask), brush->mask->width * brush->mask->height * brush->mask->bytes, TRUE); return_vals = gimp_pdb_execute_procedure_by_name (dialog->pdb, dialog->caller_context, NULL, dialog->callback_name, G_TYPE_STRING, object->name, G_TYPE_DOUBLE, gimp_context_get_opacity (dialog->context) * 100.0, GIMP_TYPE_INT32, GIMP_BRUSH_SELECT (dialog)->spacing, GIMP_TYPE_INT32, gimp_context_get_paint_mode (dialog->context), GIMP_TYPE_INT32, brush->mask->width, GIMP_TYPE_INT32, brush->mask->height, GIMP_TYPE_INT32, array->length, GIMP_TYPE_INT8_ARRAY, array, GIMP_TYPE_INT32, closing, G_TYPE_NONE); gimp_array_free (array); return return_vals; }
static void gimp_plug_in_manager_add_to_db (GimpPlugInManager *manager, GimpContext *context, GimpPlugInProcedure *proc) { gimp_pdb_register_procedure (manager->gimp->pdb, GIMP_PROCEDURE (proc)); if (proc->file_proc) { GValueArray *return_vals; GError *error = NULL; if (proc->image_types) { return_vals = gimp_pdb_execute_procedure_by_name (manager->gimp->pdb, context, NULL, &error, "gimp-register-save-handler", G_TYPE_STRING, gimp_object_get_name (proc), G_TYPE_STRING, proc->extensions, G_TYPE_STRING, proc->prefixes, G_TYPE_NONE); } else { return_vals = gimp_pdb_execute_procedure_by_name (manager->gimp->pdb, context, NULL, &error, "gimp-register-magic-load-handler", G_TYPE_STRING, gimp_object_get_name (proc), G_TYPE_STRING, proc->extensions, G_TYPE_STRING, proc->prefixes, G_TYPE_STRING, proc->magics, G_TYPE_NONE); } g_value_array_free (return_vals); if (error) { gimp_message_literal (manager->gimp, NULL, GIMP_MESSAGE_ERROR, error->message); g_error_free (error); } } }
static GValueArray * gimp_font_select_run_callback (GimpPdbDialog *dialog, GimpObject *object, gboolean closing) { return gimp_pdb_execute_procedure_by_name (dialog->pdb, dialog->caller_context, NULL, dialog->callback_name, G_TYPE_STRING, object->name, GIMP_TYPE_INT32, closing, G_TYPE_NONE); }
static void about_dialog_load_url (GtkAboutDialog *dialog, const gchar *url, gpointer data) { GimpContext *context = GIMP_CONTEXT (data); GValueArray *return_vals; return_vals = gimp_pdb_execute_procedure_by_name (context->gimp->pdb, context, NULL, PDB_URL_LOAD, G_TYPE_STRING, url, G_TYPE_NONE); g_value_array_free (return_vals); }
static gdouble gimp_pdb_progress_run_callback (GimpPdbProgress *progress, GimpProgressCommand command, const gchar *text, gdouble value) { gdouble retval = 0; if (progress->callback_name && ! progress->callback_busy) { GimpValueArray *return_vals; progress->callback_busy = TRUE; return_vals = gimp_pdb_execute_procedure_by_name (progress->pdb, progress->context, NULL, NULL, progress->callback_name, GIMP_TYPE_INT32, command, G_TYPE_STRING, text, G_TYPE_DOUBLE, value, G_TYPE_NONE); if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) != GIMP_PDB_SUCCESS) { gimp_message (progress->context->gimp, NULL, GIMP_MESSAGE_ERROR, _("Unable to run %s callback. " "The corresponding plug-in may have crashed."), g_type_name (G_TYPE_FROM_INSTANCE (progress))); } else if (gimp_value_array_length (return_vals) >= 2 && G_VALUE_HOLDS_DOUBLE (gimp_value_array_index (return_vals, 1))) { retval = g_value_get_double (gimp_value_array_index (return_vals, 1)); } gimp_value_array_unref (return_vals); progress->callback_busy = FALSE; } return retval; }
static void gimp_help_call (Gimp *gimp, const gchar *procedure_name, const gchar *help_domain, const gchar *help_locales, const gchar *help_id) { GimpProcedure *procedure; /* Special case the help browser */ if (! strcmp (procedure_name, "extension-gimp-help-browser-temp")) { GValueArray *return_vals; return_vals = gimp_pdb_execute_procedure_by_name (gimp->pdb, gimp_get_user_context (gimp), NULL, procedure_name, G_TYPE_STRING, help_domain, G_TYPE_STRING, help_locales, G_TYPE_STRING, help_id, G_TYPE_NONE); g_value_array_free (return_vals); return; } /* Check if a help parser is already running */ procedure = gimp_pdb_lookup_procedure (gimp->pdb, "extension-gimp-help-temp"); if (! procedure) { GValueArray *args = NULL; gint n_domains = 0; gchar **help_domains = NULL; gchar **help_uris = NULL; procedure = gimp_pdb_lookup_procedure (gimp->pdb, "extension-gimp-help"); if (! procedure) /* FIXME: error msg */ return; n_domains = gimp_plug_in_manager_get_help_domains (gimp->plug_in_manager, &help_domains, &help_uris); args = gimp_procedure_get_arguments (procedure); gimp_value_array_truncate (args, 4); g_value_set_int (&args->values[0], n_domains); gimp_value_take_stringarray (&args->values[1], help_domains, n_domains); g_value_set_int (&args->values[2], n_domains); gimp_value_take_stringarray (&args->values[3], help_uris, n_domains); gimp_procedure_execute_async (procedure, gimp, gimp_get_user_context (gimp), NULL, args, NULL); g_value_array_free (args); } /* Check if the help parser started properly */ procedure = gimp_pdb_lookup_procedure (gimp->pdb, "extension-gimp-help-temp"); if (procedure) { GValueArray *return_vals; #ifdef GIMP_HELP_DEBUG g_printerr ("Calling help via %s: %s %s %s\n", procedure_name, help_domain ? help_domain : "(null)", help_locales ? help_locales : "(null)", help_id ? help_id : "(null)"); #endif return_vals = gimp_pdb_execute_procedure_by_name (gimp->pdb, gimp_get_user_context (gimp), NULL, "extension-gimp-help-temp", G_TYPE_STRING, procedure_name, G_TYPE_STRING, help_domain, G_TYPE_STRING, help_locales, G_TYPE_STRING, help_id, G_TYPE_NONE); g_value_array_free (return_vals); } }
GimpPDBStatusType file_save (Gimp *gimp, GimpImage *image, GimpProgress *progress, const gchar *uri, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, gboolean change_saved_state, gboolean export_backward, gboolean export_forward, GError **error) { GimpDrawable *drawable; GimpValueArray *return_vals; GimpPDBStatusType status; gchar *filename; gint32 image_ID; gint32 drawable_ID; g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail ((export_backward && export_forward) == FALSE, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, GIMP_PDB_CALLING_ERROR); drawable = gimp_image_get_active_drawable (image); if (! drawable) return GIMP_PDB_EXECUTION_ERROR; filename = file_utils_filename_from_uri (uri); if (filename) { /* check if we are saving to a file */ if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Not a regular file")); status = GIMP_PDB_EXECUTION_ERROR; goto out; } if (g_access (filename, W_OK) != 0) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, g_strerror (errno)); status = GIMP_PDB_EXECUTION_ERROR; goto out; } } if (file_proc->handles_uri) { g_free (filename); filename = g_strdup (uri); } } else { filename = g_strdup (uri); } /* ref the image, so it can't get deleted during save */ g_object_ref (image); image_ID = gimp_image_get_ID (image); drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable)); return_vals = gimp_pdb_execute_procedure_by_name (image->gimp->pdb, gimp_get_user_context (gimp), progress, error, gimp_object_get_name (file_proc), GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, image_ID, GIMP_TYPE_DRAWABLE_ID, drawable_ID, G_TYPE_STRING, filename, G_TYPE_STRING, uri, G_TYPE_NONE); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); gimp_value_array_unref (return_vals); if (status == GIMP_PDB_SUCCESS) { GimpDocumentList *documents; GimpImagefile *imagefile; if (change_saved_state) { gimp_image_set_uri (image, uri); gimp_image_set_save_proc (image, file_proc); /* Forget the import source when we save. We interpret a * save as that the user is not interested in being able * to quickly export back to the original any longer */ gimp_image_set_imported_uri (image, NULL); gimp_image_clean_all (image); } else if (export_backward) { /* We exported the image back to its imported source, * change nothing about export/import flags, only set * the export state to clean */ gimp_image_export_clean_all (image); gimp_object_name_changed (GIMP_OBJECT (image)); } else if (export_forward) { /* Remember the last entered Export URI for the image. We * only need to do this explicitly when exporting. It * happens implicitly when saving since the GimpObject name * of a GimpImage is the last-save URI */ gimp_image_set_exported_uri (image, uri); /* An image can not be considered both exported and imported * at the same time, so stop consider it as imported now * that we consider it exported. */ gimp_image_set_imported_uri (image, NULL); gimp_image_export_clean_all (image); } if (export_backward || export_forward) gimp_image_exported (image, uri); else gimp_image_saved (image, uri); documents = GIMP_DOCUMENT_LIST (image->gimp->documents); imagefile = gimp_document_list_add_uri (documents, uri, file_proc->mime_type); /* only save a thumbnail if we are saving as XCF, see bug #25272 */ if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL) gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image); } else if (status != GIMP_PDB_CANCEL) { if (error && *error == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("%s plug-in could not save image"), gimp_plug_in_procedure_get_label (file_proc)); } } gimp_image_flush (image); g_object_unref (image); out: g_free (filename); return status; }
gboolean plug_in_icc_profile_apply_rgb (GimpImage *image, GimpContext *context, GimpProgress *progress, GimpRunMode run_mode, GError **error) { Gimp *gimp; GimpProcedure *procedure; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); gimp = image->gimp; if (gimp_image_get_base_type (image) == GIMP_GRAY) { g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED, _("Can't apply color profile to grayscale image (%s)"), ICC_PROFILE_APPLY_RGB_PROC); return FALSE; } procedure = gimp_pdb_lookup_procedure (gimp->pdb, ICC_PROFILE_APPLY_RGB_PROC); if (procedure && procedure->num_args >= 2 && GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) && GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1])) { GimpValueArray *return_vals; GimpPDBStatusType status; GimpColorProfilePolicy policy = GIMP_COLOR_PROFILE_POLICY_ASK; gboolean success; return_vals = gimp_pdb_execute_procedure_by_name (gimp->pdb, context, progress, error, ICC_PROFILE_APPLY_RGB_PROC, GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, gimp_image_get_ID (image), G_TYPE_NONE); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); switch (status) { case GIMP_PDB_SUCCESS: policy = GIMP_COLOR_PROFILE_POLICY_CONVERT; success = TRUE; break; case GIMP_PDB_CANCEL: policy = GIMP_COLOR_PROFILE_POLICY_KEEP; success = TRUE; break; default: if (error && *error == NULL) g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED, _("Error running '%s'"), ICC_PROFILE_APPLY_RGB_PROC); success = FALSE; break; } if (success && gimp_value_array_length (return_vals) > 1) { GValue *value = gimp_value_array_index (return_vals, 1); if (GIMP_VALUE_HOLDS_INT32 (value) && g_value_get_int (value)) { g_object_set (G_OBJECT (gimp->config), "color-profile-policy", policy, NULL); } } gimp_value_array_unref (return_vals); return success; } g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_NOT_FOUND, _("Plug-In missing (%s)"), ICC_PROFILE_APPLY_RGB_PROC); return FALSE; }
GimpPDBStatusType file_save (Gimp *gimp, GimpImage *image, GimpProgress *progress, GFile *file, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, gboolean change_saved_state, gboolean export_backward, gboolean export_forward, GError **error) { GimpDrawable *drawable; GimpValueArray *return_vals; GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR; GFile *local_file = NULL; gchar *path = NULL; gchar *uri = NULL; gint32 image_ID; gint32 drawable_ID; GError *my_error = NULL; g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (G_IS_FILE (file), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail ((export_backward && export_forward) == FALSE, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, GIMP_PDB_CALLING_ERROR); /* ref image and file, so they can't get deleted during save */ g_object_ref (image); g_object_ref (file); drawable = gimp_image_get_active_drawable (image); if (! drawable) goto out; /* 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_WRITE, G_FILE_QUERY_INFO_NONE, NULL, error); if (! info) goto out; 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); goto out; } if (! g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Permission denied")); g_object_unref (info); goto out; } g_object_unref (info); } 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; goto out; } if (! file_proc->handles_uri) { path = g_file_get_path (file); if (! path) { local_file = file_remote_upload_image_prepare (gimp, file, progress, &my_error); if (! local_file) { if (my_error) g_propagate_error (error, my_error); else status = GIMP_PDB_CANCEL; goto out; } path = g_file_get_path (local_file); } } if (! path) path = g_file_get_uri (file); uri = g_file_get_uri (file); image_ID = gimp_image_get_ID (image); drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable)); return_vals = gimp_pdb_execute_procedure_by_name (image->gimp->pdb, gimp_get_user_context (gimp), progress, error, gimp_object_get_name (file_proc), GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, image_ID, GIMP_TYPE_DRAWABLE_ID, drawable_ID, G_TYPE_STRING, path, G_TYPE_STRING, uri, G_TYPE_NONE); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); gimp_value_array_unref (return_vals); if (local_file) { if (status == GIMP_PDB_SUCCESS) { GError *my_error = NULL; if (! file_remote_upload_image_finish (gimp, file, local_file, progress, &my_error)) { status = GIMP_PDB_EXECUTION_ERROR; if (my_error) g_propagate_error (error, my_error); else status = GIMP_PDB_CANCEL; } } g_file_delete (local_file, NULL, NULL); g_object_unref (local_file); } if (status == GIMP_PDB_SUCCESS) { GimpDocumentList *documents; GimpImagefile *imagefile; if (change_saved_state) { gimp_image_set_file (image, file); gimp_image_set_save_proc (image, file_proc); /* Forget the import source when we save. We interpret a * save as that the user is not interested in being able * to quickly export back to the original any longer */ gimp_image_set_imported_file (image, NULL); gimp_image_clean_all (image); } else if (export_backward) { /* We exported the image back to its imported source, * change nothing about export/import flags, only set * the export state to clean */ gimp_image_export_clean_all (image); gimp_object_name_changed (GIMP_OBJECT (image)); } else if (export_forward) { /* Remember the last entered Export URI for the image. We * only need to do this explicitly when exporting. It * happens implicitly when saving since the GimpObject name * of a GimpImage is the last-save URI */ gimp_image_set_exported_file (image, file); gimp_image_set_export_proc (image, file_proc); /* An image can not be considered both exported and imported * at the same time, so stop consider it as imported now * that we consider it exported. */ gimp_image_set_imported_file (image, NULL); gimp_image_export_clean_all (image); } if (export_backward || export_forward) gimp_image_exported (image, file); else gimp_image_saved (image, file); documents = GIMP_DOCUMENT_LIST (image->gimp->documents); imagefile = gimp_document_list_add_file (documents, file, file_proc->mime_type); /* only save a thumbnail if we are saving as XCF, see bug #25272 */ if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL) gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image, NULL); } else if (status != GIMP_PDB_CANCEL) { if (error && *error == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("%s plug-in could not save image"), gimp_plug_in_procedure_get_label (file_proc)); } } gimp_image_flush (image); out: g_object_unref (file); g_object_unref (image); g_free (path); g_free (uri); return status; }
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 = file_procedure_find (gimp->plug_in_manager->load_procs, file, error); if (! file_proc) return NULL; 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->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; } 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); 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); 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) { file_open_sanitize_image (image, as_new); /* 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_plug_in_procedure_get_label (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_plug_in_procedure_get_label (file_proc)); } gimp_value_array_unref (return_vals); if (image) { file_open_handle_color_profile (image, context, progress, run_mode); 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); } } return image; }
/** * file_open_thumbnail: * @gimp: * @context: * @progress: * @file: an image file * @size: requested size of the thumbnail * @mime_type: return location for image MIME type * @image_width: return location for image width * @image_height: return location for image height * @format: return location for image format (set to NULL if unknown) * @num_layers: return location for number of layers * (set to -1 if the number of layers is not known) * @error: * * Attempts to load a thumbnail by using a registered thumbnail loader. * * Return value: the thumbnail image */ GimpImage * file_open_thumbnail (Gimp *gimp, GimpContext *context, GimpProgress *progress, GFile *file, gint size, const gchar **mime_type, gint *image_width, gint *image_height, const Babl **format, gint *num_layers, GError **error) { GimpPlugInProcedure *file_proc; GimpProcedure *procedure; 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 (mime_type != NULL, NULL); g_return_val_if_fail (image_width != NULL, NULL); g_return_val_if_fail (image_height != NULL, NULL); g_return_val_if_fail (format != NULL, NULL); g_return_val_if_fail (num_layers != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); *image_width = 0; *image_height = 0; *format = NULL; *num_layers = -1; file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, file, NULL); if (! file_proc || ! file_proc->thumb_loader) return NULL; procedure = gimp_pdb_lookup_procedure (gimp->pdb, file_proc->thumb_loader); if (procedure && procedure->num_args >= 2 && procedure->num_values >= 1) { GimpPDBStatusType status; GimpValueArray *return_vals; GimpImage *image = NULL; gchar *path = NULL; if (! file_proc->handles_uri) path = g_file_get_path (file); if (! path) path = g_file_get_uri (file); return_vals = gimp_pdb_execute_procedure_by_name (gimp->pdb, context, progress, error, gimp_object_get_name (procedure), G_TYPE_STRING, path, GIMP_TYPE_INT32, size, G_TYPE_NONE); g_free (path); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); if (status == GIMP_PDB_SUCCESS && GIMP_VALUE_HOLDS_IMAGE_ID (gimp_value_array_index (return_vals, 1))) { image = gimp_value_get_image (gimp_value_array_index (return_vals, 1), gimp); if (gimp_value_array_length (return_vals) >= 3 && G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 2)) && G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 3))) { *image_width = MAX (0, g_value_get_int (gimp_value_array_index (return_vals, 2))); *image_height = MAX (0, g_value_get_int (gimp_value_array_index (return_vals, 3))); if (gimp_value_array_length (return_vals) >= 5 && G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 4))) { gint value = g_value_get_int (gimp_value_array_index (return_vals, 4)); switch (value) { case GIMP_RGB_IMAGE: *format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA, FALSE); break; case GIMP_RGBA_IMAGE: *format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA, TRUE); break; case GIMP_GRAY_IMAGE: *format = gimp_babl_format (GIMP_GRAY, GIMP_PRECISION_U8_GAMMA, FALSE); break; case GIMP_GRAYA_IMAGE: *format = gimp_babl_format (GIMP_GRAY, GIMP_PRECISION_U8_GAMMA, TRUE); break; case GIMP_INDEXED_IMAGE: case GIMP_INDEXEDA_IMAGE: { const Babl *rgb; const Babl *rgba; babl_new_palette ("-gimp-indexed-format-dummy", &rgb, &rgba); if (value == GIMP_INDEXED_IMAGE) *format = rgb; else *format = rgba; } break; default: break; } } if (gimp_value_array_length (return_vals) >= 6 && G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 5))) { *num_layers = MAX (0, g_value_get_int (gimp_value_array_index (return_vals, 5))); } } if (image) { file_open_sanitize_image (image, FALSE); *mime_type = file_proc->mime_type; #ifdef GIMP_UNSTABLE g_printerr ("opened thumbnail at %d x %d\n", gimp_image_get_width (image), gimp_image_get_height (image)); #endif } } gimp_value_array_unref (return_vals); return image; } return NULL; }
GimpImage * file_open_image (Gimp *gimp, GimpContext *context, GimpProgress *progress, const gchar *uri, const gchar *entered_filename, gboolean as_new, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, GimpPDBStatusType *status, const gchar **mime_type, GError **error) { GValueArray *return_vals; gchar *filename; GimpImage *image = 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 (status != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); *status = GIMP_PDB_EXECUTION_ERROR; if (! file_proc) file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, uri, error); if (! file_proc) return NULL; filename = file_utils_filename_from_uri (uri); if (filename) { /* check if we are opening a file */ if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { g_free (filename); g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Not a regular file")); return NULL; } if (g_access (filename, R_OK) != 0) { g_free (filename); g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, g_strerror (errno)); return NULL; } } } else { filename = g_strdup (uri); } 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, filename, G_TYPE_STRING, entered_filename, G_TYPE_NONE); g_free (filename); *status = g_value_get_enum (&return_vals->values[0]); if (*status == GIMP_PDB_SUCCESS) { image = gimp_value_get_image (&return_vals->values[1], gimp); if (image) { file_open_sanitize_image (image, as_new); /* 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_plug_in_procedure_get_label (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_plug_in_procedure_get_label (file_proc)); } g_value_array_free (return_vals); if (image) { file_open_handle_color_profile (image, context, progress, run_mode); if (file_open_file_proc_is_import (file_proc)) { /* Remember the import source */ gimp_image_set_imported_uri (image, uri); /* We shall treat this file as an Untitled file */ gimp_image_set_uri (image, NULL); } } return image; }
/** * file_open_thumbnail: * @gimp: * @context: * @progress: * @uri: the URI of the image file * @size: requested size of the thumbnail * @mime_type: return location for image MIME type * @image_width: return location for image width * @image_height: return location for image height * @type: return location for image type (set to -1 if unknown) * @num_layers: return location for number of layers * (set to -1 if the number of layers is not known) * @error: * * Attempts to load a thumbnail by using a registered thumbnail loader. * * Return value: the thumbnail image */ GimpImage * file_open_thumbnail (Gimp *gimp, GimpContext *context, GimpProgress *progress, const gchar *uri, gint size, const gchar **mime_type, gint *image_width, gint *image_height, GimpImageType *type, gint *num_layers, GError **error) { GimpPlugInProcedure *file_proc; GimpProcedure *procedure; 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 (mime_type != NULL, NULL); g_return_val_if_fail (image_width != NULL, NULL); g_return_val_if_fail (image_height != NULL, NULL); g_return_val_if_fail (type != NULL, NULL); g_return_val_if_fail (num_layers != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); *image_width = 0; *image_height = 0; *type = -1; *num_layers = -1; file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, uri, NULL); if (! file_proc || ! file_proc->thumb_loader) return NULL; procedure = gimp_pdb_lookup_procedure (gimp->pdb, file_proc->thumb_loader); if (procedure && procedure->num_args >= 2 && procedure->num_values >= 1) { GimpPDBStatusType status; GValueArray *return_vals; gchar *filename; GimpImage *image = NULL; filename = file_utils_filename_from_uri (uri); if (! filename) filename = g_strdup (uri); return_vals = gimp_pdb_execute_procedure_by_name (gimp->pdb, context, progress, error, gimp_object_get_name (procedure), G_TYPE_STRING, filename, GIMP_TYPE_INT32, size, G_TYPE_NONE); g_free (filename); status = g_value_get_enum (&return_vals->values[0]); if (status == GIMP_PDB_SUCCESS && GIMP_VALUE_HOLDS_IMAGE_ID (&return_vals->values[1])) { image = gimp_value_get_image (&return_vals->values[1], gimp); if (return_vals->n_values >= 3 && G_VALUE_HOLDS_INT (&return_vals->values[2]) && G_VALUE_HOLDS_INT (&return_vals->values[3])) { *image_width = MAX (0, g_value_get_int (&return_vals->values[2])); *image_height = MAX (0, g_value_get_int (&return_vals->values[3])); if (return_vals->n_values >= 5 && G_VALUE_HOLDS_INT (&return_vals->values[4])) { gint value = g_value_get_int (&return_vals->values[4]); if (gimp_enum_get_value (GIMP_TYPE_IMAGE_TYPE, value, NULL, NULL, NULL, NULL)) { *type = value; } } if (return_vals->n_values >= 6 && G_VALUE_HOLDS_INT (&return_vals->values[5])) { *num_layers = MAX (0, g_value_get_int (&return_vals->values[5])); } } if (image) { file_open_sanitize_image (image, FALSE); *mime_type = file_proc->mime_type; #ifdef GIMP_UNSTABLE g_printerr ("opened thumbnail at %d x %d\n", gimp_image_get_width (image), gimp_image_get_height (image)); #endif } } g_value_array_free (return_vals); return image; } return NULL; }
GimpPDBStatusType file_save (GimpImage *image, GimpContext *context, GimpProgress *progress, const gchar *uri, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, gboolean save_a_copy, GError **error) { GimpDrawable *drawable; GValueArray *return_vals; GimpPDBStatusType status; gchar *filename; gint32 image_ID; gint32 drawable_ID; g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, GIMP_PDB_CALLING_ERROR); drawable = gimp_image_get_active_drawable (image); if (! drawable) return GIMP_PDB_EXECUTION_ERROR; filename = file_utils_filename_from_uri (uri); if (filename) { /* check if we are saving to a file */ if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", _("Not a regular file")); status = GIMP_PDB_EXECUTION_ERROR; goto out; } if (g_access (filename, W_OK) != 0) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, "%s", g_strerror (errno)); status = GIMP_PDB_EXECUTION_ERROR; goto out; } } } else { filename = g_strdup (uri); } /* ref the image, so it can't get deleted during save */ g_object_ref (image); image_ID = gimp_image_get_ID (image); drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable)); return_vals = gimp_pdb_execute_procedure_by_name (image->gimp->pdb, context, progress, error, GIMP_OBJECT (file_proc)->name, GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, image_ID, GIMP_TYPE_DRAWABLE_ID, drawable_ID, G_TYPE_STRING, filename, G_TYPE_STRING, uri, G_TYPE_NONE); status = g_value_get_enum (&return_vals->values[0]); g_value_array_free (return_vals); if (status == GIMP_PDB_SUCCESS) { GimpDocumentList *documents; GimpImagefile *imagefile; if (save_a_copy) { /* remember the "save-a-copy" filename for the next invocation */ g_object_set_data_full (G_OBJECT (image), "gimp-image-save-a-copy", g_strdup (uri), (GDestroyNotify) g_free); } else { /* reset the "save-a-copy" filename when the image URI changes */ if (strcmp (uri, gimp_image_get_uri (image))) g_object_set_data (G_OBJECT (image), "gimp-image-save-a-copy", NULL); gimp_image_set_uri (image, uri); gimp_image_set_save_proc (image, file_proc); gimp_image_clean_all (image); } gimp_image_saved (image, uri); documents = GIMP_DOCUMENT_LIST (image->gimp->documents); imagefile = gimp_document_list_add_uri (documents, uri, file_proc->mime_type); /* only save a thumbnail if we are saving as XCF, see bug #25272 */ if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL) gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image); } else if (status != GIMP_PDB_CANCEL) { if (error && *error == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("%s plug-in could not save image"), gimp_plug_in_procedure_get_label (file_proc)); } } gimp_image_flush (image); g_object_unref (image); out: g_free (filename); return status; }