Reducing palette length and bit depth changes image
Brought to you by:
glennrp
If source image is a 8-bit depth palette PNG that only uses 4 unique colours but does not use black colour, reducing bit depth to 2 and palette length to 4 colour via switches "-reduce -brute -rem alla -bit_depth 2 -plte_len 4" causes PNGCrush to turn one colour to black (see attachment acme). In addition, using -reduce switch alone does not reduce output images bit depth or palette length in such case.
acme.png
Logged In: YES
user_id=7859
Originator: NO
thanks
After working with the attachment, it turns out the -reduce switch does not perform color-type or bit-depth reduction at all. It should have reduce bit depth based on the number of unique colours, but fails to deliver. I ended up having to use pngout to finish the job and find out the uselessness of the -reduce switch. The bug also affects processing of greyscale images, not just palette images. To further confusing the situation, the manual describes -plte_len switch as follows:
Be sure not to truncate it to less than the greatest index present in IDAT.
How does a user suppose to know what is the greatest index present in IDAT, when the source IDAT is compressed, and the source image's palette order may be unknown to user? The -plte_len should be made loseless and rearranges palette order, unless user chooses to preserve source image's palette order.
note: The change log of pngcrush 1.7.15 mentions it forces bit_depth to 1, 2, or 4 when -plte_len is <=2, <=4, or <=16 and the -bit_depth option is not present. However, without a precompiled binary this pngcrush release, I am unable to verify the effectiveness of this feature. Besides, this does not imply the -reduce switch will intelligently shrinks palette, which has not been working in the latest pngcrush binary (1.7.13 at the time of writing).
Turning one color to black is obviously a bug. It still exists in pngcrush-1.7.15.
The "-reduce" option only gives pngcrush permission to reduce an all-gray image to
grayscale, and to remove an all-opaque alpha channel. It does not do anything
with paletted images, as you have observed.
The current version of ImageMagick does much of what you want. It reduces
your acme.png (2127 bytes) to 5 colors (the 4 present in the image plus the one in the bKGD
chunk, 914 bytes). Using the ImageMagick "-define PNG:exclude-chunk=bkgd,text,ztxt" yields
a 652-byte file. Following the ImageMagick conversion, pngcrush further
reduces it to 640 bytes.
This seems to be fixed in pngcrush-1.7.79