diff options
Diffstat (limited to 'src/core/SkColorSpace_Base.h')
-rw-r--r-- | src/core/SkColorSpace_Base.h | 210 |
1 files changed, 110 insertions, 100 deletions
diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h index d18b631072..6289b09f50 100644 --- a/src/core/SkColorSpace_Base.h +++ b/src/core/SkColorSpace_Base.h @@ -12,120 +12,130 @@ #include "SkData.h" #include "SkTemplates.h" -struct SkGammas : SkRefCnt { - - // There are four possible representations for gamma curves. kNone_Type is used - // as a placeholder until the struct is initialized. It is not a valid value. - enum class Type : uint8_t { - kNone_Type, - kNamed_Type, - kValue_Type, - kTable_Type, - kParam_Type, - }; - - // Contains information for a gamma table. - struct Table { - size_t fOffset; - int fSize; - - const float* table(const SkGammas* base) const { - return SkTAddOffset<const float>(base, sizeof(SkGammas) + fOffset); - } - }; - - // Contains the parameters for a parametric curve. - struct Params { - // Y = (aX + b)^g + c for X >= d - // Y = eX + f otherwise - float fG; - float fA; - float fB; - float fC; - float fD; - float fE; - float fF; - }; - - // Contains the actual gamma curve information. Should be interpreted - // based on the type of the gamma curve. - union Data { - Data() - : fTable{ 0, 0 } - {} - - inline bool operator==(const Data& that) const { - return this->fTable.fOffset == that.fTable.fOffset && - this->fTable.fSize == that.fTable.fSize; - } - - SkColorSpace::GammaNamed fNamed; - float fValue; - Table fTable; - size_t fParamOffset; - - const Params& params(const SkGammas* base) const { - return *SkTAddOffset<const Params>(base, sizeof(SkGammas) + fParamOffset); - } - }; - - bool isNamed(int i) const { - SkASSERT(0 <= i && i < 3); - return (&fRedType)[i] == Type::kNamed_Type; +struct SkGammaCurve { + bool isNamed() const { + bool result = (SkColorSpace::kNonStandard_GammaNamed != fNamed); + SkASSERT(!result || (0.0f == fValue)); + SkASSERT(!result || (0 == fTableSize)); + SkASSERT(!result || (0.0f == fG && 0.0f == fE)); + return result; } - bool isValue(int i) const { - SkASSERT(0 <= i && i < 3); - return (&fRedType)[i] == Type::kValue_Type; + bool isValue() const { + bool result = (0.0f != fValue); + SkASSERT(!result || SkColorSpace::kNonStandard_GammaNamed == fNamed); + SkASSERT(!result || (0 == fTableSize)); + SkASSERT(!result || (0.0f == fG && 0.0f == fE)); + return result; } - bool isTable(int i) const { - SkASSERT(0 <= i && i < 3); - return (&fRedType)[i] == Type::kTable_Type; + bool isTable() const { + bool result = (0 != fTableSize); + SkASSERT(!result || SkColorSpace::kNonStandard_GammaNamed == fNamed); + SkASSERT(!result || (0.0f == fValue)); + SkASSERT(!result || (0.0f == fG && 0.0f == fE)); + SkASSERT(!result || fTable); + return result; } - bool isParametric(int i) const { - SkASSERT(0 <= i && i < 3); - return (&fRedType)[i] == Type::kParam_Type; + bool isParametric() const { + bool result = (0.0f != fG || 0.0f != fE); + SkASSERT(!result || SkColorSpace::kNonStandard_GammaNamed == fNamed); + SkASSERT(!result || (0.0f == fValue)); + SkASSERT(!result || (0 == fTableSize)); + return result; } - const Data& data(int i) const { - SkASSERT(0 <= i && i < 3); - return (&fRedData)[i]; + // We have four different ways to represent gamma. + // (1) A known, named type: + SkColorSpace::GammaNamed fNamed; + + // (2) A single value: + float fValue; + + // (3) A lookup table: + uint32_t fTableSize; + std::unique_ptr<float[]> fTable; + + // (4) Parameters for a curve: + // Y = (aX + b)^g + c for X >= d + // Y = eX + f otherwise + float fG; + float fA; + float fB; + float fC; + float fD; + float fE; + float fF; + + SkGammaCurve() + : fNamed(SkColorSpace::kNonStandard_GammaNamed) + , fValue(0.0f) + , fTableSize(0) + , fTable(nullptr) + , fG(0.0f) + , fA(0.0f) + , fB(0.0f) + , fC(0.0f) + , fD(0.0f) + , fE(0.0f) + , fF(0.0f) + {} + + bool quickEquals(const SkGammaCurve& that) const { + return (this->fNamed == that.fNamed) && (this->fValue == that.fValue) && + (this->fTableSize == that.fTableSize) && (this->fTable == that.fTable) && + (this->fG == that.fG) && (this->fA == that.fA) && (this->fB == that.fB) && + (this->fC == that.fC) && (this->fD == that.fD) && (this->fE == that.fE) && + (this->fF == that.fF); } +}; - const float* table(int i) const { - SkASSERT(isTable(i)); - return (&fRedData)[i].fTable.table(this); +struct SkGammas : public SkRefCnt { +public: + static SkColorSpace::GammaNamed Named(SkGammaCurve curves[3]) { + if (SkColorSpace::kLinear_GammaNamed == curves[0].fNamed && + SkColorSpace::kLinear_GammaNamed == curves[1].fNamed && + SkColorSpace::kLinear_GammaNamed == curves[2].fNamed) + { + return SkColorSpace::kLinear_GammaNamed; + } + + if (SkColorSpace::kSRGB_GammaNamed == curves[0].fNamed && + SkColorSpace::kSRGB_GammaNamed == curves[1].fNamed && + SkColorSpace::kSRGB_GammaNamed == curves[2].fNamed) + { + return SkColorSpace::kSRGB_GammaNamed; + } + + if (SkColorSpace::k2Dot2Curve_GammaNamed == curves[0].fNamed && + SkColorSpace::k2Dot2Curve_GammaNamed == curves[1].fNamed && + SkColorSpace::k2Dot2Curve_GammaNamed == curves[2].fNamed) + { + return SkColorSpace::k2Dot2Curve_GammaNamed; + } + + return SkColorSpace::kNonStandard_GammaNamed; } - const Params& params(int i) const { - SkASSERT(isParametric(i)); - return (&fRedData)[i].params(this); + const SkGammaCurve& operator[](int i) const { + SkASSERT(0 <= i && i < 3); + return (&fRed)[i]; } - SkGammas() - : fRedType(Type::kNone_Type) - , fGreenType(Type::kNone_Type) - , fBlueType(Type::kNone_Type) + const SkGammaCurve fRed; + const SkGammaCurve fGreen; + const SkGammaCurve fBlue; + + SkGammas(SkGammaCurve red, SkGammaCurve green, SkGammaCurve blue) + : fRed(std::move(red)) + , fGreen(std::move(green)) + , fBlue(std::move(blue)) {} - // These fields should only be modified when initializing the struct. - Data fRedData; - Data fGreenData; - Data fBlueData; - Type fRedType; - Type fGreenType; - Type fBlueType; - - // Objects of this type are sometimes created in a custom fashion using - // sk_malloc_throw and therefore must be sk_freed. We overload new to - // also call sk_malloc_throw so that memory can be unconditionally released - // using sk_free in an overloaded delete. Overloading regular new means we - // must also overload placement new. - void* operator new(size_t size) { return sk_malloc_throw(size); } - void* operator new(size_t, void* p) { return p; } - void operator delete(void* p) { sk_free(p); } + SkGammas() {} + + friend class SkColorSpace; }; struct SkColorLookUpTable : public SkRefCnt { @@ -163,8 +173,8 @@ private: SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZ, Named named); - SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, GammaNamed gammaNamed, - sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ, sk_sp<SkData> profileData); + SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, sk_sp<SkGammas> gammas, + const SkMatrix44& toXYZ, sk_sp<SkData> profileData); sk_sp<SkColorLookUpTable> fColorLUT; sk_sp<SkGammas> fGammas; |