[FIXED] PNG: read/write degrades/corrupts image

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

[FIXED] PNG: read/write degrades/corrupts image

Post by tc33 »

Reference post: viewtopic.php?f=1&t=22128

Test environment: IM 6.8.0.2 x64 debug, MSVC 11, Win7 x64

Problem: a simple file read & file write changes the shading of the following image (via color reduction), unless '-set colorspace RGB' is specified.
http://cssignet.free.fr/png-test-corpus ... dbe-c0.png

Another file with the same issue (but more noticeable), notice the grays turn to blacks:
http://cssignet.free.fr/png-test-corpus ... dbe-c4.png

I am using the Magick++ interface, but was also able to reproduce this same behavior with convert.exe. I can post a resulting output file if needed, but the output issue is clear upon comparison; the images become progressively darker, and contain fewer colors, with each iteration.

Convert.exe:
convert "01-c3-shouldbe-c0.png" "01-c3-shouldbe-c0.converted.png"

Magick++ (same behavior)
Image input;
input.read( "01-c3-shouldbe-c0.png" );
input.write( "01-c3-shouldbe-c0.imread.png" );

Moreover, looping on a read/write causes the progressive degradation of the image on each loop iteration. See referenced post for code sample.
Reference post: viewtopic.php?f=1&t=22128

Thank you
Last edited by tc33 on 2013-01-31T16:18:45-07:00, edited 1 time in total.
Jason S
Posts: 103
Joined: 2010-12-14T19:42:12-07:00
Authentication code: 8675308

Re: PNG: read/write degrades/corrupts image

Post by Jason S »

I guess that ImageMagick reads the image, converts it from sRGB (or a similar colorspace) to linear color, and writes it out as linear color, but (mis)labels it as sRGB. And it does this because the (paletted) image's pixels all happen to be shades of gray.

The immediate problem is that the output image's colorspace label does not match its colorspace. Labeling it as linear color would be better than nothing, but it really ought to be converted back to sRGB.

Another problem is that it treats an image in a special way if all its pixels are gray, regardless of whether it is actually encoded as a grayscale image.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: PNG: read/write degrades/corrupts image

Post by NicolasRobidoux »

Another problem is that it treats an image in a special way if all its pixels are gray, regardless of whether it is actually encoded as a grayscale image.
I can confirm the problem. (Actually checked the Forum to see if someone else had reported it.)
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: PNG: read/write degrades/corrupts image

Post by NicolasRobidoux »

For example: Donwload Image

Code: Select all

convert MiniOrg.png out.png
messes up the pixel intensities and actually turns the 3-band original into a 1-band one.

Code: Select all

Version: ImageMagick 6.8.0-2 2012-10-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP  HDRI
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: PNG: read/write degrades/corrupts image

Post by NicolasRobidoux »

Still broken with svn 9745:

Code: Select all

Version: ImageMagick 6.8.0-3 2012-10-22 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP  HDRI
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: PNG: read/write degrades/corrupts image

Post by NicolasRobidoux »

Code: Select all

convert MiniOrg.png -define png:color-type=2 temp.png
fixes the 3-band greyscale to different looking 1-band greyscale.
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: PNG: read/write degrades/corrupts image

Post by glennrp »

This was already posted in the "users" forum and I answered it there.

If the image has only gray pixels, there may be a confusion of sRGB versus RGB, and it's possible that a loop is continually converting back and forth and losing precision each time around. I have noticed that that happens when converting between PNG and PNG24 formats, unless -colorspace RGB is used. I have not yet nailed down exactly what is happening but am working on it (I didn't try looping the command but assume the the loss would accumulate; I'll test that now)... Yes, the number of colors decreases continually unless I use "-colorspace rgb".
tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

Re: PNG: read/write degrades/corrupts image

Post by tc33 »

As a follow up, I stumbled on a workaround while doing some grayscale image processing. Basically, I manually set the colorspace to RGB and then call IsGrayImage in attribute.c, which contains auto-detect logic based on image pixel data.

Also, I noticed that any transparent, non-gray pixels will cause IsGrayImage to return false, since the PNG image decoder (or something else?) returns the pixel value even if the pixel is fully transparent. Not sure if this is by design. Here's an example PNG file; note that if you do a straight command-line conversion to bmp you'll see the non-gray pixels. http://cssignet.free.fr/png-test-corpus ... gbdata.png

To workaround the transparent pixel issue, I use the SetImageAlphaChannel with BackgroundAlphaChannel to eliminate these transparent pixels before calling IsGrayImage.

Here's an excerpt of my Magick++ solution:

Code: Select all

#include <Magick++.h>  // Magick++
#include <magick/channel.h>	// SetImageAlphaChannel
#include <magick/attribute.h>	// IsGrayImage


bool is_gray_img( const Magick::Image& img )
{
	Magick::Image cpy = Magick::Image( img );

	// if colorspace is sRGB, must change colorspace to RGB, forcing IsGrayImage to auto-detect based on pixel data
	if ( cpy.image()->colorspace == MagickCore::ColorspaceType::sRGBColorspace )
		cpy.image()->colorspace = MagickCore::ColorspaceType::RGBColorspace;

        // eliminate alpha channel garbage
	if ( cpy.constImage()->matte )
		SetImageAlphaChannel( cpy.image(), MagickCore::AlphaChannelType::BackgroundAlphaChannel ) ;

	return IsGrayImage( cpy.constImage(), &cpy.image()->exception );
}	// is_gray_img


// image load routine...
Magick::Image img;  

// load image data here

// set grayscale type if appropriate
if ( is_gray_img( img ) )
    img.colorspaceType( MagickCore::ColorspaceType::GRAYColorspace );

// now the image is handled properly

tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

Re: PNG: read/write degrades/corrupts image

Post by tc33 »

Glenn, I was looking through the changelog for IM 6.8.2.x. I noted that you have made changes related to PNG en/decoding that may have addressed these issues, but I can't be certain. Were both of these issues addressed? The first issue being the grayscale image, the second being the transparent pixel issue I noted in my previous post.

Thanks for your continued support/improvements!
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: PNG: read/write degrades/corrupts image

Post by glennrp »

tc33 wrote:Glenn, I was looking through the changelog for IM 6.8.2.x. I noted that you have made changes related to PNG en/decoding that may have addressed these issues, but I can't be certain. Were both of these issues addressed? The first issue being the grayscale image, the second being the transparent pixel issue I noted in my previous post.

Thanks for your continued support/improvements!
The transparent-pixel issue is outside the scope of the png encoder. The png encoder writes whatever ImageMagick hands it, and in this case it receives an image with garbage colors that are not visible if the viewer accounts for the alpha channel. The bug is in whatever application created the image in the first place.
tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

Re: PNG: read/write degrades/corrupts image

Post by tc33 »

Thanks for your response regarding the transparent pixel issue. Is the grayscale image issue still open then?
tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

Re: PNG: read/write degrades/corrupts image

Post by tc33 »

Fixed/confirmed in IM 6.8.2.2. Thank you!
Post Reply