gimp/libgimp/gimpexport.c

718 lines
20 KiB
C
Raw Normal View History

/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpexport.c
* Copyright (C) 1999-2000 Sven Neumann <sven@gimp.org>
*
* This library is free software; you can redistribute it and/or
1999-11-18 05:13:50 +08:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
1999-11-18 05:13:50 +08:00
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gimp.h"
#include "gimpui.h"
#include "libgimp-intl.h"
typedef void (* ExportFunc) (gint32 imageID,
gint32 *drawable_ID);
/* the export action structure */
typedef struct
{
ExportFunc default_action;
ExportFunc alt_action;
gchar *reason;
gchar *possibilities[2];
gint choice;
} ExportAction;
/* the functions that do the actual export */
static void
export_merge (gint32 image_ID,
gint32 *drawable_ID)
{
2000-02-09 01:04:19 +08:00
gint32 nlayers;
gint32 nvisible = 0;
gint32 i;
gint32 *layers;
2000-02-09 01:04:19 +08:00
gint32 merged;
gint32 transp;
2000-02-09 01:04:19 +08:00
layers = gimp_image_get_layers (image_ID, &nlayers);
for (i = 0; i < nlayers; i++)
{
if (gimp_drawable_visible (layers[i]))
nvisible++;
2000-02-09 01:04:19 +08:00
}
if (nvisible <= 1)
{
/* if there is only one (or zero) visible layer, add a new transparent
layer that has the same size as the canvas. The merge that follows
will ensure that the offset, opacity and size are correct */
transp = gimp_layer_new (image_ID, "-",
gimp_image_width (image_ID),
gimp_image_height (image_ID),
gimp_drawable_type (*drawable_ID) | 1,
100.0, GIMP_NORMAL_MODE);
gimp_image_add_layer (image_ID, transp, 1);
gimp_selection_none (image_ID);
gimp_edit_clear (transp);
nvisible++;
}
2000-02-09 01:04:19 +08:00
if (nvisible > 1)
{
g_free (layers);
merged = gimp_image_merge_visible_layers (image_ID, GIMP_CLIP_TO_IMAGE);
if (merged != -1)
*drawable_ID = merged;
else
return; /* shouldn't happen */
layers = gimp_image_get_layers (image_ID, &nlayers);
}
/* remove any remaining (invisible) layers */
for (i = 0; i < nlayers; i++)
{
if (layers[i] != *drawable_ID)
gimp_image_remove_layer (image_ID, layers[i]);
}
g_free (layers);
}
static void
export_flatten (gint32 image_ID,
gint32 *drawable_ID)
{
2000-02-09 01:04:19 +08:00
gint32 flattened;
flattened = gimp_image_flatten (image_ID);
if (flattened != -1)
*drawable_ID = flattened;
}
static void
export_convert_rgb (gint32 image_ID,
gint32 *drawable_ID)
{
gimp_image_convert_rgb (image_ID);
}
static void
export_convert_grayscale (gint32 image_ID,
gint32 *drawable_ID)
{
gimp_image_convert_grayscale (image_ID);
}
static void
export_convert_indexed (gint32 image_ID,
gint32 *drawable_ID)
{
2000-02-09 01:04:19 +08:00
gint32 nlayers;
/* check alpha */
g_free (gimp_image_get_layers (image_ID, &nlayers));
if (nlayers > 1 || gimp_drawable_has_alpha (*drawable_ID))
gimp_image_convert_indexed (image_ID, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, 255, FALSE, FALSE, "");
else
gimp_image_convert_indexed (image_ID, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, 256, FALSE, FALSE, "");
}
static void
export_add_alpha (gint32 image_ID,
gint32 *drawable_ID)
{
2000-02-09 01:04:19 +08:00
gint32 nlayers;
gint32 i;
gint32 *layers;
layers = gimp_image_get_layers (image_ID, &nlayers);
for (i = 0; i < nlayers; i++)
{
if (!gimp_drawable_has_alpha (layers[i]))
gimp_layer_add_alpha (layers[i]);
}
g_free (layers);
}
/* a set of predefined actions */
static ExportAction export_action_merge =
{
export_merge,
NULL,
N_("can't handle layers"),
2000-01-11 23:48:00 +08:00
{ N_("Merge Visible Layers"), NULL },
0
};
static ExportAction export_action_merge_single =
{
export_merge,
NULL,
N_("can't handle layer offsets, size or opacity"),
{ N_("Merge Visible Layers"), NULL },
0
};
static ExportAction export_action_animate_or_merge =
{
export_merge,
NULL,
N_("can only handle layers as animation frames"),
{ N_("Merge Visible Layers"), N_("Save as Animation")},
0
};
static ExportAction export_action_animate_or_flatten =
{
export_flatten,
NULL,
N_("can only handle layers as animation frames"),
{ N_("Flatten Image"), N_("Save as Animation") },
0
};
static ExportAction export_action_merge_flat =
{
export_flatten,
NULL,
N_("can't handle layers"),
{ N_("Flatten Image"), NULL },
0
};
static ExportAction export_action_flatten =
{
export_flatten,
NULL,
N_("can't handle transparency"),
{ N_("Flatten Image"), NULL },
0
};
static ExportAction export_action_convert_rgb =
{
export_convert_rgb,
NULL,
N_("can only handle RGB images"),
{ N_("Convert to RGB"), NULL },
0
};
static ExportAction export_action_convert_grayscale =
{
export_convert_grayscale,
NULL,
N_("can only handle grayscale images"),
2000-01-11 23:48:00 +08:00
{ N_("Convert to Grayscale"), NULL },
0
};
static ExportAction export_action_convert_indexed =
{
export_convert_indexed,
NULL,
N_("can only handle indexed images"),
{ N_("Convert to Indexed using default settings\n"
2000-01-11 23:48:00 +08:00
"(Do it manually to tune the result)"), NULL },
0
};
static ExportAction export_action_convert_rgb_or_grayscale =
{
export_convert_rgb,
export_convert_grayscale,
N_("can only handle RGB or grayscale images"),
2000-01-11 23:48:00 +08:00
{ N_("Convert to RGB"), N_("Convert to Grayscale")},
0
};
static ExportAction export_action_convert_rgb_or_indexed =
{
export_convert_rgb,
export_convert_indexed,
N_("can only handle RGB or indexed images"),
{ N_("Convert to RGB"), N_("Convert to Indexed using default settings\n"
2000-01-11 23:48:00 +08:00
"(Do it manually to tune the result)")},
0
};
static ExportAction export_action_convert_indexed_or_grayscale =
{
export_convert_indexed,
export_convert_grayscale,
N_("can only handle grayscale or indexed images"),
{ N_("Convert to Indexed using default settings\n"
2000-01-11 23:48:00 +08:00
"(Do it manually to tune the result)"),
N_("Convert to Grayscale") },
0
};
static ExportAction export_action_add_alpha =
{
export_add_alpha,
NULL,
N_("needs an alpha channel"),
2000-01-11 23:48:00 +08:00
{ N_("Add Alpha Channel"), NULL},
0
};
/* dialog functions */
1999-10-04 07:48:33 +08:00
static GtkWidget *dialog = NULL;
static GimpExportReturnType dialog_return = GIMP_EXPORT_CANCEL;
static void
export_export_callback (GtkWidget *widget,
gpointer data)
{
gtk_widget_destroy (dialog);
dialog_return = GIMP_EXPORT_EXPORT;
1999-10-04 07:48:33 +08:00
}
static void
export_confirm_callback (GtkWidget *widget,
gpointer data)
{
gtk_widget_destroy (dialog);
dialog_return = GIMP_EXPORT_EXPORT;
}
1999-10-04 07:48:33 +08:00
static void
export_skip_callback (GtkWidget *widget,
gpointer data)
{
gtk_widget_destroy (dialog);
dialog_return = GIMP_EXPORT_IGNORE;
}
static void
export_cancel_callback (GtkWidget *widget,
gpointer data)
{
dialog_return = GIMP_EXPORT_CANCEL;
dialog = NULL;
gtk_main_quit ();
}
static void
export_toggle_callback (GtkWidget *widget,
gpointer data)
{
gint *choice = (gint*)data;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
*choice = 0;
else
*choice = 1;
}
static gint
confirm_save_dialog (const gchar *saving_what,
const gchar *format_name)
{
GtkWidget *vbox;
GtkWidget *label;
gchar *text;
dialog_return = GIMP_EXPORT_CANCEL;
g_return_val_if_fail (saving_what != NULL && format_name != NULL, dialog_return);
/*
* Plug-ins must have called gtk_init () before calling gimp_export ().
* Otherwise bad things will happen now!!
*/
/* the dialog */
dialog = gimp_dialog_new (_("Confirm Save"), "confirm_save",
gimp_standard_help_func, "dialogs/confirm_save.html",
GTK_WIN_POS_MOUSE,
FALSE, FALSE, FALSE,
_("Confirm"), export_confirm_callback,
NULL, NULL, NULL, TRUE, FALSE,
_("Cancel"), gtk_widget_destroy,
NULL, 1, NULL, FALSE, TRUE,
NULL);
app/gimpprogress.c app/nav_window.c app/ops_buttons.c app/undo_history.c 2001-12-29 Michael Natterer <mitch@gimp.org> * app/gimpprogress.c * app/nav_window.c * app/ops_buttons.c * app/undo_history.c * app/display/gimpdisplayshell.c * app/gui/about-dialog.c * app/gui/brush-editor.c * app/gui/channels-commands.c * app/gui/color-area.c * app/gui/color-notebook.c * app/gui/color-select.c * app/gui/colormap-dialog.c * app/gui/convert-dialog.c * app/gui/device-status-dialog.c * app/gui/file-new-dialog.c * app/gui/file-open-dialog.c * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/info-dialog.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-editor.c * app/gui/palettes-commands.c * app/gui/paths-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/splash.c * app/gui/tips-dialog.c * app/gui/toolbox.c * app/gui/user-install-dialog.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimplevelstool.c * app/tools/gimpposterizetool.c * app/tools/gimprotatetool.c * app/tools/gimpthresholdtool.c * app/tools/paint_options.c * app/tools/selection_options.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcolorpanel.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpconstrainedhwrapbox.c * app/widgets/gimpcontainergridview.c * app/widgets/gimpcontainerlistview.c * app/widgets/gimpcontainermenuimpl.c * app/widgets/gimpdialogfactory.c * app/widgets/gimpdnd.c * app/widgets/gimpdock.c * app/widgets/gimpdockbook.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.c * app/widgets/gimpfontselection-dialog.c * app/widgets/gimphistogramview.c * app/widgets/gimpitemfactory.c * app/widgets/gimplayerlistitem.c * app/widgets/gimplistitem.[ch] * app/widgets/gimpmenuitem.c * app/widgets/gimppreview.[ch] * app/widgets/gtkhwrapbox.c * app/widgets/gtkvwrapbox.c * app/widgets/gtkwrapbox.c * libgimp/gimpbrushmenu.c * libgimp/gimpexport.c * libgimp/gimpgradientmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * libgimpwidgets/gimpbutton.c * libgimpwidgets/gimpchainbutton.[ch] * libgimpwidgets/gimpcolorarea.h * libgimpwidgets/gimpcolorbutton.c * libgimpwidgets/gimpfileselection.c * libgimpwidgets/gimphelpui.c * libgimpwidgets/gimpoffsetarea.c * libgimpwidgets/gimppatheditor.c * libgimpwidgets/gimppixmap.h * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpstock.[ch] * libgimpwidgets/gimpwidgets.h * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/Events.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/Lighting/lighting_ui.c * plug-ins/MapObject/mapobject_ui.c * plug-ins/bmp/bmpwrite.c * plug-ins/dbbrowser/dbbrowser_utils.c * plug-ins/fits/fits.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/fp/fp_misc.c * plug-ins/gfig/gfig.c * plug-ins/gflare/gflare.c * plug-ins/gfli/gfli.c * plug-ins/gimpressionist/*.c * plug-ins/imagemap/*.[ch] * plug-ins/maze/maze_face.c * plug-ins/mosaic/mosaic.c * plug-ins/pagecurl/pagecurl.c * plug-ins/print/print_gimp.h * plug-ins/rcm/rcm_callback.c * plug-ins/rcm/rcm_dialog.c * plug-ins/rcm/rcm_misc.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * plug-ins/script-fu/script-fu-server.c * plug-ins/sel2path/sel2path.c * plug-ins/sel2path/sel2path_adv_dialog.c * plug-ins/sgi/sgi.c * plug-ins/webbrowser/webbrowser.c * plug-ins/xjt/xjt.c * plug-ins/common/[A-n]*.c: compile with GTK_DISABLE_DEPRECATED defined. Not everything is fully ported yet, had to #undef GTK_DISABLE_DEPRECATED in many places and added #warnings when doing so. * pixmaps/Makefile.am * pixmaps/chain.xpm: removed. * themes/Default/Makefile.am * themes/Default/images/Makefile.am * themes/Default/images/stock-button-hchain-broken.png * themes/Default/images/stock-button-hchain.png * themes/Default/images/stock-button-vchain-broken.png * themes/Default/images/stock-button-vchain.png: new stock icons.
2001-12-29 21:26:29 +08:00
g_signal_connect (G_OBJECT (dialog), "destroy",
G_CALLBACK (export_cancel_callback),
NULL);
vbox = gtk_vbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_widget_show (vbox);
text = g_strdup_printf (_("You are about to save %s as %s.\n"
"This will not save the visible layers."),
saving_what, format_name);
label = gtk_label_new (text);
g_free (text);
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_show (dialog);
gtk_main ();
return dialog_return;
}
static gint
export_dialog (GSList *actions,
const gchar *format_name)
{
2000-01-11 23:48:00 +08:00
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *label;
GSList *list;
gchar *text;
ExportAction *action;
dialog_return = GIMP_EXPORT_CANCEL;
g_return_val_if_fail (actions != NULL && format_name != NULL, dialog_return);
/*
* Plug-ins must have called gtk_init () before calling gimp_export ().
* Otherwise bad things will happen now!!
*/
/* the dialog */
2000-01-11 23:48:00 +08:00
dialog = gimp_dialog_new (_("Export File"), "export_file",
gimp_standard_help_func, "dialogs/export_file.html",
GTK_WIN_POS_MOUSE,
FALSE, FALSE, FALSE,
_("Export"), export_export_callback,
NULL, NULL, NULL, TRUE, FALSE,
_("Ignore"), export_skip_callback,
NULL, NULL, NULL, FALSE, FALSE,
2001-08-04 03:52:08 +08:00
GTK_STOCK_CANCEL, gtk_widget_destroy,
2000-01-11 23:48:00 +08:00
NULL, 1, NULL, FALSE, TRUE,
NULL);
g_signal_connect (G_OBJECT (dialog), "destroy",
G_CALLBACK (export_cancel_callback),
NULL);
/* the headline */
vbox = gtk_vbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_widget_show (vbox);
2000-01-11 23:48:00 +08:00
label = gtk_label_new (_("Your image should be exported before it "
"can be saved for the following reasons:"));
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
for (list = actions; list; list = list->next)
{
2000-01-11 23:48:00 +08:00
action = (ExportAction *) (list->data);
text = g_strdup_printf ("%s %s", format_name, gettext (action->reason));
frame = gtk_frame_new (text);
g_free (text);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2000-01-11 23:48:00 +08:00
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (frame), hbox);
2000-01-11 23:48:00 +08:00
gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
if (action->possibilities[0] && action->possibilities[1])
{
GSList *radio_group = NULL;
button = gtk_radio_button_new_with_label (radio_group,
gettext (action->possibilities[0]));
gtk_label_set_justify (GTK_LABEL (GTK_BIN (button)->child),
GTK_JUSTIFY_LEFT);
radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
g_signal_connect (G_OBJECT (button), "toggled",
G_CALLBACK (export_toggle_callback),
&action->choice);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_widget_show (button);
button = gtk_radio_button_new_with_label (radio_group,
gettext (action->possibilities[1]));
gtk_label_set_justify (GTK_LABEL (GTK_BIN (button)->child),
GTK_JUSTIFY_LEFT);
radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
}
else if (action->possibilities[0])
{
label = gtk_label_new (gettext (action->possibilities[0]));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
gtk_widget_show (label);
action->choice = 0;
}
else if (action->possibilities[1])
{
label = gtk_label_new (gettext (action->possibilities[1]));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
gtk_widget_show (label);
action->choice = 1;
}
gtk_widget_show (hbox);
gtk_widget_show (frame);
}
/* the footline */
2000-02-09 01:04:19 +08:00
label = gtk_label_new (_("The export conversion won't modify your original image."));
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_show (dialog);
gtk_main ();
2000-01-11 23:48:00 +08:00
return dialog_return;
}
2000-02-05 02:55:32 +08:00
/**
* 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).
2000-02-05 02:55:32 +08:00
* @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
2000-02-05 02:55:32 +08:00
* 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.
2000-02-05 02:55:32 +08:00
*
* If the user chooses to Ignore the export problem, the image_ID
* and drawable_ID is not altered, GIMP_EXPORT_IGNORE is returned and
2000-02-05 02:55:32 +08:00
* the save_plugin should try to save the original image. If the
* user chooses Cancel, GIMP_EXPORT_CANCEL is returned and the
2000-02-05 02:55:32 +08:00
* save_plugin should quit itself with status #STATUS_CANCEL.
*
2000-02-05 03:15:53 +08:00
* Returns: An enum of #GimpExportReturnType describing the user_action.
**/
1999-10-04 07:48:33 +08:00
GimpExportReturnType
gimp_export_image (gint32 *image_ID,
gint32 *drawable_ID,
const gchar *format_name,
GimpExportCapabilities capabilities)
{
GSList *actions = NULL;
GSList *list;
GimpImageBaseType type;
2000-02-09 01:04:19 +08:00
gint32 i;
gint32 nlayers;
gint32* layers;
gint offset_x;
gint offset_y;
gboolean added_flatten = FALSE;
gboolean background_has_alpha = TRUE;
ExportAction *action;
2000-02-05 02:55:32 +08:00
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;
/* ask for confirmation if the user is not saving a layer (see bug #51114) */
if (!gimp_drawable_is_layer (*drawable_ID)
&& !(capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS))
{
if (gimp_drawable_is_layer_mask (*drawable_ID))
dialog_return = confirm_save_dialog (_("a layer mask"), format_name);
else if (gimp_drawable_is_channel (*drawable_ID))
dialog_return = confirm_save_dialog (_("a channel (saved selection)"),
format_name);
else
; /* this should not happen */
/* cancel - the user can then select an appropriate layer to save */
if (dialog_return == GIMP_EXPORT_CANCEL)
return GIMP_EXPORT_CANCEL;
}
/* check alpha */
2000-02-05 02:55:32 +08:00
layers = gimp_image_get_layers (*image_ID, &nlayers);
for (i = 0; i < nlayers; 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 == nlayers - 1 && gimp_layer_get_visible (layers[i]))
background_has_alpha = FALSE;
if (capabilities & GIMP_EXPORT_NEEDS_ALPHA)
{
actions = g_slist_prepend (actions, &export_action_add_alpha);
break;
}
}
}
g_free (layers);
/* check if layer size != canvas size, opacity != 100%, or offsets != 0 */
if (!added_flatten && nlayers == 1 && gimp_drawable_is_layer (*drawable_ID)
&& !(capabilities & GIMP_EXPORT_CAN_HANDLE_LAYERS))
{
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);
added_flatten = TRUE;
}
}
}
/* check multiple layers */
else if (!added_flatten && nlayers > 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 (background_has_alpha || capabilities & GIMP_EXPORT_NEEDS_ALPHA)
actions = g_slist_prepend (actions, &export_action_merge);
else
actions = g_slist_prepend (actions, &export_action_merge_flat);
}
}
/* check the image type */
2000-02-05 02:55:32 +08:00
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);
}
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);
}
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);
}
break;
}
if (actions)
{
actions = g_slist_reverse (actions);
2000-02-05 02:55:32 +08:00
dialog_return = export_dialog (actions, format_name);
}
else
dialog_return = GIMP_EXPORT_IGNORE;
if (dialog_return == GIMP_EXPORT_EXPORT)
{
2000-02-05 02:55:32 +08:00
*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)
{
action = (ExportAction*)(list->data);
if (action->choice == 0 && action->default_action)
2000-02-05 02:55:32 +08:00
action->default_action (*image_ID, drawable_ID);
else if (action->choice == 1 && action->alt_action)
2000-02-05 02:55:32 +08:00
action->alt_action (*image_ID, drawable_ID);
}
}
g_slist_free (actions);
2000-01-11 23:48:00 +08:00
return dialog_return;
}