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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 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             : #ifndef SkColorSpacePriv_DEFINED
       8             : #define SkColorSpacePriv_DEFINED
       9             : 
      10             : #include <math.h>
      11             : 
      12             : #include "SkColorSpace_Base.h"
      13             : 
      14             : #define SkColorSpacePrintf(...)
      15             : 
      16             : static constexpr float gSRGB_toXYZD50[] {
      17             :     0.4360747f, 0.3850649f, 0.1430804f, // Rx, Gx, Bx
      18             :     0.2225045f, 0.7168786f, 0.0606169f, // Ry, Gy, Gz
      19             :     0.0139322f, 0.0971045f, 0.7141733f, // Rz, Gz, Bz
      20             : };
      21             : 
      22             : static constexpr float gAdobeRGB_toXYZD50[] {
      23             :     0.6097559f, 0.2052401f, 0.1492240f, // Rx, Gx, Bx
      24             :     0.3111242f, 0.6256560f, 0.0632197f, // Ry, Gy, Gz
      25             :     0.0194811f, 0.0608902f, 0.7448387f, // Rz, Gz, Bz
      26             : };
      27             : 
      28             : static constexpr float gDCIP3_toXYZD50[] {
      29             :     0.515102f,   0.291965f,  0.157153f,  // Rx, Gx, Bx
      30             :     0.241182f,   0.692236f,  0.0665819f, // Ry, Gy, Gz
      31             :    -0.00104941f, 0.0418818f, 0.784378f,  // Rz, Gz, Bz
      32             : };
      33             : 
      34             : static constexpr float gRec2020_toXYZD50[] {
      35             :     0.673459f,   0.165661f,  0.125100f,  // Rx, Gx, Bx
      36             :     0.279033f,   0.675338f,  0.0456288f, // Ry, Gy, Gz
      37             :    -0.00193139f, 0.0299794f, 0.797162f,  // Rz, Gz, Bz
      38             : };
      39             : 
      40           0 : static inline void to_xyz_d50(SkMatrix44* toXYZD50, SkColorSpace::Gamut gamut) {
      41           0 :     switch (gamut) {
      42             :         case SkColorSpace::kSRGB_Gamut:
      43           0 :             toXYZD50->set3x3RowMajorf(gSRGB_toXYZD50);
      44           0 :             break;
      45             :         case SkColorSpace::kAdobeRGB_Gamut:
      46           0 :             toXYZD50->set3x3RowMajorf(gAdobeRGB_toXYZD50);
      47           0 :             break;
      48             :         case SkColorSpace::kDCIP3_D65_Gamut:
      49           0 :             toXYZD50->set3x3RowMajorf(gDCIP3_toXYZD50);
      50           0 :             break;
      51             :         case SkColorSpace::kRec2020_Gamut:
      52           0 :             toXYZD50->set3x3RowMajorf(gRec2020_toXYZD50);
      53           0 :             break;
      54             :     }
      55           0 : }
      56             : 
      57           0 : static inline bool color_space_almost_equal(float a, float b) {
      58           0 :     return SkTAbs(a - b) < 0.01f;
      59             : }
      60             : 
      61             : // Let's use a stricter version for transfer functions.  Worst case, these are encoded
      62             : // in ICC format, which offers 16-bits of fractional precision.
      63           0 : static inline bool transfer_fn_almost_equal(float a, float b) {
      64           0 :     return SkTAbs(a - b) < 0.001f;
      65             : }
      66             : 
      67           0 : static inline bool is_zero_to_one(float v) {
      68             :     // Because we allow a value just barely larger than 1, the client can use an
      69             :     // entirely linear transfer function.
      70           0 :     return (0.0f <= v) && (v <= nextafterf(1.0f, 2.0f));
      71             : }
      72             : 
      73           0 : static inline bool is_valid_transfer_fn(const SkColorSpaceTransferFn& coeffs) {
      74           0 :     if (SkScalarIsNaN(coeffs.fA) || SkScalarIsNaN(coeffs.fB) ||
      75           0 :         SkScalarIsNaN(coeffs.fC) || SkScalarIsNaN(coeffs.fD) ||
      76           0 :         SkScalarIsNaN(coeffs.fE) || SkScalarIsNaN(coeffs.fF) ||
      77           0 :         SkScalarIsNaN(coeffs.fG))
      78             :     {
      79           0 :         return false;
      80             :     }
      81             : 
      82           0 :     if (!is_zero_to_one(coeffs.fD)) {
      83           0 :         return false;
      84             :     }
      85             : 
      86           0 :     if (coeffs.fD == 0.0f) {
      87             :         // Y = (aX + b)^g + e  for always
      88           0 :         if (0.0f == coeffs.fA || 0.0f == coeffs.fG) {
      89             :             SkColorSpacePrintf("A or G is zero, constant transfer function "
      90             :                                "is nonsense");
      91           0 :             return false;
      92             :         }
      93             :     }
      94             : 
      95           0 :     if (coeffs.fD >= 1.0f) {
      96             :         // Y = cX + f          for always
      97           0 :         if (0.0f == coeffs.fC) {
      98             :             SkColorSpacePrintf("C is zero, constant transfer function is "
      99             :                                "nonsense");
     100           0 :             return false;
     101             :         }
     102             :     }
     103             : 
     104           0 :     if ((0.0f == coeffs.fA || 0.0f == coeffs.fG) && 0.0f == coeffs.fC) {
     105             :         SkColorSpacePrintf("A or G, and C are zero, constant transfer function "
     106             :                            "is nonsense");
     107           0 :         return false;
     108             :     }
     109             : 
     110           0 :     if (coeffs.fC < 0.0f) {
     111             :         SkColorSpacePrintf("Transfer function must be increasing");
     112           0 :         return false;
     113             :     }
     114             : 
     115           0 :     if (coeffs.fA < 0.0f || coeffs.fG < 0.0f) {
     116             :         SkColorSpacePrintf("Transfer function must be positive or increasing");
     117           0 :         return false;
     118             :     }
     119             : 
     120           0 :     return true;
     121             : }
     122             : 
     123           0 : static inline bool is_almost_srgb(const SkColorSpaceTransferFn& coeffs) {
     124           0 :     return transfer_fn_almost_equal(1.0f / 1.055f,   coeffs.fA) &&
     125           0 :            transfer_fn_almost_equal(0.055f / 1.055f, coeffs.fB) &&
     126           0 :            transfer_fn_almost_equal(1.0f / 12.92f,   coeffs.fC) &&
     127           0 :            transfer_fn_almost_equal(0.04045f,        coeffs.fD) &&
     128           0 :            transfer_fn_almost_equal(0.00000f,        coeffs.fE) &&
     129           0 :            transfer_fn_almost_equal(0.00000f,        coeffs.fF) &&
     130           0 :            transfer_fn_almost_equal(2.40000f,        coeffs.fG);
     131             : }
     132             : 
     133           0 : static inline bool is_almost_2dot2(const SkColorSpaceTransferFn& coeffs) {
     134           0 :     return transfer_fn_almost_equal(1.0f, coeffs.fA) &&
     135           0 :            transfer_fn_almost_equal(0.0f, coeffs.fB) &&
     136           0 :            transfer_fn_almost_equal(0.0f, coeffs.fE) &&
     137           0 :            transfer_fn_almost_equal(2.2f, coeffs.fG) &&
     138           0 :            coeffs.fD <= 0.0f;
     139             : }
     140             : 
     141           0 : static inline bool is_almost_linear(const SkColorSpaceTransferFn& coeffs) {
     142             :     // OutputVal = InputVal ^ 1.0f
     143             :     const bool linearExp =
     144           0 :             transfer_fn_almost_equal(1.0f, coeffs.fA) &&
     145           0 :             transfer_fn_almost_equal(0.0f, coeffs.fB) &&
     146           0 :             transfer_fn_almost_equal(0.0f, coeffs.fE) &&
     147           0 :             transfer_fn_almost_equal(1.0f, coeffs.fG) &&
     148           0 :             coeffs.fD <= 0.0f;
     149             : 
     150             :     // OutputVal = 1.0f * InputVal
     151             :     const bool linearFn =
     152           0 :             transfer_fn_almost_equal(1.0f, coeffs.fC) &&
     153           0 :             transfer_fn_almost_equal(0.0f, coeffs.fF) &&
     154           0 :             coeffs.fD >= 1.0f;
     155             : 
     156           0 :     return linearExp || linearFn;
     157             : }
     158             : 
     159           0 : static inline void value_to_parametric(SkColorSpaceTransferFn* coeffs, float exponent) {
     160           0 :     coeffs->fA = 1.0f;
     161           0 :     coeffs->fB = 0.0f;
     162           0 :     coeffs->fC = 0.0f;
     163           0 :     coeffs->fD = 0.0f;
     164           0 :     coeffs->fE = 0.0f;
     165           0 :     coeffs->fF = 0.0f;
     166           0 :     coeffs->fG = exponent;
     167           0 : }
     168             : 
     169           0 : static inline bool named_to_parametric(SkColorSpaceTransferFn* coeffs,
     170             :                                        SkGammaNamed gammaNamed) {
     171           0 :     switch (gammaNamed) {
     172             :         case kSRGB_SkGammaNamed:
     173           0 :             coeffs->fA = 1.0f / 1.055f;
     174           0 :             coeffs->fB = 0.055f / 1.055f;
     175           0 :             coeffs->fC = 1.0f / 12.92f;
     176           0 :             coeffs->fD = 0.04045f;
     177           0 :             coeffs->fE = 0.0f;
     178           0 :             coeffs->fF = 0.0f;
     179           0 :             coeffs->fG = 2.4f;
     180           0 :             return true;
     181             :         case k2Dot2Curve_SkGammaNamed:
     182           0 :             value_to_parametric(coeffs, 2.2f);
     183           0 :             return true;
     184             :         case kLinear_SkGammaNamed:
     185           0 :             coeffs->fA = 0.0f;
     186           0 :             coeffs->fB = 0.0f;
     187           0 :             coeffs->fC = 1.0f;
     188             :             // Make sure that we use the linear segment of the transfer function even
     189             :             // when the x-value is 1.0f.
     190           0 :             coeffs->fD = nextafterf(1.0f, 2.0f);
     191           0 :             coeffs->fE = 0.0f;
     192           0 :             coeffs->fF = 0.0f;
     193           0 :             coeffs->fG = 0.0f;
     194           0 :             return true;
     195             :         default:
     196           0 :             return false;
     197             :     }
     198             : }
     199             : #endif  // SkColorSpacePriv_DEFINED

Generated by: LCOV version 1.13