| Index: src/core/SkColorSpace.cpp
|
| diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
|
| index be27a49c0ff8fff9bac63e8fa2bd40df5be69a87..381aa21de9df48894eee6e41f4a93267d913e150 100644
|
| --- a/src/core/SkColorSpace.cpp
|
| +++ b/src/core/SkColorSpace.cpp
|
| @@ -88,36 +88,32 @@ void SkFloat3x3::dump() const {
|
|
|
| static int32_t gUniqueColorSpaceID;
|
|
|
| -SkColorSpace::SkColorSpace(const SkFloat3& gamma, const SkFloat3x3& toXYZD50, Named named)
|
| - : fGamma(gamma)
|
| +SkColorSpace::SkColorSpace(SkGammas gammas, const SkFloat3x3& toXYZD50, Named named)
|
| + : fGammas(std::move(gammas))
|
| , fToXYZD50(toXYZD50)
|
| , fToXYZOffset({ 0.0f, 0.0f, 0.0f })
|
| , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
|
| , fNamed(named)
|
| {
|
| for (int i = 0; i < 3; ++i) {
|
| - SkASSERT(SkFloatIsFinite(gamma.fVec[i]));
|
| for (int j = 0; j < 3; ++j) {
|
| SkASSERT(SkFloatIsFinite(toXYZD50.fMat[3*i + j]));
|
| }
|
| }
|
| }
|
|
|
| -SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, const SkFloat3& gamma, const SkFloat3x3& toXYZD50,
|
| +SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas, const SkFloat3x3& toXYZD50,
|
| const SkFloat3& toXYZOffset)
|
| : fColorLUT(std::move(colorLUT))
|
| - , fGamma(gamma)
|
| + , fGammas(gammas)
|
| , fToXYZD50(toXYZD50)
|
| , fToXYZOffset(toXYZOffset)
|
| , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
|
| , fNamed(kUnknown_Named)
|
| {}
|
|
|
| -sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, const SkFloat3& gamma) {
|
| +sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, SkGammas gammas) {
|
| for (int i = 0; i < 3; ++i) {
|
| - if (!SkFloatIsFinite(gamma.fVec[i]) || gamma.fVec[i] < 0) {
|
| - return nullptr;
|
| - }
|
| for (int j = 0; j < 3; ++j) {
|
| if (!SkFloatIsFinite(toXYZD50.fMat[3*i + j])) {
|
| return nullptr;
|
| @@ -131,24 +127,21 @@ sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, const SkFlo
|
| return nullptr;
|
| }
|
|
|
| - return sk_sp<SkColorSpace>(new SkColorSpace(gamma, toXYZD50, kUnknown_Named));
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUnknown_Named));
|
| }
|
|
|
| void SkColorSpace::dump() const {
|
| fToXYZD50.dump();
|
| - fGamma.dump();
|
| }
|
|
|
| //////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
| -const SkFloat3 gDevice_gamma {{ 0, 0, 0 }};
|
| const SkFloat3x3 gDevice_toXYZD50 {{
|
| 1, 0, 0,
|
| 0, 1, 0,
|
| 0, 0, 1
|
| }};
|
|
|
| -const SkFloat3 gSRGB_gamma {{ 2.2f, 2.2f, 2.2f }};
|
| const SkFloat3x3 gSRGB_toXYZD50 {{
|
| 0.4358f, 0.2224f, 0.0139f, // * R
|
| 0.3853f, 0.7170f, 0.0971f, // * G
|
| @@ -158,10 +151,11 @@ const SkFloat3x3 gSRGB_toXYZD50 {{
|
| sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
| switch (named) {
|
| case kDevice_Named:
|
| - return sk_sp<SkColorSpace>(new SkColorSpace(gDevice_gamma, gDevice_toXYZD50,
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(std::move(SkGammas()), gDevice_toXYZD50,
|
| kDevice_Named));
|
| case kSRGB_Named:
|
| - return sk_sp<SkColorSpace>(new SkColorSpace(gSRGB_gamma, gSRGB_toXYZD50, kSRGB_Named));
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(std::move(SkGammas::sRGB()), gSRGB_toXYZD50,
|
| + kSRGB_Named));
|
| default:
|
| break;
|
| }
|
| @@ -372,7 +366,7 @@ static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a');
|
|
|
| // FIXME (msarett):
|
| // We need to handle the possibility that the gamma curve does not correspond to 2.2f.
|
| -static bool load_gammas(float* gammas, uint32_t numGammas, const uint8_t* src, size_t len) {
|
| +static bool load_gammas(SkGamma* gammas, uint32_t numGammas, const uint8_t* src, size_t len) {
|
| for (uint32_t i = 0; i < numGammas; i++) {
|
| if (len < 12) {
|
| // FIXME (msarett):
|
| @@ -395,7 +389,8 @@ static bool load_gammas(float* gammas, uint32_t numGammas, const uint8_t* src, s
|
| // Some tags require a gamma curve, but the author doesn't actually want
|
| // to transform the data. In this case, it is common to see a curve with
|
| // a count of 0.
|
| - gammas[i] = 1.0f;
|
| + gammas[i].fFlag = SkGamma::kGammaUseValueFlag;
|
| + gammas[i].fValue = 1.0f;
|
| break;
|
| } else if (len < 12 + 2 * count) {
|
| SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
|
| @@ -406,24 +401,29 @@ static bool load_gammas(float* gammas, uint32_t numGammas, const uint8_t* src, s
|
| if (1 == count) {
|
| // Table entry is the exponent (bias 256).
|
| uint16_t value = read_big_endian_short((const uint8_t*) table);
|
| - gammas[i] = value / 256.0f;
|
| + gammas[i].fFlag = SkGamma::kGammaUseValueFlag;
|
| + gammas[i].fValue = value / 256.0f;
|
| SkColorSpacePrintf("gamma %d %g\n", value, *gamma);
|
| break;
|
| }
|
|
|
| - // Print the interpolation table. For now, we ignore this and guess 2.2f.
|
| - for (uint32_t i = 0; i < count; i++) {
|
| - SkColorSpacePrintf("curve[%d] %d\n", i,
|
| - read_big_endian_short((const uint8_t*) &table[i]));
|
| + // Fill in the interpolation table.
|
| + // FIXME (msarett):
|
| + // We should recognize commonly occurring tables and just set gamma to 2.2f.
|
| + gammas[i].fFlag = SkGamma::kGammaUseTableFlag;
|
| + gammas[i].fTableSize = count;
|
| + gammas[i].fTable = std::unique_ptr(new float[count]);
|
| + for (uint32_t j = 0; j < count; j++) {
|
| + gammas[i].fTable[j] =
|
| + (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f;
|
| }
|
| -
|
| - gammas[i] = 2.2f;
|
| break;
|
| }
|
| case kTAG_ParaCurveType:
|
| // Guess 2.2f.
|
| SkColorSpacePrintf("parametric curve\n");
|
| - gammas[i] = 2.2f;
|
| + gammas[i].fFlag = SkGamma::kGammaUseValueFlag;
|
| + gammas[i].fValue = 2.2f;
|
|
|
| switch(read_big_endian_short(src + 8)) {
|
| case 0:
|
|
|