diff --git a/plug-ins/common/file-png.c b/plug-ins/common/file-png.c index e34f0af6cf..f798999ca8 100644 --- a/plug-ins/common/file-png.c +++ b/plug-ins/common/file-png.c @@ -106,6 +106,17 @@ typedef struct } PngSaveGui; +/* These are not saved or restored. */ +typedef struct +{ + gboolean has_trns; + png_bytep trans; + int num_trans; + gboolean has_plte; + png_colorp palette; + int num_palette; +} +PngGlobals; /* * Local functions... @@ -175,6 +186,7 @@ static const PngSaveVals defaults = }; static PngSaveVals pngvals; +static PngGlobals pngg; /* @@ -1217,7 +1229,6 @@ save_image (const gchar *filename, GimpPixelRgn pixel_rgn; /* Pixel region for layer */ png_structp pp; /* PNG read pointer */ png_infop info; /* PNG info pointer */ - gint num_colors; /* Number of colors in colormap */ gint offx, offy; /* Drawable offsets from origin */ guchar **pixels, /* Pixel rows */ *fixed, /* Fixed-up pixel data */ @@ -1230,7 +1241,6 @@ save_image (const gchar *filename, struct tm *gmt; /* GMT broken down */ int color_type; int bit_depth; - png_colorp palette; guchar remap[256]; /* Re-mapping for the palette */ @@ -1309,9 +1319,9 @@ save_image (const gchar *filename, case GIMP_INDEXED_IMAGE: bpp = 1; color_type = PNG_COLOR_TYPE_PALETTE; - palette = (png_colorp) gimp_image_get_colormap (image_ID, &num_colors); - png_set_PLTE (pp, info, palette, num_colors); - bit_depth = get_bit_depth_for_palette (num_colors); + pngg.has_plte = TRUE; + pngg.palette = (png_colorp) gimp_image_get_colormap (image_ID, &pngg.num_palette); + bit_depth = get_bit_depth_for_palette (pngg.num_palette); break; case GIMP_INDEXEDA_IMAGE: @@ -1326,6 +1336,29 @@ save_image (const gchar *filename, return FALSE; } + /* Set the image dimensions, bit depth, interlacing and compression */ + + png_set_IHDR (pp, info, drawable->width, drawable->height, + bit_depth, + color_type, + pngvals.interlaced ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + + if (pngg.has_trns) + { + png_set_tRNS (pp, info, pngg.trans, pngg.num_trans, NULL); + } + + if (pngg.has_plte) + { + png_set_PLTE (pp, info, pngg.palette, pngg.num_palette); + } + + /* Set the compression level */ + + png_set_compression_level (pp, pngvals.compression_level); + /* All this stuff is optional extras, if the user is aiming for smallest possible file size she can turn them all off */ @@ -1420,18 +1453,6 @@ save_image (const gchar *filename, } #endif - /* - * Set the image dimensions, bit depth, interlacing and compression - */ - - png_set_IHDR (pp, info, drawable->width, drawable->height, - bit_depth, - color_type, - pngvals.interlaced ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, - PNG_FILTER_TYPE_BASE); - png_set_compression_level (pp, pngvals.compression_level); - if (pngvals.comment) { GimpParasite *parasite; @@ -1721,7 +1742,7 @@ respin_cmap (png_structp pp, gint32 image_ID, GimpDrawable *drawable) { - static const guchar trans[] = { 0 }; + static guchar trans[] = { 0 }; gint colors; guchar *before; @@ -1748,10 +1769,13 @@ respin_cmap (png_structp pp, * index - do like gif2png and swap * index 0 and index transparent */ { - png_color palette[256]; + static png_color palette[256]; gint i; - png_set_tRNS (pp, info, (png_bytep) trans, 1, NULL); + /* Set tRNS chunk values for writing later. */ + pngg.has_trns = TRUE; + pngg.trans = trans; + pngg.num_trans = 1; /* Transform all pixels with a value = transparent to * 0 and vice versa to compensate for re-ordering in palette @@ -1772,7 +1796,10 @@ respin_cmap (png_structp pp, palette[i].blue = before[3 * remap[i] + 2]; } - png_set_PLTE (pp, info, palette, colors); + /* Set PLTE chunk values for writing later. */ + pngg.has_plte = TRUE; + pngg.palette = palette; + pngg.num_palette = colors; } else { @@ -1780,12 +1807,19 @@ respin_cmap (png_structp pp, * transparency & just use the full palette */ g_message (_("Couldn't losslessly save transparency, " "saving opacity instead.")); - png_set_PLTE (pp, info, (png_colorp) before, colors); + + /* Set PLTE chunk values for writing later. */ + pngg.has_plte = TRUE; + pngg.palette = (png_colorp) before; + pngg.num_palette = colors; } } else { - png_set_PLTE (pp, info, (png_colorp) before, colors); + /* Set PLTE chunk values for writing later. */ + pngg.has_plte = TRUE; + pngg.palette = (png_colorp) before; + pngg.num_palette = colors; } return get_bit_depth_for_palette (colors);