|The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly.|
|Home Applications Applications: Image Converters pngcheck|
Originally written by Alexander Lehmann as a simple tool to check PNG
images for corruption, such as might occur if the file were
transferred in text mode, pngcheck was subsequently extended by
Andreas Dilger, Greg Roelofs, and others, evolving into a nearly
complete PNG syntax checker and content dumper. The latest versions
(1.99-grr1 is current as of this writing) even include partial support
for MNG files, the multi-image PNG extension described in
Chapter 12, "Multiple-Image Network Graphics" (Multiple-Image Network Graphics). pngcheck is
most often used to understand why a particular image is larger than
expected--perhaps a 16-color image was saved in 24-bit RGB format
instead of palette format, or a truecolor image was saved with minimal
compression and no filtering. But it can also be used simply to test
and print their dimensions, image types, and approximate compression
The most basic use of pngcheck involves giving it one or more filenames and no options, like so:
pngcheck foo.png foo2.png foo3.png
This results in output similar to the following, except that here the lines have been wrapped to fit the page:
No errors detected in foo.png (578x802, 24-bit RGB, interlaced, 54.7%). No errors detected in foo2.png (32x32, 4-bit colormap, interlaced, 36.1%). No errors detected in foo3.png (32x32, 64-bit RGB+alpha, non-interlaced, 58.1%).
An image that has been corrupted in some way might cause an error message such as the following:
foo4.png: File is CORRUPTED by text conversion. foo4.png: Chunk name 00 0d 49 48 doesn't conform to naming rules.
But pngcheck is most useful for seeing what's inside a PNG image. The -v option, for verbose mode, prints the name of each chunk within the file, along with some basic information wherever appropriate. Because it can be a tad lengthy, it is often a good idea to pipe the program's verbose output through a paging filter such as more. The following example works on both Unix-based systems and DOS, OS/2, and Windows command lines:
pngcheck -v imgcomp.png | more File: imgcomp.png (34163 bytes) chunk IHDR at offset 0x0000c, length 13 640 x 480 image, 32-bit RGB+alpha, non-interlaced chunk gAMA at offset 0x00025, length 4: 0.45455 chunk IDAT at offset 0x00035, length 8192 zlib: deflated, 32K window, default compression chunk IDAT at offset 0x02041, length 8192 chunk IDAT at offset 0x0404d, length 8192 chunk IDAT at offset 0x06059, length 8192 chunk IDAT at offset 0x08065, length 1274 chunk IEND at offset 0x0856b, length 0 No errors detected in imgcomp.png (97.2% compression).
In this example, we see a fairly basic PNG file, a truecolor image with an alpha channel, composed of only four chunk types: the required IHDR, IDAT, and IEND chunks (described in Chapter 8, "PNG Basics"), plus the optional but highly recommended gamma-correction chunk, gAMA (Chapter 10, "Gamma Correction and Precision Color"). Because the image primarily consists of solid-colored regions and simple gradients, it compressed unusually well; this probably indicates that dynamic filtering was used, but there is no way to be certain, given the preceding information.
However, pngcheck can optionally use the zlib compression library in order to look inside the compressed image data. In this case, it supports a -vv option (``very verbose'') that prints out all of the preceding information plus filtering information. The filter output can be extremely long; for just the first IDAT chunk in the preceding example, it looks like this:
chunk IDAT at offset 0x00035, length 8192 zlib: deflated, 32K window, default compression zlib line filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4 1 4 1 4 1 4 2 4 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 2 (200 out of 480)
The details are too complex to cover right now, but filtering and compression are discussed in Chapter 9, "Compression and Filtering". All that matters here is that different filters have been used for different rows in the image, indicating that some sort of dynamic filtering was applied (which is generally good). Unfiltered images, on the other hand, will have all zeros for the filter numbers, and statically filtered images will use only a single filter type. In most cases, that means the image is not compressed as well as it could be. One major exception, however, is palette-based images; they rarely respond well to filtering, and most programs don't try.
pngcheck also supports more specific types of output. Its -p option, for example, is another rather verbose case; it prints the contents of the palette and optional transparency chunks for colormapped images. This can be useful in conjunction with a program such as pngcrush, for example, when one wishes to specify a particular color as transparent, but more commonly it is used to check whether the transparency chunk is full of needless opaque values. Consider the following example:
pngcheck -p foo5.png File: foo5.png (146 bytes) PLTE chunk: 4 palette entries 0: ( 0,255, 0) = (0x00,0xff,0x00) 1: (255, 0, 0) = (0xff,0x00,0x00) 2: (255,255, 0) = (0xff,0xff,0x00) 3: ( 0, 0,255) = (0x00,0x00,0xff) tRNS chunk: 3 transparency entries 0: 255 = 0xff 1: 255 = 0xff 2: 0 = 0x00 No errors detected in foo5.png (32x32, 2-bit colormap, non-interlaced, 43.0%).
Here we have a four-color image: bright green, red, yellow, and blue. The colors of the palette are listed as RGB triplets in both decimal and hexadecimal (base 16) for convenience. The palette itself is unremarkable; what is more interesting is the transparency chunk, tRNS. It includes three entries, but the first two have the value 255, which indicates that the corresponding palette entries should be treated as completely opaque. But all palette entries are considered opaque unless explicitly given a non-opaque transparency value--in other words, any transparency entries with the value 255 are redundant and represent wasted space. In this case, the only non-opaque entry corresponds to the third color, yellow; a smart PNG-writing program would have reordered the palette so that yellow was the first entry, thus shaving two bytes off the file. It is not uncommon to be able to save 100 or more bytes in this manner, which can represent 10% to 20% of the file size for small web graphics. In rare cases, it may be worthwhile to waste a few transparency entries so that the most common pixels in the image are all at the beginning of the palette (i.e., so they all have index values near zero); with filtering enabled, the compression engine may be able to make up the difference and then some. But as of early 1999, filtering has yet to be demonstrated effective on essentially any kind of palette-based image, so the possibility of recovering wasted transparency entries with improved compression is a rather tenuous one.
The other type of verbose pngcheck output is more useful to ordinary users, not just content developers trying to optimize things. The -t option prints not only text chunks' keywords but also their contents:
pngcheck -t ct1n0g04.png File: ct1n0g04.png (796 bytes) Title:PngSuite Author:Willem A.J. van Schaik (firstname.lastname@example.org) Copyright:Copyright Willem van Schaik, Singapore 1995 Description:A compilation of a set of images created to test the various color-types of the PNG format. Included are black&white, color, paletted, with alpha channel, with transparency formats. All bit-depths allowed according to the spec are present. Software:Created on a NeXTstation color using "pnmtopng". Disclaimer:Freeware. No errors detected in ct1n0g04.png (32x32, 4-bit grayscale, non-interlaced, -55.5%).
This example, using one of Willem van Schaik's test images from the PNG Suite, contains six text chunks with keywords Title, Author, Copyright, Description, Software, and Disclaimer. The content of each chunk immediately follows the keyword and colon; this is not the most readable approach, but the information is available and usually understandable with only a little squinting. One deficiency of the current version is that it does not display the contents of compressed text chunks (zTXt), even when using the zlib compression library. This is promised to be fixed in a future version, however.
The latest version of pngcheck can be found at the PNG home site,
|Home Applications Applications: Image Converters pngcheck|