OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkColorSpace.h" | 8 #include "SkColorSpace.h" |
9 #include "SkColorSpace_Base.h" | 9 #include "SkColorSpace_Base.h" |
10 #include "SkColorSpacePriv.h" | 10 #include "SkColorSpacePriv.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 | 40 |
41 // This is equal to the header size according to the ICC specification (128) | 41 // This is equal to the header size according to the ICC specification (128) |
42 // plus the size of the tag count (4). We include the tag count since we | 42 // plus the size of the tag count (4). We include the tag count since we |
43 // always require it to be present anyway. | 43 // always require it to be present anyway. |
44 static constexpr size_t kICCHeaderSize = 132; | 44 static constexpr size_t kICCHeaderSize = 132; |
45 | 45 |
46 // Contains a signature (4), offset (4), and size (4). | 46 // Contains a signature (4), offset (4), and size (4). |
47 static constexpr size_t kICCTagTableEntrySize = 12; | 47 static constexpr size_t kICCTagTableEntrySize = 12; |
48 | 48 |
49 static constexpr uint32_t kRGB_ColorSpace = SkSetFourByteTag('R', 'G', 'B', ' '
); | 49 static constexpr uint32_t kRGB_ColorSpace = SkSetFourByteTag('R', 'G', 'B',
' '); |
50 static constexpr uint32_t kDisplay_Profile = SkSetFourByteTag('m', 'n', 't', 'r'
); | 50 static constexpr uint32_t kDisplay_Profile = SkSetFourByteTag('m', 'n', 't',
'r'); |
51 static constexpr uint32_t kInput_Profile = SkSetFourByteTag('s', 'c', 'n', 'r'
); | 51 static constexpr uint32_t kInput_Profile = SkSetFourByteTag('s', 'c', 'n',
'r'); |
52 static constexpr uint32_t kOutput_Profile = SkSetFourByteTag('p', 'r', 't', 'r'
); | 52 static constexpr uint32_t kOutput_Profile = SkSetFourByteTag('p', 'r', 't',
'r'); |
53 static constexpr uint32_t kXYZ_PCSSpace = SkSetFourByteTag('X', 'Y', 'Z', ' '
); | 53 static constexpr uint32_t kColorSpace_Profile = SkSetFourByteTag('s', 'p', 'a',
'c'); |
54 static constexpr uint32_t kACSP_Signature = SkSetFourByteTag('a', 'c', 's', 'p'
); | 54 static constexpr uint32_t kXYZ_PCSSpace = SkSetFourByteTag('X', 'Y', 'Z',
' '); |
| 55 static constexpr uint32_t kACSP_Signature = SkSetFourByteTag('a', 'c', 's',
'p'); |
55 | 56 |
56 struct ICCProfileHeader { | 57 struct ICCProfileHeader { |
57 uint32_t fSize; | 58 uint32_t fSize; |
58 | 59 |
59 // No reason to care about the preferred color management module (ex: Adobe,
Apple, etc.). | 60 // No reason to care about the preferred color management module (ex: Adobe,
Apple, etc.). |
60 // We're always going to use this one. | 61 // We're always going to use this one. |
61 uint32_t fCMMType_ignored; | 62 uint32_t fCMMType_ignored; |
62 | 63 |
63 uint32_t fVersion; | 64 uint32_t fVersion; |
64 uint32_t fProfileClass; | 65 uint32_t fProfileClass; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 dst[i] = read_big_endian_uint(src); | 108 dst[i] = read_big_endian_uint(src); |
108 } | 109 } |
109 } | 110 } |
110 | 111 |
111 bool valid() const { | 112 bool valid() const { |
112 return_if_false(fSize >= kICCHeaderSize, "Size is too small"); | 113 return_if_false(fSize >= kICCHeaderSize, "Size is too small"); |
113 | 114 |
114 uint8_t majorVersion = fVersion >> 24; | 115 uint8_t majorVersion = fVersion >> 24; |
115 return_if_false(majorVersion <= 4, "Unsupported version"); | 116 return_if_false(majorVersion <= 4, "Unsupported version"); |
116 | 117 |
117 // These are the three basic classes of profiles that we might expect to
see embedded | 118 // These are the four basic classes of profiles that we might expect to
see embedded |
118 // in images. Four additional classes exist, but they generally are use
d as a convenient | 119 // in images. Additional classes exist, but they generally are used as
a convenient |
119 // way for CMMs to store calculated transforms. | 120 // way for CMMs to store calculated transforms. |
120 return_if_false(fProfileClass == kDisplay_Profile || | 121 return_if_false(fProfileClass == kDisplay_Profile || |
121 fProfileClass == kInput_Profile || | 122 fProfileClass == kInput_Profile || |
122 fProfileClass == kOutput_Profile, | 123 fProfileClass == kOutput_Profile || |
| 124 fProfileClass == kColorSpace_Profile, |
123 "Unsupported profile"); | 125 "Unsupported profile"); |
124 | 126 |
125 // TODO (msarett): | 127 // TODO (msarett): |
126 // All the profiles we've tested so far use RGB as the input color space
. | 128 // All the profiles we've tested so far use RGB as the input color space
. |
127 return_if_false(fInputColorSpace == kRGB_ColorSpace, "Unsupported color
space"); | 129 return_if_false(fInputColorSpace == kRGB_ColorSpace, "Unsupported color
space"); |
128 | 130 |
129 // TODO (msarett): | 131 // TODO (msarett): |
130 // All the profiles we've tested so far use XYZ as the profile connectio
n space. | 132 // All the profiles we've tested so far use XYZ as the profile connectio
n space. |
131 return_if_false(fPCS == kXYZ_PCSSpace, "Unsupported PCS space"); | 133 return_if_false(fPCS == kXYZ_PCSSpace, "Unsupported PCS space"); |
132 | 134 |
133 return_if_false(fSignature == kACSP_Signature, "Bad signature"); | 135 return_if_false(fSignature == kACSP_Signature, "Bad signature"); |
134 | 136 |
135 // TODO (msarett): | 137 // TODO (msarett): |
136 // Should we treat different rendering intents differently? | 138 // Should we treat different rendering intents differently? |
137 // Valid rendering intents include kPerceptual (0), kRelative (1), | 139 // Valid rendering intents include kPerceptual (0), kRelative (1), |
138 // kSaturation (2), and kAbsolute (3). | 140 // kSaturation (2), and kAbsolute (3). |
139 return_if_false(fRenderingIntent <= 3, "Bad rendering intent"); | 141 if (fRenderingIntent <= 3) { |
| 142 // Warn rather than fail here. Occasionally, we see perfectly |
| 143 // normal profiles with wacky rendering intents. |
| 144 SkColorSpacePrintf("Warning, bad rendering intent.\n"); |
| 145 } |
140 | 146 |
141 return_if_false(color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[0
]), 0.96420f) && | 147 return_if_false(color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[0
]), 0.96420f) && |
142 color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[1
]), 1.00000f) && | 148 color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[1
]), 1.00000f) && |
143 color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[2
]), 0.82491f), | 149 color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[2
]), 0.82491f), |
144 "Illuminant must be D50"); | 150 "Illuminant must be D50"); |
145 | 151 |
146 return_if_false(fTagCount <= 100, "Too many tags"); | 152 return_if_false(fTagCount <= 100, "Too many tags"); |
147 | 153 |
148 return true; | 154 return true; |
149 } | 155 } |
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1045 ptr32[4] = SkEndian_SwapBE32(0x000116cc); | 1051 ptr32[4] = SkEndian_SwapBE32(0x000116cc); |
1046 ptr += kTAG_XYZ_Bytes; | 1052 ptr += kTAG_XYZ_Bytes; |
1047 | 1053 |
1048 // Write copyright tag | 1054 // Write copyright tag |
1049 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); | 1055 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); |
1050 | 1056 |
1051 // TODO (msarett): Should we try to hold onto the data so we can return imme
diately if | 1057 // TODO (msarett): Should we try to hold onto the data so we can return imme
diately if |
1052 // the client calls again? | 1058 // the client calls again? |
1053 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); | 1059 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); |
1054 } | 1060 } |
OLD | NEW |