Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2016 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkICC_DEFINED
      9 #define SkICC_DEFINED
     10 
     11 #include "SkData.h"
     12 #include "SkRefCnt.h"
     13 
     14 struct SkColorSpaceTransferFn;
     15 class SkColorSpace;
     16 class SkData;
     17 class SkMatrix44;
     18 
     19 class SK_API SkICC : public SkRefCnt {
     20 public:
     21 
     22     /**
     23      *  Parse an ICC profile.
     24      *
     25      *  Returns nullptr if the data is not a valid ICC profile or if the profile
     26      *  input space is not RGB.
     27      */
     28     static sk_sp<SkICC> Make(const void*, size_t);
     29 
     30     /**
     31      *  If the gamut can be represented as transformation into XYZ D50, returns
     32      *  true and sets the proper values in |toXYZD50|.
     33      *
     34      *  If not, returns false.  This indicates that the ICC data is too complex
     35      *  to isolate a simple gamut transformation.
     36      */
     37     bool toXYZD50(SkMatrix44* toXYZD50) const;
     38 
     39     /**
     40      *  If the transfer function can be represented as coefficients to the standard
     41      *  equation, returns true and sets |fn| to the proper values.
     42      *
     43      *  If not, returns false.  This indicates one of the following:
     44      *  (1) The R, G, and B transfer functions are not the same.
     45      *  (2) The transfer function is represented as a table that we have not managed
     46      *      to match to a standard curve.
     47      *  (3) The ICC data is too complex to isolate a single transfer function.
     48      */
     49     bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const;
     50 
     51     /**
     52      *  Please do not call this unless isNumericalTransferFn() has been called and it
     53      *  fails.  SkColorSpaceTransferFn is the preferred representation.
     54      *
     55      *  If it is not possible to represent the R, G, and B transfer functions numerically
     56      *  and it is still necessary to get the transfer function, this will return the
     57      *  transfer functions as three tables (R, G, and B).
     58      *
     59      *  If possible, this will return tables of the same length as they were specified in
     60      *  the ICC profile.  This means that the lengths of the three tables are not
     61      *  guaranteed to be the same.  If the ICC representation was not a table, the length
     62      *  will be chosen arbitrarily.
     63      *
     64      *  The lengths of the tables are all guaranteed to be at least 2.  Entries in the
     65      *  tables are guaranteed to be in [0, 1].
     66      *
     67      *  This API may be deleted in favor of a numerical approximation of the raw data.
     68      *
     69      *  This function may fail, indicating that the ICC profile does not have transfer
     70      *  functions.
     71      */
     72     struct Channel {
     73         // Byte offset of the start of the table in |fStorage|
     74         size_t fOffset;
     75         int    fCount;
     76     };
     77     struct Tables {
     78         Channel fRed;
     79         Channel fGreen;
     80         Channel fBlue;
     81 
     82         const float* red() {
     83             return (const float*) (fStorage->bytes() + fRed.fOffset);
     84         }
     85         const float* green() {
     86             return (const float*) (fStorage->bytes() + fGreen.fOffset);
     87         }
     88         const float* blue() {
     89             return (const float*) (fStorage->bytes() + fBlue.fOffset);
     90         }
     91 
     92         sk_sp<SkData> fStorage;
     93     };
     94     bool rawTransferFnData(Tables* tables) const;
     95 
     96     /**
     97      *  Write an ICC profile with transfer function |fn| and gamut |toXYZD50|.
     98      */
     99     static sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50);
    100 
    101 private:
    102     SkICC(sk_sp<SkColorSpace> colorSpace);
    103 
    104     sk_sp<SkColorSpace> fColorSpace;
    105 
    106     friend class ICCTest;
    107 };
    108 
    109 #endif
    110