PNG (Portable Network Graphics) Specification, Tenth Draft

Revision date: 5 May, 1995

Previous page

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 which conform to the format specified in the preceding chapters. However, best results will usually be achieved by following these recommendations.

Bitdepth scaling

When scaling input values that have a bit depth that cannot be directly represented in PNG, an excellent approximation to the correct value can be achieved by shifting the valid bits to begin in the most significant bit and repeating the most significant bits into the open bits.

For example, if 5 bits per channel are available in the source data, conversion to a bitdepth of 8 can be achieved as follows:

If the value for a sample in the source data is 27 (in a range from 0-31), then the original bits are:

4 3 2 1 0
---------
1 1 0 1 1
Converted to a bitdepth of 8, the best value is 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
Note that this scaling can be reversed simply by shifting right.

Scaling by simply shifting left by three bits is incorrect, since the resulting data would have a range less than the desired full range. (For 5-bit input data, the maximum output would be 248 = 11111000, which is not full brightness.)

It is recommended that the sBIT chunk be included when bitdepth scaling has been performed, to record the original data depth.

Encoder gamma handling

If it is possible for the encoder to determine the image gamma, or to make a strong guess based on the hardware on which it runs, then the encoder is strongly encouraged to output the gAMA chunk.

A linear brightness level, expressed as a floating-point value in the range 0 to 1, may be converted to a gamma-corrected pixel value by

  gbright := bright ^ gamma
  pixelval := ROUND(gbright * MAXPIXVAL)
Computer graphics renderers often do not perform gamma encoding, instead making pixel values directly proportional to scene brightness. This "linear" pixel encoding is equivalent to gamma encoding with a gamma of 1.0, so graphics programs that produce linear pixels should always put out a gAMA chunk specifying a gamma of 1.0.

If the encoder knows that the image has been displayed satisfactorily on a display of gamma display_gamma, then the image can be marked as having gamma 1.0/display_gamma.

It is not recommended that encoders attempt to convert supplied images to a different gamma. Store the data in the file without conversion, and record the source gamma. Gamma conversion at encode time is a bad idea because gamma adjustment of digital pixel data is inherently lossy, due to roundoff error (8 or so bits is not really enough accuracy). Thus encode-time conversion permanently degrades the image. Worse, if the eventual decoder wants the data with some other gamma, then two conversions occur, each introducing roundoff error. Better to store the data losslessly and incur at most one conversion when the image is finally displayed.

Gamma does not apply to alpha channel values; alpha is always represented linearly.

See Recommendations for Decoders: Decoder gamma handling for more details.

Alpha channel creation

The alpha channel may 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.

Encoders should keep in mind the possibility that a viewer 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 viewers 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 RGB value by the corresponding alpha value, then multiplying by the maximum value for the image bit depth. In valid premultiplied data, the RGB 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).

Filter selection

For images of color type 3 (palette-based color), filter type 0 (none) is usually the most effective.

Filter type 0 is also recommended for images of bit depths less than 8. For low-bit-depth grayscale images, it may be a net win to expand the image to 8-bit representation and apply filtering, but this is rare.

For truecolor and grayscale images, any of the five filters may prove the most effective. If an encoder wishes to use a fixed filter choice, the Paeth filter is most likely to be the best.

For best compression of truecolor and grayscale images, we recommend an adaptive filtering approach in which a filter is chosen for each scanline. The following simple heuristic has performed well in early tests: compute the output scanline using all five filters, and select the filter which gives the smallest sum of absolute values of outputs. (Consider the output bytes as signed differences for this test.) This method usually outperforms any single fixed filter choice. However, it is likely that much better heuristics will be found as more experience is gained with PNG.

Filtering according to these recommendations is effective on interlaced as well as noninterlaced images.

Text chunk processing

Note that a nonempty keyword must be provided for each text chunk. The generic keyword "Comment" may be used if no better description of the text is available.

Encoders should discourage the creation of single lines of text longer than 79 characters, in order to facilitate easy reading.

If an encoder chooses to support output of zTXt compressed text chunks, it is recommended that text less than 1K (1024 bytes) in size be output using uncompressed tEXt chunks. In particular, it is recommended that the basic title and author keywords always be output using uncompressed tEXt chunks. Lengthy disclaimers, on the other hand, are an ideal candidate for zTXt.

Placing large tEXt and zTXt chunks after the image data (after IDAT) may speed up image display in some situations, since the decoder won't have to read over the text to get to the image data. But it is recommended that small text chunks, such as the image title, appear before IDAT.

Registering proprietary chunks

If you want others outside your organization to understand a chunk type that you invent, contact the maintainers of the PNG specification to submit a proposed chunk name and definition for addition to the list of special-purpose public chunks (see Additional Chunk Types).

New public chunks will be 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.

If you do not desire that others outside your organization understand the chunk type, you may use a private chunk name by specifying a lowercase letter for the second character. Such chunk types need not be registered. But note that others may use the same private chunk name, so it is prudent to store additional identifying information at the beginning of the chunk data.

Please note that if you want to use a private chunk for information that is not essential to view the image, and have any desire whatsoever that others not using your own viewer software be able to view the image, you should use an ancillary chunk type (first character is lowercase) rather than a critical chunk type (first character uppercase).

If an ancillary chunk is to contain textual information that might be of interest to a human user, it is recommended that a special chunk type not be used. Instead use a tEXt chunk and define a suitable keyword. In this way, the information will be available to users not using your software.

If of general usefulness, new keywords for tEXt chunks may be registered with the maintainers of the PNG specification. Keywords should be chosen to be reasonably self-explanatory, since the idea is to let other users figure out what the chunk contains.

Back to PNG table of contents

Next page