Sep 3, 2014 at 10:29 PM
In version 1.1 I can't seem to encode and then decode a Gray32 fixed point image and get the original result. As it turns out this appears to be due to the following code in WriteImagePlaneHeader():
    case BD_32S:
        if(pSCP->nLenMantissaOrShift == 0)
            pSCP->nLenMantissaOrShift = 10;//default
        PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);
Simply commenting out the two if lines makes 32 bit fixed point work as expected.

The following lines for BD_32F also seem to impose a mystery shift, not sure what that is about?
Sep 3, 2014 at 10:58 PM
Edited Sep 3, 2014 at 11:01 PM
My knowledge of the codec internals is very limited but this is what the standard says:
SHIFT_BITS is an 8-bit syntax element that is present when OUTPUT_BITDEPTH is equal to BD16, BD16S, or BD32S. SHIFT_BITS is used to left-shift the sample values in the output formatting stage as specified in subclause 9.10.7.
JPEG XR does not enable fully lossless compression for 32-bit data in general. The encoding and decoding
algorithms use 32-bit computations, and some dynamic range is lost to necessary headroom for signal processing calculations such as overlap and core transform computations. A minimum of 22 bits and typically 24 bits or more precision is retained through the end-to-end encoding and decoding process.
I could imagine that by shifting the lowest 32 - 22 = 10 bits out compression is improved without removing precision because in general only 22 bits are guaranteed to be retained. This is just the first idea that came to my mind and could be utterly wrong. In any case, I am sure there's a catch when you remove those two lines (effectively setting SHIFT_BITS to zero)..
Sep 4, 2014 at 4:37 PM
Thanks Christoph

My test case was setting values in the visible region of 32but fixed point (0 to 16M). With that shift present doesn't encode/decode losslessly, and with it commented out it does. Seems like the visible range of an HDR format you'd expect to be able to do losslessly, even if you can't do it all.

I just tested, and with the 2 lines of setting nLenMantissaOrShift commented out I can encode values from -2^27 to +2^27 and get them back without loss, but using 2^28 fails. So, it seems to be lossless for 28 bits which is really great.

That said, I can only do lossless on +- 2^27 with the lines commented out.

BTW, I misread that section of the docs and thought lack of lossless only applied to 32bit floats, but clearly 32S also has the same headroom issue.


Leica Geosystems, Inc
4550 Norris Canyon Road
San Ramon, CA 94583 USA
Direct +1 925 790 2340
Mobile +1 925 577 3479
Fax +1 925 790 2384