/** * gimp_drawable_is_layer_mask: * @drawable_ID: The drawable. * * Deprecated: Use gimp_item_is_layer_mask() instead. * * Returns: TRUE if the drawable is a layer mask, FALSE otherwise. */ gboolean gimp_drawable_is_layer_mask (gint32 drawable_ID) { return gimp_item_is_layer_mask (drawable_ID); }
/** * gimp_export_image: * @image_ID: Pointer to the image_ID. * @drawable_ID: Pointer to the drawable_ID. * @format_name: The (short) name of the image_format (e.g. JPEG or GIF). * @capabilities: What can the image_format do? * * Takes an image and a drawable to be saved together with a * description of the capabilities of the image_format. If the * type of image doesn't match the capabilities of the format * a dialog is opened that informs the user that the image has * to be exported and offers to do the necessary conversions. * * If the user chooses to export the image, a copy is created. * This copy is then converted, the image_ID and drawable_ID * are changed to point to the new image and the procedure returns * GIMP_EXPORT_EXPORT. The save_plugin has to take care of deleting the * created image using gimp_image_delete() when it has saved it. * * If the user chooses to Ignore the export problem, the image_ID * and drawable_ID is not altered, GIMP_EXPORT_IGNORE is returned and * the save_plugin should try to save the original image. If the * user chooses Cancel, GIMP_EXPORT_CANCEL is returned and the * save_plugin should quit itself with status %GIMP_PDB_CANCEL. * * If @format_name is NULL, no dialogs will be shown and this function * will behave as if the user clicked on the 'Export' button, if a * dialog would have been shown. * * Returns: An enum of #GimpExportReturn describing the user_action. **/ GimpExportReturn gimp_export_image (gint32 *image_ID, gint32 *drawable_ID, const gchar *format_name, GimpExportCapabilities capabilities) { GSList *actions = NULL; GimpImageBaseType type; gint32 i; gint32 n_layers; gint32 *layers; gboolean interactive = FALSE; gboolean added_flatten = FALSE; gboolean has_layer_masks = FALSE; gboolean background_has_alpha = TRUE; GimpExportReturn retval = GIMP_EXPORT_CANCEL; g_return_val_if_fail (*image_ID > -1 && *drawable_ID > -1, FALSE); /* do some sanity checks */ if (capabilities & GIMP_EXPORT_NEEDS_ALPHA) capabilities |= GIMP_EXPORT_CAN_HANDLE_ALPHA; if (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION) capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS; if (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS) capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS; if (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS) capabilities |= GIMP_EXPORT_CAN_HANDLE_ALPHA; if (format_name && g_getenv ("GIMP_INTERACTIVE_EXPORT")) interactive = TRUE; /* ask for confirmation if the user is not saving a layer (see bug #51114) */ if (interactive && ! gimp_item_is_layer (*drawable_ID) && ! (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS)) { if (gimp_item_is_layer_mask (*drawable_ID)) { retval = confirm_save_dialog (_("You are about to save a layer mask as %s.\n" "This will not save the visible layers."), format_name); } else if (gimp_item_is_channel (*drawable_ID)) { retval = confirm_save_dialog (_("You are about to save a channel (saved selection) as %s.\n" "This will not save the visible layers."), format_name); } else { /* this should not happen */ g_warning ("%s: unknown drawable type!", G_STRFUNC); } /* cancel - the user can then select an appropriate layer to save */ if (retval == GIMP_EXPORT_CANCEL) return GIMP_EXPORT_CANCEL; } /* check alpha and layer masks */ layers = gimp_image_get_layers (*image_ID, &n_layers); for (i = 0; i < n_layers; i++) { if (gimp_drawable_has_alpha (layers[i])) { if (! (capabilities & GIMP_EXPORT_CAN_HANDLE_ALPHA)) { actions = g_slist_prepend (actions, &export_action_flatten); added_flatten = TRUE; break; } } else { /* If this is the last layer, it's visible and has no alpha * channel, then the image has a "flat" background */ if (i == n_layers - 1 && gimp_item_get_visible (layers[i])) background_has_alpha = FALSE; if (capabilities & GIMP_EXPORT_NEEDS_ALPHA) { actions = g_slist_prepend (actions, &export_action_add_alpha); break; } } } if (! added_flatten) { for (i = 0; i < n_layers; i++) { if (gimp_layer_get_mask (layers[i]) != -1) has_layer_masks = TRUE; } } if (! added_flatten) { gint32 n_children; gint32 *children; children = gimp_item_get_children (layers[0], &n_children); /* check if layer size != canvas size, opacity != 100%, or offsets != 0 */ if (n_layers == 1 && ! children && gimp_item_is_layer (*drawable_ID) && ! (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS)) { gint offset_x; gint offset_y; gimp_drawable_offsets (*drawable_ID, &offset_x, &offset_y); if ((gimp_layer_get_opacity (*drawable_ID) < 100.0) || (gimp_image_width (*image_ID) != gimp_drawable_width (*drawable_ID)) || (gimp_image_height (*image_ID) != gimp_drawable_height (*drawable_ID)) || offset_x || offset_y) { if (capabilities & GIMP_EXPORT_CAN_HANDLE_ALPHA) { actions = g_slist_prepend (actions, &export_action_merge_single); } else { actions = g_slist_prepend (actions, &export_action_flatten); } } } /* check multiple layers */ else if (n_layers > 1) { if (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION) { if (background_has_alpha || capabilities & GIMP_EXPORT_NEEDS_ALPHA) actions = g_slist_prepend (actions, &export_action_animate_or_merge); else actions = g_slist_prepend (actions, &export_action_animate_or_flatten); } else if (! (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS)) { if (capabilities & GIMP_EXPORT_NEEDS_ALPHA) actions = g_slist_prepend (actions, &export_action_merge); else actions = g_slist_prepend (actions, &export_action_merge_or_flatten); } } /* check for a single toplevel layer group */ else if (children) { if (! (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS)) { if (capabilities & GIMP_EXPORT_NEEDS_ALPHA) actions = g_slist_prepend (actions, &export_action_merge); else actions = g_slist_prepend (actions, &export_action_merge_or_flatten); } } g_free (children); /* check layer masks */ if (has_layer_masks && ! (capabilities & GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS)) actions = g_slist_prepend (actions, &export_action_apply_masks); } g_free (layers); /* check the image type */ type = gimp_image_base_type (*image_ID); switch (type) { case GIMP_RGB: if (! (capabilities & GIMP_EXPORT_CAN_HANDLE_RGB)) { if ((capabilities & GIMP_EXPORT_CAN_HANDLE_INDEXED) && (capabilities & GIMP_EXPORT_CAN_HANDLE_GRAY)) actions = g_slist_prepend (actions, &export_action_convert_indexed_or_grayscale); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_INDEXED) actions = g_slist_prepend (actions, &export_action_convert_indexed); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_GRAY) actions = g_slist_prepend (actions, &export_action_convert_grayscale); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_BITMAP) actions = g_slist_prepend (actions, &export_action_convert_bitmap); } break; case GIMP_GRAY: if (! (capabilities & GIMP_EXPORT_CAN_HANDLE_GRAY)) { if ((capabilities & GIMP_EXPORT_CAN_HANDLE_RGB) && (capabilities & GIMP_EXPORT_CAN_HANDLE_INDEXED)) actions = g_slist_prepend (actions, &export_action_convert_rgb_or_indexed); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_RGB) actions = g_slist_prepend (actions, &export_action_convert_rgb); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_INDEXED) actions = g_slist_prepend (actions, &export_action_convert_indexed); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_BITMAP) actions = g_slist_prepend (actions, &export_action_convert_bitmap); } break; case GIMP_INDEXED: if (! (capabilities & GIMP_EXPORT_CAN_HANDLE_INDEXED)) { if ((capabilities & GIMP_EXPORT_CAN_HANDLE_RGB) && (capabilities & GIMP_EXPORT_CAN_HANDLE_GRAY)) actions = g_slist_prepend (actions, &export_action_convert_rgb_or_grayscale); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_RGB) actions = g_slist_prepend (actions, &export_action_convert_rgb); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_GRAY) actions = g_slist_prepend (actions, &export_action_convert_grayscale); else if (capabilities & GIMP_EXPORT_CAN_HANDLE_BITMAP) { gint n_colors; g_free (gimp_image_get_colormap (*image_ID, &n_colors)); if (n_colors > 2) actions = g_slist_prepend (actions, &export_action_convert_bitmap); } } break; } if (actions) { actions = g_slist_reverse (actions); if (interactive) retval = export_dialog (actions, format_name); else retval = GIMP_EXPORT_EXPORT; } else { retval = GIMP_EXPORT_IGNORE; } if (retval == GIMP_EXPORT_EXPORT) { GSList *list; *image_ID = gimp_image_duplicate (*image_ID); *drawable_ID = gimp_image_get_active_layer (*image_ID); gimp_image_undo_disable (*image_ID); for (list = actions; list; list = list->next) { export_action_perform (list->data, *image_ID, drawable_ID); } } g_slist_free (actions); return retval; }