About Logarithmic Color Space

If you never ever have to deal with film scans, consider yourself lucky and skip this section and go take a well-deserved nap. Otherwise, once you have read this, you might also want to read part of the Brinkmann Course, specifically Section 3.7, Nonlinear Color Spaces. You still also might want to take a short nap.


The Logarithmic Cineon File

OK, time to get your pillows ready, here comes the history and math lesson all in one nasty blow:

Way back in the day, Kodak came out with the Cineon file format to support their scanners and recorders. Because processors were slow, disk space and RAM expensive, and networks poky, they developed an efficient compression of color based on the principle that the human eye is more sensitive to low- and mid-tones than to highlights. Therefore, these highlights can be compressed, saving the amount of data in the file. This resulted in a smaller, 10-bit file, making those poky systems run a little bit more efficiently. As a simplified example (and this is really a simplification), if you have five levels of brightness from black to white, and you cannot detect a difference between levels 4 and 5, why not just collapse them together, leaving only four values to juggle? Note this compression is different from file compression techniques, which look for bit patterns that can be abbreviated in their description. The Cineon file is compressed in its color space, but not its actual digital file structure.

When you graph this compression out, you get a logarithmic curve, thus the catchy description of "log" space. Normally, color is described in a "linear" range - low, midtones, and highlights are of equal weight. Here are two example images.

The first set represents linear space; every value has an equal mathematical distance in brightness to its neighbor:

 


The second set represents a ramp converted to logarithmic space, where the brightness is weighted:


 

These images do not appear to have a pure black or white. The graph also shows that the highlights are flattened (compressed), and the blacks have more attention. This is why Cineon frames typically seem to have a very low contrast, mostly in the highlights. Since the Y axis represents the output data, it contains less data than the X axis. You can therefore store this in a smaller file than you might otherwise use, to which the Cineon 10-bit format is nicely adapted as good balance between color range and speed.

Log compression is not inherent or unique to the Cineon file format. You can store logarithmic color data in any file type, and you can store linear color space data into a .cin file. Logarithmic color space is simply the result of a color correction.



Color Correction and Logarithmic Space

So, if the logarithmic format is so swank, why bother to convert back to the linear color space? First of all, it is unnatural to the eye – you have to convert back to linear space to see it properly. More importantly, compression also means that any color corrections applied in log space produce unpredictable results, since shadows, midtones and highlights have an uneven application of many color correctors.

In this example, the first image is the original plate in logarithmic color space. The second image is converted back to linear space, and therefore looks more natural to the eye. Particularly, you can see the subtlety of the clouds (which is completely lost in the log plate):

Plate in log space
Plate in linear space


A Color - Mult node is applied to the log image with a very slight red color. It is difficult to gauge the result in the first image, since it is still in log space. The other image has a nice tinting of the clouds to turn them pink (assuming you want pink clouds, ahem).

Mult in log space
Mult in linear space


When the log image is converted to the more natural linear space, you can see that the "slight" red multiplier applied before the conversion has completely blown the image into the red range:

Mult in log space viewed in linear space:

This is bad.

Therefore, you are mathematically urged to color correct in linear color space, or view a conversion to linear using a VLUT while you tweak the color correction.



Converting Between Logarithmic and Linear Color Spaces

As previously mentioned, logarithmic images are simply a result of a color correction. This correction has been standardized by Kodak (it's on Cinesite's website at http://www.cinesite.co.uk/la/scanrec/techdocs.html if you are mind-bogglingly bored one day). Everyone's conversion function is essentially the same. The Shake node that handles this correction is called Color - LogLin. You can convert from log to linear, or linear to log color space (thus my catchy name for the node).

The numbers are arranged from 0 to 1023, with the black and white points standardized at 90 and 685. Adjusting these points up and down 90 points is equivalent to 1 f-stop of film exposure. You can therefore make color timing adjustments in the LogLin conversion.

Typically, a LogLin node is applied after a FileIn to convert it from log space to linear. You do your composite in linear space, convert back to log at the very end, and attach the FileOut after that. In this tree, LogLin1 has a conversion setting of log to lin, and LogLin2 has lin to log:

 

This example also shows compositing in an imaginary 3D-rendered element, read in by the FileIn named LinearCGElement. These elements are almost always rendered in linear space, so no conversion is necessary.

If you are simply doing color timing, as in the following example, you have the added benefit of all the color corrections concatenating into one internal operation:

Wedging and Color Timing

So, why have numbers in the LogLin operator? These numbers are used to color correct your plate as a sort of calibration of your entire input/output system. There are (at least) two fundamental ways of doing this: Wedging and Color Timing. The following two methods are only suggestions. Every facility probably has its own system – there is no standard. Isn't film fun?

When wedging a shot, you ensure that the files output from your entire digital process match the original film print. There are multiple places that color changes can intentionally or accidentally occur – exposing film in the camera, printing the workprint, scanning the data into digital format, digitally compositing, recording the digital plate onto film and developing the print. You are saved on one hand in that much of this process is out of your hands – the print lab guy was cranky because his Frappucino was warmed up by the poor sap who couriered it over, so what can you do? To limit discrepancies, use the Wedge macro under doc/cook/macros to wedge a shot. This is a macro for LogLin that puts in pre-set variations of the offset values and contrast values, stepping up and down to try to find a match of the original scan. The process involves something like this:

This process is generally done for every shot. At a larger studio, there is likely an entire department to do the color timing for you. Count yourself lucky to be in such a wise and far-sighted studio.

The second technique to handle the color process is to not handle it at all – let the Color Timer for the production or the developing lab handle it. These are guys who sit around in a cave and adjust exposures on film all day for a living. Nice. While this is easier, you do surrender some control over the process. However, this is a perfectly acceptable technique used in many large effects houses. When you employ this technique, you use the same values in your LogLin going in and out of your color spaces. You may adjust the numbers slightly, but be sure to use the same numbers in both operators. For example, because a physical piece of negative has a slight orange cast, your positive scan might have a slight green cast to it. You may want to adjust for this in the LogLin operator. A good technique is to adjust your log to lin LogLin, copy the node (Ctrl+C), and then paste a linked copy back in (Shift+Ctrl+V). Next, adjust the conversion setting of the second LogLin to linear to log. If you adjust the original LogLin, the copy takes the same values because you made a linked copy.

 

Logarithmic Space and Float Bit Depth

OK, here is where it gets tricky. If you examine the the logarithmic to linear conversion curve, you can see that clipping occurs above 685:



The LogLin operator does have a rolloff operator, which helps alleviate the sharp corner at the 685 point, but this is inherently a compromise – you are throwing data away. You do not really see this data disposal in linear color space. However, once you convert back to logarithmic space, the clipping is evident. Let's take a look at the greyscale first. The left image is a ramp with a log to lin conversion applied to it. It is now in linear color space. The right image is the left image converted back into log color space. Quite a bit of clipping has occured:

Log greyscale converted to linear space
Previous example converted back to log space

 

 

The following images are from a log plate. The left image is the original plate. The right image is the output plate, also in log space, that has been passed through the log > lin > log conversion process:

Original log image
Output log image

 

Notice that the highlights in the hair detail are lost, and it looks more like taffy than hair. Yummy.

The following images are graphs that represent the log plates in the above illustrations. The left graph represents the entire range of the log image. Keep in mind this represents all of the potential values – few log plates have this entire range. The right image displays the result of the log > lin > log conversion process:

Graph of original ramp
Graph of output ramp

 

So, why is this happening? If you look back at the original log > lin conversion graph, the curve suggests that it should continue past one. However, these values are clipped, as we have seen. In the following illustration, the red line represents the potential information we can derive from the color conversion. However, it is clipped at 1 because values can only be stored from 0 to 1 in 8 or 16 bits.

 

As the illustration suggests, if data could be preserved above 1, you could always access the date and life would be happy. Luckily (OK, actually by design), you can convert your images to a higher bit depth called float. Whereas 8 and 16 bits are always in a 0 to 1 range, float can describe any number and is ideal for working with logarithmic images when converting to linear space and back to log space. If you merely keep your images in linear space because you are going out to a linear format, float is not necessary.

The following image shows a modification of the compositing tree from the section "Converting Between Logarithmic and Linear Color Spaces". An Other - Bytes node is inserted, and bumps the image up to 4 bytes (32 bits, or float):

 

Notice that you are not obligated to promote your 3D-rendered element (here represented with LinearCGPlate) to float since it is already in linear space. The second Bytes operator at the end of the tree is in case you go out to an .iff format – you may want to convert it back down to 16 bits for smaller storage costs. Cineon is always stored at 10 bits, and therefore does not need the second Bytes operator. You also want to remove the Alpha channel, either in the FileOut operator, or explicitly with a SetAlpha node (setting it to 0).

Just to be handy, the following is a table of file sizes for 2k plates. Draw your own conclusions:

2K RGB Plate
Size
Cineon, 10 bits
12 MB
IFF, 8 bits 9 MB
IFF, 16 bits 18 MB
IFF, float 36 MB

In addition to storage requirements, working in float costs you rendering time, a minimum of 20 percent, but is usually much higher than that.

Looking at Float Values You can use the Float View ViewerScript to look at values that are above 1 or below 0. To look at these values, create a Ramp, and depth to float. Then, apply a Color - LogLin. When you turn on the Float View, the top 35 percent turns white, indicating values above 1, and the lower 9 percent turns black, indicating values below 0. Everything else turns grey, indicating values between 0 and 1.

If you are just color timing, (just doing color corrections that concatenate), there is no need to convert to float space. All concatenating color correctors, including the two to comvert in and out of linear space are calculated simultaneously. Therefore, the following tree is still accurate:

 

As an alternative to float, use the rolloff parameter in the LogLin node, but it involves inherent compression and banding of your data. The rolloff parameter gves your curve a rolloff (compare to the standard log curves), which can help preserve some highlights, and allows you to stay in 16 bits. However, as shown in the next example, when the same image is converted back to log space, there is still some cutoff in the upper and lower ranges, but the lower ranges also band. Use at your own risk...

Graph of linearization with rolloff
Graph of re-log with rolloff

 

 

Float Bit Depth and Third-Party Plugins

Most of the third-party plugins, including Primatte and Keylight, do not support float (only 8 and 16-bits). To ensure your highlights are maintained, try the following:

If the plugin works on one channel (for example. both Primatte and Keylight can isolate their effect on the Alpha channel), try the following:

Here is a sample tree:

 

Two exceptions:

Applying gentle pressure to the plugin manufacturer to support float images is also a nice alternative, but less productive in the short run.