SkColorSpace_A2B.h revision e9edf8cc50e50998f7074023f974ec034cfcec4c
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 195476128f0a88217414f05e6a7ee518cdb411d026raftias// matrix operations, as well as have multiple TRC functions. The CLUT also 205476128f0a88217414f05e6a7ee518cdb411d026raftias// allows conversion between non-3-channel input color spaces ie CMYK(4) to 215476128f0a88217414f05e6a7ee518cdb411d026raftias// a workable PCS (ie XYZ). 229488833428e83c93a7e6002f4d056084fb57112fraftias// 235476128f0a88217414f05e6a7ee518cdb411d026raftias// AtoBType, lut8Type and lut16Type A2B0 tag types are supported. There are 245476128f0a88217414f05e6a7ee518cdb411d026raftias// also MPET (multi-processing-elements) A2B0 tags in the standard which allow 255476128f0a88217414f05e6a7ee518cdb411d026raftias// you to combine these 3 primitives (TRC, CLUT, matrix) in any order/quantity. 265476128f0a88217414f05e6a7ee518cdb411d026raftias// MPET tags are currently unsupported by the MakeICC parser, could be supported 275476128f0a88217414f05e6a7ee518cdb411d026raftias// here by the nature of the design. 289488833428e83c93a7e6002f4d056084fb57112fraftiasclass SkColorSpace_A2B : public SkColorSpace_Base { 299488833428e83c93a7e6002f4d056084fb57112fraftiaspublic: 3036703d9d368050a20764b5336534bd718fd00a6eBrian Osman const SkMatrix44* onToXYZD50() const override { 319488833428e83c93a7e6002f4d056084fb57112fraftias // the matrix specified in A2B0 profiles is not necessarily 329488833428e83c93a7e6002f4d056084fb57112fraftias // a to-XYZ matrix, as to-Lab is supported as well so returning 339488833428e83c93a7e6002f4d056084fb57112fraftias // that could be misleading. Additionally, B-curves are applied 349488833428e83c93a7e6002f4d056084fb57112fraftias // after the matrix is, but a toXYZD50 matrix is the last thing 359488833428e83c93a7e6002f4d056084fb57112fraftias // applied in order to get into the (XYZ) profile connection space. 369488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 379488833428e83c93a7e6002f4d056084fb57112fraftias } 389488833428e83c93a7e6002f4d056084fb57112fraftias 3936703d9d368050a20764b5336534bd718fd00a6eBrian Osman uint32_t onToXYZD50Hash() const override { 4036703d9d368050a20764b5336534bd718fd00a6eBrian Osman // See onToXYZD50()'s comment. 41bbf251bf225489a0939fff6df938035a290f4d16Brian Osman return 0; 42bbf251bf225489a0939fff6df938035a290f4d16Brian Osman } 43bbf251bf225489a0939fff6df938035a290f4d16Brian Osman 4436703d9d368050a20764b5336534bd718fd00a6eBrian Osman const SkMatrix44* onFromXYZD50() const override { 4536703d9d368050a20764b5336534bd718fd00a6eBrian Osman // See onToXYZD50()'s comment. Also, A2B0 profiles are not supported 469488833428e83c93a7e6002f4d056084fb57112fraftias // as destination color spaces, so an inverse matrix is never wanted. 479488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 489488833428e83c93a7e6002f4d056084fb57112fraftias } 495476128f0a88217414f05e6a7ee518cdb411d026raftias 50113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry // There is no single gamma curve in an A2B0 profile 5136703d9d368050a20764b5336534bd718fd00a6eBrian Osman SkGammaNamed onGammaNamed() const override { return kNonStandard_SkGammaNamed; } 52113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry bool onGammaCloseToSRGB() const override { return false; } 53113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry bool onGammaIsLinear() const override { return false; } 54113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override { return false; } 559488833428e83c93a7e6002f4d056084fb57112fraftias 56f78b55cb94f4ac89b76a26d5a56d6380aa8fea6bLeon Scroggins III bool onIsCMYK() const override { return SkColorSpace::kCMYK_Type == fICCType; } 577f15b682f4e3e0f61a56d3bbdb8163d3a54b997cMatt Sarett 58e9edf8cc50e50998f7074023f974ec034cfcec4cBrian Osman const SkData* onProfileData() const override { return fProfileData.get(); } 59e9edf8cc50e50998f7074023f974ec034cfcec4cBrian Osman 60b1e6cfdb28b7a3db9ab64f90a709df725c1a9c43Mike Klein sk_sp<SkColorSpace> makeLinearGamma() const override { 6112313f072b3563d652a789e28140f70b48e57e03Brian Osman // TODO: Analyze the extrema of our projection into XYZ and use suitable primaries? 6212313f072b3563d652a789e28140f70b48e57e03Brian Osman // For now, just fall back to a default, because we don't have a good answer. 6377a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett return SkColorSpace::MakeSRGBLinear(); 6412313f072b3563d652a789e28140f70b48e57e03Brian Osman } 6512313f072b3563d652a789e28140f70b48e57e03Brian Osman 66b1e6cfdb28b7a3db9ab64f90a709df725c1a9c43Mike Klein sk_sp<SkColorSpace> makeSRGBGamma() const override { 6712313f072b3563d652a789e28140f70b48e57e03Brian Osman // See comment in makeLinearGamma 6877a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett return SkColorSpace::MakeSRGB(); 6912313f072b3563d652a789e28140f70b48e57e03Brian Osman } 7012313f072b3563d652a789e28140f70b48e57e03Brian Osman 71026f223d8641beeae19ed0bdbeca738be62256f5raftias Type type() const override { return Type::kA2B; } 729488833428e83c93a7e6002f4d056084fb57112fraftias 73026f223d8641beeae19ed0bdbeca738be62256f5raftias class Element { 74026f223d8641beeae19ed0bdbeca738be62256f5raftias public: 755476128f0a88217414f05e6a7ee518cdb411d026raftias Element(SkGammaNamed gammaNamed, int channelCount) 76026f223d8641beeae19ed0bdbeca738be62256f5raftias : fType(Type::kGammaNamed) 77026f223d8641beeae19ed0bdbeca738be62256f5raftias , fGammaNamed(gammaNamed) 78026f223d8641beeae19ed0bdbeca738be62256f5raftias , fMatrix(SkMatrix44::kUninitialized_Constructor) 795476128f0a88217414f05e6a7ee518cdb411d026raftias , fInputChannels(channelCount) 80e8ea07a6127971aea8183303b9abfa9856b7a54craftias , fOutputChannels(channelCount) { 81e8ea07a6127971aea8183303b9abfa9856b7a54craftias SkASSERT(gammaNamed != kNonStandard_SkGammaNamed); 82e8ea07a6127971aea8183303b9abfa9856b7a54craftias } 83026f223d8641beeae19ed0bdbeca738be62256f5raftias 84026f223d8641beeae19ed0bdbeca738be62256f5raftias explicit Element(sk_sp<SkGammas> gammas) 85026f223d8641beeae19ed0bdbeca738be62256f5raftias : fType(Type::kGammas) 86026f223d8641beeae19ed0bdbeca738be62256f5raftias , fGammas(std::move(gammas)) 875476128f0a88217414f05e6a7ee518cdb411d026raftias , fMatrix(SkMatrix44::kUninitialized_Constructor) 885476128f0a88217414f05e6a7ee518cdb411d026raftias , fInputChannels(fGammas->channels()) 89197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias , fOutputChannels(fGammas->channels()) { 90197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias for (int i = 0; i < fGammas->channels(); ++i) { 91197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias if (SkGammas::Type::kTable_Type == fGammas->type(i)) { 92197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias SkASSERT(fGammas->data(i).fTable.fSize >= 2); 93197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias } 94197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias } 95197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias } 96026f223d8641beeae19ed0bdbeca738be62256f5raftias 97026f223d8641beeae19ed0bdbeca738be62256f5raftias explicit Element(sk_sp<SkColorLookUpTable> colorLUT) 98026f223d8641beeae19ed0bdbeca738be62256f5raftias : fType(Type::kCLUT) 99026f223d8641beeae19ed0bdbeca738be62256f5raftias , fCLUT(std::move(colorLUT)) 100026f223d8641beeae19ed0bdbeca738be62256f5raftias , fMatrix(SkMatrix44::kUninitialized_Constructor) 1015476128f0a88217414f05e6a7ee518cdb411d026raftias , fInputChannels(fCLUT->inputChannels()) 1025476128f0a88217414f05e6a7ee518cdb411d026raftias , fOutputChannels(fCLUT->outputChannels()) 103026f223d8641beeae19ed0bdbeca738be62256f5raftias {} 104026f223d8641beeae19ed0bdbeca738be62256f5raftias 105026f223d8641beeae19ed0bdbeca738be62256f5raftias explicit Element(const SkMatrix44& matrix) 106026f223d8641beeae19ed0bdbeca738be62256f5raftias : fType(Type::kMatrix) 107026f223d8641beeae19ed0bdbeca738be62256f5raftias , fMatrix(matrix) 1085476128f0a88217414f05e6a7ee518cdb411d026raftias , fInputChannels(3) 1095476128f0a88217414f05e6a7ee518cdb411d026raftias , fOutputChannels(3) 110026f223d8641beeae19ed0bdbeca738be62256f5raftias {} 1115476128f0a88217414f05e6a7ee518cdb411d026raftias 112026f223d8641beeae19ed0bdbeca738be62256f5raftias enum class Type { 113026f223d8641beeae19ed0bdbeca738be62256f5raftias kGammaNamed, 114026f223d8641beeae19ed0bdbeca738be62256f5raftias kGammas, 115026f223d8641beeae19ed0bdbeca738be62256f5raftias kCLUT, 116026f223d8641beeae19ed0bdbeca738be62256f5raftias kMatrix 117026f223d8641beeae19ed0bdbeca738be62256f5raftias }; 118026f223d8641beeae19ed0bdbeca738be62256f5raftias 119026f223d8641beeae19ed0bdbeca738be62256f5raftias Type type() const { return fType; } 120026f223d8641beeae19ed0bdbeca738be62256f5raftias 121026f223d8641beeae19ed0bdbeca738be62256f5raftias SkGammaNamed gammaNamed() const { 122026f223d8641beeae19ed0bdbeca738be62256f5raftias SkASSERT(Type::kGammaNamed == fType); 123026f223d8641beeae19ed0bdbeca738be62256f5raftias return fGammaNamed; 124026f223d8641beeae19ed0bdbeca738be62256f5raftias } 125026f223d8641beeae19ed0bdbeca738be62256f5raftias 126026f223d8641beeae19ed0bdbeca738be62256f5raftias const SkGammas& gammas() const { 127026f223d8641beeae19ed0bdbeca738be62256f5raftias SkASSERT(Type::kGammas == fType); 128026f223d8641beeae19ed0bdbeca738be62256f5raftias return *fGammas; 129026f223d8641beeae19ed0bdbeca738be62256f5raftias } 130026f223d8641beeae19ed0bdbeca738be62256f5raftias 131026f223d8641beeae19ed0bdbeca738be62256f5raftias const SkColorLookUpTable& colorLUT() const { 132026f223d8641beeae19ed0bdbeca738be62256f5raftias SkASSERT(Type::kCLUT == fType); 133026f223d8641beeae19ed0bdbeca738be62256f5raftias return *fCLUT; 134026f223d8641beeae19ed0bdbeca738be62256f5raftias } 135026f223d8641beeae19ed0bdbeca738be62256f5raftias 136026f223d8641beeae19ed0bdbeca738be62256f5raftias const SkMatrix44& matrix() const { 137026f223d8641beeae19ed0bdbeca738be62256f5raftias SkASSERT(Type::kMatrix == fType); 138026f223d8641beeae19ed0bdbeca738be62256f5raftias return fMatrix; 139026f223d8641beeae19ed0bdbeca738be62256f5raftias } 140026f223d8641beeae19ed0bdbeca738be62256f5raftias 1415476128f0a88217414f05e6a7ee518cdb411d026raftias int inputChannels() const { return fInputChannels; } 1425476128f0a88217414f05e6a7ee518cdb411d026raftias 1435476128f0a88217414f05e6a7ee518cdb411d026raftias int outputChannels() const { return fOutputChannels; } 1445476128f0a88217414f05e6a7ee518cdb411d026raftias 145026f223d8641beeae19ed0bdbeca738be62256f5raftias private: 146026f223d8641beeae19ed0bdbeca738be62256f5raftias Type fType; 147026f223d8641beeae19ed0bdbeca738be62256f5raftias SkGammaNamed fGammaNamed; 148026f223d8641beeae19ed0bdbeca738be62256f5raftias sk_sp<SkGammas> fGammas; 149026f223d8641beeae19ed0bdbeca738be62256f5raftias sk_sp<SkColorLookUpTable> fCLUT; 150026f223d8641beeae19ed0bdbeca738be62256f5raftias SkMatrix44 fMatrix; 1515476128f0a88217414f05e6a7ee518cdb411d026raftias int fInputChannels; 1525476128f0a88217414f05e6a7ee518cdb411d026raftias int fOutputChannels; 153026f223d8641beeae19ed0bdbeca738be62256f5raftias }; 1545476128f0a88217414f05e6a7ee518cdb411d026raftias const Element& element(int i) const { return fElements[i]; } 1555476128f0a88217414f05e6a7ee518cdb411d026raftias 1562563601fc2b0505619f905f86bd249ae630197ccraftias int count() const { return (int)fElements.size(); } 1579488833428e83c93a7e6002f4d056084fb57112fraftias 1589488833428e83c93a7e6002f4d056084fb57112fraftias // the intermediate profile connection space that this color space 1599488833428e83c93a7e6002f4d056084fb57112fraftias // represents the transformation to 1609488833428e83c93a7e6002f4d056084fb57112fraftias enum class PCS : uint8_t { 1619488833428e83c93a7e6002f4d056084fb57112fraftias kLAB, // CIELAB 1629488833428e83c93a7e6002f4d056084fb57112fraftias kXYZ // CIEXYZ 1639488833428e83c93a7e6002f4d056084fb57112fraftias }; 1645476128f0a88217414f05e6a7ee518cdb411d026raftias 1659488833428e83c93a7e6002f4d056084fb57112fraftias PCS pcs() const { return fPCS; } 1669488833428e83c93a7e6002f4d056084fb57112fraftias 167f78b55cb94f4ac89b76a26d5a56d6380aa8fea6bLeon Scroggins III SkColorSpace::Type iccType() const { return fICCType; } 1685476128f0a88217414f05e6a7ee518cdb411d026raftias 169f78b55cb94f4ac89b76a26d5a56d6380aa8fea6bLeon Scroggins III SkColorSpace_A2B(SkColorSpace::Type iccType, std::vector<Element> elements, PCS pcs, 1705476128f0a88217414f05e6a7ee518cdb411d026raftias sk_sp<SkData> profileData); 171026f223d8641beeae19ed0bdbeca738be62256f5raftias 172595599f46261225dfc67ab4d91d326e099558239Matt Sarettprivate: 173e9edf8cc50e50998f7074023f974ec034cfcec4cBrian Osman sk_sp<SkData> fProfileData; 174e9edf8cc50e50998f7074023f974ec034cfcec4cBrian Osman 175f78b55cb94f4ac89b76a26d5a56d6380aa8fea6bLeon Scroggins III SkColorSpace::Type fICCType; 17662458a6778bc39eea5360301a67d192b3a263df1Mike Klein std::vector<Element> fElements; 1775476128f0a88217414f05e6a7ee518cdb411d026raftias PCS fPCS; 178026f223d8641beeae19ed0bdbeca738be62256f5raftias 1795476128f0a88217414f05e6a7ee518cdb411d026raftias friend class SkColorSpace_Base; 1802563601fc2b0505619f905f86bd249ae630197ccraftias friend class ColorSpaceXformTest; 1819488833428e83c93a7e6002f4d056084fb57112fraftias typedef SkColorSpace_Base INHERITED; 1829488833428e83c93a7e6002f4d056084fb57112fraftias}; 1839488833428e83c93a7e6002f4d056084fb57112fraftias 1849488833428e83c93a7e6002f4d056084fb57112fraftias#endif 185