Chromium Code Reviews| 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 |