don't fiddle with the source image, a save plug-in should save, nothing

2004-11-26  Sven Neumann  <sven@gimp.org>

	* plug-ins/winicon/icosave.c: don't fiddle with the source image,
	a save plug-in should save, nothing else.

	* plug-ins/winicon/main.[ch]: handle all sorts of image types.
	Fixes bug #157803.
This commit is contained in:
Sven Neumann 2004-11-26 18:44:29 +00:00 committed by Sven Neumann
parent ec5a467857
commit 1b81778c9a
4 changed files with 58 additions and 126 deletions

View File

@ -1,3 +1,11 @@
2004-11-26 Sven Neumann <sven@gimp.org>
* plug-ins/winicon/icosave.c: don't fiddle with the source image,
a save plug-in should save, nothing else.
* plug-ins/winicon/main.[ch]: handle all sorts of image types.
Fixes bug #157803.
2004-11-26 Sven Neumann <sven@gimp.org>
* tools/pdbgen/pdb/drawable.pdb: fixed docs for

View File

@ -161,8 +161,8 @@ ico_show_icon_dialog (gint32 image_ID,
/* Scale the thing to approximately fit its content, but not too large ... */
gtk_window_set_default_size (GTK_WINDOW (dialog),
350,
(num_layers > 5 ? 500 : num_layers * 100));
500,
120 + (num_layers > 4 ? 400 : num_layers * 100));
icon_depths = g_object_get_data (G_OBJECT (dialog), "icon_depths");
@ -707,31 +707,6 @@ ico_save (MsIcon *ico)
return GIMP_PDB_SUCCESS;
}
static void
ico_sync_image_to_ico (gint32 image,
gint *icon_depths)
{
gint *layers;
gint i, num_layers;
layers = gimp_image_get_layers(image, &num_layers);
for (i = 0; i < num_layers; i++)
{
if (icon_depths[i] < icon_depths[num_layers + i])
{
D(("Layer '%s' was reduced to %i bpp -- updating source image.\n",
gimp_layer_get_name (layers[i]), icon_depths[i]));
ico_image_reduce_layer_bpp (layers[i], icon_depths[i]);
}
}
g_free(layers);
}
static gboolean
ico_layers_too_big (gint32 image)
{
@ -800,10 +775,7 @@ SaveICO (const gchar *filename,
D(("icon data created ...\n"));
if ( (exit_state = ico_save(&ico)) == GIMP_PDB_SUCCESS)
{
ico_sync_image_to_ico (image, icon_depths);
}
exit_state = ico_save(&ico);
D(("*** icon saved, exit status %i.\n\n", exit_state));

View File

@ -105,7 +105,7 @@ query (void)
"Christian Kreibich <christian@whoop.org>",
"2002",
N_("Microsoft Windows icon"),
"INDEXEDA, GRAYA, RGBA",
"*",
GIMP_PLUGIN,
G_N_ELEMENTS (save_args), 0,
save_args, NULL);
@ -275,67 +275,6 @@ ico_cmap_contains_black (guchar *cmap,
return FALSE;
}
void
ico_image_reduce_layer_bpp (guint32 layer,
gint bpp)
{
GimpPixelRgn src_pixel_rgn, dst_pixel_rgn;
gint32 tmp_image;
gint32 tmp_layer;
gint w, h;
guchar *buffer;
w = gimp_drawable_width (layer);
h = gimp_drawable_height (layer);
if (bpp <= 8)
{
GimpDrawable *drawable = gimp_drawable_get (layer);
GimpDrawable *tmp;
buffer = g_new (guchar, w * h * 4);
tmp_image = gimp_image_new (gimp_drawable_width (layer),
gimp_drawable_height (layer),
GIMP_RGB);
tmp_layer = gimp_layer_new (tmp_image, "tmp", w, h,
GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);
tmp = gimp_drawable_get (tmp_layer);
gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, TRUE, FALSE);
gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_image_add_layer (tmp_image, tmp_layer, 0);
gimp_image_convert_indexed (tmp_image,
GIMP_FS_DITHER,
GIMP_MAKE_PALETTE,
1 << bpp,
TRUE,
FALSE,
"dummy");
gimp_image_convert_rgb (tmp_image);
gimp_pixel_rgn_init (&src_pixel_rgn, tmp, 0, 0, w, h, FALSE, FALSE);
gimp_pixel_rgn_init (&dst_pixel_rgn, drawable, 0, 0, w, h, TRUE, FALSE);
gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_drawable_detach (tmp);
gimp_image_delete (tmp_image);
gimp_drawable_detach (drawable);
g_free (buffer);
}
}
void
ico_image_get_reduced_buf (guint32 layer,
gint bpp,
@ -358,17 +297,20 @@ ico_image_get_reduced_buf (guint32 layer,
buffer = g_new (guchar, w * h * 4);
if (bpp <= 8)
if (bpp <= 8 || drawable->bpp != 4)
{
gint32 image = gimp_drawable_get_image (layer);
GimpDrawable *tmp;
tmp_image = gimp_image_new (gimp_drawable_width (layer),
gimp_drawable_height (layer),
GIMP_RGB);
gimp_image_base_type (image));
gimp_image_undo_disable (tmp_image);
tmp_layer = gimp_layer_new (tmp_image, "tmp", w, h,
gimp_drawable_type (layer),
100, GIMP_NORMAL_MODE);
gimp_image_add_layer (tmp_image, tmp_layer, 0);
tmp = gimp_drawable_get (tmp_layer);
@ -376,56 +318,68 @@ ico_image_get_reduced_buf (guint32 layer,
gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, TRUE, FALSE);
gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_drawable_flush (tmp);
gimp_drawable_update (tmp, 0, 0, w, h);
gimp_drawable_detach (tmp);
gimp_image_add_layer (tmp_image, tmp_layer, 0);
if (! gimp_drawable_is_rgb (tmp_layer))
gimp_image_convert_rgb (tmp_image);
gimp_image_convert_indexed (tmp_image,
GIMP_FS_DITHER,
GIMP_MAKE_PALETTE,
1 << bpp,
TRUE,
FALSE,
"dummy");
cmap = gimp_image_get_colormap (tmp_image, num_colors);
if (*num_colors == (1 << bpp) &&
!ico_cmap_contains_black(cmap, *num_colors))
if (bpp <= 8)
{
/* Damn. Windows icons with color maps need the color black.
We need to eliminate one more color to make room for black: */
gimp_image_convert_rgb (tmp_image);
gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, TRUE, FALSE);
gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_drawable_flush (tmp);
gimp_image_convert_indexed (tmp_image,
GIMP_FS_DITHER,
GIMP_MAKE_PALETTE,
(1 << bpp) - 1,
1 << bpp,
TRUE,
FALSE,
"dummy");
cmap = gimp_image_get_colormap (tmp_image, num_colors);
*cmap_out = g_memdup (cmap, *num_colors * 3);
if (*num_colors == (1 << bpp) &&
!ico_cmap_contains_black(cmap, *num_colors))
{
/* Windows icons with color maps need the color black.
* We need to eliminate one more color to make room for black.
*/
gimp_image_convert_rgb (tmp_image);
tmp = gimp_drawable_get (tmp_layer);
gimp_pixel_rgn_init (&dst_pixel_rgn,
tmp, 0, 0, w, h, TRUE, FALSE);
gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_drawable_update (tmp, 0, 0, w, h);
gimp_drawable_detach (tmp);
gimp_image_convert_indexed (tmp_image,
GIMP_FS_DITHER,
GIMP_MAKE_PALETTE,
(1 << bpp) - 1,
TRUE,
FALSE,
"dummy");
cmap = gimp_image_get_colormap (tmp_image, num_colors);
*cmap_out = g_memdup (cmap, *num_colors * 3);
}
gimp_image_convert_rgb (tmp_image);
}
gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, FALSE, FALSE);
gimp_pixel_rgn_get_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_layer_add_alpha (tmp_layer);
tmp = gimp_drawable_get (tmp_layer);
gimp_pixel_rgn_init (&src_pixel_rgn, tmp, 0, 0, w, h, FALSE, FALSE);
gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
gimp_drawable_detach (tmp);
gimp_image_delete (tmp_image);
}
else
{
gimp_pixel_rgn_init (&dst_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
gimp_pixel_rgn_get_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
}
gimp_drawable_detach (drawable);

View File

@ -96,8 +96,6 @@ guint8 * ico_alloc_map (gint width,
gint height,
gint bpp,
gint *len);
void ico_image_reduce_layer_bpp (guint32 layer,
gint bpp);
void ico_image_get_reduced_buf (guint32 layer,
gint bpp,
gint *num_colors,