SkColorSpacePriv.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. #include <math.h>
  10. #include "include/core/SkColorSpace.h"
  11. #include "include/private/SkFixed.h"
  12. #define SkColorSpacePrintf(...)
  13. // A gamut narrower than sRGB, useful for testing.
  14. static constexpr skcms_Matrix3x3 gNarrow_toXYZD50 = {{
  15. { 0.190974f, 0.404865f, 0.368380f },
  16. { 0.114746f, 0.582937f, 0.302318f },
  17. { 0.032925f, 0.153615f, 0.638669f },
  18. }};
  19. static inline bool color_space_almost_equal(float a, float b) {
  20. return SkTAbs(a - b) < 0.01f;
  21. }
  22. // Let's use a stricter version for transfer functions. Worst case, these are encoded
  23. // in ICC format, which offers 16-bits of fractional precision.
  24. static inline bool transfer_fn_almost_equal(float a, float b) {
  25. return SkTAbs(a - b) < 0.001f;
  26. }
  27. static inline bool is_valid_transfer_fn(const skcms_TransferFunction& coeffs) {
  28. if (SkScalarIsNaN(coeffs.a) || SkScalarIsNaN(coeffs.b) ||
  29. SkScalarIsNaN(coeffs.c) || SkScalarIsNaN(coeffs.d) ||
  30. SkScalarIsNaN(coeffs.e) || SkScalarIsNaN(coeffs.f) ||
  31. SkScalarIsNaN(coeffs.g))
  32. {
  33. return false;
  34. }
  35. if (coeffs.d < 0.0f) {
  36. return false;
  37. }
  38. if (coeffs.d == 0.0f) {
  39. // Y = (aX + b)^g + e for always
  40. if (0.0f == coeffs.a || 0.0f == coeffs.g) {
  41. SkColorSpacePrintf("A or G is zero, constant transfer function "
  42. "is nonsense");
  43. return false;
  44. }
  45. }
  46. if (coeffs.d >= 1.0f) {
  47. // Y = cX + f for always
  48. if (0.0f == coeffs.c) {
  49. SkColorSpacePrintf("C is zero, constant transfer function is "
  50. "nonsense");
  51. return false;
  52. }
  53. }
  54. if ((0.0f == coeffs.a || 0.0f == coeffs.g) && 0.0f == coeffs.c) {
  55. SkColorSpacePrintf("A or G, and C are zero, constant transfer function "
  56. "is nonsense");
  57. return false;
  58. }
  59. if (coeffs.c < 0.0f) {
  60. SkColorSpacePrintf("Transfer function must be increasing");
  61. return false;
  62. }
  63. if (coeffs.a < 0.0f || coeffs.g < 0.0f) {
  64. SkColorSpacePrintf("Transfer function must be positive or increasing");
  65. return false;
  66. }
  67. return true;
  68. }
  69. static inline bool is_almost_srgb(const skcms_TransferFunction& coeffs) {
  70. return transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.a, coeffs.a) &&
  71. transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.b, coeffs.b) &&
  72. transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.c, coeffs.c) &&
  73. transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.d, coeffs.d) &&
  74. transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.e, coeffs.e) &&
  75. transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.f, coeffs.f) &&
  76. transfer_fn_almost_equal(SkNamedTransferFn::kSRGB.g, coeffs.g);
  77. }
  78. static inline bool is_almost_2dot2(const skcms_TransferFunction& coeffs) {
  79. return transfer_fn_almost_equal(1.0f, coeffs.a) &&
  80. transfer_fn_almost_equal(0.0f, coeffs.b) &&
  81. transfer_fn_almost_equal(0.0f, coeffs.e) &&
  82. transfer_fn_almost_equal(2.2f, coeffs.g) &&
  83. coeffs.d <= 0.0f;
  84. }
  85. static inline bool is_almost_linear(const skcms_TransferFunction& coeffs) {
  86. // OutputVal = InputVal ^ 1.0f
  87. const bool linearExp =
  88. transfer_fn_almost_equal(1.0f, coeffs.a) &&
  89. transfer_fn_almost_equal(0.0f, coeffs.b) &&
  90. transfer_fn_almost_equal(0.0f, coeffs.e) &&
  91. transfer_fn_almost_equal(1.0f, coeffs.g) &&
  92. coeffs.d <= 0.0f;
  93. // OutputVal = 1.0f * InputVal
  94. const bool linearFn =
  95. transfer_fn_almost_equal(1.0f, coeffs.c) &&
  96. transfer_fn_almost_equal(0.0f, coeffs.f) &&
  97. coeffs.d >= 1.0f;
  98. return linearExp || linearFn;
  99. }
  100. // Return raw pointers to commonly used SkColorSpaces.
  101. // No need to ref/unref these, but if you do, do it in pairs.
  102. SkColorSpace* sk_srgb_singleton();
  103. SkColorSpace* sk_srgb_linear_singleton();
  104. #endif // SkColorSpacePriv_DEFINED