Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2017 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 "SkColorSpace.h" |
| 9 | #include "SkRasterPipeline.h" |
| 10 | #include "Test.h" |
| 11 | |
Brian Osman | 5deadca | 2019-01-24 12:18:17 -0500 | [diff] [blame] | 12 | static void check_error(skiatest::Reporter* r, float limit, skcms_TransferFunction fn) { |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 13 | float in[256], out[256]; |
| 14 | for (int i = 0; i < 256; i++) { |
| 15 | in [i] = i / 255.0f; |
| 16 | out[i] = 0.0f; // Not likely important. Just being tidy. |
| 17 | } |
| 18 | |
Mike Klein | b11ab57 | 2018-10-24 06:42:14 -0400 | [diff] [blame] | 19 | SkRasterPipeline_MemoryCtx ip = { in, 0}, |
| 20 | op = {out, 0}; |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 21 | |
Mike Klein | b24704d | 2017-05-24 07:53:00 -0400 | [diff] [blame] | 22 | SkRasterPipeline_<256> p; |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 23 | p.append(SkRasterPipeline::load_f32, &ip); |
Mike Klein | 4eebd9e | 2018-07-11 14:49:51 -0400 | [diff] [blame] | 24 | p.append(SkRasterPipeline::parametric, &fn); |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 25 | p.append(SkRasterPipeline::store_f32, &op); |
| 26 | |
Mike Klein | 45c16fa | 2017-07-18 18:15:13 -0400 | [diff] [blame] | 27 | p.run(0,0, 256/4,1); |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 28 | |
| 29 | |
| 30 | for (int i = 0; i < 256; i++) { |
Brian Osman | 5deadca | 2019-01-24 12:18:17 -0500 | [diff] [blame] | 31 | float want = (in[i] <= fn.d) ? fn.c * in[i] + fn.f |
| 32 | : powf(in[i] * fn.a + fn.b, fn.g) + fn.e; |
Mike Klein | 4eebd9e | 2018-07-11 14:49:51 -0400 | [diff] [blame] | 33 | if (i % 4 == 3) { // alpha should stay unchanged. |
| 34 | want = in[i]; |
| 35 | } |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 36 | float err = fabsf(out[i] - want); |
| 37 | if (err > limit) { |
| 38 | ERRORF(r, "At %d, error was %g (got %g, want %g)", i, err, out[i], want); |
| 39 | } |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | static void check_error(skiatest::Reporter* r, float limit, float gamma) { |
Brian Osman | 5deadca | 2019-01-24 12:18:17 -0500 | [diff] [blame] | 44 | skcms_TransferFunction fn = {0,0,0,0,0,0,0}; |
| 45 | fn.g = gamma; |
| 46 | fn.a = 1; |
Mike Klein | c7be003 | 2017-04-25 15:51:23 -0400 | [diff] [blame] | 47 | check_error(r, limit, fn); |
Mike Klein | 8f2911f | 2017-04-19 12:40:52 -0400 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | DEF_TEST(Parametric_sRGB, r) { |
| 51 | // Test our good buddy the sRGB transfer function in resplendent 7-parameter glory. |
| 52 | check_error(r, 1/510.0f, { |
| 53 | 2.4f, |
| 54 | 1.0f / 1.055f, |
| 55 | 0.055f / 1.055f, |
| 56 | 1.0f / 12.92f, |
| 57 | 0.04045f, |
| 58 | 0.0f, |
| 59 | 0.0f, |
| 60 | }); |
| 61 | } |
| 62 | |
| 63 | // A nice little spread of simple gammas. |
| 64 | DEF_TEST(Parametric_1dot0, r) { check_error(r, 1/510.0f, 1.0f); } |
| 65 | |
| 66 | DEF_TEST(Parametric_1dot2, r) { check_error(r, 1/510.0f, 1.2f); } |
| 67 | DEF_TEST(Parametric_1dot4, r) { check_error(r, 1/510.0f, 1.4f); } |
| 68 | DEF_TEST(Parametric_1dot8, r) { check_error(r, 1/510.0f, 1.8f); } |
| 69 | DEF_TEST(Parametric_2dot0, r) { check_error(r, 1/510.0f, 2.0f); } |
| 70 | DEF_TEST(Parametric_2dot2, r) { check_error(r, 1/510.0f, 2.2f); } |
| 71 | DEF_TEST(Parametric_2dot4, r) { check_error(r, 1/510.0f, 2.4f); } |
| 72 | |
| 73 | DEF_TEST(Parametric_inv_1dot2, r) { check_error(r, 1/510.0f, 1/1.2f); } |
| 74 | DEF_TEST(Parametric_inv_1dot4, r) { check_error(r, 1/510.0f, 1/1.4f); } |
| 75 | DEF_TEST(Parametric_inv_1dot8, r) { check_error(r, 1/510.0f, 1/1.8f); } |
| 76 | DEF_TEST(Parametric_inv_2dot0, r) { check_error(r, 1/510.0f, 1/2.0f); } |
| 77 | DEF_TEST(Parametric_inv_2dot2, r) { check_error(r, 1/510.0f, 1/2.2f); } |
| 78 | DEF_TEST(Parametric_inv_2dot4, r) { check_error(r, 1/510.0f, 1/2.4f); } |