gimp/plug-ins/common/file-gif-save.c

2510 lines
71 KiB
C
Raw Normal View History

/* GIF exporting file filter for GIMP
1997-11-25 06:05:25 +08:00
*
* Copyright
* - Adam D. Moss
* - Peter Mattis
* - Spencer Kimball
1997-11-25 06:05:25 +08:00
*
* Based around original GIF code by David Koblas.
1997-11-25 06:05:25 +08:00
*
*
* Version 4.1.0 - 2003-06-16
* Adam D. Moss - <adam@gimp.org> <adam@foxbox.org>
1997-11-25 06:05:25 +08:00
*/
/*
* This filter uses code taken from the "giftopnm" and "ppmtogif" programs
* which are part of the "netpbm" package.
*/
/*
* "The Graphics Interchange Format(c) is the Copyright property of
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
* CompuServe Incorporated."
1997-11-25 06:05:25 +08:00
*/
/* Copyright notice for GIF code from which this plugin was long ago */
/* derived (David Koblas has granted permission to relicense): */
/* +-------------------------------------------------------------------+ */
/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@extra.com) | */
/* +-------------------------------------------------------------------+ */
1997-11-25 06:05:25 +08:00
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
#include "config.h"
1997-11-25 06:05:25 +08:00
#include <string.h>
configure.in po-plug-ins/POTFILES.in plug-ins/common/Makefile.am 2000-01-25 Michael Natterer <mitch@gimp.org> * configure.in * po-plug-ins/POTFILES.in * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl * plug-ins/megawidget/*: removed. (There were only 3 functions left which were used by ~5 plugins, so I moved the resp. functions to the plugins). More preview stuff to come... * app/airbrush_blob.c * modules/colorsel_triangle.c * modules/colorsel_water.c: use G_PI instead of M_PI. * app/procedural_db.h * libgimp/gimpenums.h * plug-ins/script-fu/script-fu-constants.c * tools/pdbgen/enums.pl: new PDB return value STATUS_CANCEL which indicates that "Cancel" was pressed in a plugin dialog. (Useful only for file load/save plugins). * app/fileops.[ch] * app/menus.c: changes to handle STATUS_CANCEL correctly. Did some code cleanup in fileops.[ch]. Pop up a warning if File->Save failed. * app/plug_in.c: return_val[0] is of type PDB_STATUS, not PDB_INT32. * libgimp/gimpmath.h: new constant G_MAXRAND which equals to RAND_MAX if it exists or to G_MAXINT otherwise. * libgimp/gimpwidgets.[ch]: new function gimp_random_seed_new() which creates a spinbutton and a "Time" toggle. Call the function which does the "set_sensitive" magic from the radio button callback. * plug-ins/[75 plugins]: - Return STATUS_CANCEL in all file load/save dialogs if "Cancel" was pressed. - Standardized the file plugins' "run" functions. - Use G_PI and G_MAXRAND everywhere. - Added tons of scales and spinbuttons instead of text entries. - Applied uniform packing/spacings all over the place. - Reorganized some UIs (stuff like moving the preview to the top left corner of the dialog). - Removed many ui helper functions and callbacks and use the stuff from libgimp instead. - I tried not to restrict the range of possible values when I replaced entries with spinbuttons/scales but may have failed, though in some cases. Please test ;-) - #include <libgimp/gimpmath.h> where appropriate and use it's constants. - Indentation, s/int/gint/ et.al., code cleanup. RFC: The plugins are definitely not useable with GIMP 1.0 any more, so shouldn't we remove all the remaining compatibility stuff ??? (like "#ifdef GIMP_HAVE_PARASITES")
2000-01-26 01:46:56 +08:00
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
#include "libgimp/stdplugins-intl.h"
1997-11-25 06:05:25 +08:00
#define SAVE_PROC "file-gif-save"
#define PLUG_IN_BINARY "file-gif-save"
/* uncomment the line below for a little debugging info */
/* #define GIFDEBUG yesplease */
configure.in po-plug-ins/POTFILES.in plug-ins/common/Makefile.am 2000-01-25 Michael Natterer <mitch@gimp.org> * configure.in * po-plug-ins/POTFILES.in * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl * plug-ins/megawidget/*: removed. (There were only 3 functions left which were used by ~5 plugins, so I moved the resp. functions to the plugins). More preview stuff to come... * app/airbrush_blob.c * modules/colorsel_triangle.c * modules/colorsel_water.c: use G_PI instead of M_PI. * app/procedural_db.h * libgimp/gimpenums.h * plug-ins/script-fu/script-fu-constants.c * tools/pdbgen/enums.pl: new PDB return value STATUS_CANCEL which indicates that "Cancel" was pressed in a plugin dialog. (Useful only for file load/save plugins). * app/fileops.[ch] * app/menus.c: changes to handle STATUS_CANCEL correctly. Did some code cleanup in fileops.[ch]. Pop up a warning if File->Save failed. * app/plug_in.c: return_val[0] is of type PDB_STATUS, not PDB_INT32. * libgimp/gimpmath.h: new constant G_MAXRAND which equals to RAND_MAX if it exists or to G_MAXINT otherwise. * libgimp/gimpwidgets.[ch]: new function gimp_random_seed_new() which creates a spinbutton and a "Time" toggle. Call the function which does the "set_sensitive" magic from the radio button callback. * plug-ins/[75 plugins]: - Return STATUS_CANCEL in all file load/save dialogs if "Cancel" was pressed. - Standardized the file plugins' "run" functions. - Use G_PI and G_MAXRAND everywhere. - Added tons of scales and spinbuttons instead of text entries. - Applied uniform packing/spacings all over the place. - Reorganized some UIs (stuff like moving the preview to the top left corner of the dialog). - Removed many ui helper functions and callbacks and use the stuff from libgimp instead. - I tried not to restrict the range of possible values when I replaced entries with spinbuttons/scales but may have failed, though in some cases. Please test ;-) - #include <libgimp/gimpmath.h> where appropriate and use it's constants. - Indentation, s/int/gint/ et.al., code cleanup. RFC: The plugins are definitely not useable with GIMP 1.0 any more, so shouldn't we remove all the remaining compatibility stuff ??? (like "#ifdef GIMP_HAVE_PARASITES")
2000-01-26 01:46:56 +08:00
enum
{
DISPOSE_UNSPECIFIED,
DISPOSE_COMBINE,
DISPOSE_REPLACE
};
1997-11-25 06:05:25 +08:00
typedef struct _Gif Gif;
typedef struct _GifClass GifClass;
struct _Gif
{
GimpPlugIn parent_instance;
};
struct _GifClass
{
GimpPlugInClass parent_class;
};
#define GIF_TYPE (gif_get_type ())
#define GIF (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIF_TYPE, Gif))
GType gif_get_type (void) G_GNUC_CONST;
static GList * gif_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * gif_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
static GimpValueArray * gif_save (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
gint n_drawables,
GimpDrawable **drawables,
GFile *file,
GimpMetadata *metadata,
GimpProcedureConfig *config,
gpointer run_data);
static gboolean save_image (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GimpImage *orig_image,
GObject *config,
GError **error);
static GimpPDBStatusType sanity_check (GFile *file,
GimpImage **image,
GimpRunMode run_mode,
GError **error);
static gboolean bad_bounds_dialog (void);
static gboolean save_dialog (GimpImage *image,
GimpProcedure *procedure,
GObject *config);
G_DEFINE_TYPE (Gif, gif, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (GIF_TYPE)
DEFINE_STD_SET_I18N
1997-11-25 06:05:25 +08:00
static gint Interlace; /* For compression code */
1997-11-25 06:05:25 +08:00
static void
gif_class_init (GifClass *klass)
{
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
1997-11-25 06:05:25 +08:00
plug_in_class->query_procedures = gif_query_procedures;
plug_in_class->create_procedure = gif_create_procedure;
plug_in_class->set_i18n = STD_SET_I18N;
}
2014-05-17 00:36:34 +08:00
1997-11-25 06:05:25 +08:00
static void
gif_init (Gif *gif)
1997-11-25 06:05:25 +08:00
{
}
static GList *
gif_query_procedures (GimpPlugIn *plug_in)
{
return g_list_append (NULL, g_strdup (SAVE_PROC));
}
static GimpProcedure *
gif_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
if (! strcmp (name, SAVE_PROC))
{
procedure = gimp_save_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
FALSE, gif_save, NULL, NULL);
gimp_procedure_set_image_types (procedure, "INDEXED*, GRAY*");
gimp_procedure_set_menu_label (procedure, _("GIF image"));
gimp_file_procedure_set_format_name (GIMP_FILE_PROCEDURE (procedure),
_("GIF"));
gimp_procedure_set_documentation (procedure,
_("exports files in GIF "
"file format"),
/* xgettext: no-c-format */
_("Export a file in GIF "
"format, with possible animation, "
"transparency, and comment. To export "
"an animation, operate on a multi-layer "
"file and give the 'as-animation' "
"parameter as TRUE. The plug-in will "
"interpret <50% alpha as transparent. "
"When run non-interactively, the value "
"for the comment is taken from the "
"'gimp-comment' parasite."),
name);
gimp_procedure_set_attribution (procedure,
"Spencer Kimball, Peter Mattis, "
"Adam Moss, David Koblas",
"Spencer Kimball, Peter Mattis, "
"Adam Moss, David Koblas",
"1995-1997");
gimp_file_procedure_set_handles_remote (GIMP_FILE_PROCEDURE (procedure),
TRUE);
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
"image/gif");
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"gif");
GIMP_PROC_ARG_BOOLEAN (procedure, "interlace",
_("_Interlace"),
_("Try to export as interlaced"),
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "loop",
_("Loop _Forever"),
_("(animated gif) Loop infinitely"),
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "number-of-repeats",
_("_Number of repeats"),
_("(animated gif) Number of repeats "
"(Ignored if 'loop' is TRUE)"),
0, G_MAXSHORT - 1, 0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "default-delay",
_("_Delay between frames when unspecified"),
_("(animated gif) Default delay between frames "
"in milliseconds"),
0, G_MAXINT, 100,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "default-dispose",
_("Frame disposal _when unspecified"),
_("(animated gif) Default disposal type "
"(0=`don't care`, "
"1=combine, "
"2=replace)"),
0, 2, 0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "as-animation",
_("_As animation"),
_("Export GIF as animation?"),
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "force-delay",
_("_Use delay entered above for all frames"),
_("(animated gif) Use specified delay for all frames"),
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "force-dispose",
_("Use dis_posal entered above "
"for all frames"),
_("(animated gif) Use specified disposal for all frames"),
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-comment",
_("Sa_ve comment"),
_("Save the image comment in the GIF file"),
gimp_export_comment (),
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_STRING (procedure, "gimp-comment",
_("Commen_t"),
_("Image comment"),
gimp_get_default_comment (),
G_PARAM_READWRITE);
gimp_procedure_set_argument_sync (procedure, "gimp-comment",
GIMP_ARGUMENT_SYNC_PARASITE);
}
return procedure;
}
static GimpValueArray *
gif_save (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
gint n_drawables,
GimpDrawable **drawables,
GFile *file,
GimpMetadata *metadata,
GimpProcedureConfig *config,
gpointer run_data)
1997-11-25 06:05:25 +08:00
{
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GimpImage *orig_image;
GimpImage *sanitized_image = NULL;
GError *error = NULL;
1997-11-25 06:05:25 +08:00
2012-09-23 05:19:32 +08:00
gegl_init (NULL, NULL);
orig_image = image;
if (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS)
gimp_ui_init (PLUG_IN_BINARY);
status = sanity_check (file, &image, run_mode, &error);
1997-11-25 06:05:25 +08:00
/* Get the export options */
if (status == GIMP_PDB_SUCCESS)
1997-11-25 06:05:25 +08:00
{
/* If the sanity check succeeded, the image_ID will point to a
* duplicate image to delete later.
*/
sanitized_image = image;
if (run_mode == GIMP_RUN_INTERACTIVE)
{
if (! save_dialog (image, procedure, G_OBJECT (config)))
{
gimp_image_delete (sanitized_image);
1997-11-25 06:05:25 +08:00
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
}
}
}
1997-11-25 06:05:25 +08:00
if (status == GIMP_PDB_SUCCESS)
{
/* Create an exportable image based on the export options */
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
{
GimpExportCapabilities capabilities;
gboolean as_animation;
capabilities = (GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
g_object_get (config,
"as-animation", &as_animation,
NULL);
if (as_animation)
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS;
export = gimp_export_image (&image, &n_drawables, &drawables, "GIF",
capabilities);
if (export == GIMP_EXPORT_CANCEL)
{
if (sanitized_image)
gimp_image_delete (sanitized_image);
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
}
break;
}
default:
break;
}
1997-11-25 06:05:25 +08:00
if (n_drawables != 1)
{
g_set_error (&error, G_FILE_ERROR, 0,
_("GIF format does not support multiple layers."));
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CALLING_ERROR,
error);
}
if (! save_image (file, image, drawables[0], orig_image, G_OBJECT (config),
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
}
2016-04-15 01:49:00 +08:00
gimp_image_delete (sanitized_image);
}
if (export == GIMP_EXPORT_EXPORT)
{
gimp_image_delete (image);
g_free (drawables);
}
1997-11-25 06:05:25 +08:00
return gimp_procedure_new_return_values (procedure, status, error);
}
1997-11-25 06:05:25 +08:00
/* ppmtogif.c - read a portable pixmap and produce a GIF file
**
1999-11-20 10:20:04 +08:00
** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
** Lempel-Ziv compression based on "compress".
1997-11-25 06:05:25 +08:00
**
** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
**
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
**
** The Graphics Interchange Format(c) is the Copyright property of
** CompuServe Incorporated. GIF(sm) is a Service Mark property of
** CompuServe Incorporated.
*/
#define MAXCOLORS 256
/*
* Pointer to function returning an int
*/
typedef gint (* ifunptr) (gint x,
gint y);
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
static gint find_unused_ia_color (const guchar *pixels,
gint numpixels,
gint num_indices,
gint *colors);
2016-04-15 01:49:00 +08:00
static void special_flatten_indexed_alpha (guchar *pixels,
gint transparent,
gint numpixels);
2016-04-15 01:49:00 +08:00
static gint colors_to_bpp (gint colors);
static gint bpp_to_colors (gint bpp);
static gint get_pixel (gint x,
gint y);
static gint gif_next_pixel (ifunptr getpixel);
static void bump_pixel (void);
2016-04-15 01:49:00 +08:00
static gboolean gif_encode_header (GOutputStream *output,
gboolean gif89,
gint width,
gint height,
gint background,
gint bpp,
gint *red,
gint *green,
gint *blue,
ifunptr get_pixel,
GError **error);
static gboolean gif_encode_graphic_control_ext (GOutputStream *output,
gint disposal,
gint delay89,
gint n_frames,
gint width,
gint height,
gint transparent,
gint bpp,
ifunptr get_pixel,
GError **error);
static gboolean gif_encode_image_data (GOutputStream *output,
gint width,
gint height,
gint interlace,
gint bpp,
ifunptr get_pixel,
gint offset_x,
gint offset_y,
GError **error);
static gboolean gif_encode_close (GOutputStream *output,
GError **error);
static gboolean gif_encode_loop_ext (GOutputStream *output,
guint n_loops,
GError **error);
static gboolean gif_encode_comment_ext (GOutputStream *output,
const gchar *comment,
GError **error);
1997-11-25 06:05:25 +08:00
static gint rowstride;
static guchar *pixels;
static gint cur_progress;
static gint max_progress;
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
static gboolean compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error);
static gboolean no_compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error);
static gboolean rle_compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error);
static gboolean normal_compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error);
static gboolean put_byte (GOutputStream *output,
guchar b,
GError **error);
static gboolean put_word (GOutputStream *output,
gint w,
GError **error);
static gboolean put_string (GOutputStream *output,
const gchar *s,
GError **error);
static gboolean output_code (GOutputStream *output,
gint code,
GError **error);
static gboolean cl_block (GOutputStream *output,
GError **error);
static void cl_hash (glong hsize);
static void char_init (void);
static gboolean char_out (GOutputStream *output,
gint c,
GError **error);
static gboolean char_flush (GOutputStream *output,
GError **error);
1997-11-25 06:05:25 +08:00
static gint
find_unused_ia_color (const guchar *pixels,
gint numpixels,
gint num_indices,
gint *colors)
1997-11-25 06:05:25 +08:00
{
gboolean ix_used[256];
gint i;
1997-11-25 06:05:25 +08:00
#ifdef GIFDEBUG
g_printerr ("GIF: fuiac: Image claims to use %d/%d indices - finding free "
"index...\n", *colors, num_indices);
#endif
1997-11-25 06:05:25 +08:00
for (i = 0; i < 256; i++)
ix_used[i] = FALSE;
1997-11-25 06:05:25 +08:00
for (i = 0; i < numpixels; i++)
{
if (pixels[i * 2 + 1])
ix_used[pixels[i * 2]] = TRUE;
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
for (i = num_indices - 1; i >= 0; i--)
{
if (! ix_used[i])
{
#ifdef GIFDEBUG
g_printerr ("GIF: Found unused color index %d.\n", (int) i);
#endif
return i;
}
}
1997-11-25 06:05:25 +08:00
/* Couldn't find an unused color index within the number of bits per
* pixel we wanted. Will have to increment the number of colors in
* the image and assign a transparent pixel there.
*/
if (*colors < 256)
{
(*colors)++;
g_printerr ("GIF: 2nd pass "
"- Increasing bounds and using color index %d.\n",
*colors - 1);
return ((*colors) - 1);
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
g_message (_("Couldn't simply reduce colors further. Exporting as opaque."));
return -1;
1997-11-25 06:05:25 +08:00
}
static void
1997-11-25 06:05:25 +08:00
special_flatten_indexed_alpha (guchar *pixels,
gint transparent,
gint numpixels)
1997-11-25 06:05:25 +08:00
{
2021-05-25 04:36:31 +08:00
gint i;
1997-11-25 06:05:25 +08:00
/* Each transparent pixel in the image is mapped to a uniform value
* for encoding, if image already has <=255 colors
*/
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
if (transparent == -1) /* tough, no indices left for the trans. index */
1997-11-25 06:05:25 +08:00
{
for (i = 0; i < numpixels; i++)
pixels[i] = pixels[i * 2];
1997-11-25 06:05:25 +08:00
}
else /* make transparent */
{
for (i = 0; i < numpixels; i++)
{
if (! (pixels[i * 2 + 1] & 128))
{
pixels[i] = (guchar) transparent;
}
else
{
pixels[i] = pixels[i * 2];
}
}
1997-11-25 06:05:25 +08:00
}
}
static gint
parse_ms_tag (const gchar *str)
1997-11-25 06:05:25 +08:00
{
gint sum = 0;
1997-11-25 06:05:25 +08:00
gint offset = 0;
gint length;
length = strlen (str);
1997-11-25 06:05:25 +08:00
find_another_bra:
1998-04-29 18:48:02 +08:00
while ((offset < length) && (str[offset] != '('))
1997-11-25 06:05:25 +08:00
offset++;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
if (offset >= length)
1997-11-25 06:05:25 +08:00
return(-1);
if (! g_ascii_isdigit (str[++offset]))
1998-04-29 18:48:02 +08:00
goto find_another_bra;
1997-11-25 06:05:25 +08:00
do
{
sum *= 10;
sum += str[offset] - '0';
offset++;
}
while ((offset < length) && (g_ascii_isdigit (str[offset])));
1997-11-25 06:05:25 +08:00
if (length - offset <= 2)
1997-11-25 06:05:25 +08:00
return(-3);
if ((g_ascii_toupper (str[offset]) != 'M') ||
(g_ascii_toupper (str[offset + 1]) != 'S'))
return -4;
1997-11-25 06:05:25 +08:00
return sum;
1997-11-25 06:05:25 +08:00
}
static gint
parse_disposal_tag (const gchar *str,
gint default_dispose)
1997-11-25 06:05:25 +08:00
{
gint offset = 0;
gint length;
length = strlen (str);
1997-11-25 06:05:25 +08:00
while ((offset + 9) <= length)
1997-11-25 06:05:25 +08:00
{
if (strncmp (&str[offset], "(combine)", 9) == 0)
return 0x01;
if (strncmp (&str[offset], "(replace)", 9) == 0)
return 0x02 ;
1997-11-25 06:05:25 +08:00
offset++;
}
return default_dispose;
1997-11-25 06:05:25 +08:00
}
static GimpPDBStatusType
2016-04-15 01:49:00 +08:00
sanity_check (GFile *file,
GimpImage **image,
GimpRunMode run_mode,
GError **error)
1997-11-25 06:05:25 +08:00
{
GList *layers;
GList *list;
gint image_width;
gint image_height;
1997-11-25 06:05:25 +08:00
image_width = gimp_image_get_width (*image);
image_height = gimp_image_get_height (*image);
1997-11-25 06:05:25 +08:00
if (image_width > G_MAXUSHORT || image_height > G_MAXUSHORT)
{
g_set_error (error, 0, 0,
_("Unable to export '%s'. "
"The GIF file format does not support images that are "
"more than %d pixels wide or tall."),
2016-04-15 01:49:00 +08:00
gimp_file_get_utf8_name (file), G_MAXUSHORT);
return GIMP_PDB_EXECUTION_ERROR;
}
1997-11-25 06:05:25 +08:00
/*** Iterate through the layers to make sure they're all ***/
/*** within the bounds of the image ***/
*image = gimp_image_duplicate (*image);
layers = gimp_image_list_layers (*image);
for (list = layers; list; list = g_list_next (list))
1997-11-25 06:05:25 +08:00
{
GimpDrawable *drawable = list->data;
gint offset_x;
gint offset_y;
gimp_drawable_get_offsets (drawable, &offset_x, &offset_y);
1997-11-25 06:05:25 +08:00
if (offset_x < 0 ||
offset_y < 0 ||
offset_x + gimp_drawable_get_width (drawable) > image_width ||
offset_y + gimp_drawable_get_height (drawable) > image_height)
{
g_list_free (layers);
/* Image has illegal bounds - ask the user what it wants to do */
/* Do the crop if we can't talk to the user, or if we asked
* the user and they said yes.
*/
if ((run_mode == GIMP_RUN_NONINTERACTIVE) || bad_bounds_dialog ())
{
gimp_image_crop (*image, image_width, image_height, 0, 0);
return GIMP_PDB_SUCCESS;
}
else
{
gimp_image_delete (*image);
return GIMP_PDB_CANCEL;
}
}
1997-11-25 06:05:25 +08:00
}
g_list_free (layers);
1997-11-25 06:05:25 +08:00
return GIMP_PDB_SUCCESS;
1997-11-25 06:05:25 +08:00
}
static gboolean
save_image (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GimpImage *orig_image,
GObject *config,
GError **error)
1997-11-25 06:05:25 +08:00
{
2012-09-23 05:19:32 +08:00
GeglBuffer *buffer;
GimpImageType drawable_type;
const Babl *format = NULL;
2016-04-15 01:49:00 +08:00
GOutputStream *output;
2012-09-23 05:19:32 +08:00
gint Red[MAXCOLORS];
gint Green[MAXCOLORS];
gint Blue[MAXCOLORS];
guchar *cmap;
guint rows, cols;
gint BitsPerPixel;
gint liberalBPP = 0;
gint useBPP = 0;
2012-09-23 05:19:32 +08:00
gint colors;
gint i;
gint transparent;
gint offset_x, offset_y;
GList *layers;
GList *list;
2012-09-23 05:19:32 +08:00
gint nlayers;
gboolean is_gif89 = FALSE;
gint Delay89;
gint Disposal;
gchar *layer_name;
GimpRGB background;
guchar bgred, bggreen, bgblue;
guchar bgindex = 0;
guint best_error = 0xFFFFFFFF;
gboolean config_interlace;
gboolean config_loop;
gint config_number_of_repeats;
gint config_default_delay;
gint config_default_dispose;
gboolean config_use_default_delay;
gboolean config_use_default_dispose;
gboolean config_as_animation;
gboolean config_save_comment;
gchar *config_comment;
g_object_get (config,
"interlace", &config_interlace,
"loop", &config_loop,
"number-of-repeats", &config_number_of_repeats,
"default-delay", &config_default_delay,
"default-dispose", &config_default_dispose,
"force-delay", &config_use_default_delay,
"force-dispose", &config_use_default_dispose,
"as-animation", &config_as_animation,
"save-comment", &config_save_comment,
"gimp-comment", &config_comment,
NULL);
/* The GIF spec says 7bit ASCII for the comment block. */
if (config_save_comment && config_comment && strlen (config_comment))
{
const gchar *c = config_comment;
gint len;
for (len = strlen (c); len; c++, len--)
{
if ((guchar) *c > 127)
{
plug-ins/FractalExplorer/Dialogs.c 2003-11-15 Michael Natterer <mitch@gimp.org> * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/bmp/bmpread.c * plug-ins/bmp/bmpwrite.c * plug-ins/common/CEL.c * plug-ins/common/CML_explorer.c * plug-ins/common/animoptimize.c * plug-ins/common/bz2.c * plug-ins/common/convmatrix.c * plug-ins/common/curve_bend.c * plug-ins/common/dicom.c * plug-ins/common/gauss_iir.c * plug-ins/common/gauss_rle.c * plug-ins/common/gbr.c * plug-ins/common/gif.c * plug-ins/common/gifload.c * plug-ins/common/gih.c * plug-ins/common/grid.c * plug-ins/common/gtm.c * plug-ins/common/gz.c * plug-ins/common/hrz.c * plug-ins/common/jpeg.c * plug-ins/common/mail.c * plug-ins/common/mapcolor.c * plug-ins/common/pat.c * plug-ins/common/pcx.c * plug-ins/common/pix.c * plug-ins/common/png.c * plug-ins/common/pnm.c * plug-ins/common/ps.c * plug-ins/common/psd.c * plug-ins/common/psd_save.c * plug-ins/common/psp.c * plug-ins/common/sel_gauss.c * plug-ins/common/spheredesigner.c * plug-ins/common/sunras.c * plug-ins/common/svg.c * plug-ins/common/tga.c * plug-ins/common/tiff.c * plug-ins/common/wmf.c * plug-ins/common/xbm.c * plug-ins/common/xwd.c * plug-ins/faxg3/faxg3.c * plug-ins/fits/fits.c * plug-ins/flame/flame.c * plug-ins/gfig/gfig.c * plug-ins/gflare/gflare.c * plug-ins/gfli/gfli.c * plug-ins/gimpressionist/brush.c * plug-ins/gimpressionist/ppmtool.c * plug-ins/helpbrowser/domain.c * plug-ins/ifscompose/ifscompose.c * plug-ins/sgi/sgi.c * plug-ins/twain/twain.c * plug-ins/winsnap/winsnap.c * plug-ins/xjt/xjt.c: removed explicit newlines from messages. Made file open/save messages the same all over the place. Reduced number of translatable strings by adding some more "standard" messages. Removed plug-in names from messages. Added some random mnemonics. Unmarked some strings for translation and added some that were forgotten. General message cleanup. Removed trailing whitespace.
2003-11-15 21:53:33 +08:00
g_message (_("The GIF format only supports comments in "
"7bit ASCII encoding. No comment is saved."));
g_free (config_comment);
config_comment = NULL;
config_save_comment = FALSE;
break;
}
}
}
else
{
config_save_comment = FALSE;
}
1997-11-25 06:05:25 +08:00
/* get a list of layers for this image */
layers = gimp_image_list_layers (image);
nlayers = g_list_length (layers);
1997-11-25 06:05:25 +08:00
drawable_type = gimp_drawable_type (layers->data);
1997-11-25 06:05:25 +08:00
/* If the image has multiple layers (i.e. will be animated), a
* comment, or transparency, then it must be encoded as a GIF89a
* file, not a vanilla GIF87a.
*/
if (nlayers > 1)
{
is_gif89 = TRUE;
/* Layers can be with or without alpha channel. Make sure we set
* alpha if there is at least one layer with alpha channel. */
if (drawable_type == GIMP_GRAY_IMAGE ||
drawable_type == GIMP_INDEXED_IMAGE)
{
for (list = layers; list; list = g_list_next (list))
{
GimpImageType dr_type = gimp_drawable_type (list->data);
if (dr_type == GIMP_GRAYA_IMAGE ||
dr_type == GIMP_INDEXEDA_IMAGE)
{
drawable_type = dr_type;
break;
}
}
}
}
if (config_save_comment)
1997-11-25 06:05:25 +08:00
is_gif89 = TRUE;
switch (drawable_type)
{
case GIMP_INDEXEDA_IMAGE:
1997-11-25 06:05:25 +08:00
is_gif89 = TRUE;
case GIMP_INDEXED_IMAGE:
cmap = gimp_image_get_colormap (image, NULL, &colors);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
tools/pdbgen/Makefile.am tools/pdbgen/groups.pl removed the "Palette" pdb 2004-09-22 Michael Natterer <mitch@gimp.org> * tools/pdbgen/Makefile.am * tools/pdbgen/groups.pl * tools/pdbgen/pdb/palette.pdb: removed the "Palette" pdb group... * tools/pdbgen/pdb/context.pdb: and added its functions to the "Context" namespace instead. * app/pdb/Makefile.am * app/pdb/palette_cmds.c: removed. * app/pdb/procedural_db.c: added them to the pdb_compat hash table. * libgimp/Makefile.am * libgimp/gimppalette_pdb.[ch]: removed. * libgimp/gimppalette.[ch]: new files holding compat functions which call gimp_context_*() functions. * libgimp/gimp.h * libgimp/gimpui.c: changed accordingly. * app/pdb/context_cmds.c * app/pdb/internal_procs.c * libgimp/gimp_pdb.h * libgimp/gimpcontext_pdb.[ch]: regenerated. * plug-ins/MapObject/mapobject_image.c * plug-ins/MapObject/mapobject_preview.c * plug-ins/common/apply_lens.c * plug-ins/common/blinds.c * plug-ins/common/borderaverage.c * plug-ins/common/checkerboard.c * plug-ins/common/colortoalpha.c * plug-ins/common/cubism.c * plug-ins/common/exchange.c * plug-ins/common/film.c * plug-ins/common/gif.c * plug-ins/common/grid.c * plug-ins/common/mapcolor.c * plug-ins/common/mblur.c * plug-ins/common/mng.c * plug-ins/common/mosaic.c * plug-ins/common/papertile.c * plug-ins/common/png.c * plug-ins/common/polar.c * plug-ins/common/semiflatten.c * plug-ins/common/sinus.c * plug-ins/common/sparkle.c * plug-ins/common/vpropagate.c * plug-ins/common/warp.c * plug-ins/common/whirlpinch.c * plug-ins/gfig/gfig-style.c * plug-ins/gfli/gfli.c * plug-ins/ifscompose/ifscompose.c * plug-ins/maze/handy.c * plug-ins/pagecurl/pagecurl.c * plug-ins/pygimp/gimpmodule.c * plug-ins/script-fu/scripts/*.scm: changed accordingly.
2004-09-23 02:43:09 +08:00
gimp_context_get_background (&background);
gimp_rgb_get_uchar (&background, &bgred, &bggreen, &bgblue);
1997-11-25 06:05:25 +08:00
for (i = 0; i < colors; i++)
{
Red[i] = *cmap++;
Green[i] = *cmap++;
Blue[i] = *cmap++;
}
1997-11-25 06:05:25 +08:00
for ( ; i < 256; i++)
{
Red[i] = bgred;
Green[i] = bggreen;
Blue[i] = bgblue;
}
1997-11-25 06:05:25 +08:00
break;
case GIMP_GRAYA_IMAGE:
1997-11-25 06:05:25 +08:00
is_gif89 = TRUE;
case GIMP_GRAY_IMAGE:
colors = 256; /* FIXME: Not ideal. */
1997-11-25 06:05:25 +08:00
for ( i = 0; i < 256; i++)
{
Red[i] = Green[i] = Blue[i] = i;
}
1997-11-25 06:05:25 +08:00
break;
default:
g_message (_("Cannot export RGB color images. Convert to "
plug-ins/FractalExplorer/Dialogs.c 2003-11-15 Michael Natterer <mitch@gimp.org> * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/bmp/bmpread.c * plug-ins/bmp/bmpwrite.c * plug-ins/common/CEL.c * plug-ins/common/CML_explorer.c * plug-ins/common/animoptimize.c * plug-ins/common/bz2.c * plug-ins/common/convmatrix.c * plug-ins/common/curve_bend.c * plug-ins/common/dicom.c * plug-ins/common/gauss_iir.c * plug-ins/common/gauss_rle.c * plug-ins/common/gbr.c * plug-ins/common/gif.c * plug-ins/common/gifload.c * plug-ins/common/gih.c * plug-ins/common/grid.c * plug-ins/common/gtm.c * plug-ins/common/gz.c * plug-ins/common/hrz.c * plug-ins/common/jpeg.c * plug-ins/common/mail.c * plug-ins/common/mapcolor.c * plug-ins/common/pat.c * plug-ins/common/pcx.c * plug-ins/common/pix.c * plug-ins/common/png.c * plug-ins/common/pnm.c * plug-ins/common/ps.c * plug-ins/common/psd.c * plug-ins/common/psd_save.c * plug-ins/common/psp.c * plug-ins/common/sel_gauss.c * plug-ins/common/spheredesigner.c * plug-ins/common/sunras.c * plug-ins/common/svg.c * plug-ins/common/tga.c * plug-ins/common/tiff.c * plug-ins/common/wmf.c * plug-ins/common/xbm.c * plug-ins/common/xwd.c * plug-ins/faxg3/faxg3.c * plug-ins/fits/fits.c * plug-ins/flame/flame.c * plug-ins/gfig/gfig.c * plug-ins/gflare/gflare.c * plug-ins/gfli/gfli.c * plug-ins/gimpressionist/brush.c * plug-ins/gimpressionist/ppmtool.c * plug-ins/helpbrowser/domain.c * plug-ins/ifscompose/ifscompose.c * plug-ins/sgi/sgi.c * plug-ins/twain/twain.c * plug-ins/winsnap/winsnap.c * plug-ins/xjt/xjt.c: removed explicit newlines from messages. Made file open/save messages the same all over the place. Reduced number of translatable strings by adding some more "standard" messages. Removed plug-in names from messages. Added some random mnemonics. Unmarked some strings for translation and added some that were forgotten. General message cleanup. Removed trailing whitespace.
2003-11-15 21:53:33 +08:00
"indexed color or grayscale first."));
1997-11-25 06:05:25 +08:00
return FALSE;
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
/* find earliest index in palette which is closest to the background
* color, and ATTEMPT to use that as the GIF's default background
* color.
*/
for (i = 255; i >= 0; --i)
{
guint local_error = 0;
local_error += (Red[i] - bgred) * (Red[i] - bgred);
local_error += (Green[i] - bggreen) * (Green[i] - bggreen);
local_error += (Blue[i] - bgblue) * (Blue[i] - bgblue);
if (local_error <= best_error)
{
bgindex = i;
best_error = local_error;
}
}
1997-11-25 06:05:25 +08:00
/* init the progress meter */
gimp_progress_init_printf (_("Exporting '%s'"),
2016-04-15 01:49:00 +08:00
gimp_file_get_utf8_name (file));
1997-11-25 06:05:25 +08:00
/* open the destination file for writing */
2016-04-15 01:49:00 +08:00
output = G_OUTPUT_STREAM (g_file_replace (file,
NULL, FALSE, G_FILE_CREATE_NONE,
NULL, error));
if (output)
{
GDataOutputStream *data_output;
data_output = g_data_output_stream_new (output);
g_object_unref (output);
g_data_output_stream_set_byte_order (data_output,
G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
output = G_OUTPUT_STREAM (data_output);
}
else
1997-11-25 06:05:25 +08:00
{
return FALSE;
}
/* write the GIFheader */
if (colors < 256)
{
/* we keep track of how many bits we promised to have in
* liberalBPP, so that we don't accidentally come under this
* when doing clever transparency stuff where we can re-use
* wasted indices.
*/
liberalBPP = BitsPerPixel =
colors_to_bpp (colors + ((drawable_type==GIMP_INDEXEDA_IMAGE) ? 1 : 0));
}
1997-11-25 06:05:25 +08:00
else
{
liberalBPP = BitsPerPixel =
colors_to_bpp (256);
if (drawable_type == GIMP_INDEXEDA_IMAGE)
{
g_printerr ("GIF: Too many colors?\n");
}
}
1997-11-25 06:05:25 +08:00
cols = gimp_image_get_width (image);
rows = gimp_image_get_height (image);
Interlace = config_interlace;
2016-04-15 01:49:00 +08:00
if (! gif_encode_header (output, is_gif89, cols, rows, bgindex,
BitsPerPixel, Red, Green, Blue, get_pixel,
error))
return FALSE;
1997-11-25 06:05:25 +08:00
/* If the image has multiple layers it'll be made into an animated
* GIF, so write out the looping extension
*/
if (nlayers > 1)
{
/* If 'Forever' toggle was checked, override number_of_repeats */
if (config_loop)
config_number_of_repeats = 0;
if (config_loop || config_number_of_repeats > 0)
if (! gif_encode_loop_ext (output, config_number_of_repeats, error))
return FALSE;
}
1997-11-25 06:05:25 +08:00
/* Write comment extension - mustn't be written before the looping ext. */
if (config_save_comment && config_comment && strlen (config_comment))
1997-11-25 06:05:25 +08:00
{
if (! gif_encode_comment_ext (output, config_comment, error))
2016-04-15 01:49:00 +08:00
return FALSE;
1997-11-25 06:05:25 +08:00
}
/*** Now for each layer in the image, save an image in a compound GIF ***/
/************************************************************************/
cur_progress = 0;
max_progress = nlayers * rows;
1997-11-25 06:05:25 +08:00
layers = g_list_reverse (layers);
for (list = layers, i = nlayers - 1;
list && i >= 0;
list = g_list_next (list), i--, cur_progress = (nlayers - i) * rows)
1997-11-25 06:05:25 +08:00
{
GimpDrawable *drawable = list->data;
drawable_type = gimp_drawable_type (drawable);
if (drawable_type == GIMP_GRAYA_IMAGE)
{
format = babl_format ("Y'A u8");
}
else if (drawable_type == GIMP_GRAY_IMAGE)
{
format = babl_format ("Y' u8");
}
buffer = gimp_drawable_get_buffer (drawable);
gimp_drawable_get_offsets (drawable, &offset_x, &offset_y);
cols = gimp_drawable_get_width (drawable);
rows = gimp_drawable_get_height (drawable);
2012-09-23 05:19:32 +08:00
rowstride = cols;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
2012-09-23 05:19:32 +08:00
pixels = g_new (guchar, (cols * rows *
(((drawable_type == GIMP_INDEXEDA_IMAGE) ||
(drawable_type == GIMP_GRAYA_IMAGE)) ? 2 : 1)));
1997-11-25 06:05:25 +08:00
2012-09-23 05:19:32 +08:00
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, cols, rows), 1.0,
format, pixels,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
1997-11-25 06:05:25 +08:00
/* sort out whether we need to do transparency jiggery-pokery */
2012-09-23 05:19:32 +08:00
if ((drawable_type == GIMP_INDEXEDA_IMAGE) ||
(drawable_type == GIMP_GRAYA_IMAGE))
{
/* Try to find an entry which isn't actually used in the
* image, for a transparency index.
*/
transparent =
find_unused_ia_color (pixels,
2012-09-23 05:19:32 +08:00
cols * rows,
bpp_to_colors (colors_to_bpp (colors)),
&colors);
special_flatten_indexed_alpha (pixels,
transparent,
2012-09-23 05:19:32 +08:00
cols * rows);
}
1997-11-25 06:05:25 +08:00
else
{
transparent = -1;
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
BitsPerPixel = colors_to_bpp (colors);
1997-11-25 06:05:25 +08:00
if (BitsPerPixel != liberalBPP)
{
/* We were able to re-use an index within the existing
* bitspace, whereas the estimate in the header was
* pessimistic but still needs to be upheld...
*/
#ifdef GIFDEBUG
static gboolean onceonly = FALSE;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
if (! onceonly)
{
g_warning ("Promised %d bpp, pondered writing chunk with %d bpp!",
liberalBPP, BitsPerPixel);
onceonly = TRUE;
}
#endif
}
useBPP = (BitsPerPixel > liberalBPP) ? BitsPerPixel : liberalBPP;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
1997-11-25 06:05:25 +08:00
if (is_gif89)
{
if (i > 0 && ! config_use_default_dispose)
{
layer_name = gimp_item_get_name (list->next->data);
Disposal = parse_disposal_tag (layer_name,
config_default_dispose);
g_free (layer_name);
}
else
{
Disposal = config_default_dispose;
}
layer_name = gimp_item_get_name (GIMP_ITEM (drawable));
Delay89 = parse_ms_tag (layer_name);
g_free (layer_name);
if (Delay89 < 0 || config_use_default_delay)
Delay89 = (config_default_delay + 5) / 10;
else
Delay89 = (Delay89 + 5) / 10;
/* don't allow a CPU-sucking completely 0-delay looping anim */
if ((nlayers > 1) && config_loop && (Delay89 == 0))
{
static gboolean onceonly = FALSE;
if (! onceonly)
{
g_message (_("Delay inserted to prevent evil "
"CPU-sucking animation."));
onceonly = TRUE;
}
Delay89 = 1;
}
2016-04-15 01:49:00 +08:00
if (! gif_encode_graphic_control_ext (output,
Disposal, Delay89, nlayers,
cols, rows,
transparent,
useBPP,
get_pixel,
error))
return FALSE;
}
2016-04-15 01:49:00 +08:00
if (! gif_encode_image_data (output, cols, rows,
(rows > 4) ? config_interlace : 0,
2016-04-15 01:49:00 +08:00
useBPP,
get_pixel,
offset_x, offset_y,
error))
return FALSE;
gimp_progress_update (1.0);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
2012-09-23 05:19:32 +08:00
g_object_unref (buffer);
1997-11-25 06:05:25 +08:00
g_free (pixels);
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
g_list_free (layers);
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
if (! gif_encode_close (output, error))
return FALSE;
1997-11-25 06:05:25 +08:00
return TRUE;
}
static gboolean
bad_bounds_dialog (void)
1997-11-25 06:05:25 +08:00
{
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
GtkWidget *dialog;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gboolean crop;
1997-11-25 06:05:25 +08:00
dialog = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
_("The image you are trying to export as a "
"GIF contains layers which extend beyond "
"the actual borders of the image."));
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("Cr_op"), GTK_RESPONSE_OK,
NULL);
1997-11-25 06:05:25 +08:00
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
gimp_window_set_transient (GTK_WINDOW (dialog));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("The GIF file format does not "
"allow this. You may choose "
"whether to crop all of the "
"layers to the image borders, "
"or cancel this export."));
1997-11-25 06:05:25 +08:00
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
gtk_widget_show (dialog);
1997-11-25 06:05:25 +08:00
crop = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
gtk_widget_destroy (dialog);
1997-11-25 06:05:25 +08:00
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
return crop;
1997-11-25 06:05:25 +08:00
}
static gboolean
save_dialog (GimpImage *image,
GimpProcedure *procedure,
GObject *config)
1997-11-25 06:05:25 +08:00
{
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *text_view;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
GtkTextBuffer *text_buffer;
gint32 n_layers;
gboolean animation_supported;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gboolean run;
1997-11-25 06:05:25 +08:00
g_free (gimp_image_get_layers (image, &n_layers));
animation_supported = n_layers > 1;
dialog = gimp_save_procedure_dialog_new (GIMP_SAVE_PROCEDURE (procedure),
GIMP_PROCEDURE_CONFIG (config),
image);
configure.in po-plug-ins/POTFILES.in plug-ins/common/Makefile.am 2000-01-25 Michael Natterer <mitch@gimp.org> * configure.in * po-plug-ins/POTFILES.in * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl * plug-ins/megawidget/*: removed. (There were only 3 functions left which were used by ~5 plugins, so I moved the resp. functions to the plugins). More preview stuff to come... * app/airbrush_blob.c * modules/colorsel_triangle.c * modules/colorsel_water.c: use G_PI instead of M_PI. * app/procedural_db.h * libgimp/gimpenums.h * plug-ins/script-fu/script-fu-constants.c * tools/pdbgen/enums.pl: new PDB return value STATUS_CANCEL which indicates that "Cancel" was pressed in a plugin dialog. (Useful only for file load/save plugins). * app/fileops.[ch] * app/menus.c: changes to handle STATUS_CANCEL correctly. Did some code cleanup in fileops.[ch]. Pop up a warning if File->Save failed. * app/plug_in.c: return_val[0] is of type PDB_STATUS, not PDB_INT32. * libgimp/gimpmath.h: new constant G_MAXRAND which equals to RAND_MAX if it exists or to G_MAXINT otherwise. * libgimp/gimpwidgets.[ch]: new function gimp_random_seed_new() which creates a spinbutton and a "Time" toggle. Call the function which does the "set_sensitive" magic from the radio button callback. * plug-ins/[75 plugins]: - Return STATUS_CANCEL in all file load/save dialogs if "Cancel" was pressed. - Standardized the file plugins' "run" functions. - Use G_PI and G_MAXRAND everywhere. - Added tons of scales and spinbuttons instead of text entries. - Applied uniform packing/spacings all over the place. - Reorganized some UIs (stuff like moving the preview to the top left corner of the dialog). - Removed many ui helper functions and callbacks and use the stuff from libgimp instead. - I tried not to restrict the range of possible values when I replaced entries with spinbuttons/scales but may have failed, though in some cases. Please test ;-) - #include <libgimp/gimpmath.h> where appropriate and use it's constants. - Indentation, s/int/gint/ et.al., code cleanup. RFC: The plugins are definitely not useable with GIMP 1.0 any more, so shouldn't we remove all the remaining compatibility stuff ??? (like "#ifdef GIMP_HAVE_PARASITES")
2000-01-26 01:46:56 +08:00
#define MAX_COMMENT 240
text_view = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
"gimp-comment",
GTK_TYPE_TEXT_VIEW);
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
g_object_set_data (G_OBJECT (text_buffer), "max-len",
GINT_TO_POINTER (MAX_COMMENT));
gimp_procedure_dialog_fill_scrolled_window (GIMP_PROCEDURE_DIALOG (dialog),
"comment-scrolled",
"gimp-comment");
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
"comment-frame", "save-comment", FALSE,
"comment-scrolled");
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
"interlace", "comment-frame", NULL);
if (animation_supported)
{
GtkWidget *grid;
GtkWidget *widget;
GtkListStore *store;
grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (grid), 1);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_widget_show (grid);
widget = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
"number-of-repeats",
GIMP_TYPE_LABEL_SPIN);
gtk_grid_attach (GTK_GRID (grid), widget, 0, 0, 1, 1);
gtk_widget_set_visible (widget, TRUE);
widget = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
"loop", GTK_TYPE_CHECK_BUTTON);
gtk_grid_attach (GTK_GRID (grid), widget, 1, 0, 1, 1);
gimp_procedure_dialog_set_sensitive (GIMP_PROCEDURE_DIALOG (dialog),
"number-of-repeats", TRUE,
config, "loop",
TRUE);
widget = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
"default-delay",
GIMP_TYPE_LABEL_SPIN);
gtk_grid_attach (GTK_GRID (grid), widget, 0, 1, 1, 1);
gtk_widget_set_visible (widget, TRUE);
widget = gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
"milliseconds",
_("milliseconds"),
FALSE, FALSE);
gtk_label_set_xalign (GTK_LABEL (widget), 0.1);
gtk_grid_attach (GTK_GRID (grid), widget, 1, 1, 1, 1);
gtk_widget_set_visible (widget, TRUE);
store = gimp_int_store_new (_("I don't care"),
DISPOSE_UNSPECIFIED,
_("Cumulative layers (combine)"),
DISPOSE_COMBINE,
_("One frame per layer (replace)"),
DISPOSE_REPLACE,
NULL);
widget = gimp_procedure_dialog_get_int_combo (GIMP_PROCEDURE_DIALOG (dialog),
"default-dispose",
GIMP_INT_STORE (store));
gtk_grid_attach (GTK_GRID (grid), widget, 0, 2, 2, 1);
gtk_widget_set_visible (widget, TRUE);
vbox = gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"animation-vbox", "force-delay",
"force-dispose", NULL);
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
gtk_box_reorder_child (GTK_BOX (vbox), grid, 0);
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
"ani-frame", "as-animation", FALSE,
"animation-vbox");
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
"ani-frame", NULL);
}
configure.in po-plug-ins/POTFILES.in plug-ins/common/Makefile.am 2000-01-25 Michael Natterer <mitch@gimp.org> * configure.in * po-plug-ins/POTFILES.in * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl * plug-ins/megawidget/*: removed. (There were only 3 functions left which were used by ~5 plugins, so I moved the resp. functions to the plugins). More preview stuff to come... * app/airbrush_blob.c * modules/colorsel_triangle.c * modules/colorsel_water.c: use G_PI instead of M_PI. * app/procedural_db.h * libgimp/gimpenums.h * plug-ins/script-fu/script-fu-constants.c * tools/pdbgen/enums.pl: new PDB return value STATUS_CANCEL which indicates that "Cancel" was pressed in a plugin dialog. (Useful only for file load/save plugins). * app/fileops.[ch] * app/menus.c: changes to handle STATUS_CANCEL correctly. Did some code cleanup in fileops.[ch]. Pop up a warning if File->Save failed. * app/plug_in.c: return_val[0] is of type PDB_STATUS, not PDB_INT32. * libgimp/gimpmath.h: new constant G_MAXRAND which equals to RAND_MAX if it exists or to G_MAXINT otherwise. * libgimp/gimpwidgets.[ch]: new function gimp_random_seed_new() which creates a spinbutton and a "Time" toggle. Call the function which does the "set_sensitive" magic from the radio button callback. * plug-ins/[75 plugins]: - Return STATUS_CANCEL in all file load/save dialogs if "Cancel" was pressed. - Standardized the file plugins' "run" functions. - Use G_PI and G_MAXRAND everywhere. - Added tons of scales and spinbuttons instead of text entries. - Applied uniform packing/spacings all over the place. - Reorganized some UIs (stuff like moving the preview to the top left corner of the dialog). - Removed many ui helper functions and callbacks and use the stuff from libgimp instead. - I tried not to restrict the range of possible values when I replaced entries with spinbuttons/scales but may have failed, though in some cases. Please test ;-) - #include <libgimp/gimpmath.h> where appropriate and use it's constants. - Indentation, s/int/gint/ et.al., code cleanup. RFC: The plugins are definitely not useable with GIMP 1.0 any more, so shouldn't we remove all the remaining compatibility stuff ??? (like "#ifdef GIMP_HAVE_PARASITES")
2000-01-26 01:46:56 +08:00
else
{
GtkWidget *hint;
/* Used to create vbox to store hintbox in */
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
"spacer", " ",
FALSE, FALSE);
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
"no-ani-title", _("Animated GIF"),
FALSE, FALSE);
vbox = gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"no-animation-vbox", "spacer",
NULL);
hint = gimp_hint_box_new (_("You can only export as animation when the "
"image has more than one layer.\n"
"The image you are trying to export only "
"has one layer."));
gtk_box_pack_start (GTK_BOX (vbox), hint, FALSE, FALSE, 0);
gtk_widget_set_margin_bottom (vbox, 12);
gtk_widget_show (hint);
gtk_box_reorder_child (GTK_BOX (vbox), hint, 0);
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
"no-ani-frame", "no-ani-title", FALSE,
"no-animation-vbox");
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
"no-ani-frame", NULL);
}
1997-11-25 06:05:25 +08:00
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
gtk_widget_show (dialog);
1997-11-25 06:05:25 +08:00
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
Added parent window API to the GimpProgress interface and to the libgimp 2005-09-09 Michael Natterer <mitch@gimp.org> Added parent window API to the GimpProgress interface and to the libgimp progress stuff. Might look strange, but does the right thing in almost all cases (image window, file dialog, script-fu dialog etc). Fixes bug #62988. * app/core/gimpprogress.[ch]: added GimpProgress::get_window() which should return a toplevel window ID if the progress is in a window that wants to be the transient parent of plug-in dialogs. * app/widgets/gimpwidgets-utils.[ch] (gimp_window_get_native): new function which returns the window handle of a GtkWindow's GdkWindow. * app/widgets/gimpfiledialog.c: implement ::get_window(). * app/display/gimpdisplay.[ch]: ditto. Removed window handle API. * app/gui/gui-vtable.c: changed accordingly. * libgimpbase/gimpbaseenums.[ch] (enum GimpProgressCommand): added GIMP_PROGRESS_COMMAND_GET_WINDOW. * app/plug-in/plug-in-progress.[ch] (plug_in_progress_get_window): new function. Also renamed some functions to match the GimpProgress interface, and not the legacy PDB procedure names. * tools/pdbgen/pdb/progress.pdb * app/core/gimppdbprogress.c: implement get_window() on both sides of the wire, keeping backward compatibility (hopefully). * libgimp/gimpprogress.[ch]: deprecated gimp_progress_install() and added gimp_progress_install_vtable() which takes a vtable with padding to be extensible. Added get_window() vtable entry and dispatch it accordingly. Also added pulse() which was implemented in a hackish way before. Everything is of course backward compatible. * libgimp/gimpprogressbar.c: inmplement the get_window() stuff so a plug-in dialog containing a progress can be the transient parent of another dialog in another plug-in. * libgimp/gimpui.[ch] (gimp_ui_get_progress_window): new function which returns a foreign GdkWindow of this plug-ins progress window. Renamed gimp_window_set_transient_for_default_display() to gimp_window_set_transient() and make it use the progress' window handle instead of the display's (which is the right thing to do in almost all cases). * libgimp/gimp.def * libgimp/gimpui.def: add the new functions. * tools/pdbgen/enums.pl * app/pdb/internal_procs.c * app/pdb/progress_cmds.c * libgimp/gimpprogress_pdb.[ch]: regenerated. * libgimp/gimpexport.c * plug-ins/*/*.c: follow API change.
2005-09-10 02:07:31 +08:00
gtk_widget_destroy (dialog);
1997-11-25 06:05:25 +08:00
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
return run;
1997-11-25 06:05:25 +08:00
}
static int
colors_to_bpp (gint colors)
1997-11-25 06:05:25 +08:00
{
gint bpp;
1997-11-25 06:05:25 +08:00
if (colors <= 2)
bpp = 1;
else if (colors <= 4)
bpp = 2;
else if (colors <= 8)
bpp = 3;
else if (colors <= 16)
bpp = 4;
else if (colors <= 32)
bpp = 5;
else if (colors <= 64)
bpp = 6;
else if (colors <= 128)
bpp = 7;
else if (colors <= 256)
bpp = 8;
else
{
g_warning ("GIF: colors_to_bpp - Eep! too many colors: %d\n", colors);
1997-11-25 06:05:25 +08:00
return 8;
}
return bpp;
}
static int
bpp_to_colors (gint bpp)
{
gint colors;
if (bpp > 8)
{
g_warning ("GIF: bpp_to_colors - Eep! bpp==%d !\n", bpp);
return 256;
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
colors = 1 << bpp;
return colors;
}
static gint
get_pixel (gint x,
gint y)
1997-11-25 06:05:25 +08:00
{
return *(pixels + (rowstride * (long) y) + (long) x);
}
/*****************************************************************************
*
* GIFENCODE.C - GIF Image compression interface
*
* GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
* BitsPerPixel, Red, Green, Blue, get_pixel )
1997-11-25 06:05:25 +08:00
*
*****************************************************************************/
configure.in po-plug-ins/POTFILES.in plug-ins/common/Makefile.am 2000-01-25 Michael Natterer <mitch@gimp.org> * configure.in * po-plug-ins/POTFILES.in * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl * plug-ins/megawidget/*: removed. (There were only 3 functions left which were used by ~5 plugins, so I moved the resp. functions to the plugins). More preview stuff to come... * app/airbrush_blob.c * modules/colorsel_triangle.c * modules/colorsel_water.c: use G_PI instead of M_PI. * app/procedural_db.h * libgimp/gimpenums.h * plug-ins/script-fu/script-fu-constants.c * tools/pdbgen/enums.pl: new PDB return value STATUS_CANCEL which indicates that "Cancel" was pressed in a plugin dialog. (Useful only for file load/save plugins). * app/fileops.[ch] * app/menus.c: changes to handle STATUS_CANCEL correctly. Did some code cleanup in fileops.[ch]. Pop up a warning if File->Save failed. * app/plug_in.c: return_val[0] is of type PDB_STATUS, not PDB_INT32. * libgimp/gimpmath.h: new constant G_MAXRAND which equals to RAND_MAX if it exists or to G_MAXINT otherwise. * libgimp/gimpwidgets.[ch]: new function gimp_random_seed_new() which creates a spinbutton and a "Time" toggle. Call the function which does the "set_sensitive" magic from the radio button callback. * plug-ins/[75 plugins]: - Return STATUS_CANCEL in all file load/save dialogs if "Cancel" was pressed. - Standardized the file plugins' "run" functions. - Use G_PI and G_MAXRAND everywhere. - Added tons of scales and spinbuttons instead of text entries. - Applied uniform packing/spacings all over the place. - Reorganized some UIs (stuff like moving the preview to the top left corner of the dialog). - Removed many ui helper functions and callbacks and use the stuff from libgimp instead. - I tried not to restrict the range of possible values when I replaced entries with spinbuttons/scales but may have failed, though in some cases. Please test ;-) - #include <libgimp/gimpmath.h> where appropriate and use it's constants. - Indentation, s/int/gint/ et.al., code cleanup. RFC: The plugins are definitely not useable with GIMP 1.0 any more, so shouldn't we remove all the remaining compatibility stuff ??? (like "#ifdef GIMP_HAVE_PARASITES")
2000-01-26 01:46:56 +08:00
static gint Width, Height;
static gint curx, cury;
static glong CountDown;
static gint Pass = 0;
1997-11-25 06:05:25 +08:00
/*
* Bump the 'curx' and 'cury' to point to the next pixel
*/
static void
bump_pixel (void)
1997-11-25 06:05:25 +08:00
{
/*
* Bump the current X position
*/
curx++;
1997-11-25 06:05:25 +08:00
/*
* If we are at the end of a scan line, set curx back to the beginning
* If we are interlaced, bump the cury to the appropriate spot,
* otherwise, just increment it.
*/
if (curx == Width)
{
Cleaned up and improved the message system: 2003-06-13 Michael Natterer <mitch@gimp.org> Cleaned up and improved the message system: * app/core/gimp.[ch]: added "const gchar *domain" to GimpMessageFunc (a NULL domain means the message is from the GIMP core, everything else is a plug-in). * app/errors.c: pass "domain == NULL" to gimp_message(). * tools/pdbgen/pdb/message.pdb: derive the message domain from the current plug-in's menu_path (evil hack but works reasonably well). * app/pdb/message_cmds.c: regenerated. * app/widgets/gimpwidgets-utils.[ch] (gimp_message_box): added a header showing the message domain and changed the dialog layout to follow the HIG more closely. * app/gui/error-console-dialog.[ch]: removed. * app/widgets/gimperrorconsole.[ch] * app/gui/error-console-commands.[ch] * app/gui/error-console-menu.[ch]: new files containing a re-implementation of the error console dialog. * app/gui/Makefile.am * app/gui/dialogs-constructors.c * app/gui/gui.c * app/gui/menus.c * app/widgets/Makefile.am * app/widgets/widgets-types.h: changed accordingly. * app/display/gimpprogress.c: added more spacing and removed the separator (more HIG compliant). * plug-ins/[most plug-ins].c: Changed lots of messages and progress strings: - Removed plug-in names from messages since that's automatically covered by "domain" now. - Put all filenames in ''. - Changed "Loading" to "Opening". - Added "..." to all progress messages. - Cleaned up all file open/save error messages to look the same and include g_strerror(errno). - Removed special casing for progress bars and *always* show them, not only if run_mode != GIMP_RUN_NONINTERACTIVE (we can't expect all plug-ins to do this correctly but need to hack the core to sort out unwanted progress bars). Unrelated: - Cleaned up indentation, spacing, #includes, coding style and other stuff while I was at all these files.
2003-06-13 22:37:00 +08:00
cur_progress++;
if ((cur_progress % 20) == 0)
gimp_progress_update ((gdouble) cur_progress / (gdouble) max_progress);
1997-11-25 06:05:25 +08:00
curx = 0;
if (! Interlace)
++cury;
1997-11-25 06:05:25 +08:00
else
{
switch (Pass)
{
case 0:
cury += 8;
if (cury >= Height)
{
Pass++;
cury = 4;
}
break;
case 1:
cury += 8;
if (cury >= Height)
{
Pass++;
cury = 2;
}
break;
case 2:
cury += 4;
if (cury >= Height)
{
Pass++;
cury = 1;
}
break;
case 3:
cury += 2;
break;
}
}
1997-11-25 06:05:25 +08:00
}
}
/*
* Return the next pixel from the image
*/
static gint
gif_next_pixel (ifunptr getpixel)
1997-11-25 06:05:25 +08:00
{
gint r;
1997-11-25 06:05:25 +08:00
if (CountDown == 0)
return EOF;
--CountDown;
r = (*getpixel) (curx, cury);
bump_pixel ();
1997-11-25 06:05:25 +08:00
return r;
}
/* public */
2016-04-15 01:49:00 +08:00
static gboolean
gif_encode_header (GOutputStream *output,
gboolean gif89,
gint GWidth,
gint GHeight,
gint Background,
gint BitsPerPixel,
gint Red[],
gint Green[],
gint Blue[],
ifunptr get_pixel,
GError **error)
1997-11-25 06:05:25 +08:00
{
gint B;
gint RWidth, RHeight;
gint Resolution;
gint ColorMapSize;
gint i;
1997-11-25 06:05:25 +08:00
ColorMapSize = 1 << BitsPerPixel;
RWidth = Width = GWidth;
RHeight = Height = GHeight;
Resolution = BitsPerPixel;
/*
* Calculate number of bits we are expecting
*/
CountDown = (long) Width *(long) Height;
/*
* Indicate which pass we are on (if interlace)
*/
Pass = 0;
/*
* Set up the current x and y position
*/
curx = cury = 0;
/*
* Write the Magic header
*/
2016-04-15 01:49:00 +08:00
if (! put_string (output, gif89 ? "GIF89a" : "GIF87a", error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Write out the screen width and height
*/
2016-04-15 01:49:00 +08:00
if (! put_word (output, RWidth, error) ||
! put_word (output, RHeight, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Indicate that there is a global color map
1997-11-25 06:05:25 +08:00
*/
B = 0x80; /* Yes, there is a color map */
1997-11-25 06:05:25 +08:00
/*
* OR in the resolution
*/
B |= (Resolution - 1) << 5;
/*
* OR in the Bits per Pixel
*/
B |= (BitsPerPixel - 1);
/*
* Write it out
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, B, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Write out the Background color
1997-11-25 06:05:25 +08:00
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, Background, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Byte of 0's (future expansion)
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, 0, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Write out the Global Color Map
1997-11-25 06:05:25 +08:00
*/
for (i = 0; i < ColorMapSize; i++)
1997-11-25 06:05:25 +08:00
{
2016-04-15 01:49:00 +08:00
if (! put_byte (output, Red[i], error) ||
! put_byte (output, Green[i], error) ||
! put_byte (output, Blue[i], error))
return FALSE;
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
return TRUE;
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
static gboolean
gif_encode_graphic_control_ext (GOutputStream *output,
int Disposal,
int Delay89,
int NumFramesInImage,
int GWidth,
int GHeight,
int Transparent,
int BitsPerPixel,
ifunptr get_pixel,
GError **error)
1997-11-25 06:05:25 +08:00
{
2011-10-03 15:19:06 +08:00
Width = GWidth;
Height = GHeight;
1997-11-25 06:05:25 +08:00
/*
* Calculate number of bits we are expecting
*/
CountDown = (long) Width *(long) Height;
/*
* Indicate which pass we are on (if interlace)
*/
Pass = 0;
/*
* Set up the current x and y position
*/
curx = cury = 0;
/*
* Write out extension for transparent color index, if necessary.
1997-11-25 06:05:25 +08:00
*/
if ( (Transparent >= 0) || (NumFramesInImage > 1) )
{
/* Extension Introducer - fixed. */
2016-04-15 01:49:00 +08:00
if (! put_byte (output, '!', error))
return FALSE;
1997-11-25 06:05:25 +08:00
/* Graphic Control Label - fixed. */
2016-04-15 01:49:00 +08:00
if (! put_byte (output, 0xf9, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/* Block Size - fixed. */
2016-04-15 01:49:00 +08:00
if (! put_byte (output, 4, error))
return FALSE;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
1997-11-25 06:05:25 +08:00
/* Packed Fields - XXXdddut (d=disposal, u=userInput, t=transFlag) */
/* s8421 */
2016-04-15 01:49:00 +08:00
if (! put_byte (output,
((Transparent >= 0) ? 0x01 : 0x00) /* TRANSPARENCY */
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
/* DISPOSAL */
| ((NumFramesInImage > 1) ? (Disposal << 2) : 0x00 ),
/* 0x03 or 0x01 build frames cumulatively */
/* 0x02 clears frame before drawing */
/* 0x00 'don't care' */
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
error))
return FALSE;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
2016-04-15 01:49:00 +08:00
if (! put_word (output, Delay89, error))
return FALSE;
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
if (! put_byte (output, Transparent, error) ||
! put_byte (output, 0, error))
return FALSE;
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
return TRUE;
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
static gboolean
gif_encode_image_data (GOutputStream *output,
int GWidth,
int GHeight,
int GInterlace,
int BitsPerPixel,
ifunptr get_pixel,
gint offset_x,
gint offset_y,
GError **error)
1997-11-25 06:05:25 +08:00
{
2016-04-15 01:49:00 +08:00
gint LeftOfs, TopOfs;
gint InitCodeSize;
1997-11-25 06:05:25 +08:00
Interlace = GInterlace;
2016-04-15 01:49:00 +08:00
Width = GWidth;
Height = GHeight;
LeftOfs = (gint) offset_x;
TopOfs = (gint) offset_y;
1997-11-25 06:05:25 +08:00
/*
* Calculate number of bits we are expecting
*/
CountDown = (long) Width * (long) Height;
1997-11-25 06:05:25 +08:00
/*
* Indicate which pass we are on (if interlace)
*/
Pass = 0;
/*
* The initial code size
*/
if (BitsPerPixel <= 1)
InitCodeSize = 2;
else
InitCodeSize = BitsPerPixel;
/*
* Set up the current x and y position
*/
curx = cury = 0;
/*
* Write an Image separator
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, ',', error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Write the Image header
*/
2016-04-15 01:49:00 +08:00
if (! put_word (output, LeftOfs, error) ||
! put_word (output, TopOfs, error) ||
! put_word (output, Width, error) ||
! put_word (output, Height, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Write out whether or not the image is interlaced
*/
if (Interlace)
2016-04-15 01:49:00 +08:00
{
if (! put_byte (output, 0x40, error))
return FALSE;
}
1997-11-25 06:05:25 +08:00
else
2016-04-15 01:49:00 +08:00
{
if (! put_byte (output, 0x00, error))
return FALSE;
}
1997-11-25 06:05:25 +08:00
/*
* Write out the initial code size
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, InitCodeSize, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Go and actually compress the data
*/
2016-04-15 01:49:00 +08:00
if (! compress (output, InitCodeSize + 1, get_pixel, error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* Write out a Zero-length packet (to end the series)
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, 0, error))
return FALSE;
1997-11-25 06:05:25 +08:00
#if 0
1997-11-25 06:05:25 +08:00
/***************************/
Interlace = GInterlace;
Width = GWidth;
Height = GHeight;
1997-11-25 06:05:25 +08:00
LeftOfs = TopOfs = 0;
CountDown = (long) Width *(long) Height;
Pass = 0;
/*
* The initial code size
*/
if (BitsPerPixel <= 1)
InitCodeSize = 2;
else
InitCodeSize = BitsPerPixel;
/*
* Set up the current x and y position
*/
curx = cury = 0;
#endif
2016-04-15 01:49:00 +08:00
return TRUE;
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
static gboolean
gif_encode_close (GOutputStream *output,
GError **error)
1997-11-25 06:05:25 +08:00
{
/*
* Write the GIF file terminator
*/
2016-04-15 01:49:00 +08:00
if (! put_byte (output, ';', error))
return FALSE;
1997-11-25 06:05:25 +08:00
/*
* And close the file
*/
2016-04-15 01:49:00 +08:00
return g_output_stream_close (output, NULL, error);
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
static gboolean
gif_encode_loop_ext (GOutputStream *output,
guint num_loops,
GError **error)
1997-11-25 06:05:25 +08:00
{
2016-04-15 01:49:00 +08:00
return (put_byte (output, 0x21, error) &&
put_byte (output, 0xff, error) &&
put_byte (output, 0x0b, error) &&
put_string (output, "NETSCAPE2.0", error) &&
put_byte (output, 0x03, error) &&
put_byte (output, 0x01, error) &&
put_word (output, num_loops, error) &&
put_byte (output, 0x00, error));
/* NOTE: num_loops == 0 means 'loop infinitely' */
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
static gboolean
gif_encode_comment_ext (GOutputStream *output,
const gchar *comment,
GError **error)
1997-11-25 06:05:25 +08:00
{
1999-11-20 10:20:04 +08:00
if (!comment || !*comment)
2016-04-15 01:49:00 +08:00
return TRUE;
1997-11-25 06:05:25 +08:00
if (strlen (comment) > 240)
{
g_printerr ("GIF: warning:"
"comment too large - comment block not written.\n");
2016-04-15 01:49:00 +08:00
return TRUE;
}
2016-04-15 01:49:00 +08:00
return (put_byte (output, 0x21, error) &&
put_byte (output, 0xfe, error) &&
put_byte (output, strlen (comment), error) &&
put_string (output, comment, error) &&
put_byte (output, 0x00, error));
1997-11-25 06:05:25 +08:00
}
/*
2016-04-15 01:49:00 +08:00
* Write stuff to the GIF file
1997-11-25 06:05:25 +08:00
*/
2016-04-15 01:49:00 +08:00
static gboolean
put_byte (GOutputStream *output,
guchar b,
GError **error)
{
return g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (output),
b, NULL, error);
}
static gboolean
put_word (GOutputStream *output,
gint w,
GError **error)
{
return g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (output),
w, NULL, error);
}
static gboolean
put_string (GOutputStream *output,
const gchar *s,
GError **error)
1997-11-25 06:05:25 +08:00
{
2016-04-15 01:49:00 +08:00
return g_data_output_stream_put_string (G_DATA_OUTPUT_STREAM (output),
s, NULL, error);
1997-11-25 06:05:25 +08:00
}
/***************************************************************************
*
* GIFCOMPR.C - GIF Image compression routines
*
* Lempel-Ziv compression based on 'compress'. GIF modifications by
* David Rowley (mgardi@watdcsu.waterloo.edu)
*
***************************************************************************/
/*
* General DEFINEs
*/
2016-04-15 01:49:00 +08:00
#define GIF_BITS 12
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
#define HSIZE 5003 /* 80% occupancy */
1997-11-25 06:05:25 +08:00
/*
* GIF Image compression - modified 'compress'
*
* Based on: compress.c - File compression ala IEEE Computer, June 1984.
*
* By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
* Jim McKie (decvax!mcvax!jim)
* Steve Davies (decvax!vax135!petsd!peora!srd)
* Ken Turkowski (decvax!decwrl!turtlevax!ken)
* James A. Woods (decvax!ihnp4!ames!jaw)
* Joe Orost (decvax!vax135!petsd!joe)
*
*/
2016-04-15 01:49:00 +08:00
static gint n_bits; /* number of bits/code */
static gint maxbits = GIF_BITS; /* user settable max # bits/code */
static gint maxcode; /* maximum code, given n_bits */
static gint maxmaxcode = (gint) 1 << GIF_BITS; /* should NEVER generate this code */
#ifdef COMPATIBLE /* But wrong! */
#define MAXCODE(Mn_bits) ((gint) 1 << (Mn_bits) - 1)
1997-11-25 06:05:25 +08:00
#else /*COMPATIBLE */
#define MAXCODE(Mn_bits) (((gint) 1 << (Mn_bits)) - 1)
1997-11-25 06:05:25 +08:00
#endif /*COMPATIBLE */
2016-04-15 01:49:00 +08:00
static glong htab[HSIZE];
static gushort codetab[HSIZE];
1997-11-25 06:05:25 +08:00
#define HashTabOf(i) htab[i]
#define CodeTabOf(i) codetab[i]
static const gint hsize = HSIZE; /* the original reason for this being
variable was "for dynamic table sizing",
but since it was never actually changed
I made it const --Adam. */
1997-11-25 06:05:25 +08:00
static gint free_ent = 0; /* first unused entry */
1997-11-25 06:05:25 +08:00
/*
* block compression parameters -- after all codes are used up,
* and compression rate changes, start over.
*/
2016-04-15 01:49:00 +08:00
static gint clear_flg = 0;
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
static gint offset;
static glong in_count = 1; /* length of input */
static glong out_count = 0; /* # of codes output (for debugging) */
1997-11-25 06:05:25 +08:00
/*
* compress stdin to stdout
*
* Algorithm: use open addressing double hashing (no chaining) on the
* prefix code / next character combination. We do a variant of Knuth's
* algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
* secondary probe. Here, the modular division first probe is gives way
* to a faster exclusive-or manipulation. Also do block compression with
* an adaptive reset, whereby the code table is cleared when the compression
* ratio decreases, but after the table fills. The variable-length output
* codes are re-sized at this point, and a special CLEAR code is generated
* for the decompressor. Late addition: construct the table according to
* file size for noticeable speed improvement on small files. Please direct
* questions about this implementation to ames!jaw.
*/
2016-04-15 01:49:00 +08:00
static gint g_init_bits;
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
static gint ClearCode;
static gint EOFCode;
1997-11-25 06:05:25 +08:00
static gulong cur_accum;
static gint cur_bits;
1997-11-25 06:05:25 +08:00
static gulong masks[] =
{
0x0000, 0x0001, 0x0003, 0x0007,
0x000F, 0x001F, 0x003F, 0x007F,
0x00FF, 0x01FF, 0x03FF, 0x07FF,
0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
0xFFFF
};
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
static gboolean
compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error)
{
if (FALSE)
2016-04-15 01:49:00 +08:00
return no_compress (output, init_bits, ReadValue, error);
else if (FALSE)
2016-04-15 01:49:00 +08:00
return rle_compress (output, init_bits, ReadValue, error);
else
2016-04-15 01:49:00 +08:00
return normal_compress (output, init_bits, ReadValue, error);
}
2016-04-15 01:49:00 +08:00
static gboolean
no_compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error)
{
glong fcode;
gint i /* = 0 */ ;
gint c;
gint ent;
gint hsize_reg;
gint hshift;
/*
* Set up the globals: g_init_bits - initial number of bits
*/
g_init_bits = init_bits;
cur_bits = 0;
cur_accum = 0;
/*
* Set up the necessary values
*/
offset = 0;
out_count = 0;
clear_flg = 0;
in_count = 1;
ClearCode = (1 << (init_bits - 1));
EOFCode = ClearCode + 1;
free_ent = ClearCode + 2;
/* Had some problems here... should be okay now. --Adam */
n_bits = g_init_bits;
maxcode = MAXCODE (n_bits);
2016-04-15 01:49:00 +08:00
char_init();
ent = gif_next_pixel (ReadValue);
hshift = 0;
for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
++hshift;
hshift = 8 - hshift; /* set hash code range bound */
hsize_reg = hsize;
cl_hash ((glong) hsize_reg); /* clear hash table */
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ClearCode, error))
return FALSE;
while ((c = gif_next_pixel (ReadValue)) != EOF)
{
++in_count;
fcode = (long) (((long) c << maxbits) + ent);
i = (((gint) c << hshift) ^ ent); /* xor hashing */
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ent, error))
return FALSE;
++out_count;
ent = c;
if (free_ent < maxmaxcode)
{
CodeTabOf (i) = free_ent++; /* code -> hashtable */
HashTabOf (i) = fcode;
}
else
2016-04-15 01:49:00 +08:00
{
if (! cl_block (output, error))
return FALSE;
}
}
/*
* Put out the final code.
*/
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ent, error))
return FALSE;
++out_count;
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) EOFCode, error))
return FALSE;
return TRUE;
}
2016-04-15 01:49:00 +08:00
static gboolean
rle_compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error)
{
2016-04-15 01:49:00 +08:00
glong fcode;
gint i /* = 0 */ ;
gint c, last;
gint ent;
gint disp;
gint hsize_reg;
gint hshift;
/*
* Set up the globals: g_init_bits - initial number of bits
*/
g_init_bits = init_bits;
cur_bits = 0;
cur_accum = 0;
/*
* Set up the necessary values
*/
offset = 0;
out_count = 0;
clear_flg = 0;
in_count = 1;
ClearCode = (1 << (init_bits - 1));
EOFCode = ClearCode + 1;
free_ent = ClearCode + 2;
/* Had some problems here... should be okay now. --Adam */
n_bits = g_init_bits;
maxcode = MAXCODE (n_bits);
char_init ();
last = ent = gif_next_pixel (ReadValue);
hshift = 0;
for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
++hshift;
hshift = 8 - hshift; /* set hash code range bound */
hsize_reg = hsize;
cl_hash ((glong) hsize_reg); /* clear hash table */
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ClearCode, error))
return FALSE;
while ((c = gif_next_pixel (ReadValue)) != EOF)
{
++in_count;
fcode = (long) (((long) c << maxbits) + ent);
i = (((gint) c << hshift) ^ ent); /* xor hashing */
if (last == c) {
if (HashTabOf (i) == fcode)
{
ent = CodeTabOf (i);
continue;
}
else if ((long) HashTabOf (i) < 0) /* empty slot */
goto nomatch;
disp = hsize_reg - i; /* secondary hash (after G. Knott) */
if (i == 0)
disp = 1;
probe:
if ((i -= disp) < 0)
i += hsize_reg;
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
if (HashTabOf (i) == fcode)
{
ent = CodeTabOf (i);
continue;
}
if ((long) HashTabOf (i) > 0)
goto probe;
}
nomatch:
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ent, error))
return FALSE;
++out_count;
last = ent = c;
if (free_ent < maxmaxcode)
{
CodeTabOf (i) = free_ent++; /* code -> hashtable */
HashTabOf (i) = fcode;
}
else
2016-04-15 01:49:00 +08:00
{
if (! cl_block (output, error))
return FALSE;
}
}
/*
* Put out the final code.
*/
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ent, error))
return FALSE;
++out_count;
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) EOFCode, error))
return FALSE;
return TRUE;
}
2016-04-15 01:49:00 +08:00
static gboolean
normal_compress (GOutputStream *output,
gint init_bits,
ifunptr ReadValue,
GError **error)
1997-11-25 06:05:25 +08:00
{
2016-04-15 01:49:00 +08:00
glong fcode;
gint i /* = 0 */ ;
gint c;
gint ent;
gint disp;
gint hsize_reg;
gint hshift;
1997-11-25 06:05:25 +08:00
/*
* Set up the globals: g_init_bits - initial number of bits
*/
g_init_bits = init_bits;
cur_bits = 0;
cur_accum = 0;
/*
* Set up the necessary values
*/
offset = 0;
out_count = 0;
clear_flg = 0;
in_count = 1;
ClearCode = (1 << (init_bits - 1));
EOFCode = ClearCode + 1;
free_ent = ClearCode + 2;
/* Had some problems here... should be okay now. --Adam */
n_bits = g_init_bits;
maxcode = MAXCODE (n_bits);
2016-04-15 01:49:00 +08:00
char_init();
1997-11-25 06:05:25 +08:00
ent = gif_next_pixel (ReadValue);
1997-11-25 06:05:25 +08:00
hshift = 0;
for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
++hshift;
hshift = 8 - hshift; /* set hash code range bound */
1997-11-25 06:05:25 +08:00
hsize_reg = hsize;
cl_hash ((glong) hsize_reg); /* clear hash table */
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ClearCode, error))
return FALSE;
1997-11-25 06:05:25 +08:00
while ((c = gif_next_pixel (ReadValue)) != EOF)
{
1997-11-25 06:05:25 +08:00
++in_count;
fcode = (long) (((long) c << maxbits) + ent);
i = (((gint) c << hshift) ^ ent); /* xor hashing */
1997-11-25 06:05:25 +08:00
if (HashTabOf (i) == fcode)
{
ent = CodeTabOf (i);
continue;
}
else if ((long) HashTabOf (i) < 0) /* empty slot */
goto nomatch;
disp = hsize_reg - i; /* secondary hash (after G. Knott) */
1997-11-25 06:05:25 +08:00
if (i == 0)
disp = 1;
1997-11-25 06:05:25 +08:00
probe:
if ((i -= disp) < 0)
i += hsize_reg;
1997-11-25 06:05:25 +08:00
if (HashTabOf (i) == fcode)
{
ent = CodeTabOf (i);
continue;
}
1997-11-25 06:05:25 +08:00
if ((long) HashTabOf (i) > 0)
goto probe;
1997-11-25 06:05:25 +08:00
nomatch:
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ent, error))
return FALSE;
1997-11-25 06:05:25 +08:00
++out_count;
ent = c;
if (free_ent < maxmaxcode)
{
CodeTabOf (i) = free_ent++; /* code -> hashtable */
HashTabOf (i) = fcode;
}
1997-11-25 06:05:25 +08:00
else
2016-04-15 01:49:00 +08:00
{
if (! cl_block (output, error))
return FALSE;
}
1997-11-25 06:05:25 +08:00
}
1997-11-25 06:05:25 +08:00
/*
* Put out the final code.
*/
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) ent, error))
return FALSE;
1997-11-25 06:05:25 +08:00
++out_count;
2016-04-15 01:49:00 +08:00
if (! output_code (output, (gint) EOFCode, error))
return FALSE;
return TRUE;
1997-11-25 06:05:25 +08:00
}
1997-11-25 06:05:25 +08:00
/*****************************************************************
* TAG( output )
*
* Output the given code.
* Inputs:
* code: A n_bits-bit integer. If == -1, then EOF. This assumes
* that n_bits =< (long)wordsize - 1.
* Outputs:
* Outputs code to the file.
* Assumptions:
* Chars are 8 bits long.
* Algorithm:
* Maintain a GIF_BITS character long buffer (so that 8 codes will
* fit in it exactly). Use the VAX insv instruction to insert each
* code in turn. When the buffer fills up empty it and start over.
*/
2016-04-15 01:49:00 +08:00
static gboolean
output_code (GOutputStream *output,
gint code,
GError **error)
1997-11-25 06:05:25 +08:00
{
cur_accum &= masks[cur_bits];
if (cur_bits > 0)
cur_accum |= ((long) code << cur_bits);
else
cur_accum = code;
cur_bits += n_bits;
while (cur_bits >= 8)
{
2016-04-15 01:49:00 +08:00
if (! char_out (output, (guchar) (cur_accum & 0xff), error))
return FALSE;
1997-11-25 06:05:25 +08:00
cur_accum >>= 8;
cur_bits -= 8;
}
/*
* If the next entry is going to be too big for the code size,
* then increase it, if possible.
*/
if (free_ent > maxcode || clear_flg)
{
if (clear_flg)
{
maxcode = MAXCODE (n_bits = g_init_bits);
clear_flg = 0;
}
1997-11-25 06:05:25 +08:00
else
{
++n_bits;
if (n_bits == maxbits)
maxcode = maxmaxcode;
else
maxcode = MAXCODE (n_bits);
}
1997-11-25 06:05:25 +08:00
}
if (code == EOFCode)
{
/*
* At EOF, write the rest of the buffer.
*/
while (cur_bits > 0)
{
2016-04-15 01:49:00 +08:00
if (! char_out (output, (guchar) (cur_accum & 0xff), error))
return FALSE;
cur_accum >>= 8;
cur_bits -= 8;
}
1997-11-25 06:05:25 +08:00
2016-04-15 01:49:00 +08:00
if (! char_flush (output, error))
return FALSE;
1997-11-25 06:05:25 +08:00
}
2016-04-15 01:49:00 +08:00
return TRUE;
1997-11-25 06:05:25 +08:00
}
/*
* Clear out the hash table
*/
2016-04-15 01:49:00 +08:00
static gboolean
cl_block (GOutputStream *output,
GError **error) /* table clear for block compress */
1997-11-25 06:05:25 +08:00
{
cl_hash ((glong) hsize);
1997-11-25 06:05:25 +08:00
free_ent = ClearCode + 2;
clear_flg = 1;
2016-04-15 01:49:00 +08:00
return output_code (output, (gint) ClearCode, error);
1997-11-25 06:05:25 +08:00
}
static void
cl_hash (glong hsize) /* reset code table */
1997-11-25 06:05:25 +08:00
{
glong *htab_p = htab + hsize;
1997-11-25 06:05:25 +08:00
long i;
long m1 = -1;
1997-11-25 06:05:25 +08:00
i = hsize - 16;
do
{ /* might use Sys V memset(3) here */
1997-11-25 06:05:25 +08:00
*(htab_p - 16) = m1;
*(htab_p - 15) = m1;
*(htab_p - 14) = m1;
*(htab_p - 13) = m1;
*(htab_p - 12) = m1;
*(htab_p - 11) = m1;
*(htab_p - 10) = m1;
*(htab_p - 9) = m1;
*(htab_p - 8) = m1;
*(htab_p - 7) = m1;
*(htab_p - 6) = m1;
*(htab_p - 5) = m1;
*(htab_p - 4) = m1;
*(htab_p - 3) = m1;
*(htab_p - 2) = m1;
*(htab_p - 1) = m1;
htab_p -= 16;
}
while ((i -= 16) >= 0);
for (i += 16; i > 0; --i)
*--htab_p = m1;
}
/******************************************************************************
* GIF Specific routines
******************************************************************************/
/*
* Number of characters so far in this 'packet'
*/
static int a_count;
/*
* Set up the 'byte output' routine
*/
static void
char_init (void)
1997-11-25 06:05:25 +08:00
{
a_count = 0;
}
/*
* Define the storage for the packet accumulator
*/
static char accum[256];
/*
* Add a character to the end of the current packet, and if it is 254
* characters, flush the packet to disk.
*/
2016-04-15 01:49:00 +08:00
static gboolean
char_out (GOutputStream *output,
gint c,
GError **error)
1997-11-25 06:05:25 +08:00
{
accum[a_count++] = c;
2016-04-15 01:49:00 +08:00
1997-11-25 06:05:25 +08:00
if (a_count >= 254)
2016-04-15 01:49:00 +08:00
return char_flush (output, error);
return TRUE;
1997-11-25 06:05:25 +08:00
}
/*
* Flush the packet to disk, and reset the accumulator
*/
2016-04-15 01:49:00 +08:00
static gboolean
char_flush (GOutputStream *output,
GError **error)
1997-11-25 06:05:25 +08:00
{
if (a_count > 0)
{
2016-04-15 01:49:00 +08:00
if (! put_byte (output, a_count, error))
return FALSE;
if (! g_output_stream_write_all (output, accum, a_count,
NULL, NULL, error))
return FALSE;
1997-11-25 06:05:25 +08:00
a_count = 0;
}
2016-04-15 01:49:00 +08:00
return TRUE;
1997-11-25 06:05:25 +08:00
}