The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly.

Image-Defining Chunks

The most direct way to define an image in MNG is simply to incorporate one. There are two possibilities for this in the current draft specification: a PNG image without the PNG signature, or the corresponding PNG-like JPEG format, JNG (JPEG Network Graphics).[94] Just as with standalone PNGs, an embedded PNG must contain at least IHDR, IDAT, and IEND chunks. It may also include PLTE, tRNS, bKGD, gAMA, cHRM, sRGB, tEXt, iTXt, and any of the other PNG chunks we've described. The PLTE chunk is allowed to be empty in an embedded PNG, which indicates that the global MNG PLTE data is to be used instead.

[94] OK, that's a stretch, acronym-wise. But it's pronounceable, rhymes with PNG and MNG, and has a file extension, .jng, that differs by only one letter from .jpg, .png, and .mng.

An embedded JNG stream is exactly analogous to the PNG stream: it begins with a JHDR chunk, includes one or more JDAT chunks containing the actual JPEG image data, and ends with an IEND chunk. Standalone JNGs are also allowed; they must include an 8-byte JNG signature before JHDR, with the format that's shown in Table 12-2.

Table 12-2. JNG Signature Bytes

ASCII Interpretation
139 A byte with its most significant bit set (``8-bit character'')
74 J
78 N
71 G
13 Carriage-return (CR) character, a.k.a. CTRL-M or ^M
10 Line-feed (LF) character, a.k.a. CTRL-J or ^J
26 CTRL-Z or ^Z
10 Line-feed (LF) character, a.k.a. CTRL-J or ^J

JDATs simply contain JFIF-compatible JPEG data, which can be either baseline, extended sequential, or progressive--i.e., the same format used in practically every web site and commonly (but imprecisely) referred to as JPEG files. The requirements on the allowed JPEG types eliminate the less-common arithmetic and lossless JPEG variants, though the 12-bit grayscale and 36-bit color flavors are still allowed.[95] To decode the JPEG image, simply concatenate all of the JDAT data together and treat the whole as a normal JFIF-format file stream--typically, this involves feeding the data to the Independent JPEG Group's free libjpeg library.

[95] MNG optionally allows 12-bit-per-sample JPEG image data to follow the far more common 8-bit flavor, giving decoders the freedom to choose whichever is most appropriate. If both are included, it is signalled in JHDR by a bit-depth value of 20 instead of 8 or 12, and the 8-bit and 12-bit JDATs are separated by a special JSEP chunk. The 8-bit data must come first. Note that current versions of libjpeg can only be compiled to handle either 8-bit or 12-bit JPEG data, not both simultaneously.

In order to accommodate an alpha channel, a JNG stream may also include one or more grayscale IDAT chunks. The JHDR chunk defines whether the image has an alpha channel or not, and if so, what its bit depth is. Unlike PNG, which restricts alpha channels to either 8 bits or 16 bits, a JNG alpha channel may be any legal PNG grayscale depth: 1, 2, 4, 8, or 16 bits. The IDATs composing the alpha channel may come before or after or be interleaved with the JDATs to allow progressive display of an alpha-JPEG image, but no other chunk types are allowed within the block of IDATs and JDATs.

Although incorporating complete JNGs or PNGs is conceptually the simplest approach to defining images in a MNG stream, it is generally not the most efficient way. MNG provides two basic alternatives that can be much better in many cases; the first of these is delta images.[96] A delta image is simply a difference image; combining it with its parent re-creates the original image, in much the same way that combining an ``up''-filtered row of pixels with the previous row results in the original, unfiltered row. (Recall the discussion of compression filters in "Compression and Filtering".) The difference of two arbitrary images is likely to be at least as large as either parent image, but certain types of images may respond quite well to differencing. For example, consider a pair of prototype images for a web page, both containing the same background graphics and much of the same text, but differing in small, scattered regions. Since 90% of the image area is identical, the difference of the two will be 90% zeros, and therefore will compress much better than either of the original images will.

[96] Named for the Greek letter delta (Δ or δ), which is often used in science and engineering to denote differences.

Currently, MNG allows delta images to be encoded only in PNG format, and it delimits them with the DHDR and IEND chunks. In addition to the delta options for pixels given in DHDR--whether the delta applies to the main image pixels or to the alpha channel, and whether applying the delta involves pixel addition or merely replacement of an entire block--MNG defines several chunks for modifying the parent image at a higher level. Among these are the PROM chunk, for promoting the bit depth or color type of an image, including adding an alpha channel to it; the DROP and DBYK chunks, for dropping certain chunks, either by name alone or by both name and keyword; and the PPLT chunk, for modifying the parent's palette (either PLTE or tRNS, or both). The latter could be used to animate the palette of an image, for example; cycling the colors is a popular option in some fractal programs. PPLT could also be used to fade out an image by adding an opaque tRNS chunk and then progressively changing the values of all entries until the image is fully transparent.

The second and more powerful alternative to defining an image by including its complete pixel data is object manipulation. In this mode, MNG basically treats images as little pieces of paper that can be copied and pasted at will. For example, a polka-dot image could be created from a single bitmap of a circle with a transparent background, which could be copied and pasted multiple times to create the complete, composite image. Alternatively, tileable images of a few basic pipe fittings and elbow joints could be pasted together in various orientations to create an image of a maze. The three chunks used for creating or destroying images in the object sense are CLON (``clone''), PAST (``paste''), and DISC (``discard'').

The CLON chunk is the only one necessary for the first example; it not only copies an image object in the abstract sense, but also gives it a position in the current frame--either as an absolute location or as an offset from the object that was copied. In order to change the orientation of objects, as in the maze example, the PAST chunk is required; as currently defined, it only supports 180° rotations and mirror operations around the x and y axes. (90° rotations were ruled out since they are rarely supported in hardware, and abstract images are intended to map to hardware and platform-specific APIs as closely as possible.) PAST also includes options to tile an object, and not only to replace the underlying pixel data but also to composite either over or under it, assuming either the object or underlying image includes transparency information. Once component objects are no longer needed--for example, in the maze image when the maze is completely drawn--the decoder can be instructed to discard them via the DISC chunk.

Last Update: 2010-Nov-26