SkColorSpace_A2B.h revision 62458a6778bc39eea5360301a67d192b3a263df1
19488833428e83c93a7e6002f4d056084fb57112fraftias/*
29488833428e83c93a7e6002f4d056084fb57112fraftias * Copyright 2016 Google Inc.
39488833428e83c93a7e6002f4d056084fb57112fraftias *
49488833428e83c93a7e6002f4d056084fb57112fraftias * Use of this source code is governed by a BSD-style license that can be
59488833428e83c93a7e6002f4d056084fb57112fraftias * found in the LICENSE file.
69488833428e83c93a7e6002f4d056084fb57112fraftias */
79488833428e83c93a7e6002f4d056084fb57112fraftias
89488833428e83c93a7e6002f4d056084fb57112fraftias#ifndef SkColorSpace_A2B_DEFINED
99488833428e83c93a7e6002f4d056084fb57112fraftias#define SkColorSpace_A2B_DEFINED
109488833428e83c93a7e6002f4d056084fb57112fraftias
119488833428e83c93a7e6002f4d056084fb57112fraftias#include "SkColorSpace_Base.h"
129488833428e83c93a7e6002f4d056084fb57112fraftias
13026f223d8641beeae19ed0bdbeca738be62256f5raftias#include <vector>
14026f223d8641beeae19ed0bdbeca738be62256f5raftias
159488833428e83c93a7e6002f4d056084fb57112fraftias// An alternative SkColorSpace that represents all the color space data that
169488833428e83c93a7e6002f4d056084fb57112fraftias// is stored in an A2B0 ICC tag. This allows us to use alternative profile
179488833428e83c93a7e6002f4d056084fb57112fraftias// connection spaces (CIELAB instead of just CIEXYZ), use color-lookup-tables
189488833428e83c93a7e6002f4d056084fb57112fraftias// to do color space transformations not representable as TRC functions or
1962458a6778bc39eea5360301a67d192b3a263df1Mike Klein// matrix operations, as well as have multiple TRC functions. The CLUT also has
2062458a6778bc39eea5360301a67d192b3a263df1Mike Klein// the potential to allow conversion from input color spaces with a different
2162458a6778bc39eea5360301a67d192b3a263df1Mike Klein// number of channels such as CMYK (4) or GRAY (1), but that is not supported yet.
229488833428e83c93a7e6002f4d056084fb57112fraftias//
2362458a6778bc39eea5360301a67d192b3a263df1Mike Klein// Currently AtoBType A2B0 tag types are supported. There are also lut8Type,
2462458a6778bc39eea5360301a67d192b3a263df1Mike Klein// lut16Type and MPET (multi-processing-elements) A2B0 tags which allow you to
2562458a6778bc39eea5360301a67d192b3a263df1Mike Klein// combine these 3 primitives (TRC, CLUT, matrix) in any order/quantitiy,
2662458a6778bc39eea5360301a67d192b3a263df1Mike Klein// but support for that is not implemented.
279488833428e83c93a7e6002f4d056084fb57112fraftiasclass SkColorSpace_A2B : public SkColorSpace_Base {
289488833428e83c93a7e6002f4d056084fb57112fraftiaspublic:
299488833428e83c93a7e6002f4d056084fb57112fraftias    const SkMatrix44* toXYZD50() const override {
309488833428e83c93a7e6002f4d056084fb57112fraftias        // the matrix specified in A2B0 profiles is not necessarily
319488833428e83c93a7e6002f4d056084fb57112fraftias        // a to-XYZ matrix, as to-Lab is supported as well so returning
329488833428e83c93a7e6002f4d056084fb57112fraftias        // that could be misleading. Additionally, B-curves are applied
339488833428e83c93a7e6002f4d056084fb57112fraftias        // after the matrix is, but a toXYZD50 matrix is the last thing
349488833428e83c93a7e6002f4d056084fb57112fraftias        // applied in order to get into the (XYZ) profile connection space.
359488833428e83c93a7e6002f4d056084fb57112fraftias        return nullptr;
369488833428e83c93a7e6002f4d056084fb57112fraftias    }
379488833428e83c93a7e6002f4d056084fb57112fraftias
38bbf251bf225489a0939fff6df938035a290f4d16Brian Osman    uint32_t toXYZD50Hash() const override {
39bbf251bf225489a0939fff6df938035a290f4d16Brian Osman        // See toXYZD50()'s comment.
40bbf251bf225489a0939fff6df938035a290f4d16Brian Osman        return 0;
41bbf251bf225489a0939fff6df938035a290f4d16Brian Osman    }
42bbf251bf225489a0939fff6df938035a290f4d16Brian Osman
439488833428e83c93a7e6002f4d056084fb57112fraftias    const SkMatrix44* fromXYZD50() const override {
449488833428e83c93a7e6002f4d056084fb57112fraftias        // See toXYZD50()'s comment. Also, A2B0 profiles are not supported
459488833428e83c93a7e6002f4d056084fb57112fraftias        // as destination color spaces, so an inverse matrix is never wanted.
469488833428e83c93a7e6002f4d056084fb57112fraftias        return nullptr;
479488833428e83c93a7e6002f4d056084fb57112fraftias    }
4862458a6778bc39eea5360301a67d192b3a263df1Mike Klein
499488833428e83c93a7e6002f4d056084fb57112fraftias    bool onGammaCloseToSRGB() const override {
509488833428e83c93a7e6002f4d056084fb57112fraftias        // There is no single gamma curve in an A2B0 profile
519488833428e83c93a7e6002f4d056084fb57112fraftias        return false;
529488833428e83c93a7e6002f4d056084fb57112fraftias    }
5362458a6778bc39eea5360301a67d192b3a263df1Mike Klein
549488833428e83c93a7e6002f4d056084fb57112fraftias    bool onGammaIsLinear() const override {
559488833428e83c93a7e6002f4d056084fb57112fraftias        // There is no single gamma curve in an A2B0 profile
569488833428e83c93a7e6002f4d056084fb57112fraftias        return false;
579488833428e83c93a7e6002f4d056084fb57112fraftias    }
589488833428e83c93a7e6002f4d056084fb57112fraftias
5912313f072b3563d652a789e28140f70b48e57e03Brian Osman    sk_sp<SkColorSpace> makeLinearGamma() override {
6012313f072b3563d652a789e28140f70b48e57e03Brian Osman        // TODO: Analyze the extrema of our projection into XYZ and use suitable primaries?
6112313f072b3563d652a789e28140f70b48e57e03Brian Osman        // For now, just fall back to a default, because we don't have a good answer.
6212313f072b3563d652a789e28140f70b48e57e03Brian Osman        return SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named);
6312313f072b3563d652a789e28140f70b48e57e03Brian Osman    }
6412313f072b3563d652a789e28140f70b48e57e03Brian Osman
6512313f072b3563d652a789e28140f70b48e57e03Brian Osman    sk_sp<SkColorSpace> makeSRGBGamma() override {
6612313f072b3563d652a789e28140f70b48e57e03Brian Osman        // See comment in makeLinearGamma
6712313f072b3563d652a789e28140f70b48e57e03Brian Osman        return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
6812313f072b3563d652a789e28140f70b48e57e03Brian Osman    }
6912313f072b3563d652a789e28140f70b48e57e03Brian Osman
70026f223d8641beeae19ed0bdbeca738be62256f5raftias    Type type() const override { return Type::kA2B; }
719488833428e83c93a7e6002f4d056084fb57112fraftias
72026f223d8641beeae19ed0bdbeca738be62256f5raftias    class Element {
73026f223d8641beeae19ed0bdbeca738be62256f5raftias    public:
7462458a6778bc39eea5360301a67d192b3a263df1Mike Klein        explicit Element(SkGammaNamed gammaNamed)
75026f223d8641beeae19ed0bdbeca738be62256f5raftias            : fType(Type::kGammaNamed)
76026f223d8641beeae19ed0bdbeca738be62256f5raftias            , fGammaNamed(gammaNamed)
77026f223d8641beeae19ed0bdbeca738be62256f5raftias            , fMatrix(SkMatrix44::kUninitialized_Constructor)
78026f223d8641beeae19ed0bdbeca738be62256f5raftias        {}
79026f223d8641beeae19ed0bdbeca738be62256f5raftias
80026f223d8641beeae19ed0bdbeca738be62256f5raftias        explicit Element(sk_sp<SkGammas> gammas)
81026f223d8641beeae19ed0bdbeca738be62256f5raftias            : fType(Type::kGammas)
82026f223d8641beeae19ed0bdbeca738be62256f5raftias            , fGammas(std::move(gammas))
8362458a6778bc39eea5360301a67d192b3a263df1Mike Klein            , fMatrix(SkMatrix44::kUninitialized_Constructor)
84026f223d8641beeae19ed0bdbeca738be62256f5raftias        {}
85026f223d8641beeae19ed0bdbeca738be62256f5raftias
86026f223d8641beeae19ed0bdbeca738be62256f5raftias        explicit Element(sk_sp<SkColorLookUpTable> colorLUT)
87026f223d8641beeae19ed0bdbeca738be62256f5raftias            : fType(Type::kCLUT)
88026f223d8641beeae19ed0bdbeca738be62256f5raftias            , fCLUT(std::move(colorLUT))
89026f223d8641beeae19ed0bdbeca738be62256f5raftias            , fMatrix(SkMatrix44::kUninitialized_Constructor)
90026f223d8641beeae19ed0bdbeca738be62256f5raftias        {}
91026f223d8641beeae19ed0bdbeca738be62256f5raftias
92026f223d8641beeae19ed0bdbeca738be62256f5raftias        explicit Element(const SkMatrix44& matrix)
93026f223d8641beeae19ed0bdbeca738be62256f5raftias            : fType(Type::kMatrix)
94026f223d8641beeae19ed0bdbeca738be62256f5raftias            , fMatrix(matrix)
95026f223d8641beeae19ed0bdbeca738be62256f5raftias        {}
9662458a6778bc39eea5360301a67d192b3a263df1Mike Klein
97026f223d8641beeae19ed0bdbeca738be62256f5raftias        enum class Type {
98026f223d8641beeae19ed0bdbeca738be62256f5raftias            kGammaNamed,
99026f223d8641beeae19ed0bdbeca738be62256f5raftias            kGammas,
100026f223d8641beeae19ed0bdbeca738be62256f5raftias            kCLUT,
101026f223d8641beeae19ed0bdbeca738be62256f5raftias            kMatrix
102026f223d8641beeae19ed0bdbeca738be62256f5raftias        };
103026f223d8641beeae19ed0bdbeca738be62256f5raftias
104026f223d8641beeae19ed0bdbeca738be62256f5raftias        Type type() const { return fType; }
105026f223d8641beeae19ed0bdbeca738be62256f5raftias
106026f223d8641beeae19ed0bdbeca738be62256f5raftias        SkGammaNamed gammaNamed() const {
107026f223d8641beeae19ed0bdbeca738be62256f5raftias            SkASSERT(Type::kGammaNamed == fType);
108026f223d8641beeae19ed0bdbeca738be62256f5raftias            return fGammaNamed;
109026f223d8641beeae19ed0bdbeca738be62256f5raftias        }
110026f223d8641beeae19ed0bdbeca738be62256f5raftias
111026f223d8641beeae19ed0bdbeca738be62256f5raftias        const SkGammas& gammas() const {
112026f223d8641beeae19ed0bdbeca738be62256f5raftias            SkASSERT(Type::kGammas == fType);
113026f223d8641beeae19ed0bdbeca738be62256f5raftias            return *fGammas;
114026f223d8641beeae19ed0bdbeca738be62256f5raftias        }
115026f223d8641beeae19ed0bdbeca738be62256f5raftias
116026f223d8641beeae19ed0bdbeca738be62256f5raftias        const SkColorLookUpTable& colorLUT() const {
117026f223d8641beeae19ed0bdbeca738be62256f5raftias            SkASSERT(Type::kCLUT == fType);
118026f223d8641beeae19ed0bdbeca738be62256f5raftias            return *fCLUT;
119026f223d8641beeae19ed0bdbeca738be62256f5raftias        }
120026f223d8641beeae19ed0bdbeca738be62256f5raftias
121026f223d8641beeae19ed0bdbeca738be62256f5raftias        const SkMatrix44& matrix() const {
122026f223d8641beeae19ed0bdbeca738be62256f5raftias            SkASSERT(Type::kMatrix == fType);
123026f223d8641beeae19ed0bdbeca738be62256f5raftias            return fMatrix;
124026f223d8641beeae19ed0bdbeca738be62256f5raftias        }
125026f223d8641beeae19ed0bdbeca738be62256f5raftias
126026f223d8641beeae19ed0bdbeca738be62256f5raftias    private:
127026f223d8641beeae19ed0bdbeca738be62256f5raftias        Type                      fType;
128026f223d8641beeae19ed0bdbeca738be62256f5raftias        SkGammaNamed              fGammaNamed;
129026f223d8641beeae19ed0bdbeca738be62256f5raftias        sk_sp<SkGammas>           fGammas;
130026f223d8641beeae19ed0bdbeca738be62256f5raftias        sk_sp<SkColorLookUpTable> fCLUT;
131026f223d8641beeae19ed0bdbeca738be62256f5raftias        SkMatrix44                fMatrix;
132026f223d8641beeae19ed0bdbeca738be62256f5raftias    };
13362458a6778bc39eea5360301a67d192b3a263df1Mike Klein    const Element& element(size_t i) const { return fElements[i]; }
13462458a6778bc39eea5360301a67d192b3a263df1Mike Klein
1352563601fc2b0505619f905f86bd249ae630197ccraftias    int count() const { return (int)fElements.size(); }
1369488833428e83c93a7e6002f4d056084fb57112fraftias
1379488833428e83c93a7e6002f4d056084fb57112fraftias    // the intermediate profile connection space that this color space
1389488833428e83c93a7e6002f4d056084fb57112fraftias    // represents the transformation to
1399488833428e83c93a7e6002f4d056084fb57112fraftias    enum class PCS : uint8_t {
1409488833428e83c93a7e6002f4d056084fb57112fraftias        kLAB, // CIELAB
1419488833428e83c93a7e6002f4d056084fb57112fraftias        kXYZ  // CIEXYZ
1429488833428e83c93a7e6002f4d056084fb57112fraftias    };
14362458a6778bc39eea5360301a67d192b3a263df1Mike Klein
1449488833428e83c93a7e6002f4d056084fb57112fraftias    PCS pcs() const { return fPCS; }
1459488833428e83c93a7e6002f4d056084fb57112fraftias
1469488833428e83c93a7e6002f4d056084fb57112fraftiasprivate:
14762458a6778bc39eea5360301a67d192b3a263df1Mike Klein    SkColorSpace_A2B(PCS pcs, sk_sp<SkData> profileData, std::vector<Element> elements);
148026f223d8641beeae19ed0bdbeca738be62256f5raftias
14951c3fcd376c5c9972d9476b5532f6164375a38d1raftias    PCS                  fPCS;
15062458a6778bc39eea5360301a67d192b3a263df1Mike Klein    std::vector<Element> fElements;
151026f223d8641beeae19ed0bdbeca738be62256f5raftias
15262458a6778bc39eea5360301a67d192b3a263df1Mike Klein    friend class SkColorSpace;
1532563601fc2b0505619f905f86bd249ae630197ccraftias    friend class ColorSpaceXformTest;
1549488833428e83c93a7e6002f4d056084fb57112fraftias    typedef SkColorSpace_Base INHERITED;
1559488833428e83c93a7e6002f4d056084fb57112fraftias};
1569488833428e83c93a7e6002f4d056084fb57112fraftias
1579488833428e83c93a7e6002f4d056084fb57112fraftias#endif
158