summaryrefslogtreecommitdiff
path: root/core/fxcodec/codec/fx_codec_icc.cpp
diff options
context:
space:
mode:
authorbrucedawson <brucedawson@chromium.org>2016-11-01 11:22:25 -0700
committerCommit bot <commit-bot@chromium.org>2016-11-01 11:22:25 -0700
commitfcb1728c35f97a67fa0297f12bb13d3cafb01fe1 (patch)
tree4ae892cc3a59d2b4978c07899fa6f7fa662bc6cf /core/fxcodec/codec/fx_codec_icc.cpp
parent9ec22175f945d227e71c459e7e0b7c464159c18b (diff)
downloadpdfium-fcb1728c35f97a67fa0297f12bb13d3cafb01fe1.tar.xz
Fix founding difference in pdfium_test on AdobeCMYK_to_sRGB
An optimization to speed up float-to-int rounding caused a different result for one input value. This tweaks the conversion constant so that the results are identical across the entire valid range, and adds a test that checks the part of the range that is most sensitive to errors. BUG=pdfium:624 Review-Url: https://codereview.chromium.org/2466203002
Diffstat (limited to 'core/fxcodec/codec/fx_codec_icc.cpp')
-rw-r--r--core/fxcodec/codec/fx_codec_icc.cpp22
1 files changed, 11 insertions, 11 deletions
diff --git a/core/fxcodec/codec/fx_codec_icc.cpp b/core/fxcodec/codec/fx_codec_icc.cpp
index 8e48bfbfea..f0ea6bb43c 100644
--- a/core/fxcodec/codec/fx_codec_icc.cpp
+++ b/core/fxcodec/codec/fx_codec_icc.cpp
@@ -1663,17 +1663,17 @@ void AdobeCMYK_to_sRGB(FX_FLOAT c,
// Convert to uint8_t with round-to-nearest. Avoid using FXSYS_round because
// it is incredibly expensive with VC++ (tested on VC++ 2015) because round()
// is very expensive.
- // Adding 0.5f and truncating can round the wrong direction in some edge
- // cases but these do not matter in this context. For instance, the float that
- // is one ULP (unit in the last place) before 0.5 should round to zero but
- // this will round it to one. These edge cases are never hit in this function
- // due to the very limited precision of the input integers.
- // This method also doesn't handle negative or extremely large numbers, but
- // those are not needed here.
- uint8_t c1 = int(c * 255.f + 0.5f);
- uint8_t m1 = int(m * 255.f + 0.5f);
- uint8_t y1 = int(y * 255.f + 0.5f);
- uint8_t k1 = int(k * 255.f + 0.5f);
+ // The 'magic' value of 0.49999997f, the float that precedes 0.5f, was chosen
+ // because it gives identical results to FXSYS_round(). Using the constant
+ // 0.5f gives different results (1 instead of 0) for one value, 0.0019607842.
+ // That value is close to the cusp but zero is the correct answer, and
+ // getting the same answer as before is desirable.
+ // All floats from 0.0 to 1.0 were tested and now give the same results.
+ const float rounding_offset = 0.49999997f;
+ uint8_t c1 = int(c * 255.f + rounding_offset);
+ uint8_t m1 = int(m * 255.f + rounding_offset);
+ uint8_t y1 = int(y * 255.f + rounding_offset);
+ uint8_t k1 = int(k * 255.f + rounding_offset);
ASSERT(c1 == FXSYS_round(c * 255));
ASSERT(m1 == FXSYS_round(m * 255));