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

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

Issue 1933863002: Revert of Introduce SkGammas type to represent ICC gamma curves (Closed) Base URL: https://skia.googlesource.com/skia.git@delcolorspace
Patch Set: Created 4 years, 7 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 | « src/core/SkColorSpace.h ('k') | tests/ColorSpaceTest.cpp » ('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 "SkAtomics.h" 8 #include "SkAtomics.h"
9 #include "SkColorSpace.h" 9 #include "SkColorSpace.h"
10 10
11 void SkFloat3::dump() const { 11 void SkFloat3::dump() const {
12 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]); 12 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]);
13 } 13 }
14 14
15 void SkFloat3x3::dump() const { 15 void SkFloat3x3::dump() const {
16 SkDebugf("[%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f]\n", 16 SkDebugf("[%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f]\n",
17 fMat[0], fMat[1], fMat[2], 17 fMat[0], fMat[1], fMat[2],
18 fMat[3], fMat[4], fMat[5], 18 fMat[3], fMat[4], fMat[5],
19 fMat[6], fMat[7], fMat[8]); 19 fMat[6], fMat[7], fMat[8]);
20 } 20 }
21 21
22 //////////////////////////////////////////////////////////////////////////////// ////////////////// 22 //////////////////////////////////////////////////////////////////////////////// //////////////////
23 23
24 static int32_t gUniqueColorSpaceID; 24 static int32_t gUniqueColorSpaceID;
25 25
26 SkColorSpace::SkColorSpace(SkGammas gammas, const SkFloat3x3& toXYZD50, Named na med) 26 SkColorSpace::SkColorSpace(const SkFloat3& gamma, const SkFloat3x3& toXYZD50, Na med named)
27 : fGammas(std::move(gammas)) 27 : fGamma(gamma)
28 , fToXYZD50(toXYZD50) 28 , fToXYZD50(toXYZD50)
29 , fToXYZOffset({{ 0.0f, 0.0f, 0.0f }}) 29 , fToXYZOffset({{ 0.0f, 0.0f, 0.0f }})
30 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 30 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
31 , fNamed(named) 31 , fNamed(named)
32 {} 32 {}
33 33
34 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas, 34 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, const SkFloat3& gamma,
35 const SkFloat3x3& toXYZD50, const SkFloat3& toXYZOffs et) 35 const SkFloat3x3& toXYZD50, const SkFloat3& toXYZOffs et)
36 : fColorLUT(std::move(colorLUT)) 36 : fColorLUT(std::move(colorLUT))
37 , fGammas(std::move(gammas)) 37 , fGamma(gamma)
38 , fToXYZD50(toXYZD50) 38 , fToXYZD50(toXYZD50)
39 , fToXYZOffset(toXYZOffset) 39 , fToXYZOffset(toXYZOffset)
40 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 40 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
41 , fNamed(kUnknown_Named) 41 , fNamed(kUnknown_Named)
42 {} 42 {}
43 43
44 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, SkGammas ga mmas) { 44 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, const SkFlo at3& gamma) {
45 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named)); 45 return sk_sp<SkColorSpace>(new SkColorSpace(gamma, toXYZD50, kUnknown_Named) );
46 } 46 }
47 47
48 SkColorSpace::SkGammas gSRGB_gamma(2.2f, 2.2f, 2.2f); 48 const SkFloat3 gSRGB_gamma {{ 2.2f, 2.2f, 2.2f }};
49 const SkFloat3x3 gSRGB_toXYZD50 {{ 49 const SkFloat3x3 gSRGB_toXYZD50 {{
50 0.4358f, 0.2224f, 0.0139f, // * R 50 0.4358f, 0.2224f, 0.0139f, // * R
51 0.3853f, 0.7170f, 0.0971f, // * G 51 0.3853f, 0.7170f, 0.0971f, // * G
52 0.1430f, 0.0606f, 0.7139f, // * B 52 0.1430f, 0.0606f, 0.7139f, // * B
53 }}; 53 }};
54 54
55 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 55 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
56 switch (named) { 56 switch (named) {
57 case kSRGB_Named: 57 case kSRGB_Named:
58 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gSRGB_gamma), gSRGB_toXYZD50, 58 return sk_sp<SkColorSpace>(new SkColorSpace(gSRGB_gamma, gSRGB_toXYZ D50, kSRGB_Named));
59 kSRGB_Named));
60 default: 59 default:
61 break; 60 break;
62 } 61 }
63 return nullptr; 62 return nullptr;
64 } 63 }
65 64
66 //////////////////////////////////////////////////////////////////////////////// /////////////////// 65 //////////////////////////////////////////////////////////////////////////////// ///////////////////
67 66
68 #include "SkFixed.h" 67 #include "SkFixed.h"
69 #include "SkTemplates.h" 68 #include "SkTemplates.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 dst[0] = SkFixedToFloat(read_big_endian_int(src + 8)); 257 dst[0] = SkFixedToFloat(read_big_endian_int(src + 8));
259 dst[1] = SkFixedToFloat(read_big_endian_int(src + 12)); 258 dst[1] = SkFixedToFloat(read_big_endian_int(src + 12));
260 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16)); 259 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16));
261 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); 260 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]);
262 return true; 261 return true;
263 } 262 }
264 263
265 static const uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v'); 264 static const uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v');
266 static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a'); 265 static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a');
267 266
268 bool SkColorSpace::LoadGammas(SkGammaCurve* gammas, uint32_t numGammas, const ui nt8_t* src, 267 // FIXME (msarett):
269 size_t len) { 268 // We need to handle the possibility that the gamma curve does not correspond to 2.2f.
269 static bool load_gammas(float* gammas, uint32_t numGammas, const uint8_t* src, s ize_t len) {
270 for (uint32_t i = 0; i < numGammas; i++) { 270 for (uint32_t i = 0; i < numGammas; i++) {
271 if (len < 12) { 271 if (len < 12) {
272 // FIXME (msarett): 272 // FIXME (msarett):
273 // We could potentially return false here after correctly parsing *s ome* of the 273 // We could potentially return false here after correctly parsing *s ome* of the
274 // gammas correctly. Should we somehow try to indicate a partial su ccess? 274 // gammas correctly. Should we somehow try to indicate a partial su ccess?
275 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); 275 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
276 return false; 276 return false;
277 } 277 }
278 278
279 // We need to count the number of bytes in the tag, so we are able to mo ve to the 279 // We need to count the number of bytes in the tag, so we are able to mo ve to the
280 // next tag on the next loop iteration. 280 // next tag on the next loop iteration.
281 size_t tagBytes; 281 size_t tagBytes;
282 282
283 uint32_t type = read_big_endian_uint(src); 283 uint32_t type = read_big_endian_uint(src);
284 switch (type) { 284 switch (type) {
285 case kTAG_CurveType: { 285 case kTAG_CurveType: {
286 uint32_t count = read_big_endian_uint(src + 8); 286 uint32_t count = read_big_endian_uint(src + 8);
287 tagBytes = 12 + count * 2; 287 tagBytes = 12 + count * 2;
288 if (0 == count) { 288 if (0 == count) {
289 // Some tags require a gamma curve, but the author doesn't a ctually want 289 // Some tags require a gamma curve, but the author doesn't a ctually want
290 // to transform the data. In this case, it is common to see a curve with 290 // to transform the data. In this case, it is common to see a curve with
291 // a count of 0. 291 // a count of 0.
292 gammas[i].fValue = 1.0f; 292 gammas[i] = 1.0f;
293 break; 293 break;
294 } else if (len < 12 + 2 * count) { 294 } else if (len < 12 + 2 * count) {
295 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ; 295 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ;
296 return false; 296 return false;
297 } 297 }
298 298
299 const uint16_t* table = (const uint16_t*) (src + 12); 299 const uint16_t* table = (const uint16_t*) (src + 12);
300 if (1 == count) { 300 if (1 == count) {
301 // The table entry is the gamma (with a bias of 256). 301 // Table entry is the exponent (bias 256).
302 uint16_t value = read_big_endian_short((const uint8_t*) tabl e); 302 uint16_t value = read_big_endian_short((const uint8_t*) tabl e);
303 gammas[i].fValue = value / 256.0f; 303 gammas[i] = value / 256.0f;
304 SkColorSpacePrintf("gamma %d %g\n", value, *gamma); 304 SkColorSpacePrintf("gamma %d %g\n", value, *gamma);
305 break; 305 break;
306 } 306 }
307 307
308 // Fill in the interpolation table. 308 // Print the interpolation table. For now, we ignore this and g uess 2.2f.
309 // FIXME (msarett):
310 // We should recognize commonly occurring tables and just set ga mma to 2.2f.
311 gammas[i].fTableSize = count;
312 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]);
313 for (uint32_t j = 0; j < count; j++) { 309 for (uint32_t j = 0; j < count; j++) {
314 gammas[i].fTable[j] = 310 SkColorSpacePrintf("curve[%d] %d\n", j,
315 (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f; 311 read_big_endian_short((const uint8_t*) &table[j]));
316 } 312 }
313
314 gammas[i] = 2.2f;
317 break; 315 break;
318 } 316 }
319 case kTAG_ParaCurveType: 317 case kTAG_ParaCurveType:
320 // Guess 2.2f. 318 // Guess 2.2f.
321 // FIXME (msarett): Handle parametric curves.
322 SkColorSpacePrintf("parametric curve\n"); 319 SkColorSpacePrintf("parametric curve\n");
323 gammas[i].fValue = 2.2f; 320 gammas[i] = 2.2f;
324 321
325 // Determine the size of the parametric curve tag.
326 switch(read_big_endian_short(src + 8)) { 322 switch(read_big_endian_short(src + 8)) {
327 case 0: 323 case 0:
328 tagBytes = 12 + 4; 324 tagBytes = 12 + 4;
329 break; 325 break;
330 case 1: 326 case 1:
331 tagBytes = 12 + 12; 327 tagBytes = 12 + 12;
332 break; 328 break;
333 case 2: 329 case 2:
334 tagBytes = 12 + 16; 330 tagBytes = 12 + 16;
335 break; 331 break;
(...skipping 19 matching lines...) Expand all
355 tagBytes = SkAlign4(tagBytes); 351 tagBytes = SkAlign4(tagBytes);
356 if (len < tagBytes) { 352 if (len < tagBytes) {
357 return false; 353 return false;
358 } 354 }
359 355
360 src += tagBytes; 356 src += tagBytes;
361 len -= tagBytes; 357 len -= tagBytes;
362 } 358 }
363 } 359 }
364 360
365 return true; 361 // If all of the gammas we encounter are 1.0f, indicate that we failed to lo ad gammas.
362 // There is no need to apply a gamma of 1.0f.
363 for (uint32_t i = 0; i < numGammas; i++) {
364 if (1.0f != gammas[i]) {
365 return true;
366 }
367 }
368
369 return false;
366 } 370 }
367 371
368 static const uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' '); 372 static const uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' ');
369 373
370 bool SkColorSpace::LoadColorLUT(SkColorLookUpTable* colorLUT, uint32_t inputChan nels, 374 bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32 _t outputChannels,
371 uint32_t outputChannels, const uint8_t* src, siz e_t len) { 375 const uint8_t* src, size_t len) {
372 if (len < 20) { 376 if (len < 20) {
373 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); 377 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len);
374 return false; 378 return false;
375 } 379 }
376 380
377 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha nnels); 381 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels &&
382 outputChannels <= SkColorLookUpTable::kMaxChannels);
378 colorLUT->fInputChannels = inputChannels; 383 colorLUT->fInputChannels = inputChannels;
379 colorLUT->fOutputChannels = outputChannels; 384 colorLUT->fOutputChannels = outputChannels;
380 uint32_t numEntries = 1; 385 uint32_t numEntries = 1;
381 for (uint32_t i = 0; i < inputChannels; i++) { 386 for (uint32_t i = 0; i < inputChannels; i++) {
382 colorLUT->fGridPoints[i] = src[i]; 387 colorLUT->fGridPoints[i] = src[i];
383 numEntries *= src[i]; 388 numEntries *= src[i];
384 } 389 }
385 numEntries *= outputChannels; 390 numEntries *= outputChannels;
386 391
387 // Space is provided for a maximum of the 16 input channels. Now we determi ne the precision 392 // Space is provided for a maximum of the 16 input channels. Now we determi ne the precision
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 toXYZ->fMat[7] = SkFixedToFloat(read_big_endian_int(src + 20)); 434 toXYZ->fMat[7] = SkFixedToFloat(read_big_endian_int(src + 20));
430 toXYZ->fMat[2] = SkFixedToFloat(read_big_endian_int(src + 24)); 435 toXYZ->fMat[2] = SkFixedToFloat(read_big_endian_int(src + 24));
431 toXYZ->fMat[5] = SkFixedToFloat(read_big_endian_int(src + 28)); 436 toXYZ->fMat[5] = SkFixedToFloat(read_big_endian_int(src + 28));
432 toXYZ->fMat[8] = SkFixedToFloat(read_big_endian_int(src + 32)); 437 toXYZ->fMat[8] = SkFixedToFloat(read_big_endian_int(src + 32));
433 toXYZOffset->fVec[0] = SkFixedToFloat(read_big_endian_int(src + 36)); 438 toXYZOffset->fVec[0] = SkFixedToFloat(read_big_endian_int(src + 36));
434 toXYZOffset->fVec[1] = SkFixedToFloat(read_big_endian_int(src + 40)); 439 toXYZOffset->fVec[1] = SkFixedToFloat(read_big_endian_int(src + 40));
435 toXYZOffset->fVec[2] = SkFixedToFloat(read_big_endian_int(src + 44)); 440 toXYZOffset->fVec[2] = SkFixedToFloat(read_big_endian_int(src + 44));
436 return true; 441 return true;
437 } 442 }
438 443
439 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammas* gammas, SkFl oat3x3* toXYZ, 444 bool load_a2b0(SkColorLookUpTable* colorLUT, SkFloat3* gamma, SkFloat3x3* toXYZ,
440 SkFloat3* toXYZOffset, const uint8_t* src, size_t le n) { 445 SkFloat3* toXYZOffset, const uint8_t* src, size_t len) {
441 if (len < 32) { 446 if (len < 32) {
442 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); 447 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
443 return false; 448 return false;
444 } 449 }
445 450
446 uint32_t type = read_big_endian_uint(src); 451 uint32_t type = read_big_endian_uint(src);
447 if (kTAG_AtoBType != type) { 452 if (kTAG_AtoBType != type) {
448 // FIXME (msarett): Need to support lut8Type and lut16Type. 453 // FIXME (msarett): Need to support lut8Type and lut16Type.
449 SkColorSpacePrintf("Unsupported A to B tag type.\n"); 454 SkColorSpacePrintf("Unsupported A to B tag type.\n");
450 return false; 455 return false;
451 } 456 }
452 457
453 // Read the number of channels. The four bytes that we skipped are reserved and 458 // Read the number of channels. The four bytes that we skipped are reserved and
454 // must be zero. 459 // must be zero.
455 uint8_t inputChannels = src[8]; 460 uint8_t inputChannels = src[8];
456 uint8_t outputChannels = src[9]; 461 uint8_t outputChannels = src[9];
457 if (0 == inputChannels || inputChannels > SkColorLookUpTable::kMaxChannels | | 462 if (0 == inputChannels || inputChannels > SkColorLookUpTable::kMaxChannels | |
458 3 != outputChannels) { 463 0 < outputChannels || outputChannels > SkColorLookUpTable::kMaxChann els) {
459 // The color LUT assumes that there are at most 16 input channels. For RGB 464 // The color LUT assumes that there are at most 16 input channels. For RGB
460 // profiles, output channels should be 3. 465 // profiles, output channels should be 3.
461 SkColorSpacePrintf("Too many input or output channels in A to B tag.\n") ; 466 SkColorSpacePrintf("Too many input or output channels in A to B tag.\n") ;
462 return false; 467 return false;
463 } 468 }
464 469
465 // Read the offsets of each element in the A to B tag. With the exception o f A curves and 470 // Read the offsets of each element in the A to B tag. With the exception o f A curves and
466 // B curves (which we do not yet support), we will handle these elements in the order in 471 // B curves (which we do not yet support), we will handle these elements in the order in
467 // which they should be applied (rather than the order in which they occur i n the tag). 472 // which they should be applied (rather than the order in which they occur i n the tag).
468 // If the offset is non-zero it indicates that the element is present. 473 // If the offset is non-zero it indicates that the element is present.
469 uint32_t offsetToACurves = read_big_endian_int(src + 28); 474 uint32_t offsetToACurves = read_big_endian_int(src + 28);
470 uint32_t offsetToBCurves = read_big_endian_int(src + 12); 475 uint32_t offsetToBCurves = read_big_endian_int(src + 12);
471 if ((0 != offsetToACurves) || (0 != offsetToBCurves)) { 476 if ((0 != offsetToACurves) || (0 != offsetToBCurves)) {
472 // FIXME (msarett): Handle A and B curves. 477 // FIXME (msarett): Handle A and B curves.
473 // Note that the A curve is technically required in order to have a colo r LUT. 478 // Note that the A curve is technically required in order to have a colo r LUT.
474 // However, all the A curves I have seen so far have are just placeholde rs that 479 // However, all the A curves I have seen so far have are just placeholde rs that
475 // don't actually transform the data. 480 // don't actually transform the data.
476 SkColorSpacePrintf("Ignoring A and/or B curve. Output may be wrong.\n") ; 481 SkColorSpacePrintf("Ignoring A and/or B curve. Output may be wrong.\n") ;
477 } 482 }
478 483
479 uint32_t offsetToColorLUT = read_big_endian_int(src + 24); 484 uint32_t offsetToColorLUT = read_big_endian_int(src + 24);
480 if (0 != offsetToColorLUT && offsetToColorLUT < len) { 485 if (0 != offsetToColorLUT && offsetToColorLUT < len) {
481 if (!SkColorSpace::LoadColorLUT(colorLUT, inputChannels, outputChannels, 486 if (!load_color_lut(colorLUT, inputChannels, outputChannels, src + offse tToColorLUT,
482 src + offsetToColorLUT, len - offsetToCo lorLUT)) { 487 len - offsetToColorLUT)) {
483 SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n"); 488 SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n");
484 } 489 }
485 } 490 }
486 491
487 uint32_t offsetToMCurves = read_big_endian_int(src + 20); 492 uint32_t offsetToMCurves = read_big_endian_int(src + 20);
488 if (0 != offsetToMCurves && offsetToMCurves < len) { 493 if (0 != offsetToMCurves && offsetToMCurves < len) {
489 if (!SkColorSpace::LoadGammas(&gammas->fRed, outputChannels, src + offse tToMCurves, 494 if (!load_gammas(gamma->fVec, outputChannels, src + offsetToMCurves, len - offsetToMCurves))
490 len - offsetToMCurves)) { 495 {
491 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); 496 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n");
492 } 497 }
493 } 498 }
494 499
495 uint32_t offsetToMatrix = read_big_endian_int(src + 16); 500 uint32_t offsetToMatrix = read_big_endian_int(src + 16);
496 if (0 != offsetToMatrix && offsetToMatrix < len) { 501 if (0 != offsetToMatrix && offsetToMatrix < len) {
497 if (!load_matrix(toXYZ, toXYZOffset, src + offsetToMatrix, len - offsetT oMatrix)) { 502 if (!load_matrix(toXYZ, toXYZOffset, src + offsetToMatrix, len - offsetT oMatrix)) {
498 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); 503 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n");
499 } 504 }
500 } 505 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 SkFloat3x3 toXYZ; 560 SkFloat3x3 toXYZ;
556 if (!load_xyz(&toXYZ.fMat[0], r->addr((const uint8_t*) base), r- >fLength) || 561 if (!load_xyz(&toXYZ.fMat[0], r->addr((const uint8_t*) base), r- >fLength) ||
557 !load_xyz(&toXYZ.fMat[3], g->addr((const uint8_t*) base), g- >fLength) || 562 !load_xyz(&toXYZ.fMat[3], g->addr((const uint8_t*) base), g- >fLength) ||
558 !load_xyz(&toXYZ.fMat[6], b->addr((const uint8_t*) base), b- >fLength)) 563 !load_xyz(&toXYZ.fMat[6], b->addr((const uint8_t*) base), b- >fLength))
559 { 564 {
560 return_null("Need valid rgb tags for XYZ space"); 565 return_null("Need valid rgb tags for XYZ space");
561 } 566 }
562 567
563 // It is not uncommon to see missing or empty gamma tags. This indicates 568 // It is not uncommon to see missing or empty gamma tags. This indicates
564 // that we should use unit gamma. 569 // that we should use unit gamma.
565 SkGammas gammas; 570 SkFloat3 gamma {{ 1.0f, 1.0f, 1.0f }};
566 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); 571 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC);
567 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); 572 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC);
568 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); 573 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC);
569 if (!r || !SkColorSpace::LoadGammas(&gammas.fRed, 1, 574 if (!r ||
570 r->addr((const uint8_t*) bas e), r->fLength)) { 575 !load_gammas(&gamma.fVec[0], 1, r->addr((const uint8_t*) bas e), r->fLength))
576 {
571 SkColorSpacePrintf("Failed to read R gamma tag.\n"); 577 SkColorSpacePrintf("Failed to read R gamma tag.\n");
572 } 578 }
573 if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1, 579 if (!g ||
574 g->addr((const uint8_t*) bas e), g->fLength)) { 580 !load_gammas(&gamma.fVec[1], 1, g->addr((const uint8_t*) bas e), g->fLength))
581 {
575 SkColorSpacePrintf("Failed to read G gamma tag.\n"); 582 SkColorSpacePrintf("Failed to read G gamma tag.\n");
576 } 583 }
577 if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1, 584 if (!b ||
578 b->addr((const uint8_t*) bas e), b->fLength)) { 585 !load_gammas(&gamma.fVec[2], 1, b->addr((const uint8_t*) bas e), b->fLength))
586 {
579 SkColorSpacePrintf("Failed to read B gamma tag.\n"); 587 SkColorSpacePrintf("Failed to read B gamma tag.\n");
580 } 588 }
581 return SkColorSpace::NewRGB(toXYZ, std::move(gammas)); 589 return SkColorSpace::NewRGB(toXYZ, gamma);
582 } 590 }
583 591
584 // Recognize color profile specified by A2B0 tag. 592 // Recognize color profile specified by A2B0 tag.
585 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); 593 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
586 if (a2b0) { 594 if (a2b0) {
587 SkColorLookUpTable colorLUT; 595 SkColorLookUpTable colorLUT;
588 SkGammas gammas; 596 SkFloat3 gamma;
589 SkFloat3x3 toXYZ; 597 SkFloat3x3 toXYZ;
590 SkFloat3 toXYZOffset; 598 SkFloat3 toXYZOffset;
591 if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ, &toXYZOf fset, 599 if (!load_a2b0(&colorLUT, &gamma, &toXYZ, &toXYZOffset,
592 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) { 600 a2b0->addr((const uint8_t*) base), a2b0->fLength)) {
593 return_null("Failed to parse A2B0 tag"); 601 return_null("Failed to parse A2B0 tag");
594 } 602 }
595 603
596 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas), 604 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), gamma, toXYZ,
597 toXYZ, toXYZOffset)) ; 605 toXYZOffset));
598 } 606 }
599 607
600 } 608 }
601 default: 609 default:
602 break; 610 break;
603 } 611 }
604 612
605 return_null("ICC profile contains unsupported colorspace"); 613 return_null("ICC profile contains unsupported colorspace");
606 } 614 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpace.h ('k') | tests/ColorSpaceTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698