Line data Source code
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 0 : 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
|