app/Makefile.am removed. new files: the convert functionality without GUI

2001-04-18  Michael Natterer  <mitch@gimp.org>

	* app/Makefile.am
	* app/convert.[ch]: removed.
	* app/gimpimage-convert.[ch]: new files: the convert functionality
	without GUI (now called gimp_image_convert()).

	* app/gui/Makefile.am
	* app/gui/convert-dialog.[ch]: new files.

	* app/gui/commands.c
	* app/pdb/convert_cmds.c
	* po/POTFILES.in
	* tools/pdbgen/pdb/convert.pdb
	* tools/pdbgen/Makefile.am
	* tools/pdbgen/enums.pl: changed accordingly.
This commit is contained in:
Michael Natterer 2001-04-18 17:57:10 +00:00 committed by Michael Natterer
parent 9147176686
commit addaad45ea
21 changed files with 1495 additions and 5578 deletions

View File

@ -1,3 +1,20 @@
2001-04-18 Michael Natterer <mitch@gimp.org>
* app/Makefile.am
* app/convert.[ch]: removed.
* app/gimpimage-convert.[ch]: new files: the convert functionality
without GUI (now called gimp_image_convert()).
* app/gui/Makefile.am
* app/gui/convert-dialog.[ch]: new files.
* app/gui/commands.c
* app/pdb/convert_cmds.c
* po/POTFILES.in
* tools/pdbgen/pdb/convert.pdb
* tools/pdbgen/Makefile.am
* tools/pdbgen/enums.pl: changed accordingly.
2001-04-18 Michael Natterer <mitch@gimp.org>
* app/devices.[ch]

View File

@ -83,8 +83,6 @@ gimp_SOURCES = \
##
channel_ops.c \
channel_ops.h \
convert.c \
convert.h \
gdisplay.c \
gdisplay.h \
gdisplay_ops.c \
@ -174,6 +172,8 @@ gimp_SOURCES = \
gimphistogram.h \
gimpimage.c \
gimpimage.h \
gimpimage-convert.c \
gimpimage-convert.h \
gimpimage-undo.c \
gimpimage-undo.h \
gimplayer.c \

View File

@ -33,6 +33,7 @@
#include "tools/gimptoolinfo.h"
#include "tools/tool_manager.h"
#include "convert-dialog.h"
#include "errorconsole.h"
#include "info-dialog.h"
#include "info-window.h"
@ -41,7 +42,6 @@
#include "app_procs.h"
#include "commands.h"
#include "context_manager.h"
#include "convert.h"
#include "desaturate.h"
#include "channel_ops.h"
#include "equalize.h"
@ -212,7 +212,7 @@ edit_paste_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
global_edit_paste (gdisp, 0);
global_edit_paste (gdisp, FALSE);
}
void
@ -222,7 +222,7 @@ edit_paste_into_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
global_edit_paste (gdisp, 1);
global_edit_paste (gdisp, TRUE);
}
void
@ -589,18 +589,18 @@ view_info_window_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!info_window_follows_mouse)
if (! info_window_follows_mouse)
{
if (! gdisp->window_info_dialog)
gdisp->window_info_dialog = info_window_create ((void *) gdisp);
info_window_update(gdisp);
info_window_update (gdisp);
info_dialog_popup (gdisp->window_info_dialog);
}
else
{
info_window_follow_auto();
info_window_follow_auto ();
}
}
void
@ -649,7 +649,7 @@ view_toggle_rulers_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
if (! GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->origin))
{
@ -662,7 +662,7 @@ view_toggle_rulers_cmd_callback (GtkWidget *widget,
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->origin))
if (! GTK_WIDGET_VISIBLE (gdisp->origin))
{
gtk_widget_show (gdisp->origin);
gtk_widget_show (gdisp->hrule);
@ -680,14 +680,14 @@ view_toggle_statusbar_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
if (! GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_hide (gdisp->statusarea);
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->statusarea))
if (! GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_show (gdisp->statusarea);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CONVERT_H__
#define __CONVERT_H__
/* adam's extra palette stuff */
typedef enum
{
MAKE_PALETTE = 0,
REUSE_PALETTE = 1,
WEB_PALETTE = 2,
MONO_PALETTE = 3,
CUSTOM_PALETTE = 4
} ConvertPaletteType;
/* adam's extra dither stuff */
typedef enum
{
NO_DITHER = 0,
FS_DITHER = 1,
FSLOWBLEED_DITHER = 2,
FIXED_DITHER = 3,
NODESTRUCT_DITHER = 4 /* NEVER USE NODESTRUCT_DITHER EXPLICITLY */
} ConvertDitherType;
#define MAXNUMCOLORS 256
/* convert functions */
void convert_to_rgb (GimpImage *gimage);
void convert_to_grayscale (GimpImage *gimage);
void convert_to_indexed (GimpImage *gimage);
void convert_image (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type);
extern GimpPalette *theCustomPalette;
#endif /* __CONVERT_H__ */

View File

@ -101,29 +101,17 @@
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "apptypes.h"
#include "tools/brightness_contrast.h"
#include "tools/color_balance.h"
#include "tools/curves.h"
#include "tools/hue_saturation.h"
#include "tools/levels.h"
#include "tools/posterize.h"
#include "tools/threshold.h"
#include "cursorutil.h"
#include "gdisplay.h"
#include "gui/palette-select.h"
#include "context_manager.h"
#include "convert.h"
#include "floating_sel.h"
#include "fsdither.h"
#include "gimpdatafactory.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-convert.h"
#include "gimplist.h"
#include "gimplayer.h"
#include "gimppalette.h"
@ -131,8 +119,6 @@
#include "tile_manager.h"
#include "undo.h"
#include "libgimp/gimpintl.h"
/* bleh! */
static const unsigned char webpal[] =
@ -479,35 +465,9 @@ typedef struct
long dither;
} Options;
typedef struct
{
GtkWidget* shell;
GtkWidget* custom_palette_button;
GimpImage* gimage;
PaletteSelect* palette_select;
int nodither_flag;
int fsdither_flag;
int fslowbleeddither_flag;
int fixeddither_flag;
int alphadither; /* flag */
int remdups; /* flag */
int num_cols;
int palette;
int makepal_flag;
int webpal_flag;
int custompal_flag;
int monopal_flag;
int reusepal_flag;
} IndexedDialog;
static void indexed_ok_callback (GtkWidget *, gpointer);
static void indexed_cancel_callback (GtkWidget *, gpointer);
static void indexed_custom_palette_button_callback (GtkWidget *widget, gpointer data);
static void indexed_palette_select_destroy_callback (GtkWidget *widget, gpointer data);
static void rgb_converter (GimpLayer *, TileManager *, int);
static void grayscale_converter (GimpLayer *, TileManager *, int);
static void rgb_converter (GimpLayer *, TileManager *, int);
static void grayscale_converter (GimpLayer *, TileManager *, int);
static void zero_histogram_gray (CFHistogram);
static void zero_histogram_rgb (CFHistogram);
@ -523,567 +483,11 @@ compute_color_rgb (QuantizeObj *quantobj,
boxptr boxp,
int icolor);
static unsigned char found_cols[MAXNUMCOLORS][3];
static int num_found_cols;
static gboolean needs_quantize;
static GtkWidget *build_palette_button (void);
static gboolean UserHasWebPal = FALSE;
GimpPalette *theCustomPalette = NULL;
/* Defaults */
static int snum_cols = 256;
static gboolean sfsdither_flag = TRUE;
static gboolean sfslowbleeddither_flag = TRUE;
static gboolean snodither_flag = FALSE;
static gboolean sfixeddither_flag = FALSE;
static gboolean smakepal_flag = TRUE;
static gboolean salphadither_flag = FALSE;
static gboolean sremdups_flag = TRUE;
static gboolean swebpal_flag = FALSE;
static gboolean scustompal_flag = FALSE;
static gboolean smonopal_flag = FALSE;
static gboolean sreusepal_flag = FALSE;
void
convert_to_rgb (GimpImage *gimage)
{
convert_image (gimage, RGB, 0, 0, 0, 0, 0);
gdisplays_flush ();
}
void
convert_to_grayscale (GimpImage* gimage)
{
convert_image (gimage, GRAY, 0, 0, 0, 0, 0);
gdisplays_flush ();
}
void
convert_to_indexed (GimpImage *gimage)
{
IndexedDialog *dialog;
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkObject *adjustment;
GtkWidget *spinbutton;
GtkWidget *frame;
GtkWidget *custom_frame = NULL;
GtkWidget *toggle;
GSList *group = NULL;
dialog = g_new (IndexedDialog, 1);
dialog->gimage = gimage;
dialog->custom_palette_button = NULL;
dialog->palette_select = NULL;
dialog->num_cols = snum_cols;
dialog->nodither_flag = snodither_flag;
dialog->fsdither_flag = sfsdither_flag;
dialog->fslowbleeddither_flag = sfslowbleeddither_flag;
dialog->fixeddither_flag = sfixeddither_flag;
dialog->alphadither = salphadither_flag;
dialog->remdups = sremdups_flag;
dialog->makepal_flag = smakepal_flag;
dialog->webpal_flag = swebpal_flag;
dialog->custompal_flag = scustompal_flag;
dialog->monopal_flag = smonopal_flag;
dialog->reusepal_flag = sreusepal_flag;
dialog->shell =
gimp_dialog_new (_("Indexed Color Conversion"), "indexed_color_conversion",
gimp_standard_help_func,
"dialogs/convert_to_indexed.html",
GTK_WIN_POS_NONE,
FALSE, FALSE, TRUE,
_("OK"), indexed_ok_callback,
dialog, NULL, NULL, TRUE, FALSE,
_("Cancel"), indexed_cancel_callback,
dialog, NULL, NULL, FALSE, TRUE,
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog->shell)->vbox),
main_vbox);
gtk_widget_show (main_vbox);
frame = gtk_frame_new (_("General Palette Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* 'generate palette' */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (NULL, _("Generate Optimal Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->makepal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->makepal_flag);
gtk_widget_show (toggle);
if (dialog->num_cols == 256)
{
if ((! gimp_image_is_empty (gimage)) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
dialog->num_cols = 255;
}
}
spinbutton = gimp_spin_button_new (&adjustment, dialog->num_cols,
2, 256, 1, 5, 0, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&(dialog->num_cols));
gtk_box_pack_end (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
label = gtk_label_new (_("# of Colors:"));
gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_set_sensitive (GTK_WIDGET (spinbutton), dialog->num_cols);
gtk_widget_set_sensitive (GTK_WIDGET (label), dialog->num_cols);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", spinbutton);
gtk_object_set_data (GTK_OBJECT (spinbutton), "set_sensitive", label);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
dialog->custom_palette_button = build_palette_button ();
if (dialog->custom_palette_button)
{
/* create the custom_frame here, it'll be added later */
custom_frame = gtk_frame_new (_("Custom Palette Options"));
gtk_container_set_border_width (GTK_CONTAINER (custom_frame), 2);
/* The remove-duplicates toggle */
hbox = gtk_hbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (custom_frame), hbox);
toggle = gtk_check_button_new_with_label (_("Remove Unused Colors from Final Palette"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), dialog->remdups);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->remdups));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Use Custom Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->custompal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_widget_show (toggle);
gtk_signal_connect (GTK_OBJECT (dialog->custom_palette_button), "clicked",
GTK_SIGNAL_FUNC (indexed_custom_palette_button_callback),
dialog);
gtk_box_pack_end (GTK_BOX (hbox), dialog->custom_palette_button, TRUE, TRUE, 0);
gtk_widget_show (dialog->custom_palette_button);
gtk_widget_show (hbox);
gtk_widget_set_sensitive (GTK_WIDGET (custom_frame), dialog->custompal_flag);
gtk_widget_set_sensitive (GTK_WIDGET (dialog->custom_palette_button), dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_object_set_data (GTK_OBJECT (custom_frame), "set_sensitive", dialog->custom_palette_button);
}
if (!UserHasWebPal)
{
/* 'web palette'
* Only presented as an option to the user if they do not
* already have the 'Web' GIMP palette installed on their
* system.
*/
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use WWW-Optimized Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->webpal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->webpal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
}
/* 'mono palette' */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use Black/White (1-Bit) Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->monopal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->monopal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
frame = gtk_frame_new (_("Dither Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show(vbox);
/* The dither radio buttons */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (NULL, _("No Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->nodither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->nodither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Positioned Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fixeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fixeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Reduced Color Bleeding)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fslowbleeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fslowbleeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Normal)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fsdither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fsdither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* The alpha-dither toggle */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_check_button_new_with_label (_("Enable Dithering of Transparency"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->alphadither);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->alphadither));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* now add the custom_frame */
if (custom_frame)
{
gtk_box_pack_start (GTK_BOX (main_vbox), custom_frame, FALSE, FALSE, 0);
gtk_widget_show (custom_frame);
}
/* if the image isn't non-alpha/layered, set the default number of
colours to one less than max, to leave room for a transparent index
for transparent/animated GIFs */
if (! gimp_image_is_empty (gimage) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
frame = gtk_frame_new (_("[ Warning ]"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
label = gtk_label_new
(_("You are attempting to convert an image with alpha/layers "
"from RGB/GRAY to INDEXED.\nYou should not generate a "
"palette of more than 255 colors if you intend to create "
"a transparent or animated GIF file from this image."));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (vbox), label);
gtk_widget_show (label);
}
gtk_widget_show (dialog->shell);
}
static GtkWidget *
build_palette_button (void)
{
GList *list;
GimpPalette *palette;
GimpPalette *theWebPalette = NULL;
gint i;
gint default_palette;
UserHasWebPal = FALSE;
list = GIMP_LIST (global_palette_factory->container)->list;
if (! list)
{
return NULL;
}
for (i = 0, default_palette = -1;
list;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
/* Preferentially, the initial default is 'Web' if available */
if (theWebPalette == NULL &&
g_strcasecmp (GIMP_OBJECT (palette)->name, "Web") == 0)
{
theWebPalette = palette;
UserHasWebPal = TRUE;
}
/* We can't dither to > 256 colors */
if (palette->n_colors <= 256)
{
if (theCustomPalette == palette)
{
default_palette = i;
}
}
}
/* default to first one with <= 256 colors
(only used if 'web' palette not available) */
if (default_palette == -1)
{
if (theWebPalette)
{
theCustomPalette = theWebPalette;
default_palette = 1; /* dummy value */
}
else
{
for (i = 0, list = GIMP_LIST (global_palette_factory->container)->list;
list && default_palette == -1;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
default_palette = i;
}
}
}
}
if (default_palette == -1)
return NULL;
else
return gtk_button_new_with_label (GIMP_OBJECT (theCustomPalette)->name);
}
static void
indexed_ok_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
ConvertPaletteType palette_type;
ConvertDitherType dither_type;
dialog = (IndexedDialog *) data;
if (dialog->webpal_flag) palette_type = WEB_PALETTE;
else
if (dialog->custompal_flag) palette_type = CUSTOM_PALETTE;
else
if (dialog->monopal_flag) palette_type = MONO_PALETTE;
else
if (dialog->makepal_flag) palette_type = MAKE_PALETTE;
else
palette_type = REUSE_PALETTE;
if (dialog->nodither_flag) dither_type = NO_DITHER;
else
if (dialog->fsdither_flag) dither_type = FS_DITHER;
else
if (dialog->fslowbleeddither_flag) dither_type = FSLOWBLEED_DITHER;
else
dither_type = FIXED_DITHER;
/* Close the dialogs when open because they're useless for indexed images
and could crash the GIMP when used nevertheless */
color_balance_dialog_hide();
hue_saturation_dialog_hide ();
brightness_contrast_dialog_hide();
threshold_dialog_hide ();
levels_dialog_hide ();
curves_dialog_hide ();
posterize_dialog_hide ();
/* Convert the image to indexed color */
convert_image (dialog->gimage, INDEXED, dialog->num_cols,
dither_type, dialog->alphadither,
dialog->remdups, palette_type);
gdisplays_flush ();
/* Save defaults for next time */
snum_cols = dialog->num_cols;
snodither_flag = dialog->nodither_flag;
sfsdither_flag = dialog->fsdither_flag;
sfslowbleeddither_flag = dialog->fslowbleeddither_flag;
sfixeddither_flag = dialog->fixeddither_flag;
salphadither_flag = dialog->alphadither;
sremdups_flag = dialog->remdups;
smakepal_flag = dialog->makepal_flag;
swebpal_flag = dialog->webpal_flag;
scustompal_flag = dialog->custompal_flag;
smonopal_flag = dialog->monopal_flag;
sreusepal_flag = dialog->reusepal_flag;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
dialog = NULL;
}
static void
indexed_cancel_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
dialog = NULL;
}
static void
indexed_palette_select_destroy_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog)
dialog->palette_select = NULL;
}
static gint
indexed_palette_select_palette (GimpContext *context,
GimpPalette *palette,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (palette)
{
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
gtk_label_set_text (GTK_LABEL (GTK_BIN (dialog->custom_palette_button)->child),
GIMP_OBJECT (theCustomPalette)->name);
}
}
return FALSE;
}
static void
indexed_custom_palette_button_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog->palette_select == NULL)
{
dialog->palette_select =
palette_select_new (_("Select Custom Palette"),
GIMP_OBJECT (theCustomPalette)->name);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->shell), "destroy",
GTK_SIGNAL_FUNC (indexed_palette_select_destroy_callback),
dialog);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->context),
"palette_changed",
GTK_SIGNAL_FUNC (indexed_palette_select_palette),
dialog);
}
else
{
gdk_window_raise (dialog->palette_select->shell->window);
}
}
static guchar found_cols[MAXNUMCOLORS][3];
static gint num_found_cols;
static gboolean needs_quantize;
static GimpPalette *theCustomPalette = NULL;
/**********************************************************/
@ -1257,16 +661,17 @@ remap_indexed_layer (GimpLayer *layer,
}
void
convert_image (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type)
gimp_image_convert (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type,
GimpPalette *custom_palette)
{
QuantizeObj *quantobj;
GimpLayer *layer;
@ -1278,11 +683,16 @@ convert_image (GimpImage *gimage,
gboolean has_alpha;
TileManager *new_tiles;
g_return_if_fail (gimage != NULL);
g_return_if_fail (GIMP_IS_IMAGE (gimage));
quantobj = NULL;
new_layer_type = RGBA_GIMAGE;
new_layer_bytes = 4;
gimp_add_busy_cursors();
theCustomPalette = custom_palette;
gimp_add_busy_cursors ();
/* Get the floating layer if one exists */
floating_layer = gimp_image_floating_sel (gimage);

View File

@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CONVERT_H__
#define __CONVERT_H__
#ifndef __GIMP_IMAGE_CONVERT_H__
#define __GIMP_IMAGE_CONVERT_H__
/* adam's extra palette stuff */
@ -44,24 +44,17 @@ typedef enum
#define MAXNUMCOLORS 256
/* convert functions */
void convert_to_rgb (GimpImage *gimage);
void convert_to_grayscale (GimpImage *gimage);
void convert_to_indexed (GimpImage *gimage);
void convert_image (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type);
void gimp_image_convert (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type,
GimpPalette *custom_palette);
extern GimpPalette *theCustomPalette;
#endif /* __CONVERT_H__ */
#endif /* __GIMP_IMAGE_CONVERT_H__ */

View File

@ -0,0 +1,636 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; 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 "libgimpwidgets/gimpwidgets.h"
#include "apptypes.h"
#include "tools/gimptool.h"
#include "tools/tool_manager.h"
#include "gdisplay.h"
#include "palette-select.h"
#include "context_manager.h"
#include "floating_sel.h"
#include "gimpdatafactory.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-convert.h"
#include "gimplist.h"
#include "gimplayer.h"
#include "gimppalette.h"
#include "libgimp/gimpintl.h"
typedef struct
{
GtkWidget *shell;
GtkWidget *custom_palette_button;
GimpImage *gimage;
PaletteSelect *palette_select;
gint nodither_flag;
gint fsdither_flag;
gint fslowbleeddither_flag;
gint fixeddither_flag;
gint alphadither; /* flag */
gint remdups; /* flag */
gint num_cols;
gint palette;
gint makepal_flag;
gint webpal_flag;
gint custompal_flag;
gint monopal_flag;
gint reusepal_flag;
} IndexedDialog;
static void indexed_ok_callback (GtkWidget *widget,
gpointer data);
static void indexed_cancel_callback (GtkWidget *widget,
gpointer data);
static void indexed_custom_palette_button_callback (GtkWidget *widget,
gpointer data);
static void indexed_palette_select_destroy_callback (GtkWidget *widget,
gpointer data);
static GtkWidget * build_palette_button (void);
static gboolean UserHasWebPal = FALSE;
static GimpPalette *theCustomPalette = NULL;
/* Defaults */
static gint snum_cols = 256;
static gboolean sfsdither_flag = TRUE;
static gboolean sfslowbleeddither_flag = TRUE;
static gboolean snodither_flag = FALSE;
static gboolean sfixeddither_flag = FALSE;
static gboolean smakepal_flag = TRUE;
static gboolean salphadither_flag = FALSE;
static gboolean sremdups_flag = TRUE;
static gboolean swebpal_flag = FALSE;
static gboolean scustompal_flag = FALSE;
static gboolean smonopal_flag = FALSE;
static gboolean sreusepal_flag = FALSE;
void
convert_to_rgb (GimpImage *gimage)
{
gimp_image_convert (gimage, RGB, 0, 0, 0, 0, 0, NULL);
gdisplays_flush ();
}
void
convert_to_grayscale (GimpImage* gimage)
{
gimp_image_convert (gimage, GRAY, 0, 0, 0, 0, 0, NULL);
gdisplays_flush ();
}
void
convert_to_indexed (GimpImage *gimage)
{
IndexedDialog *dialog;
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkObject *adjustment;
GtkWidget *spinbutton;
GtkWidget *frame;
GtkWidget *custom_frame = NULL;
GtkWidget *toggle;
GSList *group = NULL;
dialog = g_new0 (IndexedDialog, 1);
dialog->gimage = gimage;
dialog->custom_palette_button = NULL;
dialog->palette_select = NULL;
dialog->num_cols = snum_cols;
dialog->nodither_flag = snodither_flag;
dialog->fsdither_flag = sfsdither_flag;
dialog->fslowbleeddither_flag = sfslowbleeddither_flag;
dialog->fixeddither_flag = sfixeddither_flag;
dialog->alphadither = salphadither_flag;
dialog->remdups = sremdups_flag;
dialog->makepal_flag = smakepal_flag;
dialog->webpal_flag = swebpal_flag;
dialog->custompal_flag = scustompal_flag;
dialog->monopal_flag = smonopal_flag;
dialog->reusepal_flag = sreusepal_flag;
dialog->shell =
gimp_dialog_new (_("Indexed Color Conversion"), "indexed_color_conversion",
gimp_standard_help_func,
"dialogs/convert_to_indexed.html",
GTK_WIN_POS_NONE,
FALSE, FALSE, TRUE,
_("OK"), indexed_ok_callback,
dialog, NULL, NULL, TRUE, FALSE,
_("Cancel"), indexed_cancel_callback,
dialog, NULL, NULL, FALSE, TRUE,
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog->shell)->vbox),
main_vbox);
gtk_widget_show (main_vbox);
frame = gtk_frame_new (_("General Palette Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* 'generate palette' */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (NULL, _("Generate Optimal Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->makepal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->makepal_flag);
gtk_widget_show (toggle);
if (dialog->num_cols == 256)
{
if ((! gimp_image_is_empty (gimage)) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
dialog->num_cols = 255;
}
}
spinbutton = gimp_spin_button_new (&adjustment, dialog->num_cols,
2, 256, 1, 5, 0, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&(dialog->num_cols));
gtk_box_pack_end (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
label = gtk_label_new (_("# of Colors:"));
gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_set_sensitive (GTK_WIDGET (spinbutton), dialog->num_cols);
gtk_widget_set_sensitive (GTK_WIDGET (label), dialog->num_cols);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", spinbutton);
gtk_object_set_data (GTK_OBJECT (spinbutton), "set_sensitive", label);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
dialog->custom_palette_button = build_palette_button ();
if (dialog->custom_palette_button)
{
/* create the custom_frame here, it'll be added later */
custom_frame = gtk_frame_new (_("Custom Palette Options"));
gtk_container_set_border_width (GTK_CONTAINER (custom_frame), 2);
/* The remove-duplicates toggle */
hbox = gtk_hbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (custom_frame), hbox);
toggle = gtk_check_button_new_with_label (_("Remove Unused Colors from Final Palette"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), dialog->remdups);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->remdups));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Use Custom Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->custompal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_widget_show (toggle);
gtk_signal_connect (GTK_OBJECT (dialog->custom_palette_button), "clicked",
GTK_SIGNAL_FUNC (indexed_custom_palette_button_callback),
dialog);
gtk_box_pack_end (GTK_BOX (hbox), dialog->custom_palette_button, TRUE, TRUE, 0);
gtk_widget_show (dialog->custom_palette_button);
gtk_widget_show (hbox);
gtk_widget_set_sensitive (GTK_WIDGET (custom_frame),
dialog->custompal_flag);
gtk_widget_set_sensitive (GTK_WIDGET (dialog->custom_palette_button),
dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_object_set_data (GTK_OBJECT (custom_frame), "set_sensitive",
dialog->custom_palette_button);
}
if (! UserHasWebPal)
{
/* 'web palette'
* Only presented as an option to the user if they do not
* already have the 'Web' GIMP palette installed on their
* system.
*/
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use WWW-Optimized Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->webpal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->webpal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
}
/* 'mono palette' */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use Black/White (1-Bit) Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->monopal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->monopal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
frame = gtk_frame_new (_("Dither Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show(vbox);
/* The dither radio buttons */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (NULL, _("No Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->nodither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->nodither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Positioned Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fixeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fixeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Reduced Color Bleeding)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fslowbleeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fslowbleeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Normal)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fsdither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fsdither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* The alpha-dither toggle */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_check_button_new_with_label (_("Enable Dithering of Transparency"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->alphadither);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->alphadither));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* now add the custom_frame */
if (custom_frame)
{
gtk_box_pack_start (GTK_BOX (main_vbox), custom_frame, FALSE, FALSE, 0);
gtk_widget_show (custom_frame);
}
/* if the image isn't non-alpha/layered, set the default number of
colours to one less than max, to leave room for a transparent index
for transparent/animated GIFs */
if (! gimp_image_is_empty (gimage) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
frame = gtk_frame_new (_("[ Warning ]"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
label = gtk_label_new
(_("You are attempting to convert an image with alpha/layers "
"from RGB/GRAY to INDEXED.\nYou should not generate a "
"palette of more than 255 colors if you intend to create "
"a transparent or animated GIF file from this image."));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (vbox), label);
gtk_widget_show (label);
}
gtk_widget_show (dialog->shell);
}
static GtkWidget *
build_palette_button (void)
{
GList *list;
GimpPalette *palette;
GimpPalette *theWebPalette = NULL;
gint i;
gint default_palette;
UserHasWebPal = FALSE;
list = GIMP_LIST (global_palette_factory->container)->list;
if (! list)
{
return NULL;
}
for (i = 0, default_palette = -1;
list;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
/* Preferentially, the initial default is 'Web' if available */
if (theWebPalette == NULL &&
g_strcasecmp (GIMP_OBJECT (palette)->name, "Web") == 0)
{
theWebPalette = palette;
UserHasWebPal = TRUE;
}
/* We can't dither to > 256 colors */
if (palette->n_colors <= 256)
{
if (theCustomPalette == palette)
{
default_palette = i;
}
}
}
/* default to first one with <= 256 colors
* (only used if 'web' palette not available)
*/
if (default_palette == -1)
{
if (theWebPalette)
{
theCustomPalette = theWebPalette;
default_palette = 1; /* dummy value */
}
else
{
for (i = 0, list = GIMP_LIST (global_palette_factory->container)->list;
list && default_palette == -1;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
default_palette = i;
}
}
}
}
if (default_palette == -1)
return NULL;
else
return gtk_button_new_with_label (GIMP_OBJECT (theCustomPalette)->name);
}
static void
indexed_ok_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
ConvertPaletteType palette_type;
ConvertDitherType dither_type;
dialog = (IndexedDialog *) data;
if (dialog->webpal_flag)
palette_type = WEB_PALETTE;
else if (dialog->custompal_flag)
palette_type = CUSTOM_PALETTE;
else if (dialog->monopal_flag)
palette_type = MONO_PALETTE;
else if (dialog->makepal_flag)
palette_type = MAKE_PALETTE;
else
palette_type = REUSE_PALETTE;
if (dialog->nodither_flag)
dither_type = NO_DITHER;
else if (dialog->fsdither_flag)
dither_type = FS_DITHER;
else if (dialog->fslowbleeddither_flag)
dither_type = FSLOWBLEED_DITHER;
else
dither_type = FIXED_DITHER;
/* Close the dialogs when open because they're useless for indexed
* images and could crash the GIMP when used nevertheless
*/
if (active_tool)
tool_manager_control_active (HALT, active_tool->gdisp);
/* Convert the image to indexed color */
gimp_image_convert (dialog->gimage, INDEXED, dialog->num_cols,
dither_type, dialog->alphadither,
dialog->remdups, palette_type, theCustomPalette);
gdisplays_flush ();
/* Save defaults for next time */
snum_cols = dialog->num_cols;
snodither_flag = dialog->nodither_flag;
sfsdither_flag = dialog->fsdither_flag;
sfslowbleeddither_flag = dialog->fslowbleeddither_flag;
sfixeddither_flag = dialog->fixeddither_flag;
salphadither_flag = dialog->alphadither;
sremdups_flag = dialog->remdups;
smakepal_flag = dialog->makepal_flag;
swebpal_flag = dialog->webpal_flag;
scustompal_flag = dialog->custompal_flag;
smonopal_flag = dialog->monopal_flag;
sreusepal_flag = dialog->reusepal_flag;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
}
static void
indexed_cancel_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
}
static void
indexed_palette_select_destroy_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog)
dialog->palette_select = NULL;
}
static gint
indexed_palette_select_palette (GimpContext *context,
GimpPalette *palette,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (palette)
{
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
gtk_label_set_text (GTK_LABEL (GTK_BIN (dialog->custom_palette_button)->child),
GIMP_OBJECT (theCustomPalette)->name);
}
}
return FALSE;
}
static void
indexed_custom_palette_button_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog->palette_select == NULL)
{
dialog->palette_select =
palette_select_new (_("Select Custom Palette"),
GIMP_OBJECT (theCustomPalette)->name);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->shell), "destroy",
GTK_SIGNAL_FUNC (indexed_palette_select_destroy_callback),
dialog);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->context),
"palette_changed",
GTK_SIGNAL_FUNC (indexed_palette_select_palette),
dialog);
}
else
{
gdk_window_raise (dialog->palette_select->shell->window);
}
}

View File

@ -0,0 +1,28 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CONVERT_DIALOG_H__
#define __CONVERT_DIALOG_H__
void convert_to_rgb (GimpImage *gimage);
void convert_to_grayscale (GimpImage *gimage);
void convert_to_indexed (GimpImage *gimage);
#endif /* __CONVERT_DIALOG_H__ */

View File

@ -101,29 +101,17 @@
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "apptypes.h"
#include "tools/brightness_contrast.h"
#include "tools/color_balance.h"
#include "tools/curves.h"
#include "tools/hue_saturation.h"
#include "tools/levels.h"
#include "tools/posterize.h"
#include "tools/threshold.h"
#include "cursorutil.h"
#include "gdisplay.h"
#include "gui/palette-select.h"
#include "context_manager.h"
#include "convert.h"
#include "floating_sel.h"
#include "fsdither.h"
#include "gimpdatafactory.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-convert.h"
#include "gimplist.h"
#include "gimplayer.h"
#include "gimppalette.h"
@ -131,8 +119,6 @@
#include "tile_manager.h"
#include "undo.h"
#include "libgimp/gimpintl.h"
/* bleh! */
static const unsigned char webpal[] =
@ -479,35 +465,9 @@ typedef struct
long dither;
} Options;
typedef struct
{
GtkWidget* shell;
GtkWidget* custom_palette_button;
GimpImage* gimage;
PaletteSelect* palette_select;
int nodither_flag;
int fsdither_flag;
int fslowbleeddither_flag;
int fixeddither_flag;
int alphadither; /* flag */
int remdups; /* flag */
int num_cols;
int palette;
int makepal_flag;
int webpal_flag;
int custompal_flag;
int monopal_flag;
int reusepal_flag;
} IndexedDialog;
static void indexed_ok_callback (GtkWidget *, gpointer);
static void indexed_cancel_callback (GtkWidget *, gpointer);
static void indexed_custom_palette_button_callback (GtkWidget *widget, gpointer data);
static void indexed_palette_select_destroy_callback (GtkWidget *widget, gpointer data);
static void rgb_converter (GimpLayer *, TileManager *, int);
static void grayscale_converter (GimpLayer *, TileManager *, int);
static void rgb_converter (GimpLayer *, TileManager *, int);
static void grayscale_converter (GimpLayer *, TileManager *, int);
static void zero_histogram_gray (CFHistogram);
static void zero_histogram_rgb (CFHistogram);
@ -523,567 +483,11 @@ compute_color_rgb (QuantizeObj *quantobj,
boxptr boxp,
int icolor);
static unsigned char found_cols[MAXNUMCOLORS][3];
static int num_found_cols;
static gboolean needs_quantize;
static GtkWidget *build_palette_button (void);
static gboolean UserHasWebPal = FALSE;
GimpPalette *theCustomPalette = NULL;
/* Defaults */
static int snum_cols = 256;
static gboolean sfsdither_flag = TRUE;
static gboolean sfslowbleeddither_flag = TRUE;
static gboolean snodither_flag = FALSE;
static gboolean sfixeddither_flag = FALSE;
static gboolean smakepal_flag = TRUE;
static gboolean salphadither_flag = FALSE;
static gboolean sremdups_flag = TRUE;
static gboolean swebpal_flag = FALSE;
static gboolean scustompal_flag = FALSE;
static gboolean smonopal_flag = FALSE;
static gboolean sreusepal_flag = FALSE;
void
convert_to_rgb (GimpImage *gimage)
{
convert_image (gimage, RGB, 0, 0, 0, 0, 0);
gdisplays_flush ();
}
void
convert_to_grayscale (GimpImage* gimage)
{
convert_image (gimage, GRAY, 0, 0, 0, 0, 0);
gdisplays_flush ();
}
void
convert_to_indexed (GimpImage *gimage)
{
IndexedDialog *dialog;
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkObject *adjustment;
GtkWidget *spinbutton;
GtkWidget *frame;
GtkWidget *custom_frame = NULL;
GtkWidget *toggle;
GSList *group = NULL;
dialog = g_new (IndexedDialog, 1);
dialog->gimage = gimage;
dialog->custom_palette_button = NULL;
dialog->palette_select = NULL;
dialog->num_cols = snum_cols;
dialog->nodither_flag = snodither_flag;
dialog->fsdither_flag = sfsdither_flag;
dialog->fslowbleeddither_flag = sfslowbleeddither_flag;
dialog->fixeddither_flag = sfixeddither_flag;
dialog->alphadither = salphadither_flag;
dialog->remdups = sremdups_flag;
dialog->makepal_flag = smakepal_flag;
dialog->webpal_flag = swebpal_flag;
dialog->custompal_flag = scustompal_flag;
dialog->monopal_flag = smonopal_flag;
dialog->reusepal_flag = sreusepal_flag;
dialog->shell =
gimp_dialog_new (_("Indexed Color Conversion"), "indexed_color_conversion",
gimp_standard_help_func,
"dialogs/convert_to_indexed.html",
GTK_WIN_POS_NONE,
FALSE, FALSE, TRUE,
_("OK"), indexed_ok_callback,
dialog, NULL, NULL, TRUE, FALSE,
_("Cancel"), indexed_cancel_callback,
dialog, NULL, NULL, FALSE, TRUE,
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog->shell)->vbox),
main_vbox);
gtk_widget_show (main_vbox);
frame = gtk_frame_new (_("General Palette Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* 'generate palette' */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (NULL, _("Generate Optimal Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->makepal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->makepal_flag);
gtk_widget_show (toggle);
if (dialog->num_cols == 256)
{
if ((! gimp_image_is_empty (gimage)) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
dialog->num_cols = 255;
}
}
spinbutton = gimp_spin_button_new (&adjustment, dialog->num_cols,
2, 256, 1, 5, 0, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&(dialog->num_cols));
gtk_box_pack_end (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
label = gtk_label_new (_("# of Colors:"));
gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_set_sensitive (GTK_WIDGET (spinbutton), dialog->num_cols);
gtk_widget_set_sensitive (GTK_WIDGET (label), dialog->num_cols);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", spinbutton);
gtk_object_set_data (GTK_OBJECT (spinbutton), "set_sensitive", label);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
dialog->custom_palette_button = build_palette_button ();
if (dialog->custom_palette_button)
{
/* create the custom_frame here, it'll be added later */
custom_frame = gtk_frame_new (_("Custom Palette Options"));
gtk_container_set_border_width (GTK_CONTAINER (custom_frame), 2);
/* The remove-duplicates toggle */
hbox = gtk_hbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (custom_frame), hbox);
toggle = gtk_check_button_new_with_label (_("Remove Unused Colors from Final Palette"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), dialog->remdups);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->remdups));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Use Custom Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->custompal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_widget_show (toggle);
gtk_signal_connect (GTK_OBJECT (dialog->custom_palette_button), "clicked",
GTK_SIGNAL_FUNC (indexed_custom_palette_button_callback),
dialog);
gtk_box_pack_end (GTK_BOX (hbox), dialog->custom_palette_button, TRUE, TRUE, 0);
gtk_widget_show (dialog->custom_palette_button);
gtk_widget_show (hbox);
gtk_widget_set_sensitive (GTK_WIDGET (custom_frame), dialog->custompal_flag);
gtk_widget_set_sensitive (GTK_WIDGET (dialog->custom_palette_button), dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_object_set_data (GTK_OBJECT (custom_frame), "set_sensitive", dialog->custom_palette_button);
}
if (!UserHasWebPal)
{
/* 'web palette'
* Only presented as an option to the user if they do not
* already have the 'Web' GIMP palette installed on their
* system.
*/
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use WWW-Optimized Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->webpal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->webpal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
}
/* 'mono palette' */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use Black/White (1-Bit) Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->monopal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->monopal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
frame = gtk_frame_new (_("Dither Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show(vbox);
/* The dither radio buttons */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (NULL, _("No Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->nodither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->nodither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Positioned Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fixeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fixeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Reduced Color Bleeding)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fslowbleeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fslowbleeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Normal)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fsdither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fsdither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* The alpha-dither toggle */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_check_button_new_with_label (_("Enable Dithering of Transparency"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->alphadither);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->alphadither));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* now add the custom_frame */
if (custom_frame)
{
gtk_box_pack_start (GTK_BOX (main_vbox), custom_frame, FALSE, FALSE, 0);
gtk_widget_show (custom_frame);
}
/* if the image isn't non-alpha/layered, set the default number of
colours to one less than max, to leave room for a transparent index
for transparent/animated GIFs */
if (! gimp_image_is_empty (gimage) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
frame = gtk_frame_new (_("[ Warning ]"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
label = gtk_label_new
(_("You are attempting to convert an image with alpha/layers "
"from RGB/GRAY to INDEXED.\nYou should not generate a "
"palette of more than 255 colors if you intend to create "
"a transparent or animated GIF file from this image."));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (vbox), label);
gtk_widget_show (label);
}
gtk_widget_show (dialog->shell);
}
static GtkWidget *
build_palette_button (void)
{
GList *list;
GimpPalette *palette;
GimpPalette *theWebPalette = NULL;
gint i;
gint default_palette;
UserHasWebPal = FALSE;
list = GIMP_LIST (global_palette_factory->container)->list;
if (! list)
{
return NULL;
}
for (i = 0, default_palette = -1;
list;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
/* Preferentially, the initial default is 'Web' if available */
if (theWebPalette == NULL &&
g_strcasecmp (GIMP_OBJECT (palette)->name, "Web") == 0)
{
theWebPalette = palette;
UserHasWebPal = TRUE;
}
/* We can't dither to > 256 colors */
if (palette->n_colors <= 256)
{
if (theCustomPalette == palette)
{
default_palette = i;
}
}
}
/* default to first one with <= 256 colors
(only used if 'web' palette not available) */
if (default_palette == -1)
{
if (theWebPalette)
{
theCustomPalette = theWebPalette;
default_palette = 1; /* dummy value */
}
else
{
for (i = 0, list = GIMP_LIST (global_palette_factory->container)->list;
list && default_palette == -1;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
default_palette = i;
}
}
}
}
if (default_palette == -1)
return NULL;
else
return gtk_button_new_with_label (GIMP_OBJECT (theCustomPalette)->name);
}
static void
indexed_ok_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
ConvertPaletteType palette_type;
ConvertDitherType dither_type;
dialog = (IndexedDialog *) data;
if (dialog->webpal_flag) palette_type = WEB_PALETTE;
else
if (dialog->custompal_flag) palette_type = CUSTOM_PALETTE;
else
if (dialog->monopal_flag) palette_type = MONO_PALETTE;
else
if (dialog->makepal_flag) palette_type = MAKE_PALETTE;
else
palette_type = REUSE_PALETTE;
if (dialog->nodither_flag) dither_type = NO_DITHER;
else
if (dialog->fsdither_flag) dither_type = FS_DITHER;
else
if (dialog->fslowbleeddither_flag) dither_type = FSLOWBLEED_DITHER;
else
dither_type = FIXED_DITHER;
/* Close the dialogs when open because they're useless for indexed images
and could crash the GIMP when used nevertheless */
color_balance_dialog_hide();
hue_saturation_dialog_hide ();
brightness_contrast_dialog_hide();
threshold_dialog_hide ();
levels_dialog_hide ();
curves_dialog_hide ();
posterize_dialog_hide ();
/* Convert the image to indexed color */
convert_image (dialog->gimage, INDEXED, dialog->num_cols,
dither_type, dialog->alphadither,
dialog->remdups, palette_type);
gdisplays_flush ();
/* Save defaults for next time */
snum_cols = dialog->num_cols;
snodither_flag = dialog->nodither_flag;
sfsdither_flag = dialog->fsdither_flag;
sfslowbleeddither_flag = dialog->fslowbleeddither_flag;
sfixeddither_flag = dialog->fixeddither_flag;
salphadither_flag = dialog->alphadither;
sremdups_flag = dialog->remdups;
smakepal_flag = dialog->makepal_flag;
swebpal_flag = dialog->webpal_flag;
scustompal_flag = dialog->custompal_flag;
smonopal_flag = dialog->monopal_flag;
sreusepal_flag = dialog->reusepal_flag;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
dialog = NULL;
}
static void
indexed_cancel_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
dialog = NULL;
}
static void
indexed_palette_select_destroy_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog)
dialog->palette_select = NULL;
}
static gint
indexed_palette_select_palette (GimpContext *context,
GimpPalette *palette,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (palette)
{
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
gtk_label_set_text (GTK_LABEL (GTK_BIN (dialog->custom_palette_button)->child),
GIMP_OBJECT (theCustomPalette)->name);
}
}
return FALSE;
}
static void
indexed_custom_palette_button_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog->palette_select == NULL)
{
dialog->palette_select =
palette_select_new (_("Select Custom Palette"),
GIMP_OBJECT (theCustomPalette)->name);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->shell), "destroy",
GTK_SIGNAL_FUNC (indexed_palette_select_destroy_callback),
dialog);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->context),
"palette_changed",
GTK_SIGNAL_FUNC (indexed_palette_select_palette),
dialog);
}
else
{
gdk_window_raise (dialog->palette_select->shell->window);
}
}
static guchar found_cols[MAXNUMCOLORS][3];
static gint num_found_cols;
static gboolean needs_quantize;
static GimpPalette *theCustomPalette = NULL;
/**********************************************************/
@ -1257,16 +661,17 @@ remap_indexed_layer (GimpLayer *layer,
}
void
convert_image (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type)
gimp_image_convert (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type,
GimpPalette *custom_palette)
{
QuantizeObj *quantobj;
GimpLayer *layer;
@ -1278,11 +683,16 @@ convert_image (GimpImage *gimage,
gboolean has_alpha;
TileManager *new_tiles;
g_return_if_fail (gimage != NULL);
g_return_if_fail (GIMP_IS_IMAGE (gimage));
quantobj = NULL;
new_layer_type = RGBA_GIMAGE;
new_layer_bytes = 4;
gimp_add_busy_cursors();
theCustomPalette = custom_palette;
gimp_add_busy_cursors ();
/* Get the floating layer if one exists */
floating_layer = gimp_image_floating_sel (gimage);

View File

@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CONVERT_H__
#define __CONVERT_H__
#ifndef __GIMP_IMAGE_CONVERT_H__
#define __GIMP_IMAGE_CONVERT_H__
/* adam's extra palette stuff */
@ -44,24 +44,17 @@ typedef enum
#define MAXNUMCOLORS 256
/* convert functions */
void convert_to_rgb (GimpImage *gimage);
void convert_to_grayscale (GimpImage *gimage);
void convert_to_indexed (GimpImage *gimage);
void convert_image (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following three params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type);
void gimp_image_convert (GimpImage *gimage,
GimpImageBaseType new_type,
/* The following params used only for
* new_type == INDEXED
*/
gint num_cols,
ConvertDitherType dither,
gint alpha_dither,
gint remdups,
ConvertPaletteType palette_type,
GimpPalette *custom_palette);
extern GimpPalette *theCustomPalette;
#endif /* __CONVERT_H__ */
#endif /* __GIMP_IMAGE_CONVERT_H__ */

View File

@ -21,6 +21,8 @@ libappgui_la_SOURCES = \
colormap-dialog.h \
commands.c \
commands.h \
convert-dialog.c \
convert-dialog.h \
dialogs.c \
dialogs.h \
dialogs-commands.c \

View File

@ -33,6 +33,7 @@
#include "tools/gimptoolinfo.h"
#include "tools/tool_manager.h"
#include "convert-dialog.h"
#include "errorconsole.h"
#include "info-dialog.h"
#include "info-window.h"
@ -41,7 +42,6 @@
#include "app_procs.h"
#include "commands.h"
#include "context_manager.h"
#include "convert.h"
#include "desaturate.h"
#include "channel_ops.h"
#include "equalize.h"
@ -212,7 +212,7 @@ edit_paste_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
global_edit_paste (gdisp, 0);
global_edit_paste (gdisp, FALSE);
}
void
@ -222,7 +222,7 @@ edit_paste_into_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
global_edit_paste (gdisp, 1);
global_edit_paste (gdisp, TRUE);
}
void
@ -589,18 +589,18 @@ view_info_window_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!info_window_follows_mouse)
if (! info_window_follows_mouse)
{
if (! gdisp->window_info_dialog)
gdisp->window_info_dialog = info_window_create ((void *) gdisp);
info_window_update(gdisp);
info_window_update (gdisp);
info_dialog_popup (gdisp->window_info_dialog);
}
else
{
info_window_follow_auto();
info_window_follow_auto ();
}
}
void
@ -649,7 +649,7 @@ view_toggle_rulers_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
if (! GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->origin))
{
@ -662,7 +662,7 @@ view_toggle_rulers_cmd_callback (GtkWidget *widget,
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->origin))
if (! GTK_WIDGET_VISIBLE (gdisp->origin))
{
gtk_widget_show (gdisp->origin);
gtk_widget_show (gdisp->hrule);
@ -680,14 +680,14 @@ view_toggle_statusbar_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
if (! GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_hide (gdisp->statusarea);
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->statusarea))
if (! GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_show (gdisp->statusarea);
}
}

636
app/gui/convert-dialog.c Normal file
View File

@ -0,0 +1,636 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; 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 "libgimpwidgets/gimpwidgets.h"
#include "apptypes.h"
#include "tools/gimptool.h"
#include "tools/tool_manager.h"
#include "gdisplay.h"
#include "palette-select.h"
#include "context_manager.h"
#include "floating_sel.h"
#include "gimpdatafactory.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-convert.h"
#include "gimplist.h"
#include "gimplayer.h"
#include "gimppalette.h"
#include "libgimp/gimpintl.h"
typedef struct
{
GtkWidget *shell;
GtkWidget *custom_palette_button;
GimpImage *gimage;
PaletteSelect *palette_select;
gint nodither_flag;
gint fsdither_flag;
gint fslowbleeddither_flag;
gint fixeddither_flag;
gint alphadither; /* flag */
gint remdups; /* flag */
gint num_cols;
gint palette;
gint makepal_flag;
gint webpal_flag;
gint custompal_flag;
gint monopal_flag;
gint reusepal_flag;
} IndexedDialog;
static void indexed_ok_callback (GtkWidget *widget,
gpointer data);
static void indexed_cancel_callback (GtkWidget *widget,
gpointer data);
static void indexed_custom_palette_button_callback (GtkWidget *widget,
gpointer data);
static void indexed_palette_select_destroy_callback (GtkWidget *widget,
gpointer data);
static GtkWidget * build_palette_button (void);
static gboolean UserHasWebPal = FALSE;
static GimpPalette *theCustomPalette = NULL;
/* Defaults */
static gint snum_cols = 256;
static gboolean sfsdither_flag = TRUE;
static gboolean sfslowbleeddither_flag = TRUE;
static gboolean snodither_flag = FALSE;
static gboolean sfixeddither_flag = FALSE;
static gboolean smakepal_flag = TRUE;
static gboolean salphadither_flag = FALSE;
static gboolean sremdups_flag = TRUE;
static gboolean swebpal_flag = FALSE;
static gboolean scustompal_flag = FALSE;
static gboolean smonopal_flag = FALSE;
static gboolean sreusepal_flag = FALSE;
void
convert_to_rgb (GimpImage *gimage)
{
gimp_image_convert (gimage, RGB, 0, 0, 0, 0, 0, NULL);
gdisplays_flush ();
}
void
convert_to_grayscale (GimpImage* gimage)
{
gimp_image_convert (gimage, GRAY, 0, 0, 0, 0, 0, NULL);
gdisplays_flush ();
}
void
convert_to_indexed (GimpImage *gimage)
{
IndexedDialog *dialog;
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkObject *adjustment;
GtkWidget *spinbutton;
GtkWidget *frame;
GtkWidget *custom_frame = NULL;
GtkWidget *toggle;
GSList *group = NULL;
dialog = g_new0 (IndexedDialog, 1);
dialog->gimage = gimage;
dialog->custom_palette_button = NULL;
dialog->palette_select = NULL;
dialog->num_cols = snum_cols;
dialog->nodither_flag = snodither_flag;
dialog->fsdither_flag = sfsdither_flag;
dialog->fslowbleeddither_flag = sfslowbleeddither_flag;
dialog->fixeddither_flag = sfixeddither_flag;
dialog->alphadither = salphadither_flag;
dialog->remdups = sremdups_flag;
dialog->makepal_flag = smakepal_flag;
dialog->webpal_flag = swebpal_flag;
dialog->custompal_flag = scustompal_flag;
dialog->monopal_flag = smonopal_flag;
dialog->reusepal_flag = sreusepal_flag;
dialog->shell =
gimp_dialog_new (_("Indexed Color Conversion"), "indexed_color_conversion",
gimp_standard_help_func,
"dialogs/convert_to_indexed.html",
GTK_WIN_POS_NONE,
FALSE, FALSE, TRUE,
_("OK"), indexed_ok_callback,
dialog, NULL, NULL, TRUE, FALSE,
_("Cancel"), indexed_cancel_callback,
dialog, NULL, NULL, FALSE, TRUE,
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog->shell)->vbox),
main_vbox);
gtk_widget_show (main_vbox);
frame = gtk_frame_new (_("General Palette Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* 'generate palette' */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (NULL, _("Generate Optimal Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->makepal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->makepal_flag);
gtk_widget_show (toggle);
if (dialog->num_cols == 256)
{
if ((! gimp_image_is_empty (gimage)) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
dialog->num_cols = 255;
}
}
spinbutton = gimp_spin_button_new (&adjustment, dialog->num_cols,
2, 256, 1, 5, 0, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&(dialog->num_cols));
gtk_box_pack_end (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
label = gtk_label_new (_("# of Colors:"));
gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_set_sensitive (GTK_WIDGET (spinbutton), dialog->num_cols);
gtk_widget_set_sensitive (GTK_WIDGET (label), dialog->num_cols);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", spinbutton);
gtk_object_set_data (GTK_OBJECT (spinbutton), "set_sensitive", label);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
dialog->custom_palette_button = build_palette_button ();
if (dialog->custom_palette_button)
{
/* create the custom_frame here, it'll be added later */
custom_frame = gtk_frame_new (_("Custom Palette Options"));
gtk_container_set_border_width (GTK_CONTAINER (custom_frame), 2);
/* The remove-duplicates toggle */
hbox = gtk_hbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (custom_frame), hbox);
toggle = gtk_check_button_new_with_label (_("Remove Unused Colors from Final Palette"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), dialog->remdups);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->remdups));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* 'custom' palette from dialog */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Use Custom Palette:"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->custompal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_widget_show (toggle);
gtk_signal_connect (GTK_OBJECT (dialog->custom_palette_button), "clicked",
GTK_SIGNAL_FUNC (indexed_custom_palette_button_callback),
dialog);
gtk_box_pack_end (GTK_BOX (hbox), dialog->custom_palette_button, TRUE, TRUE, 0);
gtk_widget_show (dialog->custom_palette_button);
gtk_widget_show (hbox);
gtk_widget_set_sensitive (GTK_WIDGET (custom_frame),
dialog->custompal_flag);
gtk_widget_set_sensitive (GTK_WIDGET (dialog->custom_palette_button),
dialog->custompal_flag);
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", custom_frame);
gtk_object_set_data (GTK_OBJECT (custom_frame), "set_sensitive",
dialog->custom_palette_button);
}
if (! UserHasWebPal)
{
/* 'web palette'
* Only presented as an option to the user if they do not
* already have the 'Web' GIMP palette installed on their
* system.
*/
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use WWW-Optimized Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->webpal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->webpal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
}
/* 'mono palette' */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle =
gtk_radio_button_new_with_label (group, _("Use Black/White (1-Bit) Palette"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->monopal_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->monopal_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
frame = gtk_frame_new (_("Dither Options"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show(vbox);
/* The dither radio buttons */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (NULL, _("No Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->nodither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->nodither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Positioned Color Dithering"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fixeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fixeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Reduced Color Bleeding)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fslowbleeddither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fslowbleeddither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_radio_button_new_with_label (group, _("Floyd-Steinberg Color Dithering (Normal)"));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->fsdither_flag));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->fsdither_flag);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* The alpha-dither toggle */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
toggle = gtk_check_button_new_with_label (_("Enable Dithering of Transparency"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
dialog->alphadither);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&(dialog->alphadither));
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* now add the custom_frame */
if (custom_frame)
{
gtk_box_pack_start (GTK_BOX (main_vbox), custom_frame, FALSE, FALSE, 0);
gtk_widget_show (custom_frame);
}
/* if the image isn't non-alpha/layered, set the default number of
colours to one less than max, to leave room for a transparent index
for transparent/animated GIFs */
if (! gimp_image_is_empty (gimage) &&
GIMP_IMAGE_TYPE_HAS_ALPHA (gimage->base_type))
{
frame = gtk_frame_new (_("[ Warning ]"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
label = gtk_label_new
(_("You are attempting to convert an image with alpha/layers "
"from RGB/GRAY to INDEXED.\nYou should not generate a "
"palette of more than 255 colors if you intend to create "
"a transparent or animated GIF file from this image."));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (vbox), label);
gtk_widget_show (label);
}
gtk_widget_show (dialog->shell);
}
static GtkWidget *
build_palette_button (void)
{
GList *list;
GimpPalette *palette;
GimpPalette *theWebPalette = NULL;
gint i;
gint default_palette;
UserHasWebPal = FALSE;
list = GIMP_LIST (global_palette_factory->container)->list;
if (! list)
{
return NULL;
}
for (i = 0, default_palette = -1;
list;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
/* Preferentially, the initial default is 'Web' if available */
if (theWebPalette == NULL &&
g_strcasecmp (GIMP_OBJECT (palette)->name, "Web") == 0)
{
theWebPalette = palette;
UserHasWebPal = TRUE;
}
/* We can't dither to > 256 colors */
if (palette->n_colors <= 256)
{
if (theCustomPalette == palette)
{
default_palette = i;
}
}
}
/* default to first one with <= 256 colors
* (only used if 'web' palette not available)
*/
if (default_palette == -1)
{
if (theWebPalette)
{
theCustomPalette = theWebPalette;
default_palette = 1; /* dummy value */
}
else
{
for (i = 0, list = GIMP_LIST (global_palette_factory->container)->list;
list && default_palette == -1;
i++, list = g_list_next (list))
{
palette = (GimpPalette *) list->data;
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
default_palette = i;
}
}
}
}
if (default_palette == -1)
return NULL;
else
return gtk_button_new_with_label (GIMP_OBJECT (theCustomPalette)->name);
}
static void
indexed_ok_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
ConvertPaletteType palette_type;
ConvertDitherType dither_type;
dialog = (IndexedDialog *) data;
if (dialog->webpal_flag)
palette_type = WEB_PALETTE;
else if (dialog->custompal_flag)
palette_type = CUSTOM_PALETTE;
else if (dialog->monopal_flag)
palette_type = MONO_PALETTE;
else if (dialog->makepal_flag)
palette_type = MAKE_PALETTE;
else
palette_type = REUSE_PALETTE;
if (dialog->nodither_flag)
dither_type = NO_DITHER;
else if (dialog->fsdither_flag)
dither_type = FS_DITHER;
else if (dialog->fslowbleeddither_flag)
dither_type = FSLOWBLEED_DITHER;
else
dither_type = FIXED_DITHER;
/* Close the dialogs when open because they're useless for indexed
* images and could crash the GIMP when used nevertheless
*/
if (active_tool)
tool_manager_control_active (HALT, active_tool->gdisp);
/* Convert the image to indexed color */
gimp_image_convert (dialog->gimage, INDEXED, dialog->num_cols,
dither_type, dialog->alphadither,
dialog->remdups, palette_type, theCustomPalette);
gdisplays_flush ();
/* Save defaults for next time */
snum_cols = dialog->num_cols;
snodither_flag = dialog->nodither_flag;
sfsdither_flag = dialog->fsdither_flag;
sfslowbleeddither_flag = dialog->fslowbleeddither_flag;
sfixeddither_flag = dialog->fixeddither_flag;
salphadither_flag = dialog->alphadither;
sremdups_flag = dialog->remdups;
smakepal_flag = dialog->makepal_flag;
swebpal_flag = dialog->webpal_flag;
scustompal_flag = dialog->custompal_flag;
smonopal_flag = dialog->monopal_flag;
sreusepal_flag = dialog->reusepal_flag;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
}
static void
indexed_cancel_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (dialog->palette_select)
gtk_widget_destroy (dialog->palette_select->shell);
gtk_widget_destroy (dialog->shell);
g_free (dialog);
}
static void
indexed_palette_select_destroy_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog)
dialog->palette_select = NULL;
}
static gint
indexed_palette_select_palette (GimpContext *context,
GimpPalette *palette,
gpointer data)
{
IndexedDialog *dialog;
dialog = (IndexedDialog *) data;
if (palette)
{
if (palette->n_colors <= 256)
{
theCustomPalette = palette;
gtk_label_set_text (GTK_LABEL (GTK_BIN (dialog->custom_palette_button)->child),
GIMP_OBJECT (theCustomPalette)->name);
}
}
return FALSE;
}
static void
indexed_custom_palette_button_callback (GtkWidget *widget,
gpointer data)
{
IndexedDialog *dialog = (IndexedDialog *)data;
if (dialog->palette_select == NULL)
{
dialog->palette_select =
palette_select_new (_("Select Custom Palette"),
GIMP_OBJECT (theCustomPalette)->name);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->shell), "destroy",
GTK_SIGNAL_FUNC (indexed_palette_select_destroy_callback),
dialog);
gtk_signal_connect (GTK_OBJECT (dialog->palette_select->context),
"palette_changed",
GTK_SIGNAL_FUNC (indexed_palette_select_palette),
dialog);
}
else
{
gdk_window_raise (dialog->palette_select->shell->window);
}
}

28
app/gui/convert-dialog.h Normal file
View File

@ -0,0 +1,28 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CONVERT_DIALOG_H__
#define __CONVERT_DIALOG_H__
void convert_to_rgb (GimpImage *gimage);
void convert_to_grayscale (GimpImage *gimage);
void convert_to_indexed (GimpImage *gimage);
#endif /* __CONVERT_DIALOG_H__ */

View File

@ -33,6 +33,7 @@
#include "tools/gimptoolinfo.h"
#include "tools/tool_manager.h"
#include "convert-dialog.h"
#include "errorconsole.h"
#include "info-dialog.h"
#include "info-window.h"
@ -41,7 +42,6 @@
#include "app_procs.h"
#include "commands.h"
#include "context_manager.h"
#include "convert.h"
#include "desaturate.h"
#include "channel_ops.h"
#include "equalize.h"
@ -212,7 +212,7 @@ edit_paste_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
global_edit_paste (gdisp, 0);
global_edit_paste (gdisp, FALSE);
}
void
@ -222,7 +222,7 @@ edit_paste_into_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
global_edit_paste (gdisp, 1);
global_edit_paste (gdisp, TRUE);
}
void
@ -589,18 +589,18 @@ view_info_window_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!info_window_follows_mouse)
if (! info_window_follows_mouse)
{
if (! gdisp->window_info_dialog)
gdisp->window_info_dialog = info_window_create ((void *) gdisp);
info_window_update(gdisp);
info_window_update (gdisp);
info_dialog_popup (gdisp->window_info_dialog);
}
else
{
info_window_follow_auto();
info_window_follow_auto ();
}
}
void
@ -649,7 +649,7 @@ view_toggle_rulers_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
if (! GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->origin))
{
@ -662,7 +662,7 @@ view_toggle_rulers_cmd_callback (GtkWidget *widget,
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->origin))
if (! GTK_WIDGET_VISIBLE (gdisp->origin))
{
gtk_widget_show (gdisp->origin);
gtk_widget_show (gdisp->hrule);
@ -680,14 +680,14 @@ view_toggle_statusbar_cmd_callback (GtkWidget *widget,
GDisplay *gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
if (! GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_hide (gdisp->statusarea);
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->statusarea))
if (! GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_show (gdisp->statusarea);
}
}

View File

@ -27,9 +27,9 @@
#include "procedural_db.h"
#include "context_manager.h"
#include "convert.h"
#include "gimpcontainer.h"
#include "gimpdatafactory.h"
#include "gimpimage-convert.h"
#include "gimpimage.h"
#include "gimppalette.h"
@ -57,7 +57,7 @@ convert_rgb_invoker (Argument *args)
if (success)
if ((success = (gimp_image_base_type (gimage) != RGB)))
convert_image ((void *) gimage, RGB, 0, 0, 0, 1, 0);
gimp_image_convert ((void *) gimage, RGB, 0, 0, 0, 1, 0, NULL);
return procedural_db_return_args (&convert_rgb_proc, success);
}
@ -99,7 +99,7 @@ convert_grayscale_invoker (Argument *args)
if (success)
if ((success = (gimp_image_base_type (gimage) != GRAY)))
convert_image ((void *) gimage, GRAY, 0, 0, 0, 1, 0);
gimp_image_convert ((void *) gimage, GRAY, 0, 0, 0, 1, 0, NULL);
return procedural_db_return_args (&convert_grayscale_proc, success);
}
@ -163,10 +163,10 @@ convert_indexed_invoker (Argument *args)
if (success)
{
GimpPalette *palette = NULL;
if ((success = (gimp_image_base_type (gimage) != INDEXED)))
{
GimpPalette *palette = NULL;
switch (dither_type)
{
case NO_DITHER:
@ -201,8 +201,6 @@ convert_indexed_invoker (Argument *args)
if (palette == NULL)
success = FALSE;
else
theCustomPalette = palette;
break;
@ -212,8 +210,8 @@ convert_indexed_invoker (Argument *args)
}
if (success)
convert_image ((void *) gimage, INDEXED, num_cols, dither_type,
alpha_dither, remove_unused, palette_type);
gimp_image_convert ((void *) gimage, INDEXED, num_cols, dither_type,
alpha_dither, remove_unused, palette_type, palette);
}
return procedural_db_return_args (&convert_indexed_proc, success);

View File

@ -3,7 +3,6 @@
app/app_procs.c
app/channel_ops.c
app/convert.c
app/desaturate.c
app/devices.c
app/disp_callbacks.c
@ -54,6 +53,7 @@ app/gui/color-notebook.c
app/gui/color-select.c
app/gui/colormap-dialog.c
app/gui/commands.c
app/gui/convert-dialog.c
app/gui/file-new-dialog.c
app/gui/gradient-editor.c
app/gui/gradient-select.c

View File

@ -53,9 +53,9 @@ enum_headers = \
../../app/appenv.h \
../../app/apptypes.h \
../../app/channel_ops.h \
../../app/convert.h \
../../app/errors.h \
../../app/gimpimage.h \
../../app/gimpimage-convert.h \
../../app/lut_funcs.h \
../../app/plug_in.h \
../../app/paint-funcs/paint-funcs.h \

View File

@ -254,28 +254,6 @@ package Gimp::CodeGen::enums;
mapping => { OFFSET_BACKGROUND => '0',
OFFSET_TRANSPARENT => '1' }
},
ConvertPaletteType =>
{ contig => 1,
header => 'convert.h',
symbols => [ qw(MAKE_PALETTE REUSE_PALETTE WEB_PALETTE
MONO_PALETTE CUSTOM_PALETTE) ],
mapping => { MAKE_PALETTE => '0',
REUSE_PALETTE => '1',
WEB_PALETTE => '2',
MONO_PALETTE => '3',
CUSTOM_PALETTE => '4' }
},
ConvertDitherType =>
{ contig => 1,
header => 'convert.h',
symbols => [ qw(NO_DITHER FS_DITHER FSLOWBLEED_DITHER FIXED_DITHER
NODESTRUCT_DITHER) ],
mapping => { NO_DITHER => '0',
FS_DITHER => '1',
FSLOWBLEED_DITHER => '2',
FIXED_DITHER => '3',
NODESTRUCT_DITHER => '4' }
},
StackTraceMode =>
{ contig => 1,
header => 'errors.h',
@ -309,6 +287,28 @@ package Gimp::CodeGen::enums;
CLIP_TO_BOTTOM_LAYER => '2',
FLATTEN_IMAGE => '3' }
},
ConvertPaletteType =>
{ contig => 1,
header => 'gimpimage-convert.h',
symbols => [ qw(MAKE_PALETTE REUSE_PALETTE WEB_PALETTE
MONO_PALETTE CUSTOM_PALETTE) ],
mapping => { MAKE_PALETTE => '0',
REUSE_PALETTE => '1',
WEB_PALETTE => '2',
MONO_PALETTE => '3',
CUSTOM_PALETTE => '4' }
},
ConvertDitherType =>
{ contig => 1,
header => 'gimpimage-convert.h',
symbols => [ qw(NO_DITHER FS_DITHER FSLOWBLEED_DITHER FIXED_DITHER
NODESTRUCT_DITHER) ],
mapping => { NO_DITHER => '0',
FS_DITHER => '1',
FSLOWBLEED_DITHER => '2',
FIXED_DITHER => '3',
NODESTRUCT_DITHER => '4' }
},
ChannelLutType =>
{ contig => 1,
header => 'lut_funcs.h',

View File

@ -28,7 +28,7 @@ sub simple_invoke {
%invoke = (
code => <<CODE
if ((success = (gimp_image_base_type (gimage) != $type)))
convert_image ((void *) gimage, $type, 0, 0, 0, 1, 0);
gimp_image_convert ((void *) gimage, $type, 0, 0, 0, 1, 0, NULL);
CODE
);
}
@ -99,10 +99,10 @@ HELP
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = NULL;
if ((success = (gimp_image_base_type (gimage) != INDEXED)))
{
GimpPalette *palette = NULL;
switch (dither_type)
{
case NO_DITHER:
@ -137,8 +137,6 @@ HELP
if (palette == NULL)
success = FALSE;
else
theCustomPalette = palette;
break;
@ -148,15 +146,15 @@ HELP
}
if (success)
convert_image ((void *) gimage, INDEXED, num_cols, dither_type,
alpha_dither, remove_unused, palette_type);
gimp_image_convert ((void *) gimage, INDEXED, num_cols, dither_type,
alpha_dither, remove_unused, palette_type, palette);
}
CODE
);
}
@headers = qw("context_manager.h" "gimpcontainer.h" "gimpimage.h"
"gimpdatafactory.h" "gimppalette.h" "convert.h");
"gimpdatafactory.h" "gimppalette.h" "gimpimage-convert.h");
@procs = qw(convert_rgb convert_grayscale convert_indexed);
%exports = (app => [@procs], lib => [@procs]);