After fiddling a bit with these routines, I have both good and bad news:
- good: 700D has routines very similar to 5D3 (named TwoInTwoOutJpegPath; not tested)
- good: 5D3 has two sets of routines for lossless compression (TwoInTwoOutLosslessPath and TwoInTwoOutJpegPath); both are working (second one requires some fiddling)
- bad: the routines are a bit different on 60D (not very LiveView-friendly)
- ugly: I wasn't able to decode the compressed images from 60D (just corrupted images), but didn't try too hard
- good: output bit depth (0xC0E00084) can be overriden from 14 to 15 bits
- info: a file with 15 bits is just 3 bytes (!) higher than a 14-bits one (headers show 15 bits and contents is totally different for same input image)
- bad: other bit depths (8, 10, 12) did not work at all
- bad: bit depth overriding did not work on 5D3 at all (maybe I'm missing something)
- good: the routines can accept raw image streams of arbitrary bit depths (10/12/14/16, configured with 0xC0F371FC)
- bad: the above doesn't appear to improve compression ratio at all
- ugly: compressing a zeroed out image gives a ratio of... 35.7%
! (very large encoder overhead?)
- output levels do not depend on input bit depth
- instead, 10-bit streams are padded with zero LSBs; the end result is the same as zeroing the lower bits.
From the 14/15-bit experiment, dividing the input data by some constant value (e.g. dividing by 16 for 14->10 bit conversion) probably has the same impact on file size
as if we were able to reconfigure the encoder for a lower bit depth (which we can't). That's my current understanding, but I have no hard proof on that (as I don't even know how the encoder works).
Note: the identical checksum confirms that compressing a 10-bit raw image gives the same result as converting a 14-bit image with 4 LSBs zeroed out (therefore, the unpacker module probably normalizes the values internally by adding LSBs).
Bottom line: pushing the lossless compression ratio below 50% (relative to 14-bit uncompressed raw size) is hard. Of course, it depends on noise levels and scene contents, unlike uncompressed raw, but the variations appear to be small.
(M)JPEG is, indeed, done with the same routines. The main difference is the type of data accepted as input (8-bit debayered, probably hardcoded to YUV422).