| /* |
| * 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 |