A close look at the Rec. 709 formula

Update: This document was my part of my attempt to understand and accurately implement Rec. 709, but it is misleading. I got some things significantly wrong, and I don’t really have the technical knowledge and enthusiasm to correct it. For now, you can if you really want, but please don’t believe any of it.


Rec. 709 is a gamma correction formula. It’s used by some image file formats, notably the Netpbm formats (PPM, PGM, PBM, etc.). It’s older than sRGB, and similar to it, in that it is composed of a linear segment and an exponential segment pasted together.

The ITU-R Rec. BT.709 standard gives a formula for converting from Linear to Rec. 709:

Linear (L) to Rec. 709 (V) (official)
ConditionValue
0.000 ≤ L < 0.018V = L×4.50
0.018 ≤ L ≤ 1.000 V = 1.099×L0.45 − 0.099

It does not, however, provide the inverse formula for converting from Rec. 709 to Linear, even though such a formula is pretty much necessary to do anything useful with Rec. 709. Apparently, you’re expected to derive it yourself.

Okay, I think can do that. Here’s what I get:

Rec. 709 (V) to Linear (L) (derived)
ConditionValue
0.00000000000000 ≤ V < 0.08100000000000L = R/4.50
0.08100000000000 ≤ V < 0.08124794403514undefined (or maybe constant 0.018)
0.08124794403514 ≤ V ≤ 1.00000000000000 L = ((R+0.099)/1.099)1/0.45

The undefined section bothers me. It won’t cause much of a problem in practice, because you can just arbitrarily select one of two defined formulas, and you’ll get roughly the same answer either way. But why not define an exact value?

The formula implies that the individual functions should intersect at about 0.018, but they don’t. They intersect at two points that aren’t particularly close to 0.18:

(0.01619486680714426, 0.07287690063214917)
(0.01999892065819229, 0.08999514296186531)

It can’t be a concidence that the functions intersect at almost exactly 0.020, but then, why was 0.018 chosen as the cutoff point instead of 0.020?

Maybe 0.018 was chosen because it’s near the average of the two intersection points. But that doesn’t seem like a good reason to me.

I think the 0.020 intersection point is the one that should be selected as the cutoff point. It makes the function smoother than other choices would.

If you do that, you get the following “improved” Rec. 709 formulas:

Linear to Rec. 709 (improved #1)
ConditionValue
0.00000000000000000 ≤ L < 0.01999892065819229V = L×4.50
0.01999892065819229 ≤ L ≤ 1.00000000000000000 V = 1.099×L0.45 − 0.099
Rec. 709 to Linear (improved #1)
ConditionValue
0.00000000000000000 ≤ V < 0.08999514296186531L = V/4.50
0.08999514296186531 ≤ V ≤ 1.00000000000000000 L = ((V+0.099)/1.099)1/0.45

The following simplified formulas are, for all practical purposes, equivalent to the above:

Linear to Rec. 709 (improved #2)
ConditionValue
0.00 ≤ L < 0.02V = L×4.50
0.02 ≤ L ≤ 1.00 V = 1.099×L0.45 − 0.099
Rec. 709 to Linear (improved #2)
ConditionValue
0.00 ≤ V < 0.09L = V/4.50
0.09 ≤ V ≤ 1.00 L = ((V+0.099)/1.099)1/0.45