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 #include "../src/jumper/SkJumper.h" 12 13 static void check_error(skiatest::Reporter* r, float limit, SkColorSpaceTransferFn fn) { 14 float in[256], out[256]; 15 for (int i = 0; i < 256; i++) { 16 in [i] = i / 255.0f; 17 out[i] = 0.0f; // Not likely important. Just being tidy. 18 } 19 20 SkJumper_MemoryCtx ip = { in, 0}, 21 op = {out, 0}; 22 23 SkRasterPipeline_<256> p; 24 p.append(SkRasterPipeline::load_f32, &ip); 25 p.append(SkRasterPipeline::parametric_r, &fn); 26 p.append(SkRasterPipeline::parametric_g, &fn); 27 p.append(SkRasterPipeline::parametric_b, &fn); 28 p.append(SkRasterPipeline::parametric_a, &fn); 29 p.append(SkRasterPipeline::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.fD) ? fn.fC * in[i] + fn.fF 36 : powf(in[i] * fn.fA + fn.fB, fn.fG) + fn.fE; 37 float err = fabsf(out[i] - want); 38 if (err > limit) { 39 ERRORF(r, "At %d, error was %g (got %g, want %g)", i, err, out[i], want); 40 } 41 } 42 } 43 44 static void check_error(skiatest::Reporter* r, float limit, float gamma) { 45 SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0}; 46 fn.fG = gamma; 47 fn.fA = 1; 48 check_error(r, limit, fn); 49 } 50 51 DEF_TEST(Parametric_sRGB, r) { 52 // Test our good buddy the sRGB transfer function in resplendent 7-parameter glory. 53 check_error(r, 1/510.0f, { 54 2.4f, 55 1.0f / 1.055f, 56 0.055f / 1.055f, 57 1.0f / 12.92f, 58 0.04045f, 59 0.0f, 60 0.0f, 61 }); 62 } 63 64 // A nice little spread of simple gammas. 65 DEF_TEST(Parametric_1dot0, r) { check_error(r, 1/510.0f, 1.0f); } 66 67 DEF_TEST(Parametric_1dot2, r) { check_error(r, 1/510.0f, 1.2f); } 68 DEF_TEST(Parametric_1dot4, r) { check_error(r, 1/510.0f, 1.4f); } 69 DEF_TEST(Parametric_1dot8, r) { check_error(r, 1/510.0f, 1.8f); } 70 DEF_TEST(Parametric_2dot0, r) { check_error(r, 1/510.0f, 2.0f); } 71 DEF_TEST(Parametric_2dot2, r) { check_error(r, 1/510.0f, 2.2f); } 72 DEF_TEST(Parametric_2dot4, r) { check_error(r, 1/510.0f, 2.4f); } 73 74 DEF_TEST(Parametric_inv_1dot2, r) { check_error(r, 1/510.0f, 1/1.2f); } 75 DEF_TEST(Parametric_inv_1dot4, r) { check_error(r, 1/510.0f, 1/1.4f); } 76 DEF_TEST(Parametric_inv_1dot8, r) { check_error(r, 1/510.0f, 1/1.8f); } 77 DEF_TEST(Parametric_inv_2dot0, r) { check_error(r, 1/510.0f, 1/2.0f); } 78 DEF_TEST(Parametric_inv_2dot2, r) { check_error(r, 1/510.0f, 1/2.2f); } 79 DEF_TEST(Parametric_inv_2dot4, r) { check_error(r, 1/510.0f, 1/2.4f); } 80