gfx/skia/trunk/src/core/SkMaskGamma.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /*
     2  * Copyright 2012 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkTypes.h"
    10 #include "SkColor.h"
    11 #include "SkFloatingPoint.h"
    12 #include "SkMaskGamma.h"
    14 class SkLinearColorSpaceLuminance : public SkColorSpaceLuminance {
    15     virtual SkScalar toLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luminance) const SK_OVERRIDE {
    16         SkASSERT(SK_Scalar1 == gamma);
    17         return luminance;
    18     }
    19     virtual SkScalar fromLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luma) const SK_OVERRIDE {
    20         SkASSERT(SK_Scalar1 == gamma);
    21         return luma;
    22     }
    23 };
    25 class SkGammaColorSpaceLuminance : public SkColorSpaceLuminance {
    26     virtual SkScalar toLuma(SkScalar gamma, SkScalar luminance) const SK_OVERRIDE {
    27         return SkScalarPow(luminance, gamma);
    28     }
    29     virtual SkScalar fromLuma(SkScalar gamma, SkScalar luma) const SK_OVERRIDE {
    30         return SkScalarPow(luma, SkScalarInvert(gamma));
    31     }
    32 };
    34 class SkSRGBColorSpaceLuminance : public SkColorSpaceLuminance {
    35     virtual SkScalar toLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luminance) const SK_OVERRIDE {
    36         SkASSERT(0 == gamma);
    37         //The magic numbers are derived from the sRGB specification.
    38         //See http://www.color.org/chardata/rgb/srgb.xalter .
    39         if (luminance <= 0.04045f) {
    40             return luminance / 12.92f;
    41         }
    42         return SkScalarPow((luminance + 0.055f) / 1.055f,
    43                         2.4f);
    44     }
    45     virtual SkScalar fromLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luma) const SK_OVERRIDE {
    46         SkASSERT(0 == gamma);
    47         //The magic numbers are derived from the sRGB specification.
    48         //See http://www.color.org/chardata/rgb/srgb.xalter .
    49         if (luma <= 0.0031308f) {
    50             return luma * 12.92f;
    51         }
    52         return 1.055f * SkScalarPow(luma, SkScalarInvert(2.4f))
    53                - 0.055f;
    54     }
    55 };
    57 /*static*/ const SkColorSpaceLuminance& SkColorSpaceLuminance::Fetch(SkScalar gamma) {
    58     static SkLinearColorSpaceLuminance gSkLinearColorSpaceLuminance;
    59     static SkGammaColorSpaceLuminance gSkGammaColorSpaceLuminance;
    60     static SkSRGBColorSpaceLuminance gSkSRGBColorSpaceLuminance;
    62     if (0 == gamma) {
    63         return gSkSRGBColorSpaceLuminance;
    64     } else if (SK_Scalar1 == gamma) {
    65         return gSkLinearColorSpaceLuminance;
    66     } else {
    67         return gSkGammaColorSpaceLuminance;
    68     }
    69 }
    71 static float apply_contrast(float srca, float contrast) {
    72     return srca + ((1.0f - srca) * contrast * srca);
    73 }
    75 void SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar contrast,
    76                                        const SkColorSpaceLuminance& srcConvert, SkScalar srcGamma,
    77                                        const SkColorSpaceLuminance& dstConvert, SkScalar dstGamma) {
    78     const float src = (float)srcI / 255.0f;
    79     const float linSrc = srcConvert.toLuma(srcGamma, src);
    80     //Guess at the dst. The perceptual inverse provides smaller visual
    81     //discontinuities when slight changes to desaturated colors cause a channel
    82     //to map to a different correcting lut with neighboring srcI.
    83     //See https://code.google.com/p/chromium/issues/detail?id=141425#c59 .
    84     const float dst = 1.0f - src;
    85     const float linDst = dstConvert.toLuma(dstGamma, dst);
    87     //Contrast value tapers off to 0 as the src luminance becomes white
    88     const float adjustedContrast = SkScalarToFloat(contrast) * linDst;
    90     //Remove discontinuity and instability when src is close to dst.
    91     //The value 1/256 is arbitrary and appears to contain the instability.
    92     if (fabs(src - dst) < (1.0f / 256.0f)) {
    93         float ii = 0.0f;
    94         for (int i = 0; i < 256; ++i, ii += 1.0f) {
    95             float rawSrca = ii / 255.0f;
    96             float srca = apply_contrast(rawSrca, adjustedContrast);
    97             table[i] = SkToU8(sk_float_round2int(255.0f * srca));
    98         }
    99     } else {
   100         // Avoid slow int to float conversion.
   101         float ii = 0.0f;
   102         for (int i = 0; i < 256; ++i, ii += 1.0f) {
   103             // 'rawSrca += 1.0f / 255.0f' and even
   104             // 'rawSrca = i * (1.0f / 255.0f)' can add up to more than 1.0f.
   105             // When this happens the table[255] == 0x0 instead of 0xff.
   106             // See http://code.google.com/p/chromium/issues/detail?id=146466
   107             float rawSrca = ii / 255.0f;
   108             float srca = apply_contrast(rawSrca, adjustedContrast);
   109             SkASSERT(srca <= 1.0f);
   110             float dsta = 1.0f - srca;
   112             //Calculate the output we want.
   113             float linOut = (linSrc * srca + dsta * linDst);
   114             SkASSERT(linOut <= 1.0f);
   115             float out = dstConvert.fromLuma(dstGamma, linOut);
   117             //Undo what the blit blend will do.
   118             float result = (out - dst) / (src - dst);
   119             SkASSERT(sk_float_round2int(255.0f * result) <= 255);
   121             table[i] = SkToU8(sk_float_round2int(255.0f * result));
   122         }
   123     }
   124 }

mercurial