| Index: src/core/SkColorSpace_Base.h
|
| diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h
|
| index d18b631072d928932f5dc381c19fdc70aadd76c0..6289b09f500ee393b15842558f5ff361fd0b8b84 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);
|
| +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() 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() 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() 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;
|
| + }
|
| +
|
| + // 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);
|
| + }
|
| +};
|
| +
|
| +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;
|
| }
|
| - };
|
| -
|
| - // 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;
|
| +
|
| + if (SkColorSpace::kSRGB_GammaNamed == curves[0].fNamed &&
|
| + SkColorSpace::kSRGB_GammaNamed == curves[1].fNamed &&
|
| + SkColorSpace::kSRGB_GammaNamed == curves[2].fNamed)
|
| + {
|
| + return SkColorSpace::kSRGB_GammaNamed;
|
| }
|
|
|
| - 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);
|
| + if (SkColorSpace::k2Dot2Curve_GammaNamed == curves[0].fNamed &&
|
| + SkColorSpace::k2Dot2Curve_GammaNamed == curves[1].fNamed &&
|
| + SkColorSpace::k2Dot2Curve_GammaNamed == curves[2].fNamed)
|
| + {
|
| + return SkColorSpace::k2Dot2Curve_GammaNamed;
|
| }
|
| - };
|
| -
|
| - bool isNamed(int i) const {
|
| +
|
| + return SkColorSpace::kNonStandard_GammaNamed;
|
| + }
|
| +
|
| + const SkGammaCurve& operator[](int i) const {
|
| SkASSERT(0 <= i && i < 3);
|
| - return (&fRedType)[i] == Type::kNamed_Type;
|
| - }
|
| -
|
| - bool isValue(int i) const {
|
| - SkASSERT(0 <= i && i < 3);
|
| - return (&fRedType)[i] == Type::kValue_Type;
|
| - }
|
| -
|
| - bool isTable(int i) const {
|
| - SkASSERT(0 <= i && i < 3);
|
| - return (&fRedType)[i] == Type::kTable_Type;
|
| - }
|
| -
|
| - bool isParametric(int i) const {
|
| - SkASSERT(0 <= i && i < 3);
|
| - return (&fRedType)[i] == Type::kParam_Type;
|
| - }
|
| -
|
| - const Data& data(int i) const {
|
| - SkASSERT(0 <= i && i < 3);
|
| - return (&fRedData)[i];
|
| - }
|
| -
|
| - const float* table(int i) const {
|
| - SkASSERT(isTable(i));
|
| - return (&fRedData)[i].fTable.table(this);
|
| - }
|
| -
|
| - const Params& params(int i) const {
|
| - SkASSERT(isParametric(i));
|
| - return (&fRedData)[i].params(this);
|
| - }
|
| -
|
| - SkGammas()
|
| - : fRedType(Type::kNone_Type)
|
| - , fGreenType(Type::kNone_Type)
|
| - , fBlueType(Type::kNone_Type)
|
| + return (&fRed)[i];
|
| + }
|
| +
|
| + 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 @@
|
|
|
| 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;
|
|
|