/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkICC_DEFINED #define SkICC_DEFINED #include "SkData.h" #include "SkRefCnt.h" struct SkColorSpaceTransferFn; class SkColorSpace; class SkData; class SkMatrix44; class SK_API SkICC : public SkRefCnt { public: /** * Parse an ICC profile. * * Returns nullptr if the data is not a valid ICC profile or if the profile * input space is not RGB. */ static sk_sp<SkICC> Make(const void*, size_t); /** * If the gamut can be represented as transformation into XYZ D50, returns * true and sets the proper values in |toXYZD50|. * * If not, returns false. This indicates that the ICC data is too complex * to isolate a simple gamut transformation. */ bool toXYZD50(SkMatrix44* toXYZD50) const; /** * If the transfer function can be represented as coefficients to the standard * equation, returns true and sets |fn| to the proper values. * * If not, returns false. This indicates one of the following: * (1) The R, G, and B transfer functions are not the same. * (2) The transfer function is represented as a table that we have not managed * to match to a standard curve. * (3) The ICC data is too complex to isolate a single transfer function. */ bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const; /** * Please do not call this unless isNumericalTransferFn() has been called and it * fails. SkColorSpaceTransferFn is the preferred representation. * * If it is not possible to represent the R, G, and B transfer functions numerically * and it is still necessary to get the transfer function, this will return the * transfer functions as three tables (R, G, and B). * * If possible, this will return tables of the same length as they were specified in * the ICC profile. This means that the lengths of the three tables are not * guaranteed to be the same. If the ICC representation was not a table, the length * will be chosen arbitrarily. * * The lengths of the tables are all guaranteed to be at least 2. Entries in the * tables are guaranteed to be in [0, 1]. * * This API may be deleted in favor of a numerical approximation of the raw data. * * This function may fail, indicating that the ICC profile does not have transfer * functions. */ struct Channel { // Byte offset of the start of the table in |fStorage| size_t fOffset; int fCount; }; struct Tables { Channel fRed; Channel fGreen; Channel fBlue; const float* red() { return (const float*) (fStorage->bytes() + fRed.fOffset); } const float* green() { return (const float*) (fStorage->bytes() + fGreen.fOffset); } const float* blue() { return (const float*) (fStorage->bytes() + fBlue.fOffset); } sk_sp<SkData> fStorage; }; bool rawTransferFnData(Tables* tables) const; /** * Write an ICC profile with transfer function |fn| and gamut |toXYZD50|. */ static sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50); private: SkICC(sk_sp<SkColorSpace> colorSpace); sk_sp<SkColorSpace> fColorSpace; friend class ICCTest; }; #endif