• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "modules/skcms/skcms.h"
9 #include "src/core/SkRasterPipeline.h"
10 #include "src/core/SkRasterPipelineOpContexts.h"
11 #include "src/core/SkRasterPipelineOpList.h"
12 #include "tests/Test.h"
13 
14 #include <cmath>
15 
check_error(skiatest::Reporter * r,float limit,skcms_TransferFunction fn)16 static void check_error(skiatest::Reporter* r, float limit, skcms_TransferFunction fn) {
17     float in[256], out[256];
18     for (int i = 0; i < 256; i++) {
19         in [i] = i / 255.0f;
20         out[i] = 0.0f;  // Not likely important.  Just being tidy.
21     }
22 
23     SkRasterPipeline_MemoryCtx ip = { in, 0},
24                                op = {out, 0};
25 
26     SkRasterPipeline_<256> p;
27     p.append(SkRasterPipelineOp::load_f32, &ip);
28     p.appendTransferFunction(fn);
29     p.append(SkRasterPipelineOp::store_f32, &op);
30 
31     p.run(0,0, 256/4,1);
32 
33 
34     for (int i = 0; i < 256; i++) {
35         float want = (in[i] <= fn.d) ? fn.c * in[i] + fn.f
36                                      : powf(in[i] * fn.a + fn.b, fn.g) + fn.e;
37         if (i % 4 == 3) {  // alpha should stay unchanged.
38             want = in[i];
39         }
40         float err = fabsf(out[i] - want);
41         if (err > limit) {
42             ERRORF(r, "At %d, error was %g (got %g, want %g)", i, err, out[i], want);
43         }
44     }
45 }
46 
check_error(skiatest::Reporter * r,float limit,float gamma)47 static void check_error(skiatest::Reporter* r, float limit, float gamma) {
48     skcms_TransferFunction fn = {0,0,0,0,0,0,0};
49     fn.g = gamma;
50     fn.a = 1;
51     check_error(r, limit, fn);
52 }
53 
DEF_TEST(Parametric_sRGB,r)54 DEF_TEST(Parametric_sRGB, r) {
55     // Test our good buddy the sRGB transfer function in resplendent 7-parameter glory.
56     check_error(r, 1/510.0f, {
57         2.4f,
58         1.0f / 1.055f,
59         0.055f / 1.055f,
60         1.0f / 12.92f,
61         0.04045f,
62         0.0f,
63         0.0f,
64     });
65 }
66 
67 // A nice little spread of simple gammas.
DEF_TEST(Parametric_1dot0,r)68 DEF_TEST(Parametric_1dot0, r) { check_error(r, 1/510.0f, 1.0f); }
69 
DEF_TEST(Parametric_1dot2,r)70 DEF_TEST(Parametric_1dot2, r) { check_error(r, 1/510.0f, 1.2f); }
DEF_TEST(Parametric_1dot4,r)71 DEF_TEST(Parametric_1dot4, r) { check_error(r, 1/510.0f, 1.4f); }
DEF_TEST(Parametric_1dot8,r)72 DEF_TEST(Parametric_1dot8, r) { check_error(r, 1/510.0f, 1.8f); }
DEF_TEST(Parametric_2dot0,r)73 DEF_TEST(Parametric_2dot0, r) { check_error(r, 1/510.0f, 2.0f); }
DEF_TEST(Parametric_2dot2,r)74 DEF_TEST(Parametric_2dot2, r) { check_error(r, 1/510.0f, 2.2f); }
DEF_TEST(Parametric_2dot4,r)75 DEF_TEST(Parametric_2dot4, r) { check_error(r, 1/510.0f, 2.4f); }
76 
DEF_TEST(Parametric_inv_1dot2,r)77 DEF_TEST(Parametric_inv_1dot2, r) { check_error(r, 1/510.0f, 1/1.2f); }
DEF_TEST(Parametric_inv_1dot4,r)78 DEF_TEST(Parametric_inv_1dot4, r) { check_error(r, 1/510.0f, 1/1.4f); }
DEF_TEST(Parametric_inv_1dot8,r)79 DEF_TEST(Parametric_inv_1dot8, r) { check_error(r, 1/510.0f, 1/1.8f); }
DEF_TEST(Parametric_inv_2dot0,r)80 DEF_TEST(Parametric_inv_2dot0, r) { check_error(r, 1/510.0f, 1/2.0f); }
DEF_TEST(Parametric_inv_2dot2,r)81 DEF_TEST(Parametric_inv_2dot2, r) { check_error(r, 1/510.0f, 1/2.2f); }
DEF_TEST(Parametric_inv_2dot4,r)82 DEF_TEST(Parametric_inv_2dot4, r) { check_error(r, 1/510.0f, 1/2.4f); }
83