LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkMaskGamma.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 60 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :  */
       7             : 
       8             : #include "SkTypes.h"
       9             : 
      10             : #include "SkColor.h"
      11             : #include "SkFloatingPoint.h"
      12             : #include "SkMaskGamma.h"
      13             : 
      14           0 : class SkLinearColorSpaceLuminance : public SkColorSpaceLuminance {
      15           0 :     SkScalar toLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luminance) const override {
      16           0 :         SkASSERT(SK_Scalar1 == gamma);
      17           0 :         return luminance;
      18             :     }
      19           0 :     SkScalar fromLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luma) const override {
      20           0 :         SkASSERT(SK_Scalar1 == gamma);
      21           0 :         return luma;
      22             :     }
      23             : };
      24             : 
      25           0 : class SkGammaColorSpaceLuminance : public SkColorSpaceLuminance {
      26           0 :     SkScalar toLuma(SkScalar gamma, SkScalar luminance) const override {
      27           0 :         return SkScalarPow(luminance, gamma);
      28             :     }
      29           0 :     SkScalar fromLuma(SkScalar gamma, SkScalar luma) const override {
      30           0 :         return SkScalarPow(luma, SkScalarInvert(gamma));
      31             :     }
      32             : };
      33             : 
      34           0 : class SkSRGBColorSpaceLuminance : public SkColorSpaceLuminance {
      35           0 :     SkScalar toLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luminance) const override {
      36           0 :         SkASSERT(0 == gamma);
      37             :         //The magic numbers are derived from the sRGB specification.
      38             :         //See http://www.color.org/chardata/rgb/srgb.xalter .
      39           0 :         if (luminance <= 0.04045f) {
      40           0 :             return luminance / 12.92f;
      41             :         }
      42           0 :         return SkScalarPow((luminance + 0.055f) / 1.055f,
      43             :                         2.4f);
      44             :     }
      45           0 :     SkScalar fromLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luma) const override {
      46           0 :         SkASSERT(0 == gamma);
      47             :         //The magic numbers are derived from the sRGB specification.
      48             :         //See http://www.color.org/chardata/rgb/srgb.xalter .
      49           0 :         if (luma <= 0.0031308f) {
      50           0 :             return luma * 12.92f;
      51             :         }
      52           0 :         return 1.055f * SkScalarPow(luma, SkScalarInvert(2.4f))
      53           0 :                - 0.055f;
      54             :     }
      55             : };
      56             : 
      57           0 : /*static*/ const SkColorSpaceLuminance& SkColorSpaceLuminance::Fetch(SkScalar gamma) {
      58           0 :     static SkLinearColorSpaceLuminance gSkLinearColorSpaceLuminance;
      59           0 :     static SkGammaColorSpaceLuminance gSkGammaColorSpaceLuminance;
      60           0 :     static SkSRGBColorSpaceLuminance gSkSRGBColorSpaceLuminance;
      61             : 
      62           0 :     if (0 == gamma) {
      63           0 :         return gSkSRGBColorSpaceLuminance;
      64           0 :     } else if (SK_Scalar1 == gamma) {
      65           0 :         return gSkLinearColorSpaceLuminance;
      66             :     } else {
      67           0 :         return gSkGammaColorSpaceLuminance;
      68             :     }
      69             : }
      70             : 
      71           0 : static float apply_contrast(float srca, float contrast) {
      72           0 :     return srca + ((1.0f - srca) * contrast * srca);
      73             : }
      74             : 
      75           0 : 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           0 :     const float src = (float)srcI / 255.0f;
      79           0 :     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           0 :     const float dst = 1.0f - src;
      85           0 :     const float linDst = dstConvert.toLuma(dstGamma, dst);
      86             : 
      87             :     //Contrast value tapers off to 0 as the src luminance becomes white
      88           0 :     const float adjustedContrast = SkScalarToFloat(contrast) * linDst;
      89             : 
      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           0 :     if (fabs(src - dst) < (1.0f / 256.0f)) {
      93           0 :         float ii = 0.0f;
      94           0 :         for (int i = 0; i < 256; ++i, ii += 1.0f) {
      95           0 :             float rawSrca = ii / 255.0f;
      96           0 :             float srca = apply_contrast(rawSrca, adjustedContrast);
      97           0 :             table[i] = SkToU8(sk_float_round2int(255.0f * srca));
      98             :         }
      99             :     } else {
     100             :         // Avoid slow int to float conversion.
     101           0 :         float ii = 0.0f;
     102           0 :         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           0 :             float rawSrca = ii / 255.0f;
     108           0 :             float srca = apply_contrast(rawSrca, adjustedContrast);
     109           0 :             SkASSERT(srca <= 1.0f);
     110           0 :             float dsta = 1.0f - srca;
     111             : 
     112             :             //Calculate the output we want.
     113           0 :             float linOut = (linSrc * srca + dsta * linDst);
     114           0 :             SkASSERT(linOut <= 1.0f);
     115           0 :             float out = dstConvert.fromLuma(dstGamma, linOut);
     116             : 
     117             :             //Undo what the blit blend will do.
     118           0 :             float result = (out - dst) / (src - dst);
     119           0 :             SkASSERT(sk_float_round2int(255.0f * result) <= 255);
     120             : 
     121           0 :             table[i] = SkToU8(sk_float_round2int(255.0f * result));
     122             :         }
     123             :     }
     124           0 : }

Generated by: LCOV version 1.13