1113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry/* 2113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * Copyright 2016 Google Inc. 3113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * 4113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * Use of this source code is governed by a BSD-style license that can be 5113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * found in the LICENSE file. 6113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry */ 7113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 8113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry#ifndef SkICC_DEFINED 9113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry#define SkICC_DEFINED 10113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 116f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett#include "SkData.h" 12113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry#include "SkRefCnt.h" 13113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 14113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistrystruct SkColorSpaceTransferFn; 15113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistryclass SkColorSpace; 16113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistryclass SkData; 17113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistryclass SkMatrix44; 18113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 19113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistryclass SK_API SkICC : public SkRefCnt { 20113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistrypublic: 21113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 22113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry /** 23113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * Parse an ICC profile. 24113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * 25113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * Returns nullptr if the data is not a valid ICC profile or if the profile 26113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * input space is not RGB. 27113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry */ 28113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry static sk_sp<SkICC> Make(const void*, size_t); 29113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 30113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry /** 31113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * If the gamut can be represented as transformation into XYZ D50, returns 32113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * true and sets the proper values in |toXYZD50|. 33113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * 34113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * If not, returns false. This indicates that the ICC data is too complex 35113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * to isolate a simple gamut transformation. 36113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry */ 37113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry bool toXYZD50(SkMatrix44* toXYZD50) const; 38113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 39113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry /** 40113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * If the transfer function can be represented as coefficients to the standard 41113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * equation, returns true and sets |fn| to the proper values. 42113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * 43113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * If not, returns false. This indicates one of the following: 44113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * (1) The R, G, and B transfer functions are not the same. 45113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * (2) The transfer function is represented as a table that we have not managed 46113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * to match to a standard curve. 47113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * (3) The ICC data is too complex to isolate a single transfer function. 48113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry */ 49113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const; 50113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 51113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry /** 526f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * Please do not call this unless isNumericalTransferFn() has been called and it 536f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * fails. SkColorSpaceTransferFn is the preferred representation. 54113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * 556f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * If it is not possible to represent the R, G, and B transfer functions numerically 566f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * and it is still necessary to get the transfer function, this will return the 576f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * transfer functions as three tables (R, G, and B). 586f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * 596f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * If possible, this will return tables of the same length as they were specified in 606f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * the ICC profile. This means that the lengths of the three tables are not 616f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * guaranteed to be the same. If the ICC representation was not a table, the length 626f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * will be chosen arbitrarily. 636f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * 64541b1b08a82c8deec09b2bd258e1841660bd862aMatt Sarett * The lengths of the tables are all guaranteed to be at least 2. Entries in the 65541b1b08a82c8deec09b2bd258e1841660bd862aMatt Sarett * tables are guaranteed to be in [0, 1]. 666f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * 676f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * This API may be deleted in favor of a numerical approximation of the raw data. 686f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * 696f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * This function may fail, indicating that the ICC profile does not have transfer 706f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett * functions. 71113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry */ 726f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett struct Channel { 736f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett // Byte offset of the start of the table in |fStorage| 746f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett size_t fOffset; 756f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett int fCount; 766f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett }; 776f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett struct Tables { 786f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett Channel fRed; 796f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett Channel fGreen; 806f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett Channel fBlue; 816f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett 826f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett const float* red() { 836f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett return (const float*) (fStorage->bytes() + fRed.fOffset); 846f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett } 856f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett const float* green() { 866f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett return (const float*) (fStorage->bytes() + fGreen.fOffset); 876f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett } 886f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett const float* blue() { 896f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett return (const float*) (fStorage->bytes() + fBlue.fOffset); 906f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett } 916f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett 926f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett sk_sp<SkData> fStorage; 936f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett }; 946f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett bool rawTransferFnData(Tables* tables) const; 95113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 96113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry /** 97113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry * Write an ICC profile with transfer function |fn| and gamut |toXYZD50|. 98113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry */ 99113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry static sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50); 100113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 101113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistryprivate: 102113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry SkICC(sk_sp<SkColorSpace> colorSpace); 103113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 104113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry sk_sp<SkColorSpace> fColorSpace; 1056f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett 1066f67fc29eddfb6f415f7e6a86197db5d8c8539edMatt Sarett friend class ICCTest; 107113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry}; 108113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry 109113d05fa7b26797e3e468f78ea94a214476b63fbRavi Mistry#endif 110