About Logarithmic Color Space |
Once you have read this, you might also want to read part of the Brinkmann
Course, specifically Section 3.7, Nonlinear color space. You
also might want to take a short nap.
The Logarithmic
Cineon File
Ok, time to get out your pillows, here comes the history and math lesson all in one blow:
Way back in the day, Kodak came out with their Cineon file format to support their scanners and recorders. Because processors were slow, diskspace and RAM were expensive and networks were poky, they developed an efficient compression of color based upon 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 more a little bit more efficiently. As a simplified example, and this is really a simplification, if we have 5 levels of brightness from black to white, and we can't detect a difference between levels 4 and 5, why not just collapse them togther, leaving us with only 4 values? Now we only have to hold 4 values. Note this compression is not similar to file compression techniques, which looks for bit patterns that can be abbreviated in their description. Therefore, 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 that we typically hear. Normally, we describe color in a "linear" range - low, midtones, and highlights all have equal weight. Here are two example images:
Greyscale of linear space
|
Graph of linear space
|
![]() |
![]() |
The examples below are a greyscale and graph of a ramp converted to logarithmic color space:
Greyscale of log space
|
Graph of log space
|
![]() |
![]() |
You can see that these images don't really seem to have a pure black or white. The graph also shows us 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, you can see that there is less data than on the X axis. We can therefore store this in a smaller file than we might otherwise use, to which the Cineon 10-bit format is nicely adapted.
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 this format is so swell, why bother to convert back to the linear color space at all? First of all, it is unnatural to the eye - we have to convert back to linear to see it properly. More importantly for our discussion, however, is that compression also means that any color corrections applied in this log space will produce unpredictable results, since low, midtones and highlights will have an uneven application of many color correctors, all of which are mathematically based. Here is an example. The first image is the original plate in logarithmic color space. The second image is converted back into linear space and therefore looks more natural to our 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
|
![]() |
![]() |
Now, I apply a Mult node to the log image, and use a very slight red color. The first image is difficult to really gauge the result, 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
|
![]() |
![]() |
However, let us convert the log image to the more natural linear space, and you can see that the slight red multiplier has completely blown our image into the red range:
Mult in log space
viewed in linear space:
|
![]() |
This is bad.
Therefore, you are mathematically urged to either color correct in linear color space or view a conversion to linear 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-boggling bored one day). Everybody's conversion function is essentially the same. The Shake node to handle this correction is called LogLin and is under the Color tab. 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, you apply a LogLin operator after your FileIn, converting it from log space to linear. You do your composite in linear space, and then convert back to log at the very end, attaching your 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 us compositing in an imaginary 3D-rendered element, read in by the FileIn named LinearCGElement. These elements are almost always rendered in linear space and therefore no conversion is necessary.
If you are simply doing color timing, as in the following example, you have the added benefit that all of the color corrections are concatenating into one internal operation:
Wedging and Color Timing
So, why does one even 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 ways of doing this - Wedging and Color Timing. These two methods are only suggestions. Every facility probably has its own system - there is no standard per se.
When wedging a shot, you want to make sure that the files you output from your entire digital process match up with the original film print. There are multiple places that color changes can intentionally or accidentally occur - when exposing film in the camera, when printing the workprint, when scanning the data into digital format, when digitally compositing, when recording the digital plate onto film and or when making the print. To avoid as much variation as possible, you can wedge a shot using the Wedge macro under doc/cook/macros. This is a macro for LogLin that puts in pre-set variations of the offset values as well as contrast values. The process involves something like this:
This process is generally done for every shot. If you are at a larger studio, there is probably an entire department to do this for you. Count yourself lucky to be in such a wise and far-sighted studio.
The second technique to handle this is to not handle it at all - let your production's or the developing lab's Color Timer handle it for you. These are guys who sit around and adjust exposures on film all day for a living. Nice. This is easier, but you surrender some control over the process. However, this is a perfectly acceptable technique used in many large effects houses. When working with 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 you always use the same numbers in both operators. For example, because a physical piece of negative has a slight orange cast to it, 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->lin LogLin, copy the node with Ctrl+C, and then paste a linked copy back in with Shift+Ctrl+V. Adjust the conversion setting of the second LogLin to linear to log. Now, if you adjust the original LogLin, the copy will take the same values because you made a linked copy.
Logarithmic Space and Float bit-depth
Ok, here is where it gets tricky. If we examine the the logarithmic to linear conversion curve, you can see that clipping occurs above 685:
Our LogLin operator does have a rolloff operator, which can help alleviate this sharp corner at the 685 point, but this is inherently a compromise - you are throwing data away. You won't really see this disposal in linear color space. However, once you convert back to logarithmic space, the clipping will occur. Let's take a look at the greyscale first. The first image is a ramp that has a log to lin conversion applied to it. It is now in linear color space. The second image is the first image converted back into log color space. You can see that quite a bit of clipping has occured:
log greyscale converted to
linear space
|
previous example converted
back to log space
|
![]() |
![]() |
Here are two snapshots from a log plate. The first is the original plate. The second image is also in log space after having passed through the log->lin->log conversion process:
Original log image
|
Processed log image
|
![]() |
![]() |
Notice that the highlights are lost in the hair detail, making it look more like taffy than hair. Yummy.
Finally, here are the graphs of what we have. The first graph represents the entire range of the log image. Keep in mind this represents all of the potential values - few log plates will have this entire range. The second image displays the result of the log->lin->log conversion process:
graph of original ramp
|
graph of resulting ramp
|
![]() |
![]() |
So, why is this happening? If we look back at the original log->lin conversion curve, we can plainly see that the curve suggests that it should continue past one. However, these values get clipped, as we have seen. In the next illustration, the red line represents the potential information we can derive from the color conversion. However, it gets clipped off at 1 because in 8 or 16-bits, values can only be stored from 0 to 1.
As this illustration suggests, if we could preserve data above 1, we would always have access to it 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 therefore ideal for working with logarithmic images when converting to linear space and back to log space. If you are merely keeping them in linear space because you are going out to a linear format, float is not necessary.When you work in float, clipping will not occur to your high and low-end data.
Here is how you would modify one of our previous trees. We use the Other - Bytes node, going up to 4 bytes (32 bits, or float):
Notice that we are not obligated to promote our 3D-rendered element up to float since it is already in linear space. The second Bytes operator at the end is in case you are going out to an .iff format - you might want to convert it back down to 16 bits for smaller storage costs. Cineon is always stored at 10 bits, and therefore would not need the second Bytes operator. You will additionally want to remove the alpha channel, which you can do in the FileOut operator, or explicitly with a SetAlpha node, setting it to 0.
Just to be handy, here 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 |
Working in float will also cost you in rendering time, at least 20%, sometimes even double the rendering time, depending on the nodes.
If you are just color timing, i.e., just doing color corrections that concatenate, there is no need to go to float space. All correctors, including the two to go in and out of linear space are calculated at once. Therefore, this tree is still accurate:
Float bit-depth and 3rd-Party Plugins
One problem you will have when working in float is that most of the third-party plugins, including Primatte and Keylight, do not support float, only 8 and 16-bits. You should therefore consider converting the images back to log, executing the plugin, and then converting back to linear and continuing on. This will ensure you maintain your highlights. Applying gentle pressure to the plugin manufacturer to support float images is also a nice alternative, but less productive in the short run.
When pulling keys, we recommend only pulling the key with the keyer, and doing spill suppression and compositing with other nodes. Helpful functions in this process are SwitchMatte, HueCurves, KeyMix and Over. You will not only have more control, but this workflow will also facilitate working with float images. Here is a sample tree:
Two exceptions: