PNG-GammaAppendix 18.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
<HTML>
<HEAD>
<TITLE>PNG Specification: Gamma Tutorial</TITLE>
</HEAD>

<BODY BACKGROUND="recbg.jpg">
<h2 align=right><A HREF="http://www.w3.org/"><img align=left alt="W3C:" src="http://www.w3.org/pub/WWW/Icons/WWW/w3c_48x48" width=48 height=48></A>
REC-png.html</h2>

<H1>PNG (Portable Network Graphics) Specification</H1>
<H1>Version 1.0</H1>

<h3 align=center>W3C Recommendation  <i>01-October-1996</i></h3>

<HR>
<A HREF="PNG-Rationale.html">Previous page</A>
<BR>
<A HREF="PNG-ColorAppendix.html">Next page</A>
<BR>
<A HREF="png.html">Table of contents</A>
<HR>


<H2><A NAME="GammaAppendix">13. Appendix: Gamma Tutorial</A></H2>

(This appendix is not part of the formal PNG specification.)
<P>
It would be convenient for graphics programmers if all of the components
of an imaging system were linear.  The voltage coming from an electronic
camera would be directly proportional to the intensity (power) of light
in the scene, the light emitted by a CRT would be directly
proportional to its input voltage, and so on.  However, real-world
devices do not behave in this way.  All CRT displays, almost all
photographic film, and many electronic cameras have nonlinear
signal-to-light-intensity or intensity-to-signal characteristics.
<P>
Fortunately, all of these nonlinear devices have a
transfer function that is approximated fairly well by a single type of
mathematical function: a power function.  This power function has the
general equation
<PRE>
   output = input ^ gamma
</PRE>
where <tt>^</tt> denotes exponentiation, and "gamma" (often printed
using the Greek letter gamma, thus the name) is simply the exponent of
the power function.
<P>
By convention, "input" and "output" are both scaled to the range 0..1,
with 0 representing black and 1 representing maximum white (or
red, etc).  Normalized in this way, the power function is completely
described by a single number, the exponent "gamma".
<P>
So, given a particular device, we can measure its output as a function
of its input, fit a power function to this measured transfer function,
extract the exponent, and call it gamma.  We often say "this device has
a gamma of 2.5" as a shorthand for "this device has a power-law response
with an exponent of 2.5".  We can also talk about the gamma of a
mathematical transform, or of a lookup table in a frame buffer, so long
as the input and output of the thing are related by the power-law
expression above.

<H3>How do gammas combine?</H3>

Real imaging systems will have several components, and more than one of
these can be nonlinear.  If all of the components have transfer
characteristics that are power functions, then the transfer function of
the entire system is also a power function.  The exponent (gamma) of the
whole system's transfer function is just the product of all of the
individual exponents (gammas) of the separate stages in the system.
<P>
Also, stages that are linear pose no problem, since a power function
with an exponent of 1.0 is really a linear function.  So a linear
transfer function is just a special case of a power function, with a
gamma of 1.0.
<P>
Thus, as long as our imaging system contains only stages with linear and
power-law transfer functions, we can meaningfully talk about the gamma of
the entire system.  This is indeed the case with most real imaging systems.

<H3>What should overall gamma be?</H3>

If the overall gamma of an imaging system is 1.0, its output is
linearly proportional to its input.  This means that the ratio
between the intensities of any two areas in the reproduced image will
be the same as it was in the original scene.  It might seem that this
should always be the goal of an imaging system: to accurately reproduce
the tones of the original scene.  Alas, that is not the case.
<P>
When the reproduced image is to be viewed in "bright surround"
conditions, where other white objects nearby in the room have about
the same brightness as white in the image, then an overall gamma of 1.0
does indeed give real-looking reproduction of a natural scene.
Photographic prints viewed under room light and computer displays in
bright room light are typical "bright surround" viewing conditions.
<P>
However, sometimes images are intended to be viewed in "dark surround"
conditions, where the room is substantially black except for the image.
This is typical of the way movies and slides (transparencies) are viewed
by projection.  Under these circumstances, an accurate reproduction of
the original scene results in an image that human viewers judge as
"flat" and lacking in contrast.  It turns out that the projected image
needs to have a gamma of about 1.5 relative to the original scene for
viewers to judge it "natural".  Thus, slide film is designed to have a
gamma of about 1.5, not 1.0.
<P>
There is also an intermediate condition called "dim surround", where the
rest of the room is still visible to the viewer, but is noticeably
darker than the reproduced image itself.  This is typical of television
viewing, at least in the evening, as well as subdued-light computer work
areas.  In dim surround conditions, the reproduced image needs to have a
gamma of about 1.25 relative to the original scene in order to look
natural.
<P>
The requirement for boosted contrast (gamma) in dark surround conditions
is due to the way the human visual system works, and applies equally
well to computer monitors.  Thus, a PNG viewer trying to achieve the
maximum realism for the images it displays really needs to know what the
room lighting conditions are, and adjust the gamma of the displayed
image accordingly.
<P>
If asking the user about room lighting conditions is inappropriate or
too difficult, just assume that the overall gamma (viewing_gamma as
defined below) should be 1.0 or 1.25.  That's all that most systems that
implement gamma correction do.

<H3>What is a CRT's gamma?</H3>

All CRT displays have a power-law transfer characteristic with a
gamma of about 2.5.  This is due to the physical processes involved in
controlling the electron beam in the electron gun, and has nothing
to do with the phosphor.
<P>
An exception to this rule is fancy "calibrated" CRTs that
have internal electronics to alter their transfer function.  If you have
one of these, you probably should believe what the manufacturer tells
you its gamma is.  But in all other cases, assuming 2.5 is likely to
be pretty accurate.
<P>
There are various images around that purport to measure gamma, usually
by comparing the intensity of an area containing alternating white and
black with a series of areas of continuous gray of different intensity.
These are usually not reliable.  Test images that use a "checkerboard"
pattern of black and white are the worst, because a single white pixel
will be reproduced considerably darker than a large area of white.
An image that uses alternating black and white horizontal lines (such as
the "gamma.png" test image at
<code><A HREF="ftp://ftp.uu.net/graphics/png/images/suite/gamma.png">ftp://ftp.uu.net/graphics/png/images/suite/gamma.png</A></code>)
is much better, but even it may be inaccurate at high "picture"
settings on some CRTs.
<P>
If you have a good photometer, you can measure the actual light output
of a CRT as a function of input voltage and fit a power function to
the measurements.  However, note that this procedure is very sensitive
to the CRT's black level adjustment, somewhat sensitive to its
picture adjustment, and also affected by ambient light.
Furthermore, CRTs spread some light from bright areas of an
image into nearby darker areas; a single bright spot against a black
background may be seen to have a "halo".  Your measuring technique
will need to minimize the effects of this.
<P>
Because of the difficulty of measuring gamma, using either test
images or measuring equipment, you're usually better off just
assuming gamma is 2.5 rather than trying to measure it.

<H3>What is gamma correction?</H3>

A CRT has a gamma of 2.5, and we can't change that.  To get an overall
gamma of 1.0 (or somewhere near that) for an imaging system, we need
to have at least one other component of the "image pipeline" that is
nonlinear.  If, in fact, there is only one nonlinear stage in addition
to the CRT, then it's traditional to say that the CRT has a certain
gamma, and that the other nonlinear stage provides "gamma correction"
to compensate for the CRT.  However, exactly where the "correction" is
done depends on circumstance.
<P>
In all broadcast video systems, gamma correction is done in the
camera.  This choice was made in the days when television electronics
were all analog, and a good gamma-correction circuit was expensive to
build.  The original NTSC video standard required cameras to have a
transfer function with a gamma of 1/2.2, or about 0.45.  Recently, a
more complex two-part transfer function has been adopted [SMPTE-170M],
but its behavior can be well approximated by a power function with a
gamma of 0.5.  When the resulting image is displayed on a CRT with a
gamma of 2.5, the image on screen ends up with a gamma of about 1.25
relative to the original scene, which is appropriate for "dim
surround" viewing.
<P>
These days, video signals are often digitized and stored in computer
frame buffers.  This works fine, but remember that gamma correction is
"built into" the video signal, and so the digitized video has a gamma
of about 0.5 relative to the original scene.
<P>
Computer rendering programs often produce linear samples.  To display
these correctly, intensity on the CRT needs to be directly proportional to
the sample values in the frame buffer.  This can be done with a
special hardware lookup table between the frame buffer and the CRT
hardware.  The lookup table (often called LUT) is loaded with a
mapping that implements a power function with a gamma of 0.4, thus
providing "gamma correction" for the CRT gamma.
<P>
Thus, gamma correction sometimes happens before the frame buffer,
sometimes after.  As long as images created in a particular
environment are always displayed in that environment, everything is
fine.  But when people try to exchange images, differences in gamma
correction conventions often result in images that seem far too
bright and washed out, or far too dark and contrasty.

<H3>Gamma-encoded samples are good</H3>

So, is it better to do gamma correction before or after the frame
buffer?
<P>
In an ideal world, sample values would be stored in floating point,
there would be lots of precision, and it wouldn't really matter
much.  But in reality, we're always trying to store images in as few
bits as we can.
<P>
If we decide to use samples that are linearly proportional to
intensity, and do the gamma correction in the frame buffer LUT,
it turns out that we need to use at least 12 bits for each of
red, green, and blue to have enough precision in intensity.  With any
less than that, we will sometimes see "contour bands" or "Mach bands" in
the darker areas of the image, where two adjacent sample values are still
far enough apart in intensity for the difference to be visible.
<P>
However, through an interesting coincidence, the human eye's subjective
perception of brightness is related to the physical stimulation of light
intensity in a manner that is very much like the power function used
for gamma correction.  If we apply gamma correction to measured (or
calculated) light intensity before quantizing to an integer for storage
in a frame buffer, we can get away with using many fewer
bits to store the image.  In fact, 8 bits per color is almost always
sufficient to avoid contouring artifacts.  This is because, since
gamma correction is so closely related to human perception, we are
assigning our 256 available sample codes to intensity values in a manner
that approximates how visible those intensity changes are to the eye.
Compared to a linear-sample image, we allocate fewer sample values to
brighter parts of the tonal range and more sample values to the darker
portions of the tonal range.
<P>
Thus, for the same apparent image quality, images using gamma-encoded
sample values need only about two-thirds as many bits of storage as images
using linear samples.

<H3>General gamma handling</H3>

When more than two nonlinear transfer functions are involved
in the image pipeline, the term "gamma correction" becomes too vague.
If we consider a pipeline that
involves capturing (or calculating) an image, storing it in an
image file, reading the file, and displaying the image on some
sort of display screen, there are at least 5 places in the
pipeline that could have nonlinear transfer functions.  Let's give
each a specific name for their characteristic gamma:
<DL>
<DT>camera_gamma
<DD>the characteristic of the image sensor
<DT>encoding_gamma
<DD>the gamma of any transformation performed by the software writing
the image file
<DT>decoding_gamma
<DD>the gamma of any transformation performed by the software reading
the image file
<DT>LUT_gamma
<DD>the gamma of the frame buffer LUT, if present
<DT>CRT_gamma
<DD>the gamma of the CRT, generally 2.5
</DL>
In addition, let's add a few other names:
<DL>
<DT>file_gamma
<DD>the gamma of the image in the file, relative to the original
scene.  This is
<PRE>
   file_gamma = camera_gamma * encoding_gamma
</PRE>
<DT>display_gamma
<DD>the gamma of the "display system" downstream of the frame buffer.
This is
<PRE>
   display_gamma = LUT_gamma * CRT_gamma
</PRE>
<DT>viewing_gamma
<DD>the overall gamma that we want to obtain to produce
pleasing images --- generally 1.0 to 1.5.
</DL>
The file_gamma value, as defined above, is what goes in the
<tt>gAMA</tt> chunk in a PNG file.  If file_gamma is not 1.0, we know
that gamma correction has been done on the sample values in the file,
and we could call them "gamma corrected" samples.  However, since
there can be so many different values of gamma in the image display
chain, and some of them are not known at the time the image is
written, the samples are not really being "corrected" for a specific
display condition.  We are really using a power function in the
process of encoding an intensity range into a small integer field,
and so it is more correct to say "gamma encoded" samples instead of
"gamma corrected" samples.
<P>
When displaying an image file, the image decoding program is responsible
for making the overall gamma of the system equal to the desired
viewing_gamma, by selecting the decoding_gamma appropriately.  When
displaying a PNG file, the <tt>gAMA</tt> chunk provides the file_gamma value.
The display_gamma may be known for this machine, or it might
be obtained from the system software, or the user might have to be asked
what it is.  The correct viewing_gamma depends on lighting conditions,
and that will generally have to come from the user.
<P>
Ultimately, you should have
<PRE>
   file_gamma * decoding_gamma * display_gamma = viewing_gamma
</PRE>

<H3>Some specific examples</H3>

In digital video systems, camera_gamma is about 0.5 by declaration of
the various video standards documents.  CRT_gamma is 2.5 as usual, while
encoding_gamma, decoding_gamma, and LUT_gamma are all 1.0.  As a result,
viewing_gamma ends up being about 1.25.
<P>
On frame buffers that have hardware gamma correction tables,
and that are calibrated to display linear samples correctly,
display_gamma is 1.0.
<P>
Many workstations and X terminals and PC displays lack gamma
correction lookup tables.  Here, LUT_gamma is always 1.0, so
display_gamma is 2.5.
<P>
On the Macintosh, there is a LUT.  By default, it is loaded with a
table whose gamma is about 0.72, giving a display_gamma (LUT and CRT
combined) of about 1.8.  Some Macs have a "Gamma" control panel that
allows gamma to be changed to 1.0, 1.2, 1.4, 1.8, or 2.2.  These
settings load alternate LUTs that are designed to give a
display_gamma that is equal to the label on the selected button.
Thus, the "Gamma" control panel setting can be used directly as
display_gamma in decoder calculations.
<P>
On recent SGI systems, there is a hardware gamma-correction
table whose contents are controlled by the (privileged) "gamma"
program. The gamma of the table is actually the reciprocal of
the number that "gamma" prints, and it does not include the CRT
gamma. To obtain the display_gamma, you need to find the SGI
system gamma (either by looking in a file, or asking the user) and
then calculating
<PRE>
   display_gamma = 2.5 / SGI_system_gamma
</PRE>
You will find SGI systems with the system gamma set to 1.0 and
2.2 (or higher), but the default when machines are shipped is 1.7.

<H3>A note about video gamma</H3>

The original NTSC video standards specified a simple power-law camera
transfer function with a gamma of 1/2.2 or 0.45.  This is not possible
to implement exactly in analog hardware because the function has
infinite slope at x=0, so all cameras deviated to some degree from
this ideal.  More recently, a new camera transfer function that is
physically realizable has been accepted as a standard [SMPTE-170M].
It is
<PRE>
   Vout = 4.5 * Vin                    if Vin &lt; 0.018
   Vout = 1.099 * (Vin^0.45) - 0.099   if Vin &gt;= 0.018
</PRE>
where Vin and Vout are measured on a scale of 0 to 1.  Although the
exponent remains 0.45, the multiplication and subtraction change the
shape of the transfer function, so it is no longer a pure power
function.  If you want to perform extremely precise calculations on
video signals, you should use the expression above (or its inverse, as
required).
<P>
However, PNG does not provide a way to specify that an image uses this
exact transfer function; the <tt>gAMA</tt> chunk always assumes a
pure power-law function. If we plot the two-part transfer function
above along with the family of pure power functions, we find that a
power function with a gamma of about 0.5 to 0.52 (not 0.45) most
closely approximates the transfer function.  Thus, when writing a PNG
file with data obtained from digitizing the output of a modern video
camera, the <tt>gAMA</tt> chunk should contain 0.5 or 0.52, not 0.45.
The remaining difference between the true transfer function and the
power function is insignificant for almost all purposes.  (In fact,
the alignment errors in most cameras are likely to be larger than the
difference between these functions.)  The designers of PNG deemed the
simplicity and flexibility of a power-law definition of <tt>gAMA</tt>
to be more important than being able to describe the SMPTE-170M
transfer curve exactly.
<P>
The PAL and SECAM video standards specify a power-law camera transfer
function with a gamma of 1/2.8 or 0.36 --- not the 1/2.2 of NTSC.
However, this is too low in practice, so real cameras are
likely to have their gamma set close to NTSC practice.  Just guessing
0.45 or 0.5 is likely to give you viewable results, but if you want
precise values you'll probably have to measure the particular camera.

<H3>Further reading</H3>

If you have access to the World Wide Web, read Charles Poynton's
excellent "Gamma FAQ"
<A HREF="http://www.inforamp.net/%7Epoynton/Poynton-colour.html">[GAMMA-FAQ]</A>
for more information about gamma.


<HR>
<A HREF="PNG-Rationale.html">Previous page</A>
<BR>
<A HREF="PNG-ColorAppendix.html">Next page</A>
<BR>
<A HREF="png.html">Table of contents</A>
<HR>

</BODY>
</HTML>