gimp/plug-ins/file-bmp/bmp-save.c

1036 lines
30 KiB
C
Raw Normal View History

/* bmpwrite.c Writes Bitmap files. Even RLE encoded ones. */
/* (Windows (TM) doesn't read all of those, but who */
/* cares? ;-) */
/* I changed a few things over the time, so perhaps */
/* it dos now, but now there's no Windows left on */
/* my computer... */
/* Alexander.Schulz@stud.uni-karlsruhe.de */
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
/*
* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* ----------------------------------------------------------------------------
*/
New file. * plug-ins/makefile.msc: New file. * plug-ins/*/*.c (Well, not really all files, but many): Portability fixes. Include config.h, and guard inclusion of POSIX and Unix headers like <unistd.h>, <dirent.h> and <sys/time.h>. Include <string.h> if functions from it are used. Use g_ntohl() and g_htonl() insteead of ntohl() and htonl(), thus no need to include <netinet/in.h>. Include <io.h> on Win32 when using open/read/write (which actually are defined as _open/_read/_write by glib.h). Define S_* macros if necessary on Win32. Define rint() and M_PI if necessary (these definitions should be factored out somewhere, no sense repeating them in lots of files). Open files in binary mode when needed. * plug-ins/FractalExplorer/FractalExplorer.c: Use g_malloc()/g_free(). Use g_strdup_printf(). * plug-ins/dbbrowser/dbbrowser.c: No need to include <X11/Xlib.h>. * plug-ins/destripe/destripe.c: Guard use of SIGBUS. * plug-ins/{flame/flame,hrz/hrz,pnm/pnm}.c: No need to check for NULL returns from g_malloc() and g_new() as they abort on failure. Use g_strdup_printf(). * plug-ins/gz/gz.c: Win32 version of running the subprocess. * plug-ins/hrz/hrz.c: Win32 version. Use more generic tests for non-Unix (OS/2 and Win32), for instance HAVE_MMAP. * plug-ins/script-fu/interp_slib.c: Win32 version of myruntime(). * plug-ins/script-fu/interp_sliba.c: Handle \\ (escaped backslahsh). * plug-ins/script-fu/script-fu-console.c: Bypass on Win32. * plug-ins/script-fu/script-fu-scripts.c: Portability fixes. Use g_strdup_printf() instead of separate malloc() and sprintf(). Use g_strescape() for strings being passed to Scheme. Some Win32-only stuff.
1999-05-29 09:28:24 +08:00
#include "config.h"
1997-11-25 06:05:25 +08:00
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
#include <errno.h>
1997-11-25 06:05:25 +08:00
#include <string.h>
#include <glib/gstdio.h>
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
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
1997-11-25 06:05:25 +08:00
#include "bmp.h"
#include "bmp-save.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
typedef enum
{
RGB_565,
RGBA_5551,
RGB_555,
RGB_888,
RGBA_8888,
RGBX_8888
} RGBMode;
1997-11-25 06:05:25 +08:00
static void write_image (FILE *f,
guchar *src,
gint width,
gint height,
gboolean use_run_length_encoding,
gint channels,
gint bpp,
gint spzeile,
gint MapSize,
RGBMode rgb_format,
gint mask_info_size,
gint color_space_size);
static gboolean save_dialog (GimpProcedure *procedure,
GObject *config,
gint channels);
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
static void
write_color_map (FILE *f,
gint red[MAXCOLORS],
gint green[MAXCOLORS],
gint blue[MAXCOLORS],
gint size)
{
gchar trgb[4];
gint i;
size /= 4;
trgb[3] = 0;
for (i = 0; i < size; i++)
{
trgb[0] = (guchar) blue[i];
trgb[1] = (guchar) green[i];
trgb[2] = (guchar) red[i];
Write (f, trgb, 4);
}
}
static gboolean
warning_dialog (const gchar *primary,
const gchar *secondary)
{
GtkWidget *dialog;
gboolean ok;
dialog = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL,
"%s", primary);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", secondary);
gimp_window_set_transient (GTK_WINDOW (dialog));
ok = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK);
gtk_widget_destroy (dialog);
return ok;
}
GimpPDBStatusType
save_image (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GimpRunMode run_mode,
GimpProcedure *procedure,
GObject *config,
GError **error)
1997-11-25 06:05:25 +08:00
{
gchar *filename;
FILE *outfile;
BitmapFileHead bitmap_file_head;
BitmapHead bitmap_head;
gint Red[MAXCOLORS];
gint Green[MAXCOLORS];
gint Blue[MAXCOLORS];
guchar *cmap;
gint rows, cols, Spcols, channels, MapSize, SpZeile;
glong BitsPerPixel;
gint colors;
guchar *pixels;
GeglBuffer *buffer;
const Babl *format;
GimpImageType drawable_type;
gint drawable_width;
gint drawable_height;
gint i;
gint mask_info_size;
gint color_space_size;
guint32 Mask[4];
gboolean use_rle;
gboolean write_color_space;
RGBMode rgb_format;
1997-11-25 06:05:25 +08:00
buffer = gimp_drawable_get_buffer (drawable);
drawable_type = gimp_drawable_type (drawable);
drawable_width = gimp_drawable_width (drawable);
drawable_height = gimp_drawable_height (drawable);
1997-11-25 06:05:25 +08:00
switch (drawable_type)
{
case GIMP_RGBA_IMAGE:
2012-09-22 01:18:34 +08:00
format = babl_format ("R'G'B'A u8");
colors = 0;
BitsPerPixel = 32;
MapSize = 0;
channels = 4;
g_object_set (config,
"rgb-format", RGBA_8888,
NULL);
break;
case GIMP_RGB_IMAGE:
2012-09-22 01:18:34 +08:00
format = babl_format ("R'G'B' u8");
colors = 0;
1997-11-25 06:05:25 +08:00
BitsPerPixel = 24;
MapSize = 0;
channels = 3;
g_object_set (config,
"rgb-format", RGBA_8888,
NULL);
1997-11-25 06:05:25 +08:00
break;
case GIMP_GRAYA_IMAGE:
if (run_mode == GIMP_RUN_INTERACTIVE &&
! warning_dialog (_("Cannot export indexed image with "
"transparency in BMP file format."),
_("Alpha channel will be ignored.")))
2012-09-22 01:18:34 +08:00
return GIMP_PDB_CANCEL;
/* fallthrough */
case GIMP_GRAY_IMAGE:
colors = 256;
BitsPerPixel = 8;
MapSize = 1024;
2011-05-08 23:52:31 +08:00
if (drawable_type == GIMP_GRAYA_IMAGE)
2012-09-22 01:18:34 +08:00
{
format = babl_format ("Y'A u8");
channels = 2;
}
2011-05-08 23:52:31 +08:00
else
2012-09-22 01:18:34 +08:00
{
format = babl_format ("Y' u8");
channels = 1;
}
2011-05-08 23:52:31 +08:00
1997-11-25 06:05:25 +08:00
for (i = 0; i < colors; i++)
{
Red[i] = i;
Green[i] = i;
Blue[i] = i;
}
1997-11-25 06:05:25 +08:00
break;
case GIMP_INDEXEDA_IMAGE:
if (run_mode == GIMP_RUN_INTERACTIVE &&
! warning_dialog (_("Cannot export indexed image with "
"transparency in BMP file format."),
_("Alpha channel will be ignored.")))
2012-09-22 01:18:34 +08:00
return GIMP_PDB_CANCEL;
/* fallthrough */
case GIMP_INDEXED_IMAGE:
format = gimp_drawable_get_format (drawable);
cmap = gimp_image_get_colormap (image, &colors);
MapSize = 4 * colors;
2011-05-08 23:52:31 +08:00
if (drawable_type == GIMP_INDEXEDA_IMAGE)
channels = 2;
else
channels = 1;
if (colors > 16)
BitsPerPixel = 8;
else if (colors > 2)
BitsPerPixel = 4;
else
BitsPerPixel = 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
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
break;
default:
g_assert_not_reached ();
1997-11-25 06:05:25 +08:00
}
mask_info_size = 0;
if (run_mode == GIMP_RUN_INTERACTIVE &&
(BitsPerPixel == 8 ||
BitsPerPixel == 4))
{
if (! save_dialog (procedure, config, 1))
return GIMP_PDB_CANCEL;
}
else if (BitsPerPixel == 24 ||
BitsPerPixel == 32)
{
if (run_mode == GIMP_RUN_INTERACTIVE)
{
if (! save_dialog (procedure, config, channels))
return GIMP_PDB_CANCEL;
}
g_object_get (config,
"rgb-format", &rgb_format,
NULL);
/* mask_info_size is only set to non-zero for 16- and 32-bpp */
switch (rgb_format)
{
case RGB_888:
BitsPerPixel = 24;
break;
case RGBA_8888:
BitsPerPixel = 32;
mask_info_size = 16;
break;
case RGBX_8888:
BitsPerPixel = 32;
mask_info_size = 16;
break;
case RGB_565:
BitsPerPixel = 16;
mask_info_size = 16;
break;
case RGBA_5551:
BitsPerPixel = 16;
mask_info_size = 16;
break;
case RGB_555:
BitsPerPixel = 16;
mask_info_size = 16;
break;
default:
g_return_val_if_reached (GIMP_PDB_EXECUTION_ERROR);
}
}
g_object_get (config,
"use-rle", &use_rle,
"write-color-space-info", &write_color_space,
"rgb-format", &rgb_format,
NULL);
gimp_progress_init_printf (_("Exporting '%s'"),
gimp_file_get_utf8_name (file));
filename = g_file_get_path (file);
outfile = g_fopen (filename, "wb");
g_free (filename);
if (! outfile)
1997-11-25 06:05:25 +08:00
{
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
_("Could not open '%s' for writing: %s"),
gimp_file_get_utf8_name (file), g_strerror (errno));
return GIMP_PDB_EXECUTION_ERROR;
1997-11-25 06:05:25 +08:00
}
1997-11-25 06:05:25 +08:00
/* fetch the image */
2012-09-22 01:18:34 +08:00
pixels = g_new (guchar, drawable_width * drawable_height * channels);
gegl_buffer_get (buffer,
GEGL_RECTANGLE (0, 0, drawable_width, drawable_height), 1.0,
2012-09-22 01:18:34 +08:00
format, pixels,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
g_object_unref (buffer);
1997-11-25 06:05:25 +08:00
/* Now, we need some further information ... */
2012-09-22 01:18:34 +08:00
cols = drawable_width;
rows = drawable_height;
1997-11-25 06:05:25 +08:00
/* ... that we write to our headers. */
if ((BitsPerPixel <= 8) && (cols % (8 / BitsPerPixel)))
Spcols = (((cols / (8 / BitsPerPixel)) + 1) * (8 / BitsPerPixel));
else
Spcols = cols;
if ((((Spcols * BitsPerPixel) / 8) % 4) == 0)
SpZeile = ((Spcols * BitsPerPixel) / 8);
else
SpZeile = ((gint) (((Spcols * BitsPerPixel) / 8) / 4) + 1) * 4;
if (write_color_space)
color_space_size = 68;
else
color_space_size = 0;
bitmap_file_head.bfSize = (0x36 + MapSize + (rows * SpZeile) +
mask_info_size + color_space_size);
bitmap_file_head.zzHotX = 0;
bitmap_file_head.zzHotY = 0;
bitmap_file_head.bfOffs = (0x36 + MapSize +
mask_info_size + color_space_size);
bitmap_file_head.biSize = 40 + mask_info_size + color_space_size;
bitmap_head.biWidth = cols;
bitmap_head.biHeight = rows;
bitmap_head.biPlanes = 1;
bitmap_head.biBitCnt = BitsPerPixel;
if (! use_rle)
{
if (mask_info_size > 0)
bitmap_head.biCompr = 3; /* BI_BITFIELDS */
else
bitmap_head.biCompr = 0; /* BI_RGB */
}
else if (BitsPerPixel == 8)
{
bitmap_head.biCompr = 1;
}
else if (BitsPerPixel == 4)
{
bitmap_head.biCompr = 2;
}
else
{
bitmap_head.biCompr = 0;
}
bitmap_head.biSizeIm = SpZeile * rows;
{
gdouble xresolution;
gdouble yresolution;
gimp_image_get_resolution (image, &xresolution, &yresolution);
if (xresolution > GIMP_MIN_RESOLUTION &&
yresolution > GIMP_MIN_RESOLUTION)
{
/*
* xresolution and yresolution are in dots per inch.
* the BMP spec says that biXPels and biYPels are in
* pixels per meter as long ints (actually, "DWORDS"),
* so...
* n dots inch 100 cm m dots
* ------ * ------- * ------ = ------
* inch 2.54 cm m inch
*
* We add 0.5 for proper rounding.
*/
bitmap_head.biXPels = (long int) (xresolution * 100.0 / 2.54 + 0.5);
bitmap_head.biYPels = (long int) (yresolution * 100.0 / 2.54 + 0.5);
}
}
if (BitsPerPixel <= 8)
bitmap_head.biClrUsed = 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
else
bitmap_head.biClrUsed = 0;
bitmap_head.biClrImp = bitmap_head.biClrUsed;
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
#ifdef DEBUG
printf ("\nSize: %u, Colors: %u, Bits: %u, Width: %u, Height: %u, Comp: %u, Zeile: %u\n",
(int)bitmap_file_head.bfSize,
(int)bitmap_head.biClrUsed,
bitmap_head.biBitCnt,
(int)bitmap_head.biWidth,
(int)bitmap_head.biHeight,
(int)bitmap_head.biCompr,SpZeile);
1997-11-25 06:05:25 +08:00
#endif
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
/* And now write the header and the colormap (if any) to disk */
Write (outfile, "BM", 2);
bitmap_file_head.bfSize = GUINT32_TO_LE (bitmap_file_head.bfSize);
bitmap_file_head.zzHotX = GUINT16_TO_LE (bitmap_file_head.zzHotX);
bitmap_file_head.zzHotY = GUINT16_TO_LE (bitmap_file_head.zzHotY);
bitmap_file_head.bfOffs = GUINT32_TO_LE (bitmap_file_head.bfOffs);
bitmap_file_head.biSize = GUINT32_TO_LE (bitmap_file_head.biSize);
Write (outfile, &bitmap_file_head.bfSize, 16);
bitmap_head.biWidth = GINT32_TO_LE (bitmap_head.biWidth);
bitmap_head.biHeight = GINT32_TO_LE (bitmap_head.biHeight);
bitmap_head.biPlanes = GUINT16_TO_LE (bitmap_head.biPlanes);
bitmap_head.biBitCnt = GUINT16_TO_LE (bitmap_head.biBitCnt);
bitmap_head.biCompr = GUINT32_TO_LE (bitmap_head.biCompr);
bitmap_head.biSizeIm = GUINT32_TO_LE (bitmap_head.biSizeIm);
bitmap_head.biXPels = GUINT32_TO_LE (bitmap_head.biXPels);
bitmap_head.biYPels = GUINT32_TO_LE (bitmap_head.biYPels);
bitmap_head.biClrUsed = GUINT32_TO_LE (bitmap_head.biClrUsed);
bitmap_head.biClrImp = GUINT32_TO_LE (bitmap_head.biClrImp);
Write (outfile, &bitmap_head, 36);
if (mask_info_size > 0)
{
switch (rgb_format)
{
default:
case RGB_888:
case RGBX_8888:
Mask[0] = 0x00ff0000;
Mask[1] = 0x0000ff00;
Mask[2] = 0x000000ff;
Mask[3] = 0x00000000;
break;
case RGBA_8888:
Mask[0] = 0x00ff0000;
Mask[1] = 0x0000ff00;
Mask[2] = 0x000000ff;
Mask[3] = 0xff000000;
break;
case RGB_565:
Mask[0] = 0xf800;
Mask[1] = 0x7e0;
Mask[2] = 0x1f;
Mask[3] = 0x0;
break;
case RGBA_5551:
Mask[0] = 0x7c00;
Mask[1] = 0x3e0;
Mask[2] = 0x1f;
Mask[3] = 0x8000;
break;
case RGB_555:
Mask[0] = 0x7c00;
Mask[1] = 0x3e0;
Mask[2] = 0x1f;
Mask[3] = 0x0;
break;
}
Mask[0] = GUINT32_TO_LE (Mask[0]);
Mask[1] = GUINT32_TO_LE (Mask[1]);
Mask[2] = GUINT32_TO_LE (Mask[2]);
Mask[3] = GUINT32_TO_LE (Mask[3]);
Write (outfile, &Mask, mask_info_size);
}
if (write_color_space)
{
guint32 buf[0x11];
/* Write V5 color space fields */
/* bV5CSType = LCS_sRGB */
buf[0x00] = GUINT32_TO_LE (0x73524742);
/* bV5Endpoints is set to 0 (ignored) */
for (i = 0; i < 0x09; i++)
buf[i + 1] = 0x00;
/* bV5GammaRed is set to 0 (ignored) */
buf[0x0a] = GUINT32_TO_LE (0x0);
/* bV5GammaGreen is set to 0 (ignored) */
buf[0x0b] = GUINT32_TO_LE (0x0);
/* bV5GammaBlue is set to 0 (ignored) */
buf[0x0c] = GUINT32_TO_LE (0x0);
/* bV5Intent = LCS_GM_GRAPHICS */
buf[0x0d] = GUINT32_TO_LE (0x00000002);
/* bV5ProfileData is set to 0 (ignored) */
buf[0x0e] = GUINT32_TO_LE (0x0);
/* bV5ProfileSize is set to 0 (ignored) */
buf[0x0f] = GUINT32_TO_LE (0x0);
/* bV5Reserved = 0 */
buf[0x10] = GUINT32_TO_LE (0x0);
Write (outfile, buf, color_space_size);
}
write_color_map (outfile, Red, Green, Blue, MapSize);
1997-11-25 06:05:25 +08:00
/* After that is done, we write the image ... */
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
write_image (outfile,
pixels, cols, rows,
use_rle,
channels, BitsPerPixel, SpZeile,
MapSize, rgb_format,
mask_info_size, color_space_size);
1997-11-25 06:05:25 +08:00
/* ... and exit normally */
fclose (outfile);
g_free (pixels);
return GIMP_PDB_SUCCESS;
1997-11-25 06:05:25 +08:00
}
static inline void
Make565 (guchar r,
guchar g,
guchar b,
guchar *buf)
{
gint p;
p = ((((gint) (r / 255.0 * 31.0 + 0.5)) << 11) |
(((gint) (g / 255.0 * 63.0 + 0.5)) << 5) |
(((gint) (b / 255.0 * 31.0 + 0.5))));
buf[0] = (guchar) (p & 0xff);
buf[1] = (guchar) (p >> 8);
}
static inline void
Make5551 (guchar r,
guchar g,
guchar b,
guchar a,
guchar *buf)
{
gint p;
p = ((((gint) (r / 255.0 * 31.0 + 0.5)) << 10) |
(((gint) (g / 255.0 * 31.0 + 0.5)) << 5) |
(((gint) (b / 255.0 * 31.0 + 0.5))) |
(((gint) (a / 255.0 + 0.5) << 15)));
buf[0] = (guchar) (p & 0xff);
buf[1] = (guchar) (p >> 8);
}
static void
write_image (FILE *f,
guchar *src,
gint width,
gint height,
gboolean use_run_length_encoding,
gint channels,
gint bpp,
gint spzeile,
gint MapSize,
RGBMode rgb_format,
gint mask_info_size,
gint color_space_size)
1997-11-25 06:05:25 +08:00
{
guchar buf[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 };
guint32 uint32buf;
guchar *temp, v;
guchar *row, *ketten;
gint xpos, ypos, i, j, rowstride, length, thiswidth;
gint breite, k;
guchar n, r, g, b, a;
gint cur_progress;
gint max_progress;
xpos = 0;
rowstride = width * channels;
cur_progress = 0;
max_progress = height;
/* We'll begin with the 16/24/32 bit Bitmaps, they are easy :-) */
if (bpp > 8)
{
for (ypos = height - 1; ypos >= 0; ypos--) /* for each row */
{
for (i = 0; i < width; i++) /* for each pixel */
{
temp = src + (ypos * rowstride) + (xpos * channels);
switch (rgb_format)
{
default:
case RGB_888:
buf[2] = *temp++;
buf[1] = *temp++;
buf[0] = *temp++;
xpos++;
if (channels > 3 && (guchar) *temp == 0)
buf[0] = buf[1] = buf[2] = 0xff;
Write (f, buf, 3);
break;
case RGBX_8888:
buf[2] = *temp++;
buf[1] = *temp++;
buf[0] = *temp++;
buf[3] = 0;
xpos++;
if (channels > 3 && (guchar) *temp == 0)
buf[0] = buf[1] = buf[2] = 0xff;
Write (f, buf, 4);
break;
case RGBA_8888:
buf[2] = *temp++;
buf[1] = *temp++;
buf[0] = *temp++;
buf[3] = *temp;
xpos++;
Write (f, buf, 4);
break;
case RGB_565:
r = *temp++;
g = *temp++;
b = *temp++;
if (channels > 3 && (guchar) *temp == 0)
r = g = b = 0xff;
Make565 (r, g, b, buf);
xpos++;
Write (f, buf, 2);
break;
case RGB_555:
r = *temp++;
g = *temp++;
b = *temp++;
if (channels > 3 && (guchar) *temp == 0)
r = g = b = 0xff;
Make5551 (r, g, b, 0x0, buf);
xpos++;
Write (f, buf, 2);
break;
case RGBA_5551:
r = *temp++;
g = *temp++;
b = *temp++;
a = *temp;
Make5551 (r, g, b, a, buf);
xpos++;
Write (f, buf, 2);
break;
}
}
Write (f, &buf[4], spzeile - (width * (bpp/8)));
cur_progress++;
if ((cur_progress % 5) == 0)
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
xpos = 0;
}
}
else
{
/* now it gets more difficult */
if (! use_run_length_encoding)
{
/* uncompressed 1,4 and 8 bit */
thiswidth = (width / (8 / bpp));
if (width % (8 / bpp))
thiswidth++;
for (ypos = height - 1; ypos >= 0; ypos--) /* for each row */
{
for (xpos = 0; xpos < width;) /* for each _byte_ */
{
v = 0;
for (i = 1;
(i <= (8 / bpp)) && (xpos < width);
i++, xpos++) /* for each pixel */
{
temp = src + (ypos * rowstride) + (xpos * channels);
if (channels > 1 && *(temp+1) == 0) *temp = 0x0;
v=v | ((guchar) *temp << (8 - (i * bpp)));
}
Write (f, &v, 1);
}
Write (f, &buf[3], spzeile - thiswidth);
xpos = 0;
cur_progress++;
if ((cur_progress % 5) == 0)
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
}
else
{
/* Save RLE encoded file, quite difficult */
length = 0;
buf[12] = 0;
buf[13] = 1;
buf[14] = 0;
buf[15] = 0;
row = g_new (guchar, width / (8 / bpp) + 10);
ketten = g_new (guchar, width / (8 / bpp) + 10);
for (ypos = height - 1; ypos >= 0; ypos--)
{
/* each row separately */
j = 0;
/* first copy the pixels to a buffer, making one byte
* from two 4bit pixels
*/
for (xpos = 0; xpos < width;)
{
v = 0;
for (i = 1;
(i <= (8 / bpp)) && (xpos < width);
i++, xpos++)
{
/* for each pixel */
temp = src + (ypos * rowstride) + (xpos * channels);
if (channels > 1 && *(temp+1) == 0) *temp = 0x0;
v = v | ((guchar) * temp << (8 - (i * bpp)));
}
row[j++] = v;
}
breite = width / (8 / bpp);
if (width % (8 / bpp))
breite++;
/* then check for strings of equal bytes */
for (i = 0; i < breite; i += j)
{
j = 0;
while ((i + j < breite) &&
(j < (255 / (8 / bpp))) &&
(row[i + j] == row[i]))
j++;
ketten[i] = j;
}
/* then write the strings and the other pixels to the file */
for (i = 0; i < breite;)
{
if (ketten[i] < 3)
{
/* strings of different pixels ... */
j = 0;
while ((i + j < breite) &&
(j < (255 / (8 / bpp))) &&
(ketten[i + j] < 3))
j += ketten[i + j];
/* this can only happen if j jumps over the end
* with a 2 in ketten[i+j]
*/
if (j > (255 / (8 / bpp)))
j -= 2;
/* 00 01 and 00 02 are reserved */
if (j > 2)
{
Write (f, &buf[12], 1);
n = j * (8 / bpp);
if (n + i * (8 / bpp) > width)
n--;
Write (f, &n, 1);
length += 2;
Write (f, &row[i], j);
length += j;
if ((j) % 2)
{
Write (f, &buf[12], 1);
length++;
}
}
else
{
for (k = i; k < i + j; k++)
{
n = (8 / bpp);
if (n + i * (8 / bpp) > width)
n--;
Write (f, &n, 1);
Write (f, &row[k], 1);
/*printf("%i.#|",n); */
length += 2;
}
}
i += j;
}
else
{
/* strings of equal pixels */
n = ketten[i] * (8 / bpp);
if (n + i * (8 / bpp) > width)
n--;
Write (f, &n, 1);
Write (f, &row[i], 1);
i += ketten[i];
length += 2;
}
}
Write (f, &buf[14], 2); /* End of row */
length += 2;
cur_progress++;
if ((cur_progress % 5) == 0)
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
fseek (f, -2, SEEK_CUR); /* Overwrite last End of row ... */
Write (f, &buf[12], 2); /* ... with End of file */
fseek (f, 0x22, SEEK_SET); /* Write length of image */
uint32buf = GUINT32_TO_LE (length);
Write (f, &uint32buf, 4);
fseek (f, 0x02, SEEK_SET); /* Write length of file */
length += (0x36 + MapSize + mask_info_size + color_space_size);
uint32buf = GUINT32_TO_LE (length);
Write (f, &uint32buf, 4);
g_free (ketten);
g_free (row);
}
1997-11-25 06:05:25 +08:00
}
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
gimp_progress_update (1.0);
1997-11-25 06:05:25 +08:00
}
static gboolean
format_sensitive_callback (gint value,
gpointer data)
{
gint channels = GPOINTER_TO_INT (data);
switch (value)
{
case RGBA_5551:
case RGBA_8888:
return channels == 4;
default:
return TRUE;
};
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer data)
{
gint channels = GPOINTER_TO_INT (data);
RGBMode format;
g_object_get (config,
"rgb-format", &format,
NULL);
switch (format)
{
case RGBA_5551:
case RGBA_8888:
if (channels != 4)
{
g_signal_handlers_block_by_func (config, config_notify, data);
g_object_set (config, "rgb-format", format - 1, NULL);
g_signal_handlers_unblock_by_func (config, config_notify, data);
}
break;
default:
break;
};
}
static gboolean
save_dialog (GimpProcedure *procedure,
GObject *config,
gint channels)
{
GtkWidget *dialog;
GtkWidget *toggle;
GtkWidget *vbox;
GtkWidget *frame;
GtkListStore *store;
GtkWidget *combo;
gboolean run;
dialog = gimp_procedure_dialog_new (procedure,
GIMP_PROCEDURE_CONFIG (config),
_("Export Image as BMP"));
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
/* Run-Length Encoded */
toggle = gimp_prop_check_button_new (config, "use-rle",
_("_Run-Length Encoded"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
if (channels > 1)
gtk_widget_set_sensitive (toggle, FALSE);
/* Compatibility Options */
frame = gimp_frame_new (_("Compatibility"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
toggle = gimp_prop_check_button_new (config, "write-color-space-info",
_("_Write color space information"));
gimp_help_set_help_data (toggle,
_("Some applications can not read BMP images that "
"include color space information. GIMP writes "
"color space information by default. Disabling "
"this option will cause GIMP to not write color "
"space information to the file."),
NULL);
gtk_container_add (GTK_CONTAINER (frame), toggle);
/* RGB Encoding Pptions */
frame = gimp_frame_new (_("RGB Encoding"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
if (channels < 3)
gtk_widget_set_sensitive (frame, FALSE);
store = gimp_int_store_new (_("16 bit (R5 G6 B5)"), RGB_565,
_("16 bit (A1 R5 G5 B5)"), RGBA_5551,
_("16 bit (X1 R5 G5 B5)"), RGB_555,
_("24 bit (R8 G8 B8)"), RGB_888,
_("32 bit (A8 R8 G8 B8)"), RGBA_8888,
_("32 bit (X8 R8 G8 B8)"), RGBX_8888,
NULL);
combo = gimp_prop_int_combo_box_new (config, "rgb-format",
GIMP_INT_STORE (store));
gtk_container_add (GTK_CONTAINER (frame), combo);
gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (combo),
format_sensitive_callback,
GINT_TO_POINTER (channels), NULL);
gtk_widget_show (dialog);
g_signal_connect (config, "notify::rgb-format",
G_CALLBACK (config_notify),
GINT_TO_POINTER (channels));
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
g_signal_handlers_disconnect_by_func (config,
config_notify,
GINT_TO_POINTER (channels));
gtk_widget_destroy (dialog);
return run;
}