Multiple issues with BMPv5 colorimetry

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
Jason S
Posts: 103
Joined: 2010-12-14T19:42:12-07:00
Authentication code: 8675308

Multiple issues with BMPv5 colorimetry

Post 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.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Multiple issues with BMPv5 colorimetry

Post 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.
Post Reply