Almost a year ago I published a set of scripts (and a python library) for disassembling and reassembling Canon RAW files, and wrote about that on this blog. Since then a few people have been in touch with one question or another. Recently, in one of these communications I came to know that the scripts were incorrectly interpreting the colour channels on at least one camera model. The problem seemed like it would have a fairly simple solution, so I promised to investigate.
The camera in question was the Canon EOS 600D (a.k.a. Rebel T3i), where it seemed that the scripts were confusing the pixel rows holding RG and GB data. So I took a look at the scripts again, and confirmed I was assuming a fixed interpretation of the sensor data. So I spent some time with the dcraw source code, which is always a bit of a headache. Most Canon cameras have an RG/GB Bayer pattern, that is odd rows have alternate Red/Green pixels and even rows have alternate Green/Blue pixels. However, some particular models have swapped lines instead (i.e. GB/RG order). To make things a bit more complicated, the pattern used doesn’t seem to be written anywhere in the metadata. In fact, dcraw has lots of conditionals based on camera make and model to determine the Bayer pattern.
This was consistent with what I was told. I tested the alternate Bayer order on a sample file I was given, and it worked as expected. Rather than inserting lots of conditionals (and needing to update these with every new camera model), I decided to keep the scripts simple, adding a user argument that allows direct specification of the Bayer pattern to use as a four-letter string. For most cameras, the default is “RGGB”, while for the 600D it would need to be “GBRG”. This only affects the RGB decoding/encoding steps; in each case one would need to add the following argument:
In testing with the sample file, I also realised that the RAW pixel values were exceeding the expected saturation limit for that camera, so I also added an argument to allow overriding this value. Clearly, it’s important to supply the same saturation limit both when decoding the original CR2 file and when encoding the changed one. In each case, this value is given by the following argument:
-S 65535, where 65535 can be replaced by the required saturation value. Using 65535 is generally a good default because it tries to extract 16-bit levels, which is generally beyond current sensor capabilities.
All updates have been pushed to GitHub, so all you need to do is to pull changes to get the updated scripts.
Featured image by Colin M.L. Burnett is available under a CC BY-SA 3.0 license.