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 #include "Resources.h" | 8 #include "Resources.h" |
9 #include "SkCodec.h" | 9 #include "SkCodec.h" |
10 #include "SkCodecPriv.h" | 10 #include "SkCodecPriv.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 | 23 |
24 // Use special testing entry point, so we don't skip the xform, even tho
ugh src == dst. | 24 // Use special testing entry point, so we don't skip the xform, even tho
ugh src == dst. |
25 return SlowIdentityXform(space.get()); | 25 return SlowIdentityXform(space.get()); |
26 } | 26 } |
27 }; | 27 }; |
28 | 28 |
29 static bool almost_equal(int x, int y) { | 29 static bool almost_equal(int x, int y) { |
30 return SkTAbs(x - y) <= 1; | 30 return SkTAbs(x - y) <= 1; |
31 } | 31 } |
32 | 32 |
33 static void test_identity_xform(skiatest::Reporter* r, const sk_sp<SkGammas>& ga
mmas) { | 33 static void test_identity_xform(skiatest::Reporter* r, const sk_sp<SkGammas>& ga
mmas, |
| 34 bool repeat) { |
34 // Arbitrary set of 10 pixels | 35 // Arbitrary set of 10 pixels |
35 constexpr int width = 10; | 36 constexpr int width = 10; |
36 constexpr uint32_t srcPixels[width] = { | 37 constexpr uint32_t srcPixels[width] = { |
37 0xFFABCDEF, 0xFF146829, 0xFF382759, 0xFF184968, 0xFFDE8271, | 38 0xFFABCDEF, 0xFF146829, 0xFF382759, 0xFF184968, 0xFFDE8271, |
38 0xFF32AB52, 0xFF0383BC, 0xFF000102, 0xFFFFFFFF, 0xFFDDEEFF, }; | 39 0xFF32AB52, 0xFF0383BC, 0xFF000102, 0xFFFFFFFF, 0xFFDDEEFF, }; |
39 uint32_t dstPixels[width]; | 40 uint32_t dstPixels[width]; |
40 | 41 |
41 // Create and perform an identity xform. | 42 // Create and perform an identity xform. |
42 std::unique_ptr<SkColorSpaceXform> xform = ColorSpaceXformTest::CreateIdenti
tyXform(gammas); | 43 std::unique_ptr<SkColorSpaceXform> xform = ColorSpaceXformTest::CreateIdenti
tyXform(gammas); |
43 bool result = xform->apply(select_xform_format(kN32_SkColorType), dstPixels, | 44 bool result = xform->apply(select_xform_format(kN32_SkColorType), dstPixels, |
44 SkColorSpaceXform::kBGRA_8888_ColorFormat, srcPix
els, width, | 45 SkColorSpaceXform::kBGRA_8888_ColorFormat, srcPix
els, width, |
45 kOpaque_SkAlphaType); | 46 kOpaque_SkAlphaType); |
46 REPORTER_ASSERT(r, result); | 47 REPORTER_ASSERT(r, result); |
47 | 48 |
48 // Since the src->dst matrix is the identity, and the gamma curves match, | 49 // Since the src->dst matrix is the identity, and the gamma curves match, |
49 // the pixels should be unchanged. | 50 // the pixels should be unchanged. |
50 for (int i = 0; i < width; i++) { | 51 for (int i = 0; i < width; i++) { |
51 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 0) & 0xFF), | 52 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 0) & 0xFF), |
52 SkGetPackedB32(dstPixels[i]))); | 53 SkGetPackedB32(dstPixels[i]))); |
53 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 8) & 0xFF), | 54 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 8) & 0xFF), |
54 SkGetPackedG32(dstPixels[i]))); | 55 SkGetPackedG32(dstPixels[i]))); |
55 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 16) & 0xFF), | 56 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 16) & 0xFF), |
56 SkGetPackedR32(dstPixels[i]))); | 57 SkGetPackedR32(dstPixels[i]))); |
57 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 24) & 0xFF), | 58 REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 24) & 0xFF), |
58 SkGetPackedA32(dstPixels[i]))); | 59 SkGetPackedA32(dstPixels[i]))); |
59 } | 60 } |
| 61 |
| 62 if (repeat) { |
| 63 // We should cache part of the transform after the run. So it is intere
sting |
| 64 // to make sure it still runs correctly the second time. |
| 65 test_identity_xform(r, gammas, false); |
| 66 } |
60 } | 67 } |
61 | 68 |
62 DEF_TEST(ColorSpaceXform_TableGamma, r) { | 69 DEF_TEST(ColorSpaceXform_TableGamma, r) { |
63 // Lookup-table based gamma curves | 70 // Lookup-table based gamma curves |
64 constexpr size_t tableSize = 10; | 71 constexpr size_t tableSize = 10; |
65 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(float) * tableSize)
; | 72 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(float) * tableSize)
; |
66 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); | 73 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); |
67 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kTable_Type; | 74 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kTable_Type; |
68 gammas->fRedData.fTable.fSize = gammas->fGreenData.fTable.fSize = | 75 gammas->fRedData.fTable.fSize = gammas->fGreenData.fTable.fSize = |
69 gammas->fBlueData.fTable.fSize = tableSize; | 76 gammas->fBlueData.fTable.fSize = tableSize; |
70 gammas->fRedData.fTable.fOffset = gammas->fGreenData.fTable.fOffset = | 77 gammas->fRedData.fTable.fOffset = gammas->fGreenData.fTable.fOffset = |
71 gammas->fBlueData.fTable.fOffset = 0; | 78 gammas->fBlueData.fTable.fOffset = 0; |
72 float* table = SkTAddOffset<float>(memory, sizeof(SkGammas)); | 79 float* table = SkTAddOffset<float>(memory, sizeof(SkGammas)); |
73 | 80 |
74 table[0] = 0.00f; | 81 table[0] = 0.00f; |
75 table[1] = 0.05f; | 82 table[1] = 0.05f; |
76 table[2] = 0.10f; | 83 table[2] = 0.10f; |
77 table[3] = 0.15f; | 84 table[3] = 0.15f; |
78 table[4] = 0.25f; | 85 table[4] = 0.25f; |
79 table[5] = 0.35f; | 86 table[5] = 0.35f; |
80 table[6] = 0.45f; | 87 table[6] = 0.45f; |
81 table[7] = 0.60f; | 88 table[7] = 0.60f; |
82 table[8] = 0.75f; | 89 table[8] = 0.75f; |
83 table[9] = 1.00f; | 90 table[9] = 1.00f; |
84 test_identity_xform(r, gammas); | 91 test_identity_xform(r, gammas, true); |
85 } | 92 } |
86 | 93 |
87 DEF_TEST(ColorSpaceXform_ParametricGamma, r) { | 94 DEF_TEST(ColorSpaceXform_ParametricGamma, r) { |
88 // Parametric gamma curves | 95 // Parametric gamma curves |
89 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpaceTransfe
rFn)); | 96 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpaceTransfe
rFn)); |
90 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); | 97 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); |
91 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kParam_Type; | 98 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kParam_Type; |
92 gammas->fRedData.fParamOffset = gammas->fGreenData.fParamOffset = | 99 gammas->fRedData.fParamOffset = gammas->fGreenData.fParamOffset = |
93 gammas->fBlueData.fParamOffset = 0; | 100 gammas->fBlueData.fParamOffset = 0; |
94 SkColorSpaceTransferFn* params = SkTAddOffset<SkColorSpaceTransferFn> | 101 SkColorSpaceTransferFn* params = SkTAddOffset<SkColorSpaceTransferFn> |
95 (memory, sizeof(SkGammas)); | 102 (memory, sizeof(SkGammas)); |
96 | 103 |
97 // Interval, switch xforms at 0.0031308f | 104 // Interval, switch xforms at 0.0031308f |
98 params->fD = 0.04045f; | 105 params->fD = 0.04045f; |
99 | 106 |
100 // First equation: | 107 // First equation: |
101 params->fE = 1.0f / 12.92f; | 108 params->fE = 1.0f / 12.92f; |
102 params->fF = 0.0f; | 109 params->fF = 0.0f; |
103 | 110 |
104 // Second equation: | 111 // Second equation: |
105 // Note that the function is continuous (it's actually sRGB). | 112 // Note that the function is continuous (it's actually sRGB). |
106 params->fA = 1.0f / 1.055f; | 113 params->fA = 1.0f / 1.055f; |
107 params->fB = 0.055f / 1.055f; | 114 params->fB = 0.055f / 1.055f; |
108 params->fC = 0.0f; | 115 params->fC = 0.0f; |
109 params->fG = 2.4f; | 116 params->fG = 2.4f; |
110 test_identity_xform(r, gammas); | 117 test_identity_xform(r, gammas, true); |
111 } | 118 } |
112 | 119 |
113 DEF_TEST(ColorSpaceXform_ExponentialGamma, r) { | 120 DEF_TEST(ColorSpaceXform_ExponentialGamma, r) { |
114 // Exponential gamma curves | 121 // Exponential gamma curves |
115 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); | 122 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); |
116 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kValue_Type; | 123 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kValue_Type; |
117 gammas->fRedData.fValue = gammas->fGreenData.fValue = gammas->fBlueData.fVal
ue = 1.4f; | 124 gammas->fRedData.fValue = gammas->fGreenData.fValue = gammas->fBlueData.fVal
ue = 1.4f; |
118 test_identity_xform(r, gammas); | 125 test_identity_xform(r, gammas, true); |
119 } | 126 } |
120 | 127 |
121 DEF_TEST(ColorSpaceXform_NamedGamma, r) { | 128 DEF_TEST(ColorSpaceXform_NamedGamma, r) { |
122 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); | 129 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); |
123 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kNamed_Type; | 130 gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::
kNamed_Type; |
124 gammas->fRedData.fNamed = kSRGB_SkGammaNamed; | 131 gammas->fRedData.fNamed = kSRGB_SkGammaNamed; |
125 gammas->fGreenData.fNamed = k2Dot2Curve_SkGammaNamed; | 132 gammas->fGreenData.fNamed = k2Dot2Curve_SkGammaNamed; |
126 gammas->fBlueData.fNamed = kLinear_SkGammaNamed; | 133 gammas->fBlueData.fNamed = kLinear_SkGammaNamed; |
127 test_identity_xform(r, gammas); | 134 test_identity_xform(r, gammas, true); |
128 } | 135 } |
129 | 136 |
130 DEF_TEST(ColorSpaceXform_NonMatchingGamma, r) { | 137 DEF_TEST(ColorSpaceXform_NonMatchingGamma, r) { |
131 constexpr size_t tableSize = 10; | 138 constexpr size_t tableSize = 10; |
132 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(float) * tableSize
+ | 139 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(float) * tableSize
+ |
133 sizeof(SkColorSpaceTransferFn)); | 140 sizeof(SkColorSpaceTransferFn)); |
134 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); | 141 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); |
135 | 142 |
136 float* table = SkTAddOffset<float>(memory, sizeof(SkGammas)); | 143 float* table = SkTAddOffset<float>(memory, sizeof(SkGammas)); |
137 table[0] = 0.00f; | 144 table[0] = 0.00f; |
(...skipping 20 matching lines...) Expand all Loading... |
158 gammas->fRedType = SkGammas::Type::kValue_Type; | 165 gammas->fRedType = SkGammas::Type::kValue_Type; |
159 gammas->fRedData.fValue = 1.2f; | 166 gammas->fRedData.fValue = 1.2f; |
160 | 167 |
161 gammas->fGreenType = SkGammas::Type::kTable_Type; | 168 gammas->fGreenType = SkGammas::Type::kTable_Type; |
162 gammas->fGreenData.fTable.fSize = tableSize; | 169 gammas->fGreenData.fTable.fSize = tableSize; |
163 gammas->fGreenData.fTable.fOffset = 0; | 170 gammas->fGreenData.fTable.fOffset = 0; |
164 | 171 |
165 gammas->fBlueType = SkGammas::Type::kParam_Type; | 172 gammas->fBlueType = SkGammas::Type::kParam_Type; |
166 gammas->fBlueData.fParamOffset = sizeof(float) * tableSize; | 173 gammas->fBlueData.fParamOffset = sizeof(float) * tableSize; |
167 | 174 |
168 test_identity_xform(r, gammas); | 175 test_identity_xform(r, gammas, true); |
169 } | 176 } |
170 | 177 |
171 DEF_TEST(ColorSpaceXform_applyCLUTMemoryAccess, r) { | 178 DEF_TEST(ColorSpaceXform_applyCLUTMemoryAccess, r) { |
172 // buffers larger than 1024 (or 256 in GOOGLE3) will force ColorSpaceXform_B
ase::apply() | 179 // buffers larger than 1024 (or 256 in GOOGLE3) will force ColorSpaceXform_B
ase::apply() |
173 // to heap-allocate a buffer that is used for CLUT application, and this tes
t is here to | 180 // to heap-allocate a buffer that is used for CLUT application, and this tes
t is here to |
174 // ensure that it no longer causes potential invalid memory accesses when th
is happens | 181 // ensure that it no longer causes potential invalid memory accesses when th
is happens |
175 const size_t len = 2048; | 182 const size_t len = 2048; |
176 SkAutoTMalloc<uint32_t> src(len); | 183 SkAutoTMalloc<uint32_t> src(len); |
177 SkAutoTMalloc<uint32_t> dst(len); | 184 SkAutoTMalloc<uint32_t> dst(len); |
178 for (uint32_t i = 0; i < len; ++i) { | 185 for (uint32_t i = 0; i < len; ++i) { |
179 src[i] = i; | 186 src[i] = i; |
180 } | 187 } |
181 // this ICC profile has a CLUT in it | 188 // this ICC profile has a CLUT in it |
182 const SkString filename(GetResourcePath("icc_profiles/upperRight.icc")); | 189 const SkString filename(GetResourcePath("icc_profiles/upperRight.icc")); |
183 sk_sp<SkData> iccData = SkData::MakeFromFileName(filename.c_str()); | 190 sk_sp<SkData> iccData = SkData::MakeFromFileName(filename.c_str()); |
184 REPORTER_ASSERT_MESSAGE(r, iccData, "upperRight.icc profile required for tes
t"); | 191 REPORTER_ASSERT_MESSAGE(r, iccData, "upperRight.icc profile required for tes
t"); |
185 sk_sp<SkColorSpace> srcSpace = SkColorSpace::NewICC(iccData->bytes(), iccDat
a->size()); | 192 sk_sp<SkColorSpace> srcSpace = SkColorSpace::NewICC(iccData->bytes(), iccDat
a->size()); |
186 sk_sp<SkColorSpace> dstSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Na
med); | 193 sk_sp<SkColorSpace> dstSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Na
med); |
187 auto xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get()); | 194 auto xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get()); |
188 bool result = xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, dst.ge
t(), | 195 bool result = xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, dst.ge
t(), |
189 SkColorSpaceXform::kRGBA_8888_ColorFormat, src.ge
t(), len, | 196 SkColorSpaceXform::kRGBA_8888_ColorFormat, src.ge
t(), len, |
190 kUnpremul_SkAlphaType); | 197 kUnpremul_SkAlphaType); |
191 REPORTER_ASSERT(r, result); | 198 REPORTER_ASSERT(r, result); |
192 } | 199 } |
OLD | NEW |