Software Software used to create the image
Disclaimer Legal disclaimer
Warning Warning of nature of content
Source Device used to create the image
Comment Miscellaneous comment; conversion from
GIF comment
For the Creation Time keyword, the date format defined in
section 5.2.14 of RFC1123 is suggested, but not required
[RFC-1123]. Decoders should allow for free-format text
associated with this or any other keyword.
Other keywords may be invented for other purposes. Keywords of
general interest can be registered with the maintainers of the
PNG specification. However, it is also permitted to use
private unregistered keywords. (Private keywords should be
reasonably self-explanatory, in order to minimize the chance
that the same keyword will be used for incompatible purposes by
different people.)
Both keyword and text are interpreted according to the ISO
8859-1 (Latin-1) character set [ISO-8859]. The text string can
contain any Latin-1 character. Newlines in the text string
should be represented by a single linefeed character (decimal
10); use of other control characters in the text is
discouraged.
Keywords must contain only printable Latin-1 characters and
spaces; that is, only character codes 32-126 and 161-255
decimal are allowed. To reduce the chances for human
misreading of a keyword, leading and trailing spaces are
forbidden, as are consecutive spaces. Note also that the non-
breaking space (code 160) is not permitted in keywords, since
it is visually indistinguishable from an ordinary space.
Keywords must be spelled exactly as registered, so that
decoders can use simple literal comparisons when looking for
particular keywords. In particular, keywords are considered
case-sensitive.
See Recommendations for Encoders: Text chunk processing
(Section 9.7) and Recommendations for Decoders: Text chunk
processing (Section 10.11).
4.2.8. tIME Image last-modification time
The tIME chunk gives the time of the last image modification
(not the time of initial image creation). It contains:
Year: 2 bytes (complete; for example, 1995, not 95)
Month: 1 byte (1-12)
Day: 1 byte (1-31)
Hour: 1 byte (0-23)
Minute: 1 byte (0-59)
Second: 1 byte (0-60) (yes, 60, for leap seconds; not 61,
a common error)
Universal Time (UTC, also called GMT) should be specified
rather than local time.
The tIME chunk is intended for use as an automatically-applied
time stamp that is updated whenever the image data is changed.
It is recommended that tIME not be changed by PNG editors that
do not change the image data. See also the Creation Time tEXt
keyword, which can be used for a user-supplied time.
4.2.9. tRNS Transparency
The tRNS chunk specifies that the image uses simple
transparency: either alpha values associated with palette
entries (for indexed-color images) or a single transparent
color (for grayscale and truecolor images). Although simple
transparency is not as elegant as the full alpha channel, it
requires less storage space and is sufficient for many common
cases.
For color type 3 (indexed color), the tRNS chunk contains a
series of one-byte alpha values, corresponding to entries in
the PLTE chunk:
Alpha for palette index 0: 1 byte
Alpha for palette index 1: 1 byte
... etc ...
Each entry indicates that pixels of the corresponding palette
index must be treated as having the specified alpha value.
Alpha values have the same interpretation as in an 8-bit full
alpha channel: 0 is fully transparent, 255 is fully opaque,
regardless of image bit depth. The tRNS chunk must not contain
more alpha values than there are palette entries, but tRNS can
contain fewer values than there are palette entries. In this
case, the alpha value for all remaining palette entries is
assumed to be 255. In the common case in which only palette
index 0 need be made transparent, only a one-byte tRNS chunk is
needed.
For color type 0 (grayscale), the tRNS chunk contains a single
gray level value, stored in the format:
Gray: 2 bytes, range 0 .. (2^bitdepth)-1
(For consistency, 2 bytes are used regardless of the image bit
depth.) Pixels of the specified gray level are to be treated as
transparent (equivalent to alpha value 0); all other pixels are
to be treated as fully opaque (alpha value (2^bitdepth)-1).
For color type 2 (truecolor), the tRNS chunk contains a single
RGB color value, stored in the format:
Red: 2 bytes, range 0 .. (2^bitdepth)-1
Green: 2 bytes, range 0 .. (2^bitdepth)-1
Blue: 2 bytes, range 0 .. (2^bitdepth)-1
(For consistency, 2 bytes per sample are used regardless of the
image bit depth.) Pixels of the specified color value are to be
treated as transparent (equivalent to alpha value 0); all other
pixels are to be treated as fully opaque (alpha value
(2^bitdepth)-1).
tRNS is prohibited for color types 4 and 6, since a full alpha
channel is already present in those cases.
Note: when dealing with 16-bit grayscale or truecolor data, it
is important to compare both bytes of the sample values to
determine whether a pixel is transparent. Although decoders
may drop the low-order byte of the samples for display, this
must not occur until after the data has been tested for
transparency. For example, if the grayscale level 0x0001 is
specified to be transparent, it would be incorrect to compare
only the high-order byte and decide that 0x0002 is also
transparent.
When present, the tRNS chunk must precede the first IDAT chunk,
and must follow the PLTE chunk, if any.
4.2.10. zTXt Compressed textual data
The zTXt chunk contains textual data, just as tEXt does;
however, zTXt takes advantage of compression. zTXt and tEXt
chunks are semantically equivalent, but zTXt is recommended for
storing large blocks of text.
A zTXt chunk contains:
Keyword: 1-79 bytes (character string)
Null separator: 1 byte
Compression method: 1 byte
Compressed text: n bytes
The keyword and null separator are exactly the same as in the
tEXt chunk. Note that the keyword is not compressed. The
compression method byte identifies the compression method used
in this zTXt chunk. The only value presently defined for it is
0 (deflate/inflate compression). The compression method byte is
followed by a compressed datastream that makes up the remainder
of the chunk. For compression method 0, this datastream
adheres to the zlib datastream format (see Deflate/Inflate
Compression, Chapter 5). Decompression of this datastream
yields Latin-1 text that is identical to the text that would be
stored in an equivalent tEXt chunk.
Any number of zTXt and tEXt chunks can appear in the same file.
See the preceding definition of the tEXt chunk for the
predefined keywords and the recommended format of the text.
See Recommendations for Encoders: Text chunk processing
(Section 9.7), and Recommendations for Decoders: Text chunk
processing (Section 10.11).
4.3. Summary of standard chunks
This table summarizes some properties of the standard chunk types.
Critical chunks (must appear in this order, except PLTE
is optional):
Name Multiple Ordering constraints
OK?
IHDR No Must be first
PLTE No Before IDAT
IDAT Yes Multiple IDATs must be consecutive
IEND No Must be last
Ancillary chunks (need not appear in this order):
Name Multiple Ordering constraints
OK?
cHRM No Before PLTE and IDAT
gAMA No Before PLTE and IDAT
sBIT No Before PLTE and IDAT
bKGD No After PLTE; before IDAT
hIST No After PLTE; before IDAT
tRNS No After PLTE; before IDAT
pHYs No Before IDAT
tIME No None
tEXt Yes None
zTXt Yes None
Standard keywords for tEXt and zTXt chunks:
Title Short (one line) title or caption for image
Author Name of image's creator
Description Description of image (possibly long)
Copyright Copyright notice
Creation Time Time of original image creation
Software Software used to create the image
Disclaimer Legal disclaimer
Warning Warning of nature of content
Source Device used to create the image
Comment Miscellaneous comment; conversion from
GIF comment
4.4. Additional chunk types
Additional public PNG chunk types are defined in the document "PNG
Special-Purpose Public Chunks" [PNG-EXTENSIONS]. Chunks described
there are expected to be less widely supported than those defined
in this specification. However, application authors are
encouraged to use those chunk types whenever appropriate for their
applications. Additional chunk types can be proposed for
inclusion in that list by contacting the PNG specification
maintainers at png-info@uunet.uu.net or at png-group@w3.org.
New public chunks will only be registered if they are of use to
others and do not violate the design philosophy of PNG. Chunk
registration is not automatic, although it is the intent of the
authors that it be straightforward when a new chunk of potentially
wide application is needed. Note that the creation of new
critical chunk types is discouraged unless absolutely necessary.
Applications can also use private chunk types to carry data that
is not of interest to other applications. See Recommendations for
Encoders: Use of private chunks (Section 9.8).
Decoders must be prepared to encounter unrecognized public or
private chunk type codes. Unrecognized chunk types must be
handled as described in Chunk naming conventions (Section 3.3).
5. Deflate/Inflate Compression
PNG compression method 0 (the only compression method presently
defined for PNG) specifies deflate/inflate compression with a 32K
sliding window. Deflate compression is an LZ77 derivative used in
zip, gzip, pkzip and related programs. Extensive research has been
done supporting its patent-free status. Portable C implementations
are freely available.
Deflate-compressed datastreams within PNG are stored in the "zlib"
format, which has the structure:
Compression method/flags code: 1 byte
Additional flags/check bits: 1 byte
Compressed data blocks: n bytes
Check value: 4 bytes
Further details on this format are given in the zlib specification
[RFC-1950].
For PNG compression method 0, the zlib compression method/flags code
must specify method code 8 ("deflate" compression) and an LZ77 window
size of not more than 32K. Note that the zlib compression method
number is not the same as the PNG compression method number. The
additional flags must not specify a preset dictionary.
The compressed data within the zlib datastream is stored as a series
of blocks, each of which can represent raw (uncompressed) data,
LZ77-compressed data encoded with fixed Huffman codes, or LZ77-
compressed data encoded with custom Huffman codes. A marker bit in
the final block identifies it as the last block, allowing the decoder
to recognize the end of the compressed datastream. Further details
on the compression algorithm and the encoding are given in the
deflate specification [RFC-1951].
The check value stored at the end of the zlib datastream is
calculated on the uncompressed data represented by the datastream.
Note that the algorithm used is not the same as the CRC calculation
used for PNG chunk check values. The zlib check value is useful
mainly as a cross-check that the deflate and inflate algorithms are
implemented correctly. Verifying the chunk CRCs provides adequate
confidence that the PNG file has been transmitted undamaged.
In a PNG file, the concatenation of the contents of all the IDAT
chunks makes up a zlib datastream as specified above. This
datastream decompresses to filtered image data as described elsewhere
in this document.
It is important to emphasize that the boundaries between IDAT chunks
are arbitrary and can fall anywhere in the zlib datastream. There is
not necessarily any correlation between IDAT chunk boundaries and
deflate block boundaries or any other feature of the zlib data. For
example, it is entirely possible for the terminating zlib check value
to be split across IDAT chunks.
In the same vein, there is no required correlation between the
structure of the image data (i.e., scanline boundaries) and deflate
block boundaries or IDAT chunk boundaries. The complete image data
is represented by a single zlib datastream that is stored in some
number of IDAT chunks; a decoder that assumes any more than this is
incorrect. (Of course, some encoder implementations may emit files
in which some of these structures are indeed related. But decoders
cannot rely on this.)
PNG also uses zlib datastreams in zTXt chunks. In a zTXt chunk, the
remainder of the chunk following the compression method byte is a
zlib datastream as specified above. This datastream decompresses to
the user-readable text described by the chunk's keyword. Unlike the
image data, such datastreams are not split across chunks; each zTXt
chunk contains an independent zlib datastream.
Additional documentation and portable C code for deflate and inflate
are available from the Info-ZIP archives at
<URL:ftp://ftp.uu.net/pub/archiving/zip/>.
6. Filter Algorithms
This chapter describes the filter algorithms that can be applied
before compression. The purpose of these filters is to prepare the
image data for optimum compression.
6.1. Filter types
PNG filter method 0 defines five basic filter types:
Type Name
0 None
1 Sub
2 Up
3 Average
4 Paeth
(Note that filter method 0 in IHDR specifies exactly this set of
five filter types. If the set of filter types is ever extended, a
different filter method number will be assigned to the extended
set, so that decoders need not decompress the data to discover
that it contains unsupported filter types.)
The encoder can choose which of these filter algorithms to apply
on a scanline-by-scanline basis. In the image data sent to the
compression step, each scanline is preceded by a filter type byte
that specifies the filter algorithm used for that scanline.
Filtering algorithms are applied to bytes, not to pixels,
regardless of the bit depth or color type of the image. The
filtering algorithms work on the byte sequence formed by a
scanline that has been represented as described in Image layout
(Section 2.3). If the image includes an alpha channel, the alpha
data is filtered in the same way as the image data.
When the image is interlaced, each pass of the interlace pattern
is treated as an independent image for filtering purposes. The
filters work on the byte sequences formed by the pixels actually
transmitted during a pass, and the "previous scanline" is the one
previously transmitted in the same pass, not the one adjacent in
the complete image. Note that the subimage transmitted in any one
pass is always rectangular, but is of smaller width and/or height
than the complete image. Filtering is not applied when this
subimage is empty.
For all filters, the bytes "to the left of" the first pixel in a
scanline must be treated as being zero. For filters that refer to
the prior scanline, the entire prior scanline must be treated as
being zeroes for the first scanline of an image (or of a pass of
an interlaced image).
To reverse the effect of a filter, the decoder must use the
decoded values of the prior pixel on the same line, the pixel
immediately above the current pixel on the prior line, and the
pixel just to the left of the pixel above. This implies that at
least one scanline's worth of image data will have to be stored by
the decoder at all times. Even though some filter types do not
refer to the prior scanline, the decoder will always need to store
each scanline as it is decoded, since the next scanline might use
a filter that refers to it.
PNG imposes no restriction on which filter types can be applied to
an image. However, the filters are not equally effective on all
types of data. See Recommendations for Encoders: Filter selection
(Section 9.6).
See also Rationale: Filtering (Section 12.9).
6.2. Filter type 0: None
With the None filter, the scanline is transmitted unmodified; it
is only necessary to insert a filter type byte before the data.
6.3. Filter type 1: Sub
The Sub filter transmits the difference between each byte and the
value of the corresponding byte of the prior pixel.
To compute the Sub filter, apply the following formula to each
byte of the scanline:
Sub(x) = Raw(x) - Raw(x-bpp)
where x ranges from zero to the number of bytes representing the
scanline minus one, Raw(x) refers to the raw data byte at that
byte position in the scanline, and bpp is defined as the number of
bytes per complete pixel, rounding up to one. For example, for
color type 2 with a bit depth of 16, bpp is equal to 6 (three
samples, two bytes per sample); for color type 0 with a bit depth
of 2, bpp is equal to 1 (rounding up); for color type 4 with a bit
depth of 16, bpp is equal to 4 (two-byte grayscale sample, plus
two-byte alpha sample).
Note this computation is done for each byte, regardless of bit
depth. In a 16-bit image, each MSB is predicted from the
preceding MSB and each LSB from the preceding LSB, because of the
way that bpp is defined.
Unsigned arithmetic modulo 256 is used, so that both the inputs
and outputs fit into bytes. The sequence of Sub values is
transmitted as the filtered scanline.
For all x < 0, assume Raw(x) = 0.
To reverse the effect of the Sub filter after decompression,
output the following value:
Sub(x) + Raw(x-bpp)
(computed mod 256), where Raw refers to the bytes already decoded.
6.4. Filter type 2: Up
The Up filter is just like the Sub filter except that the pixel
immediately above the current pixel, rather than just to its left,
is used as the predictor.
To compute the Up filter, apply the following formula to each byte
of the scanline:
Up(x) = Raw(x) - Prior(x)
where x ranges from zero to the number of bytes representing the
scanline minus one, Raw(x) refers to the raw data byte at that
byte position in the scanline, and Prior(x) refers to the
unfiltered bytes of the prior scanline.
Note this is done for each byte, regardless of bit depth.
Unsigned arithmetic modulo 256 is used, so that both the inputs
and outputs fit into bytes. The sequence of Up values is
transmitted as the filtered scanline.
On the first scanline of an image (or of a pass of an interlaced
image), assume Prior(x) = 0 for all x.
To reverse the effect of the Up filter after decompression, output
the following value:
Up(x) + Prior(x)
(computed mod 256), where Prior refers to the decoded bytes of the
prior scanline.
6.5. Filter type 3: Average
The Average filter uses the average of the two neighboring pixels
(left and above) to predict the value of a pixel.
To compute the Average filter, apply the following formula to each
byte of the scanline:
Average(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2)
where x ranges from zero to the number of bytes representing the
scanline minus one, Raw(x) refers to the raw data byte at that
byte position in the scanline, Prior(x) refers to the unfiltered
bytes of the prior scanline, and bpp is defined as for the Sub
filter.
Note this is done for each byte, regardless of bit depth. The
sequence of Average values is transmitted as the filtered
scanline.
The subtraction of the predicted value from the raw byte must be
done modulo 256, so that both the inputs and outputs fit into
bytes. However, the sum Raw(x-bpp)+Prior(x) must be formed
without overflow (using at least nine-bit arithmetic). floor()
indicates that the result of the division is rounded to the next
lower integer if fractional; in other words, it is an integer
division or right shift operation.
For all x < 0, assume Raw(x) = 0. On the first scanline of an
image (or of a pass of an interlaced image), assume Prior(x) = 0
for all x.
To reverse the effect of the Average filter after decompression,
output the following value:
Average(x) + floor((Raw(x-bpp)+Prior(x))/2)
where the result is computed mod 256, but the prediction is
calculated in the same way as for encoding. Raw refers to the
bytes already decoded, and Prior refers to the decoded bytes of
the prior scanline.
6.6. Filter type 4: Paeth
The Paeth filter computes a simple linear function of the three
neighboring pixels (left, above, upper left), then chooses as
predictor the neighboring pixel closest to the computed value.
This technique is due to Alan W. Paeth [PAETH].
To compute the Paeth filter, apply the following formula to each
byte of the scanline:
Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x),
Prior(x-bpp))
where x ranges from zero to the number of bytes representing the
scanline minus one, Raw(x) refers to the raw data byte at that
byte position in the scanline, Prior(x) refers to the unfiltered
bytes of the prior scanline, and bpp is defined as for the Sub
filter.
Note this is done for each byte, regardless of bit depth.
Unsigned arithmetic modulo 256 is used, so that both the inputs
and outputs fit into bytes. The sequence of Paeth values is
transmitted as the filtered scanline.
The PaethPredictor function is defined by the following
pseudocode:
function PaethPredictor (a, b, c)
begin
; a = left, b = above, c = upper left
p := a + b - c ; initial estimate
pa := abs(p - a) ; distances to a, b, c
pb := abs(p - b)
pc := abs(p - c)
; return nearest of a,b,c,
; breaking ties in order a,b,c.
if pa <= pb AND pa <= pc then return a
else if pb <= pc then return b
else return c
end
The calculations within the PaethPredictor function must be
performed exactly, without overflow. Arithmetic modulo 256 is to
be used only for the final step of subtracting the function result
from the target byte value.
Note that the order in which ties are broken is critical and must
not be altered. The tie break order is: pixel to the left, pixel
above, pixel to the upper left. (This order differs from that
given in Paeth's article.)
For all x < 0, assume Raw(x) = 0 and Prior(x) = 0. On the first
scanline of an image (or of a pass of an interlaced image), assume
Prior(x) = 0 for all x.
To reverse the effect of the Paeth filter after decompression,
output the following value:
Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))
(computed mod 256), where Raw and Prior refer to bytes already
decoded. Exactly the same PaethPredictor function is used by both
encoder and decoder.
7. Chunk Ordering Rules
To allow new chunk types to be added to PNG, it is necessary to
establish rules about the ordering requirements for all chunk types.
Otherwise a PNG editing program cannot know what to do when it
encounters an unknown chunk.
We define a "PNG editor" as a program that modifies a PNG file and
wishes to preserve as much as possible of the ancillary information
in the file. Two examples of PNG editors are a program that adds or
modifies text chunks, and a program that adds a suggested palette to
a truecolor PNG file. Ordinary image editors are not PNG editors in
this sense, because they usually discard all unrecognized information
while reading in an image. (Note: we strongly encourage programs
handling PNG files to preserve ancillary information whenever
possible.)
As an example of possible problems, consider a hypothetical new
ancillary chunk type that is safe-to-copy and is required to appear
after PLTE if PLTE is present. If our program to add a suggested
PLTE does not recognize this new chunk, it may insert PLTE in the
wrong place, namely after the new chunk. We could prevent such
problems by requiring PNG editors to discard all unknown chunks, but
that is a very unattractive solution. Instead, PNG requires
ancillary chunks not to have ordering restrictions like this.
To prevent this type of problem while allowing for future extension,
we put some constraints on both the behavior of PNG editors and the
allowed ordering requirements for chunks.
7.1. Behavior of PNG editors
The rules for PNG editors are:
* When copying an unknown unsafe-to-copy ancillary chunk, a
PNG editor must not move the chunk relative to any critical
chunk. It can relocate the chunk freely relative to other
ancillary chunks that occur between the same pair of
critical chunks. (This is well defined since the editor
must not add, delete, modify, or reorder critical chunks if
it is preserving unknown unsafe-to-copy chunks.)
* When copying an unknown safe-to-copy ancillary chunk, a PNG
editor must not move the chunk from before IDAT to after
IDAT or vice versa. (This is well defined because IDAT is
always present.) Any other reordering is permitted.
* When copying a known ancillary chunk type, an editor need
only honor the specific chunk ordering rules that exist for
that chunk type. However, it can always choose to apply the
above general rules instead.
* PNG editors must give up on encountering an unknown critical
chunk type, because there is no way to be certain that a
valid file will result from modifying a file containing such
a chunk. (Note that simply discarding the chunk is not good
enough, because it might have unknown implications for the
interpretation of other chunks.)
These rules are expressed in terms of copying chunks from an input
file to an output file, but they apply in the obvious way if a PNG
file is modified in place.
See also Chunk naming conventions (Section 3.3).
7.2. Ordering of ancillary chunks
The ordering rules for an ancillary chunk type cannot be any
stricter than this:
* Unsafe-to-copy chunks can have ordering requirements
relative to critical chunks.
* Safe-to-copy chunks can have ordering requirements relative
to IDAT.
The actual ordering rules for any particular ancillary chunk type
may be weaker. See for example the ordering rules for the
standard ancillary chunk types (Summary of standard chunks,
Section 4.3).
Decoders must not assume more about the positioning of any
ancillary chunk than is specified by the chunk ordering rules. In
particular, it is never valid to assume that a specific ancillary
chunk type occurs with any particular positioning relative to
other ancillary chunks. (For example, it is unsafe to assume that
your private ancillary chunk occurs immediately before IEND. Even
if your application always writes it there, a PNG editor might
have inserted some other ancillary chunk after it. But you can
safely assume that your chunk will remain somewhere between IDAT
and IEND.)
7.3. Ordering of critical chunks
Critical chunks can have arbitrary ordering requirements, because
PNG editors are required to give up if they encounter unknown
critical chunks. For example, IHDR has the special ordering rule
that it must always appear first. A PNG editor, or indeed any
PNG-writing program, must know and follow the ordering rules for
any critical chunk type that it can emit.
8. Miscellaneous Topics
8.1. File name extension
On systems where file names customarily include an extension
signifying file type, the extension ".png" is recommended for PNG
files. Lower case ".png" is preferred if file names are case-
sensitive.
8.2. Internet media type
The Internet Assigned Numbers Authority (IANA) has registered
"image/png" as the Internet Media Type for PNG [RFC-2045, RFC-
2048]. For robustness, decoders may choose to also support the
interim media type "image/x-png" which was in use before
registration was complete.
8.3. Macintosh file layout
In the Apple Macintosh system, the following conventions are
recommended:
* The four-byte file type code for PNG files is "PNGf". (This
code has been registered with Apple for PNG files.) The
creator code will vary depending on the creating
application.
* The contents of the data fork must be a PNG file exactly as
described in the rest of this specification.
* The contents of the resource fork are unspecified. It may
be empty or may contain application-dependent resources.
* When transferring a Macintosh PNG file to a non-Macintosh
system, only the data fork should be transferred.
8.4. Multiple-image extension
PNG itself is strictly a single-image format. However, it may be
necessary to store multiple images within one file; for example,
this is needed to convert some GIF files. In the future, a
multiple-image format based on PNG may be defined. Such a format
will be considered a separate file format and will have a
different signature. PNG-supporting applications may or may not
choose to support the multiple-image format.
See Rationale: Why not these features? (Section 12.3).
8.5. Security considerations
A PNG file or datastream is composed of a collection of explicitly
typed "chunks". Chunks whose contents are defined by the
specification could actually contain anything, including malicious
code. But there is no known risk that such malicious code could
be executed on the recipient's computer as a result of decoding
the PNG image.
The possible security risks associated with future chunk types
cannot be specified at this time. Security issues will be
considered when evaluating chunks proposed for registration as
public chunks. There is no additional security risk associated
with unknown or unimplemented chunk types, because such chunks
will be ignored, or at most be copied into another PNG file.
The tEXt and zTXt chunks contain data that is meant to be
displayed as plain text. It is possible that if the decoder
displays such text without filtering out control characters,
especially the ESC (escape) character, certain systems or
terminals could behave in undesirable and insecure ways. We
recommend that decoders filter out control characters to avoid
this risk; see Recommendations for Decoders: Text chunk processing
(Section 10.11).
Because every chunk's length is available at its beginning, and
because every chunk has a CRC trailer, there is a very robust
defense against corrupted data and against fraudulent chunks that
attempt to overflow the decoder's buffers. Also, the PNG
signature bytes provide early detection of common file
transmission errors.
A decoder that fails to check CRCs could be subject to data
corruption. The only likely consequence of such corruption is
incorrectly displayed pixels within the image. Worse things might
happen if the CRC of the IHDR chunk is not checked and the width
or height fields are corrupted. See Recommendations for Decoders:
Error checking (Section 10.1).
A poorly written decoder might be subject to buffer overflow,
because chunks can be extremely large, up to (2^31)-1 bytes long.
But properly written decoders will handle large chunks without
difficulty.
9. Recommendations for Encoders
This chapter gives some recommendations for encoder behavior. The
only absolute requirement on a PNG encoder is that it produce files
that conform to the format specified in the preceding chapters.
However, best results will usually be achieved by following these
recommendations.
9.1. Sample depth scaling
When encoding input samples that have a sample depth that cannot
be directly represented in PNG, the encoder must scale the samples
up to a sample depth that is allowed by PNG. The most accurate
scaling method is the linear equation
output = ROUND(input * MAXOUTSAMPLE / MAXINSAMPLE)
where the input samples range from 0 to MAXINSAMPLE and the
outputs range from 0 to MAXOUTSAMPLE (which is (2^sampledepth)-1).
A close approximation to the linear scaling method can be achieved
by "left bit replication", which is shifting the valid bits to
begin in the most significant bit and repeating the most
significant bits into the open bits. This method is often faster
to compute than linear scaling. As an example, assume that 5-bit
samples are being scaled up to 8 bits. If the source sample value
is 27 (in the range from 0-31), then the original bits are:
4 3 2 1 0
---------
1 1 0 1 1
Left bit replication gives a value of 222:
7 6 5 4 3 2 1 0
----------------
1 1 0 1 1 1 1 0
|=======| |===|
| Leftmost Bits Repeated to Fill Open Bits
|
Original Bits
which matches the value computed by the linear equation. Left bit
replication usually gives the same value as linear scaling, and is
never off by more than one.
A distinctly less accurate approximation is obtained by simply
left-shifting the input value and filling the low order bits with
zeroes. This scheme cannot reproduce white exactly, since it does
not generate an all-ones maximum value; the net effect is to
darken the image slightly. This method is not recommended in
general, but it does have the effect of improving compression,
particularly when dealing with greater-than-eight-bit sample
depths. Since the relative error introduced by zero-fill scaling
is small at high sample depths, some encoders may choose to use
it. Zero-fill must not be used for alpha channel data, however,
since many decoders will special-case alpha values of all zeroes
and all ones. It is important to represent both those values
exactly in the scaled data.
When the encoder writes an sBIT chunk, it is required to do the
scaling in such a way that the high-order bits of the stored
samples match the original data. That is, if the sBIT chunk
specifies a sample depth of S, the high-order S bits of the stored
data must agree with the original S-bit data values. This allows
decoders to recover the original data by shifting right. The
added low-order bits are not constrained. Note that all the above
scaling methods meet this restriction.
When scaling up source data, it is recommended that the low-order
bits be filled consistently for all samples; that is, the same
source value should generate the same sample value at any pixel
position. This improves compression by reducing the number of
distinct sample values. However, this is not a requirement, and
some encoders may choose not to follow it. For example, an
encoder might instead dither the low-order bits, improving
displayed image quality at the price of increasing file size.
In some applications the original source data may have a range
that is not a power of 2. The linear scaling equation still works
for this case, although the shifting methods do not. It is
recommended that an sBIT chunk not be written for such images,
since sBIT suggests that the original data range was exactly
0..2^S-1.
9.2. Encoder gamma handling
See Gamma Tutorial (Chapter 13) if you aren't already familiar
with gamma issues.
Proper handling of gamma encoding and the gAMA chunk in an encoder
depends on the prior history of the sample values and on whether
these values have already been quantized to integers.
If the encoder has access to sample intensity values in floating-
point or high-precision integer form (perhaps from a computer
image renderer), then it is recommended that the encoder perform
its own gamma encoding before quantizing the data to integer
values for storage in the file. Applying gamma encoding at this
stage results in images with fewer banding artifacts at a given
sample depth, or allows smaller samples while retaining the same
visual quality.
A linear intensity level, expressed as a floating-point value in
the range 0 to 1, can be converted to a gamma-encoded sample value
by
sample = ROUND((intensity ^ encoder_gamma) * MAXSAMPLE)
The file_gamma value to be written in the PNG gAMA chunk is the
same as encoder_gamma in this equation, since we are assuming the
initial intensity value is linear (in effect, camera_gamma is
1.0).
If the image is being written to a file only, the encoder_gamma
value can be selected somewhat arbitrarily. Values of 0.45 or 0.5
are generally good choices because they are common in video
systems, and so most PNG decoders should do a good job displaying
such images.
Some image renderers may simultaneously write the image to a PNG
file and display it on-screen. The displayed pixels should be
gamma corrected for the display system and viewing conditions in
use, so that the user sees a proper representation of the intended
scene. An appropriate gamma correction value is
screen_gc = viewing_gamma / display_gamma
If the renderer wants to write the same gamma-corrected sample
values to the PNG file, avoiding a separate gamma-encoding step
for file output, then this screen_gc value should be written in
the gAMA chunk. This will allow a PNG decoder to reproduce what
the file's originator saw on screen during rendering (provided the
decoder properly supports arbitrary values in a gAMA chunk).
However, it is equally reasonable for a renderer to apply gamma
correction for screen display using a gamma appropriate to the
viewing conditions, and to separately gamma-encode the sample
values for file storage using a standard value of gamma such as
0.5. In fact, this is preferable, since some PNG decoders may not
accurately display images with unusual gAMA values.
Computer graphics renderers often do not perform gamma encoding,
instead making sample values directly proportional to scene light
intensity. If the PNG encoder receives sample values that have
already been quantized into linear-light integer values, there is
no point in doing gamma encoding on them; that would just result
in further loss of information. The encoder should just write the
sample values to the PNG file. This "linear" sample encoding is
equivalent to gamma encoding with a gamma of 1.0, so graphics
programs that produce linear samples should always emit a gAMA
chunk specifying a gamma of 1.0.
When the sample values come directly from a piece of hardware, the
correct gAMA value is determined by the gamma characteristic of
the hardware. In the case of video digitizers ("frame grabbers"),
gAMA should be 0.45 or 0.5 for NTSC (possibly less for PAL or
SECAM) since video camera transfer functions are standardized.
Image scanners are less predictable. Their output samples may be
linear (gamma 1.0) since CCD sensors themselves are linear, or the
scanner hardware may have already applied gamma correction
designed to compensate for dot gain in subsequent printing (gamma
of about 0.57), or the scanner may have corrected the samples for
display on a CRT (gamma of 0.4-0.5). You will need to refer to
the scanner's manual, or even scan a calibrated gray wedge, to
determine what a particular scanner does.
File format converters generally should not attempt to convert
supplied images to a different gamma. Store the data in the PNG
file without conversion, and record the source gamma if it is
known. Gamma alteration at file conversion time causes re-
quantization of the set of intensity levels that are represented,
introducing further roundoff error with little benefit. It's
almost always better to just copy the sample values intact from
the input to the output file.
In some cases, the supplied image may be in an image format (e.g.,
TIFF) that can describe the gamma characteristic of the image. In
such cases, a file format converter is strongly encouraged to
write a PNG gAMA chunk that corresponds to the known gamma of the
source image. Note that some file formats specify the gamma of
the display system, not the camera. If the input file's gamma
value is greater than 1.0, it is almost certainly a display system
gamma, and you should use its reciprocal for the PNG gAMA.
If the encoder or file format converter does not know how an image
was originally created, but does know that the image has been
displayed satisfactorily on a display with gamma display_gamma
under lighting conditions where a particular viewing_gamma is
appropriate, then the image can be marked as having the
file_gamma:
file_gamma = viewing_gamma / display_gamma
This will allow viewers of the PNG file to see the same image that
the person running the file format converter saw. Although this
may not be precisely the correct value of the image gamma, it's
better to write a gAMA chunk with an approximately right value
than to omit the chunk and force PNG decoders to guess at an
appropriate gamma.
On the other hand, if the image file is being converted as part of
a "bulk" conversion, with no one looking at each image, then it is
better to omit the gAMA chunk entirely. If the image gamma has to
be guessed at, leave it to the decoder to do the guessing.
Gamma does not apply to alpha samples; alpha is always represented
linearly.
See also Recommendations for Decoders: Decoder gamma handling
(Section 10.5).
9.3. Encoder color handling
See Color Tutorial (Chapter 14) if you aren't already familiar
with color issues.
If it is possible for the encoder to determine the chromaticities
of the source display primaries, or to make a strong guess based
on the origin of the image or the hardware running it, then the
encoder is strongly encouraged to output the cHRM chunk. If it
does so, the gAMA chunk should also be written; decoders can do
little with cHRM if gAMA is missing.
Video created with recent video equipment probably uses the CCIR
709 primaries and D65 white point [ITU-BT709], which are:
R G B White
x 0.640 0.300 0.150 0.3127
y 0.330 0.600 0.060 0.3290
An older but still very popular video standard is SMPTE-C [SMPTE-
170M]:
R G B White
x 0.630 0.310 0.155 0.3127
y 0.340 0.595 0.070 0.3290
The original NTSC color primaries have not been used in decades.
Although you may still find the NTSC numbers listed in standards
documents, you won't find any images that actually use them.
Scanners that produce PNG files as output should insert the filter
chromaticities into a cHRM chunk and the camera_gamma into a gAMA
chunk.
In the case of hand-drawn or digitally edited images, you have to
determine what monitor they were viewed on when being produced.
Many image editing programs allow you to specify what type of
monitor you are using. This is often because they are working in
some device-independent space internally. Such programs have
enough information to write valid cHRM and gAMA chunks, and should
do so automatically.
If the encoder is compiled as a portion of a computer image
renderer that performs full-spectral rendering, the monitor values
that were used to convert from the internal device-independent
color space to RGB should be written into the cHRM chunk. Any
colors that are outside the gamut of the chosen RGB device should
be clipped or otherwise constrained to be within the gamut; PNG
does not store out of gamut colors.
If the computer image renderer performs calculations directly in
device-dependent RGB space, a cHRM chunk should not be written
unless the scene description and rendering parameters have been
adjusted to look good on a particular monitor. In that case, the
data for that monitor (if known) should be used to construct a
cHRM chunk.
There are often cases where an image's exact origins are unknown,
particularly if it began life in some other format. A few image
formats store calibration information, which can be used to fill
in the cHRM chunk. For example, all PhotoCD images use the CCIR
709 primaries and D65 whitepoint, so these values can be written
into the cHRM chunk when converting a PhotoCD file. PhotoCD also
uses the SMPTE-170M transfer function, which is closely
approximated by a gAMA of 0.5. (PhotoCD can store colors outside
the RGB gamut, so the image data will require gamut mapping before
writing to PNG format.) TIFF 6.0 files can optionally store
calibration information, which if present should be used to
construct the cHRM chunk. GIF and most other formats do not store
any calibration information.
It is not recommended that file format converters attempt to
convert supplied images to a different RGB color space. Store the
data in the PNG file without conversion, and record the source
primary chromaticities if they are known. Color space
transformation at file conversion time is a bad idea because of
gamut mismatches and rounding errors. As with gamma conversions,
it's better to store the data losslessly and incur at most one
conversion when the image is finally displayed.
See also Recommendations for Decoders: Decoder color handling
(Section 10.6).
9.4. Alpha channel creation
The alpha channel can be regarded either as a mask that
temporarily hides transparent parts of the image, or as a means
for constructing a non-rectangular image. In the first case, the
color values of fully transparent pixels should be preserved for
future use. In the second case, the transparent pixels carry no
useful data and are simply there to fill out the rectangular image
area required by PNG. In this case, fully transparent pixels
should all be assigned the same color value for best compression.
Image authors should keep in mind the possibility that a decoder
will ignore transparency control. Hence, the colors assigned to
transparent pixels should be reasonable background colors whenever
feasible.
For applications that do not require a full alpha channel, or
cannot afford the price in compression efficiency, the tRNS
transparency chunk is also available.
If the image has a known background color, this color should be
written in the bKGD chunk. Even decoders that ignore transparency
may use the bKGD color to fill unused screen area.
If the original image has premultiplied (also called "associated")
alpha data, convert it to PNG's non-premultiplied format by
dividing each sample value by the corresponding alpha value, then
multiplying by the maximum value for the image bit depth, and
rounding to the nearest integer. In valid premultiplied data, the
sample values never exceed their corresponding alpha values, so
the result of the division should always be in the range 0 to 1.
If the alpha value is zero, output black (zeroes).
9.5. Suggested palettes
A PLTE chunk can appear in truecolor PNG files. In such files,
the chunk is not an essential part of the image data, but simply
represents a suggested palette that viewers may use to present the
image on indexed-color display hardware. A suggested palette is
of no interest to viewers running on truecolor hardware.
If an encoder chooses to provide a suggested palette, it is
recommended that a hIST chunk also be written to indicate the
relative importance of the palette entries. The histogram values
are most easily computed as "nearest neighbor" counts, that is,
the approximate usage of each palette entry if no dithering is
applied. (These counts will often be available for free as a
consequence of developing the suggested palette.)
For images of color type 2 (truecolor without alpha channel), it
is recommended that the palette and histogram be computed with
reference to the RGB data only, ignoring any transparent-color
specification. If the file uses transparency (has a tRNS chunk),
viewers can easily adapt the resulting palette for use with their
intended background color. They need only replace the palette
entry closest to the tRNS color with their background color (which
may or may not match the file's bKGD color, if any).