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 "include/core/SkColorSpace.h"
9 #include "src/core/SkRasterPipeline.h"
10 #include "tests/Test.h"
11
check_error(skiatest::Reporter * r,float limit,skcms_TransferFunction fn)12 static void check_error(skiatest::Reporter* r, float limit, skcms_TransferFunction fn) {
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
19 SkRasterPipeline_MemoryCtx ip = { in, 0},
20 op = {out, 0};
21
22 SkRasterPipeline_<256> p;
23 p.append(SkRasterPipeline::load_f32, &ip);
24 p.append_transfer_function(fn);
25 p.append(SkRasterPipeline::store_f32, &op);
26
27 p.run(0,0, 256/4,1);
28
29
30 for (int i = 0; i < 256; i++) {
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;
33 if (i % 4 == 3) { // alpha should stay unchanged.
34 want = in[i];
35 }
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
check_error(skiatest::Reporter * r,float limit,float gamma)43 static void check_error(skiatest::Reporter* r, float limit, float gamma) {
44 skcms_TransferFunction fn = {0,0,0,0,0,0,0};
45 fn.g = gamma;
46 fn.a = 1;
47 check_error(r, limit, fn);
48 }
49
DEF_TEST(Parametric_sRGB,r)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.
DEF_TEST(Parametric_1dot0,r)64 DEF_TEST(Parametric_1dot0, r) { check_error(r, 1/510.0f, 1.0f); }
65
DEF_TEST(Parametric_1dot2,r)66 DEF_TEST(Parametric_1dot2, r) { check_error(r, 1/510.0f, 1.2f); }
DEF_TEST(Parametric_1dot4,r)67 DEF_TEST(Parametric_1dot4, r) { check_error(r, 1/510.0f, 1.4f); }
DEF_TEST(Parametric_1dot8,r)68 DEF_TEST(Parametric_1dot8, r) { check_error(r, 1/510.0f, 1.8f); }
DEF_TEST(Parametric_2dot0,r)69 DEF_TEST(Parametric_2dot0, r) { check_error(r, 1/510.0f, 2.0f); }
DEF_TEST(Parametric_2dot2,r)70 DEF_TEST(Parametric_2dot2, r) { check_error(r, 1/510.0f, 2.2f); }
DEF_TEST(Parametric_2dot4,r)71 DEF_TEST(Parametric_2dot4, r) { check_error(r, 1/510.0f, 2.4f); }
72
DEF_TEST(Parametric_inv_1dot2,r)73 DEF_TEST(Parametric_inv_1dot2, r) { check_error(r, 1/510.0f, 1/1.2f); }
DEF_TEST(Parametric_inv_1dot4,r)74 DEF_TEST(Parametric_inv_1dot4, r) { check_error(r, 1/510.0f, 1/1.4f); }
DEF_TEST(Parametric_inv_1dot8,r)75 DEF_TEST(Parametric_inv_1dot8, r) { check_error(r, 1/510.0f, 1/1.8f); }
DEF_TEST(Parametric_inv_2dot0,r)76 DEF_TEST(Parametric_inv_2dot0, r) { check_error(r, 1/510.0f, 1/2.0f); }
DEF_TEST(Parametric_inv_2dot2,r)77 DEF_TEST(Parametric_inv_2dot2, r) { check_error(r, 1/510.0f, 1/2.2f); }
DEF_TEST(Parametric_inv_2dot4,r)78 DEF_TEST(Parametric_inv_2dot4, r) { check_error(r, 1/510.0f, 1/2.4f); }
79