Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: src/core/SkColorSpace.cpp

Issue 2221983002: Fix Equals and serialization for rare pngs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Response to comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/core/SkColorSpace_Base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) && 61 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) &&
62 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) && 62 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) &&
63 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) && 63 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) &&
64 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) && 64 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) &&
65 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) && 65 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) &&
66 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) && 66 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) &&
67 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) && 67 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) &&
68 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f); 68 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f);
69 } 69 }
70 70
71 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(float values[3], const SkMatrix44& toXYZD50) { 71 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(const float values[3], const SkMat rix44& toXYZD50) {
72 if (0.0f > values[0] || 0.0f > values[1] || 0.0f > values[2]) { 72 if (0.0f > values[0] || 0.0f > values[1] || 0.0f > values[2]) {
73 return nullptr; 73 return nullptr;
74 } 74 }
75 75
76 GammaNamed gammaNamed = kNonStandard_GammaNamed; 76 GammaNamed gammaNamed = kNonStandard_GammaNamed;
77 if (color_space_almost_equal(2.2f, values[0]) && 77 if (color_space_almost_equal(2.2f, values[0]) &&
78 color_space_almost_equal(2.2f, values[1]) && 78 color_space_almost_equal(2.2f, values[1]) &&
79 color_space_almost_equal(2.2f, values[2])) { 79 color_space_almost_equal(2.2f, values[2])) {
80 gammaNamed = k2Dot2Curve_GammaNamed; 80 gammaNamed = k2Dot2Curve_GammaNamed;
81 } else if (color_space_almost_equal(1.0f, values[0]) && 81 } else if (color_space_almost_equal(1.0f, values[0]) &&
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 157
158 //////////////////////////////////////////////////////////////////////////////// /////////////////// 158 //////////////////////////////////////////////////////////////////////////////// ///////////////////
159 159
160 enum Version { 160 enum Version {
161 k0_Version, // Initial version, header + flags for matrix and profile 161 k0_Version, // Initial version, header + flags for matrix and profile
162 }; 162 };
163 163
164 struct ColorSpaceHeader { 164 struct ColorSpaceHeader {
165 /** 165 /**
166 * If kMatrix_Flag is set, we will write 12 floats after the header. 166 * If kMatrix_Flag is set, we will write 12 floats after the header.
167 * Should not be set at the same time as the kICC_Flag. 167 * Should not be set at the same time as the kICC_Flag or kFloatGamma_Flag.
168 */ 168 */
169 static constexpr uint8_t kMatrix_Flag = 1 << 0; 169 static constexpr uint8_t kMatrix_Flag = 1 << 0;
170 170
171 /** 171 /**
172 * If kICC_Flag is set, we will write an ICC profile after the header. 172 * If kICC_Flag is set, we will write an ICC profile after the header.
173 * The ICC profile will be written as a uint32 size, followed immediately 173 * The ICC profile will be written as a uint32 size, followed immediately
174 * by the data (padded to 4 bytes). 174 * by the data (padded to 4 bytes).
175 * Should not be set at the same time as the kMatrix_Flag. 175 * Should not be set at the same time as the kMatrix_Flag or kFloatGamma_Fl ag.
176 */ 176 */
177 static constexpr uint8_t kICC_Flag = 1 << 1; 177 static constexpr uint8_t kICC_Flag = 1 << 1;
178
179 /**
180 * If kFloatGamma_Flag is set, we will write 15 floats after the header.
181 * The first three are the gamma values, and the next twelve are the
182 * matrix.
183 * Should not be set at the same time as the kICC_Flag or kMatrix_Flag.
184 */
185 static constexpr uint8_t kFloatGamma_Flag = 1 << 2;
178 186
179 static ColorSpaceHeader Pack(Version version, SkColorSpace::Named named, 187 static ColorSpaceHeader Pack(Version version, SkColorSpace::Named named,
180 SkColorSpace::GammaNamed gammaNamed, uint8_t fl ags) { 188 SkColorSpace::GammaNamed gammaNamed, uint8_t fl ags) {
181 ColorSpaceHeader header; 189 ColorSpaceHeader header;
182 190
183 SkASSERT(k0_Version == version); 191 SkASSERT(k0_Version == version);
184 header.fVersion = (uint8_t) version; 192 header.fVersion = (uint8_t) version;
185 193
186 SkASSERT(named <= SkColorSpace::kAdobeRGB_Named); 194 SkASSERT(named <= SkColorSpace::kAdobeRGB_Named);
187 header.fNamed = (uint8_t) named; 195 header.fNamed = (uint8_t) named;
188 196
189 SkASSERT(gammaNamed <= SkColorSpace::kNonStandard_GammaNamed); 197 SkASSERT(gammaNamed <= SkColorSpace::kNonStandard_GammaNamed);
190 header.fGammaNamed = (uint8_t) gammaNamed; 198 header.fGammaNamed = (uint8_t) gammaNamed;
191 199
192 SkASSERT(flags <= kICC_Flag); 200 SkASSERT(flags <= kFloatGamma_Flag);
193 header.fFlags = flags; 201 header.fFlags = flags;
194 return header; 202 return header;
195 } 203 }
196 204
197 uint8_t fVersion; // Always zero 205 uint8_t fVersion; // Always zero
198 uint8_t fNamed; // Must be a SkColorSpace::Named 206 uint8_t fNamed; // Must be a SkColorSpace::Named
199 uint8_t fGammaNamed; // Must be a SkColorSpace::GammaNamed 207 uint8_t fGammaNamed; // Must be a SkColorSpace::GammaNamed
200 uint8_t fFlags; // Some combination of the flags listed above 208 uint8_t fFlags; // Some combination of the flags listed above
201 }; 209 };
202 210
(...skipping 23 matching lines...) Expand all
226 if (memory) { 234 if (memory) {
227 *((ColorSpaceHeader*) memory) = 235 *((ColorSpaceHeader*) memory) =
228 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam ed, 236 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam ed,
229 ColorSpaceHeader::kMatrix_Fla g); 237 ColorSpaceHeader::kMatrix_Fla g);
230 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader) ); 238 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader) );
231 fToXYZD50.as4x3ColMajorf((float*) memory); 239 fToXYZD50.as4x3ColMajorf((float*) memory);
232 } 240 }
233 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); 241 return sizeof(ColorSpaceHeader) + 12 * sizeof(float);
234 } 242 }
235 default: 243 default:
236 SkASSERT(false); 244 // Otherwise, write the gamma values and the matrix.
237 return 0; 245 if (memory) {
246 *((ColorSpaceHeader*) memory) =
247 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam ed,
248 ColorSpaceHeader::kFloatGamma _Flag);
249 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader) );
250
251 const SkGammas* gammas = as_CSB(this)->gammas();
252 SkASSERT(gammas);
253 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType &&
254 SkGammas::Type::kValue_Type == gammas->fGreenType & &
255 SkGammas::Type::kValue_Type == gammas->fBlueType);
256 *(((float*) memory) + 0) = gammas->fRedData.fValue;
257 *(((float*) memory) + 1) = gammas->fGreenData.fValue;
258 *(((float*) memory) + 2) = gammas->fBlueData.fValue;
259 memory = SkTAddOffset<void>(memory, 3 * sizeof(float));
260
261 fToXYZD50.as4x3ColMajorf((float*) memory);
262 }
263 return sizeof(ColorSpaceHeader) + 15 * sizeof(float);
238 } 264 }
239 } 265 }
240 266
241 // Otherwise, serialize the ICC data. 267 // Otherwise, serialize the ICC data.
242 size_t profileSize = as_CSB(this)->fProfileData->size(); 268 size_t profileSize = as_CSB(this)->fProfileData->size();
243 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { 269 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) {
244 return 0; 270 return 0;
245 } 271 }
246 272
247 if (memory) { 273 if (memory) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 } 321 }
296 322
297 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); 323 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
298 toXYZ.set4x3ColMajorf((const float*) data); 324 toXYZ.set4x3ColMajorf((const float*) data);
299 return NewRGB((GammaNamed) header.fGammaNamed, toXYZ); 325 return NewRGB((GammaNamed) header.fGammaNamed, toXYZ);
300 } 326 }
301 default: 327 default:
302 break; 328 break;
303 } 329 }
304 330
305 if (ColorSpaceHeader::kICC_Flag != header.fFlags || length < sizeof(uint32_t )) { 331 switch (header.fFlags) {
306 return nullptr; 332 case ColorSpaceHeader::kICC_Flag: {
333 if (length < sizeof(uint32_t)) {
334 return nullptr;
335 }
336
337 uint32_t profileSize = *((uint32_t*) data);
338 data = SkTAddOffset<const void>(data, sizeof(uint32_t));
339 length -= sizeof(uint32_t);
340 if (length < profileSize) {
341 return nullptr;
342 }
343
344 return NewICC(data, profileSize);
345 }
346 case ColorSpaceHeader::kFloatGamma_Flag: {
347 if (length < 15 * sizeof(float)) {
348 return nullptr;
349 }
350
351 float gammas[3];
352 gammas[0] = *(((const float*) data) + 0);
353 gammas[1] = *(((const float*) data) + 1);
354 gammas[2] = *(((const float*) data) + 2);
355 data = SkTAddOffset<const void>(data, 3 * sizeof(float));
356
357 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
358 toXYZ.set4x3ColMajorf((const float*) data);
359 return SkColorSpace_Base::NewRGB(gammas, toXYZ);
360 }
361 default:
362 return nullptr;
307 } 363 }
308
309 uint32_t profileSize = *((uint32_t*) data);
310 data = SkTAddOffset<const void>(data, sizeof(uint32_t));
311 length -= sizeof(uint32_t);
312 if (length < profileSize) {
313 return nullptr;
314 }
315
316 return NewICC(data, profileSize);
317 } 364 }
318 365
319 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) { 366 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) {
320 if (src == dst) { 367 if (src == dst) {
321 return true; 368 return true;
322 } 369 }
323 370
324 if (!src || !dst) { 371 if (!src || !dst) {
325 return false; 372 return false;
326 } 373 }
(...skipping 21 matching lines...) Expand all
348 } 395 }
349 396
350 // It's important to check fProfileData before named gammas. Some profiles may have named 397 // It's important to check fProfileData before named gammas. Some profiles may have named
351 // gammas, but also include other wacky features that cause us to save the d ata. 398 // gammas, but also include other wacky features that cause us to save the d ata.
352 switch (src->fGammaNamed) { 399 switch (src->fGammaNamed) {
353 case kSRGB_GammaNamed: 400 case kSRGB_GammaNamed:
354 case k2Dot2Curve_GammaNamed: 401 case k2Dot2Curve_GammaNamed:
355 case kLinear_GammaNamed: 402 case kLinear_GammaNamed:
356 return (src->fGammaNamed == dst->fGammaNamed) && (src->fToXYZD50 == dst->fToXYZD50); 403 return (src->fGammaNamed == dst->fGammaNamed) && (src->fToXYZD50 == dst->fToXYZD50);
357 default: 404 default:
358 // If |src| does not have a named gamma, fProfileData should be non- null. 405 if (src->fGammaNamed != dst->fGammaNamed) {
359 // FIXME (msarett): We may hit this case on pngs that specify float gammas. 406 return false;
360 // Gamma can be non-standard, but we don't have a p rofile 407 }
361 // to fall back on. What do we do? 408
362 return false; 409 // It is unlikely that we will reach this case.
410 sk_sp<SkData> srcData = src->serialize();
411 sk_sp<SkData> dstData = dst->serialize();
412 return srcData->size() == dstData->size() &&
413 0 == memcmp(srcData->data(), dstData->data(), srcData->size() );
363 } 414 }
364 } 415 }
365 416
366 bool SkColorSpace::gammasAreMatching() const { 417 bool SkColorSpace::gammasAreMatching() const {
367 const SkGammas* gammas = as_CSB(this)->gammas(); 418 const SkGammas* gammas = as_CSB(this)->gammas();
368 SkASSERT(gammas); 419 SkASSERT(gammas);
369 return gammas->fRedType == gammas->fGreenType && gammas->fGreenType == gamma s->fBlueType && 420 return gammas->fRedType == gammas->fGreenType && gammas->fGreenType == gamma s->fBlueType &&
370 gammas->fRedData == gammas->fGreenData && gammas->fGreenData == gamma s->fBlueData; 421 gammas->fRedData == gammas->fGreenData && gammas->fGreenData == gamma s->fBlueData;
371 } 422 }
372 423
(...skipping 21 matching lines...) Expand all
394 gammas->fBlueType == SkGammas::Type::kTable_Type; 445 gammas->fBlueType == SkGammas::Type::kTable_Type;
395 } 446 }
396 447
397 bool SkColorSpace::gammasAreParams() const { 448 bool SkColorSpace::gammasAreParams() const {
398 const SkGammas* gammas = as_CSB(this)->gammas(); 449 const SkGammas* gammas = as_CSB(this)->gammas();
399 SkASSERT(gammas); 450 SkASSERT(gammas);
400 return gammas->fRedType == SkGammas::Type::kParam_Type && 451 return gammas->fRedType == SkGammas::Type::kParam_Type &&
401 gammas->fGreenType == SkGammas::Type::kParam_Type && 452 gammas->fGreenType == SkGammas::Type::kParam_Type &&
402 gammas->fBlueType == SkGammas::Type::kParam_Type; 453 gammas->fBlueType == SkGammas::Type::kParam_Type;
403 } 454 }
OLDNEW
« no previous file with comments | « no previous file | src/core/SkColorSpace_Base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698