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


Adjusting the overall brightness of an image via gamma correction is a good first step, but it does not address the issue of color balance. Anyone who has visited a typical consumer electronics store has probably noticed that not every model on the wall of televisions displays the same way. Some may have a reddish tinge, some green; some usually display very bright, saturated colors, while others may opt for slightly paler but more realistic hues. Although one rarely sees a corresponding wall of computer monitors and LCDs all displaying the same image, there are similar differences between various manufacturers' models and even between monitors in the same production run.

The main contribution to such variations comes from the manufacturers' choices of light-emitting chemicals (phosphors) in monitors and of filters used in liquid crystal displays. In addition, some higher-end monitors (and all color TVs) allow one to adjust the color balance manually in one or more ways. The details are not particularly important; what matters is that there are differences--or to put it another way, the RGB color space is device-dependent. Understanding how one quantifies and corrects for these differences is most easily accomplished via a diagram.

Figure 10-1

Figure 10-1: Typical chromaticity diagram. (Click for full-scale version.)

Figure C-2 in the color insert, shows an interestingly shaped color blob with a numbered curve and a brighter triangle embedded in it and some numbers around its curved edge. The blob represents the complete range of hues and saturation levels that the human eye can discern; a true spectrum would wrap around the numbered edge[80] (albeit without the cyan region near the upper left). The middle is composed of smoothly interpolated mixtures, including ``white.'' The numbers on the axes give the x and y values of each hue and are directly related to the International Commission on Illumination's (CIE, for Commission Internationale de l'Éclairage) XYZ color space, a standard and device-independent color space for well over half a century. We'll come back to that shortly.

[80] The numbers give the wavelength (in nanometers) of the spectral colors along the edge. Visible light lies within the range 400 nm to 700 nm, roughly.

The brighter triangle in the middle represents the colors that can be displayed by a particular monitor (not including any brightness information) and is known as the color gamut of the display. The corners of the triangle give the maximum-intensity red, green, and blue hues; these directly correspond to the physical characteristics of the phosphors used in the display. LCDs, printers, color film, and even textile dyes have similar gamuts, though not always triangular. Perhaps the most striking feature is the fact that the monitor's gamut covers less than half of the complete color range. In other words, there are many colors that the human eye can perceive but that cannot be correctly represented on a monitor. The fact that the chromaticity diagram can be displayed on a monitor at all means that the region outside the triangle can be represented in some manner, just not the correct one. This is the source of the cyan error noted previously.

Because the diagram has been projected down from a three-dimensional color space (XYZ) to the two-dimensional xy plane, information about the relative intensities of red, green, and blue has been lost. That is, the x,y values for the red phosphor indicate what color it emits at any given intensity level and similarly for the green and blue phosphors. But we still need to know the relative intensities of the three phosphors when they are all at full power. This is where the concept of ``white'' comes in. In fact, there are many candidates for ``white,'' from the warm, yellowish whites produced by incandescent lightbulbs to the cool, bluish whites of electrical arcs and lightning.[81] The curved line in the middle represents all possible values of ``white'' for a given monitor, only one of which will be displayed as such. The associated numbers along the curve refer to the ``blackbody temperature'' or color temperature of any given white value; among other things, a star whose surface (photosphere) is at the given temperature will emit light of the given color most strongly. [82] Our Sun's surface temperature is around 6,000 degrees Kelvin, for example; not coincidentally, this is the color temperature most humans associate with ``average'' or ``true'' white.

[81] It is slightly odd that humans perceive redder light as ``warm'' and bluer light as ``cool'' when, in fact, the opposite is true. Lightning is far hotter than the filament in an incandescent bulb.

[82] Keep in mind that we are still talking about human perception. A blackbody emits a true continuum of light; a monitor emits a more limited continuum composed of three broad, overlapping curves--corresponding to the red, green, and blue phosphors. Humans perceive the monitor's ``white'' output to be the same as that of a blackbody at a particular temperature, but a spectrometer would say otherwise.

How does all of this relate to color correction in PNG? If the encoding software knows the locations of the three corners of the triangle (the primary chromaticities) and of white point, it can save these values in PNG's chromaticity chunk, cHRM. When the image is decoded on another system with a different color range, the decoder can convert the x,y chromaticity values of both systems into XYZ space, calculate any necessary adjustments between the two, and use that calculation to convert the RGB values of the image into XYZ space and then into the RGB space of the display system.

The simple way to deal with such conversions is to feed the information to a color management system (CMS), assuming one is present. All of the tricky details of conversion between different color spaces and of mapping different monitor gamuts are handled by the CMS. Color management systems are not yet in wide use on typical users' platforms, however; a decoding application that wishes to maintain optimal color fidelity will need to handle the conversions on its own. The calculations to do so are not terribly difficult, but they do involve a number of matrix operations. These are detailed in of the University of Manchester's excellent tutorial, Colour in Computer Graphics, and also in the "Color Tutorial" section of the PNG Specification, Version 1.1.

The structure of cHRM is shown in Table 10-2.

Table 10-2. cHRM Chunk

Field Length and valid range
White point x 4 bytes (0-2,147,483,647)
White point y 4 bytes (0-2,147,483,647)
Red x 4 bytes (0-2,147,483,647)
Red y 4 bytes (0-2,147,483,647)
Green x 4 bytes (0-2,147,483,647)
Green y 4 bytes (0-2,147,483,647)
Blue x 4 bytes (0-2,147,483,647)
Blue y 4 bytes (0-2,147,483,647)

Each of the eight values is an unsigned long integer, equal to the actual floating-point value multiplied by 100,000 and rounded to the nearest integer. Like the gAMA chunk, cHRM must precede all IDAT chunks and, if present, PLTE; only one cHRM chunk is allowed.

Last Update: 2010-Nov-26