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 < 0.018
Vout = 1.099 * (Vin^0.45) - 0.099 if Vin >= 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>