| 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 |