Page 1 of 1

Multiple issues with BMPv5 colorimetry

Posted: 2012-08-12T11:28:38-07:00
by Jason S
I'm using IM 6.7.8-9.

I've made some sample BMP files that may be of use, available here. The g/pal8v5.bmp and g/pal8v4.bmp files are relevant. (I can't be sure these files are correctly formed. Please tell me if you think they're not.)

Here's the main BMP documentation I'm using.

Test case: Create a BMP file, and copy it to another BMP file.

Code: Select all

$ convert logo: test1.bmp
$ convert test1.bmp test2.bmp
The files will contain the following data:

Code: Select all

test1.bmp CIEXYZ Endpoints = {0.0, 0.0, 3.9393, 0.0, 0.0, 3.9437, 0.0, 0.0, 3.9868}
test1.bmp Gamma = {0.0, 0.0, 0.0}

test2.bmp CIEXYZ Endpoints = {0.0, 0.0, 3.9990, 0.0, 0.0, 3.9991, 0.0, 0.0, 3.9997}
test2.bmp Gamma = {0.0, 0.0, 0.0}
The numbers appear to be meaningless. Also, they don't survive a round-trip through "convert".

(Note: These fields are technically supposed to be ignored in this case, because the files are labeled as sRGB. However, IM currently doesn't ignore them, so I'm taking advantage of that to make it easier to test.)

Some of the relevant code in coders/bmp.c:

Code: Select all

Reading chromaticities:
726:   bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;

Reading gamma:
750:   bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0xffff;

Writing chromaticities:
1955:   (void) WriteBlobLSBLong(image,(unsigned int)
          image->chromaticity.red_primary.x*0x3ffffff);
1957:   (void) WriteBlobLSBLong(image,(unsigned int)
          image->chromaticity.red_primary.y*0x3ffffff);
1959:   (void) WriteBlobLSBLong(image,(unsigned int)
          (1.000f-(image->chromaticity.red_primary.x+
          image->chromaticity.red_primary.y)*0x3ffffff));

Writing gamma:
1976:  (void) WriteBlobLSBLong(image,(unsigned int)
          bmp_info.gamma_scale.x*0xffff);
Suspected bugs:

- Lines 1955, 1957, 1976, etc.: Missing parens cause the "(unsigned int)" cast to happen before multiplying by 0x3ffffff or 0xffff, so the end result is usually 0.

- Lines 1959, etc.: Missing parens causes multiplication by 0x3ffffff to happen before subtracting from 1.

- I'm pretty sure the bias should be (2^something), not (2^something-1). E.g. the gamma bias should be 0x10000, not 0xffff.

- The chromaticity bias has the "decimal point" in the wrong place. It should be 0x40000000 (2^30), not 0x3ffffff (2^26-1).

- As noted above, chromaticities and gamma should be ignored unless bV5CSType field is LCS_CALIBRATED_RGB (0). Instead, I get a warning when writing to a PNG file. The BMP file is labeled as sRGB, and has the unused fields set to 0.

Code: Select all

$ convert bmpsuite/g/pal8v5.bmp test.png
convert.exe: fixed point overflow in cHRM Blue Y `test.png' @ error/png.c/Magick
PNGErrorHandler/1751.

Re: Multiple issues with BMPv5 colorimetry

Posted: 2012-08-12T12:45:32-07:00
by magick
Thanks for the problem report and patch suggestions. We'll get your patch into ImageMagick 6.7.8-10 Beta by sometime tomorrow.