Page 1 of 1

PNG00 save of PNG8 file after resize fails with >256 colours, NULL colormap

Posted: 2015-05-11T23:09:00-07:00
by GreenReaper
I got the following error from png.c trying to write a PNG:

Code: Select all

lt-convert: Cannot write PNG8 or color-type 3; colormap is NULL `SirNathanMouse_the_abduction_dc2.png' @ error/png.c/WriteOnePNGImage/9262.
Here is the image. It has a full 256-color palette, although not all of the colours appear to be used. The full command line was:

Code: Select all

convert 'the_abduction_dc.png' -resize '920x1840>' -quality 100 -strip +profile '*' -define png:exclude-chunk=gama PNG00:'SirNathanMouse_the_abduction_dc2.png'
This issue occurred with ImageMagick-6.9.1-2 and ImageMagick-6.9.1-3~beta20150509 built on Debian wheezy
The issue occurred with both --with-quantum-depth=16 and --with-quantum-depth=8
The issue does not occur if I remove the "PNG00:" at the start (it creates a 32-bit file)
It also does not occur if I use "PNG8:" (it creates an 8-bit file with 153-color palette, including a background color).

Debug output:

Code: Select all

  Domain: Coder; rights=Write; pattern="PNG00" ...
  Enter WritePNGImage()
    Format=(null)
    png00 inherited bit depth=8
    png00 inherited color type=3
    png:exclude-chunk=gama found in image options.
    png:exclude-chunk=gama found in image artifacts.
    Chunks to be excluded from the output png:
      gAMA
    Enter WriteOnePNGImage()
      IM version     = 6.9.1-3
      Libpng version = 1.2.49
      Zlib version   = 1.2.7
      image->storage_class=DirectClass
      image_info->magick= PNG00
      image->taint=MagickTrue
      Freeing bogus colormap
      Enter BUILD_PALETTE:
        image->columns=920
        image->rows=1199
        image->matte=0
        image->depth=8
        image->colors=256
        Regenerate the colormap
        Check colormap for background (65535,65535,65535)
        No room in the colormap to add background color
        image has more than 256 colors
        image->colors=256
        number_transparent     = 0
        number_opaque          > 256
        number_semitransparent = 0
        At least one pixel or the background is non-gray
      Exit BUILD_PALETTE:

Re: PNG00 save of PNG8 file after resize fails with >256 colours, NULL colormap

Posted: 2015-05-12T09:36:32-07:00
by glennrp
PNG00 means "use the same colortype as the input image". But when you -resize, you add colors so if the input was indexed and the resized image has more than 256 colors, it can't. "PNG8" doesn't fail because that forces the palette to be reduced to 256 or fewer colors. The failure you observed is the correct behavior, but the error message might be confusing. Maybe "image has too many colors" would be less confusing, or maybe not.

Re: PNG00 save of PNG8 file after resize fails with >256 colours, NULL colormap

Posted: 2015-05-12T15:47:01-07:00
by GreenReaper
I don't see that as the correct behaviour. I expect it to reduce the palette to 256 colors, because the initial image was a 256-color image. To put it another way, it should behave as "PNG8" for "PNG8" files. (I'm probably missing some subtitles of PNG or ImageMagick terminology here, but hopefully you get the gist.)

If for some reason that isn't possible, I'd expect it to produce a 32-bit PNG. I certainly wouldn't expect it to fail and produce no image, which throws our whole process workflow into disarray. :-)

This is part of an automatic thumbnailing/display scaling system and the ideal result is to have an image which of the same type, just a different size. We don't want to make 8-bit images huge, nor do we wish to reduce the quality of truecolour images, so we used PNG00.

Re: PNG00 save of PNG8 file after resize fails with >256 colours, NULL colormap

Posted: 2015-05-12T16:52:17-07:00
by fmw42
As I understand Glenn's comment, PNG00 is only pertinent if you are converting directly. IM does not keep track of that type through all the other additional commands that increase the number of colors. If you want a PNG8 output or a PNG32, then you need to query the image to determine what it is and then preface the output with PNG8: or PNG32. You can get that information from identify -verbose or use

Code: Select all

convert image -format "%[type]" info:
where you can see the options by

Code: Select all

convert -list type

Bilevel
ColorSeparation
ColorSeparationAlpha
ColorSeparationMatte
Grayscale
GrayscaleAlpha
GrayscaleMatte
Optimize
Palette
PaletteBilevelAlpha
PaletteBilevelMatte
PaletteAlpha
PaletteMatte
TrueColorAlpha
TrueColorMatte
TrueColor
I do not understand why there is an error message with respect to the use of PNG00:. But I would guess is that it is ambiguous due to all the extra processing and IM cannot tell what format to make it. Perhaps it could be changed to default to PNG24 or PNG32 depending up whether an alpha channel was in the input.

Re: PNG00 save of PNG8 file after resize fails with >256 colours, NULL colormap

Posted: 2015-05-12T19:00:40-07:00
by glennrp
GreenReaper wrote:I don't see that as the correct behaviour. I expect it to reduce the palette to 256 colors, because the initial image was a 256-color image. To put it another way, it should behave as "PNG8" for "PNG8" files. (I'm probably missing some subtitles of PNG or ImageMagick terminology here, but hopefully you get the gist.)
The PNG encoder is not receiving the original image. It is receiving a modified image that has too many colors to be represented without loss as PNG8. It could, as you suggest, reduce the palette back to 256 or fewer colors, but you probably won't like the result.
If for some reason that isn't possible, I'd expect it to produce a 32-bit PNG. I certainly wouldn't expect it to fail and produce no image, which throws our whole process workflow into disarray. :-)
It can't produce a 32-bit PNG because you have requested a PNG8.

This is part of an automatic thumbnailing/display scaling system and the ideal result is to have an image which of the same type, just a different size. We don't want to make 8-bit images huge, nor do we wish to reduce the quality of truecolour images, so we used PNG00.
But it's not just a different size. It has a different palette, that happens to have more than 256 colors. If you were to "-sample" instead of "-resize" then you would not be changing the palette and the PNG8 write would succeed. But the result is likely to be ugly.

Bottom line: don't use PNG00 if you are resizing the image or otherwise tainting the pixels.