OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkSRGB_DEFINED | 8 #ifndef SkSRGB_DEFINED |
9 #define SkSRGB_DEFINED | 9 #define SkSRGB_DEFINED |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 template <int N> | 54 template <int N> |
55 static inline SkNx<N,int> sk_linear_to_srgb(const SkNx<N,float>& x) { | 55 static inline SkNx<N,int> sk_linear_to_srgb(const SkNx<N,float>& x) { |
56 auto f = sk_linear_to_srgb_needs_trunc(x); | 56 auto f = sk_linear_to_srgb_needs_trunc(x); |
57 return SkNx_cast<int>(sk_clamp_0_255(f)); | 57 return SkNx_cast<int>(sk_clamp_0_255(f)); |
58 } | 58 } |
59 | 59 |
60 template <int N> | 60 template <int N> |
61 static inline SkNx<N,int> sk_linear_to_srgb_noclamp(const SkNx<N,float>& x) { | 61 static inline SkNx<N,int> sk_linear_to_srgb_noclamp(const SkNx<N,float>& x) { |
62 auto f = sk_linear_to_srgb_needs_trunc(x); | 62 auto f = sk_linear_to_srgb_needs_trunc(x); |
63 for (int i = 0; i < 4; i++) { | 63 for (int i = 0; i < 4; i++) { |
64 SkASSERTF(0.0f <= f[i] && f[i] < 256.0f, "f[%d] was %g, outside [0,256)\ n", i, f[i]); | 64 // Turn this assert off for now because srgb conversions may end up in r gb > a |
65 // SkASSERTF(0.0f <= f[i] && f[i] < 256.0f, "f[%d] was %g, outside [0,25 6)\n", i, f[i]); | |
mtklein_C
2016/11/02 18:48:19
There's a slightly better solution, which is to de
liyuqian
2016/11/02 19:33:11
Thank you! I saw your follow up CL. Feel free to l
| |
65 } | 66 } |
66 return SkNx_cast<int>(f); | 67 return SkNx_cast<int>(f); |
67 } | 68 } |
68 | 69 |
69 // sRGB -> linear, using math instead of table lookups, scaling better to larger SIMD vectors. | 70 // sRGB -> linear, using math instead of table lookups, scaling better to larger SIMD vectors. |
70 template <int N> | 71 template <int N> |
71 static inline SkNx<N,float> sk_linear_from_srgb_math(const SkNx<N,int>& s) { | 72 static inline SkNx<N,float> sk_linear_from_srgb_math(const SkNx<N,int>& s) { |
72 auto x = SkNx_cast<float>(s); | 73 auto x = SkNx_cast<float>(s); |
73 | 74 |
74 const float u = 1/255.0f; // x is [0,255], so x^n needs scaling by u^n. | 75 const float u = 1/255.0f; // x is [0,255], so x^n needs scaling by u^n. |
75 | 76 |
76 // Non-linear segment of sRGB curve approximated by | 77 // Non-linear segment of sRGB curve approximated by |
77 // l = 0.0025 + 0.6975x^2 + 0.3x^3 | 78 // l = 0.0025 + 0.6975x^2 + 0.3x^3 |
78 const SkNx<N,float> k0 = 0.0025f, | 79 const SkNx<N,float> k0 = 0.0025f, |
79 k2 = 0.6975f * u*u, | 80 k2 = 0.6975f * u*u, |
80 k3 = 0.3000f * u*u*u; | 81 k3 = 0.3000f * u*u*u; |
81 auto hi = SkNx_fma(x*x, SkNx_fma(x, k3, k2), k0); | 82 auto hi = SkNx_fma(x*x, SkNx_fma(x, k3, k2), k0); |
82 | 83 |
83 // Linear segment of sRGB curve: the normal slope, extended a little further than normal. | 84 // Linear segment of sRGB curve: the normal slope, extended a little further than normal. |
84 auto lo = x * (u/12.92f); | 85 auto lo = x * (u/12.92f); |
85 | 86 |
86 return (x < 14.025f).thenElse(lo, hi); | 87 return (x < 14.025f).thenElse(lo, hi); |
87 } | 88 } |
88 | 89 |
89 #endif//SkSRGB_DEFINED | 90 #endif//SkSRGB_DEFINED |
OLD | NEW |