diff --git a/src/core/SkMaskGamma.cpp b/src/core/SkMaskGamma.cpp index 449a78de93..15ecdf89e0 100644 --- a/src/core/SkMaskGamma.cpp +++ b/src/core/SkMaskGamma.cpp @@ -49,8 +49,8 @@ static float apply_contrast(float srca, float contrast) { } void SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar contrast, - const SkColorSpaceLuminance& srcConvert, - const SkColorSpaceLuminance& dstConvert) { + const SkColorSpaceLuminance& srcConvert, + const SkColorSpaceLuminance& dstConvert) { const float src = (float)srcI / 255.0f; const float linSrc = srcConvert.toLuma(src); //Guess at the dst. The perceptual inverse provides smaller visual @@ -62,19 +62,25 @@ void SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar //Contrast value tapers off to 0 as the src luminance becomes white const float adjustedContrast = SkScalarToFloat(contrast) * linDst; - const float step = 1.0f / 255.0f; //Remove discontinuity and instability when src is close to dst. //The value 1/256 is arbitrary and appears to contain the instability. if (fabs(src - dst) < (1.0f / 256.0f)) { - float rawSrca = 0.0f; - for (int i = 0; i < 256; ++i, rawSrca += step) { + float ii = 0.0f; + for (int i = 0; i < 256; ++i, ii += 1.0f) { + float rawSrca = ii / 255.0f; float srca = apply_contrast(rawSrca, adjustedContrast); table[i] = SkToU8(sk_float_round2int(255.0f * srca)); } } else { - float rawSrca = 0.0f; - for (int i = 0; i < 256; ++i, rawSrca += step) { + // Avoid slow int to float conversion. + float ii = 0.0f; + for (int i = 0; i < 256; ++i, ii += 1.0f) { + // 'rawSrca += 1.0f / 255.0f' and even + // 'rawSrca = i * (1.0f / 255.0f)' can add up to more than 1.0f. + // When this happens the table[255] == 0x0 instead of 0xff. + // See http://code.google.com/p/chromium/issues/detail?id=146466 + float rawSrca = ii / 255.0f; float srca = apply_contrast(rawSrca, adjustedContrast); SkASSERT(srca <= 1.0f); float dsta = 1.0f - srca;