MNG Structure
So that's some of what MNG can do; now let's take a closer look at what the
format looks like and how it works. To begin with, MNG is chunk-based, just
like PNG. It has an 8-byte signature similar to PNG's, but it differs
in the first two bytes, as shown in Table 12-1.
Table 12-1.
MNG Signature Bytes
|
Decimal Value |
ASCII Interpretation
|
138 |
A byte with its most significant bit set (``8-bit character'') |
77 |
M |
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 |
So while a PNG-supporting application could be trivially modified to identify
and parse a MNG stream,[92]
there is no danger that an older PNG application might mistake a MNG stream for a
PNG image. Since the file extensions differ as well (.mng instead
of .png), ordinary users are unlikely to confuse images with animations. The only cases in which they might do so are when an allowed component
type (e.g., a PNG or a JNG) is renamed with a .mng extension; such
files are considered legal MNGs.
With the exception of such renamed image formats, all MNG streams begin with
the MNG signature and MHDR chunk, and they all end with the MEND chunk.
The latter, like PNG's IEND, is an empty chunk that simply indicates the
end of the stream. MHDR, however, contains seven fields, all unsigned
32-bit integers: frame width, frame height, ticks per second, number of
layers, number of frames, total play time, and the complexity (or simplicity)
profile.
Frame width and height are just what they sound like: they give the overall
size of the displayable region in pixels. A MNG stream that contains no
visible images--say, a collection of palettes--should have its frame
dimensions set to zero.
The ticks-per-second value is essentially a scale factor for
time-related fields in other chunks, including the frame rate. In the
absence of any other timing information, animations are recommended to
be displayed at a rate of one frame per tick. For single-frame MNGs,
the ticks-per-second value is recommended to be 0, providing decoders
with an easy way to detect non-animations. Conversely, if the value
is 0 for a multiframe MNG, decoders are required to display only the
first frame unless the user specifically intervenes in some way.
``Number of layers'' refers to the total number of displayable images in the
MNG stream, including the background. This may be many more than the number
of frames, since a single frame often consists of multiple images composited
(or layered) on top of one another. Some of the layers may be empty if they
lie completely outside the clipping boundaries. The layer count is purely
advisory; if it is 0, the count is considered unspecified. At the other
end of the spectrum, a value of 231-1 (2,147,483,647) is
considered infinite.
The frame-count and play-time values are also basically what they sound
like: on an ideal computer (i.e., one with infinite processing speed), they
respectively indicate the number of frames that correspond to distinct instants
of time[93]
and the overall duration of the complete animation. As with the layer count,
these values are advisory; 0 and 231-1 correspond to
``unspecified'' and ``infinite,'' respectively.
Finally, MHDR's complexity profile provides some indication of the level of
complexity in the stream, in order to allow simple decoders to give up
immediately if the MNG file contains features they are unable to render.
The profile field is also advisory; a value of zero is allowed and indicates
that the complexity level is unspecified. But a nonzero value indicates
that the encoder has provided information about the presence or absence of
JPEG (JNG) chunks, transparency, or complex MNG features. The latter
category includes most of the animation features mentioned earlier,
including looping and object manipulation (i.e., sprites). All
possible combinations of the three categories are encoded in the lower
4 bits of the field as odd values only--all even values other
than zero are invalid, which means the lowest bit is always set if the
profile contains any useful information. The remaining bits of the
2 lower bytes are reserved for public expansion, and all but the
most significant bit of the 2 upper bytes are available for private
or experimental use. The topmost bit must be zero.
Note that any unset (0) bit guarantees that the corresponding feature
is not present or the MNG stream is invalid. A set bit, on the
other hand, does not automatically guarantee that the feature is
included, but encoders should be as accurate as possible to avoid
causing simple decoders to reject MNGs unnecessarily.
The stuff that goes between the MHDR and MEND chunks can be divided into a
few basic categories:
- Image-defining chunks
- Image-displaying chunks
- Control chunks
- Ancillary (optional) chunks
Note the distinction between defining an image
and displaying
it. This will make sense in the context of a composite frame made up of
many subimages. Alternatively, consider a sprite-based animation composed
of several sprite ``poses'' that should be read into memory (i.e., defined)
as part of the animation's initialization procedure. The sprite frames may
not actually be used until much later, perhaps only in response to user
input.
|