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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 dst[2] = SkFixedToFloat(read_big_endian_i32(src + 16)); | 233 dst[2] = SkFixedToFloat(read_big_endian_i32(src + 16)); |
234 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); | 234 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); |
235 return true; | 235 return true; |
236 } | 236 } |
237 | 237 |
238 static constexpr uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', '
v'); | 238 static constexpr uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', '
v'); |
239 static constexpr uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', '
a'); | 239 static constexpr uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', '
a'); |
240 | 240 |
241 static SkGammas::Type set_gamma_value(SkGammas::Data* data, float value) { | 241 static SkGammas::Type set_gamma_value(SkGammas::Data* data, float value) { |
242 if (color_space_almost_equal(2.2f, value)) { | 242 if (color_space_almost_equal(2.2f, value)) { |
243 data->fNamed = SkColorSpace::k2Dot2Curve_GammaNamed; | 243 data->fNamed = k2Dot2Curve_SkGammaNamed; |
244 return SkGammas::Type::kNamed_Type; | 244 return SkGammas::Type::kNamed_Type; |
245 } | 245 } |
246 | 246 |
247 if (color_space_almost_equal(1.0f, value)) { | 247 if (color_space_almost_equal(1.0f, value)) { |
248 data->fNamed = SkColorSpace::kLinear_GammaNamed; | 248 data->fNamed = kLinear_SkGammaNamed; |
249 return SkGammas::Type::kNamed_Type; | 249 return SkGammas::Type::kNamed_Type; |
250 } | 250 } |
251 | 251 |
252 if (color_space_almost_equal(0.0f, value)) { | 252 if (color_space_almost_equal(0.0f, value)) { |
253 return SkGammas::Type::kNone_Type; | 253 return SkGammas::Type::kNone_Type; |
254 } | 254 } |
255 | 255 |
256 data->fValue = value; | 256 data->fValue = value; |
257 return SkGammas::Type::kValue_Type; | 257 return SkGammas::Type::kValue_Type; |
258 } | 258 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 if (len < tagBytes) { | 303 if (len < tagBytes) { |
304 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); | 304 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); |
305 return SkGammas::Type::kNone_Type; | 305 return SkGammas::Type::kNone_Type; |
306 } | 306 } |
307 *outTagBytes = tagBytes; | 307 *outTagBytes = tagBytes; |
308 | 308 |
309 if (0 == count) { | 309 if (0 == count) { |
310 // Some tags require a gamma curve, but the author doesn't actua
lly want | 310 // Some tags require a gamma curve, but the author doesn't actua
lly want |
311 // to transform the data. In this case, it is common to see a c
urve with | 311 // to transform the data. In this case, it is common to see a c
urve with |
312 // a count of 0. | 312 // a count of 0. |
313 outData->fNamed = SkColorSpace::kLinear_GammaNamed; | 313 outData->fNamed = kLinear_SkGammaNamed; |
314 return SkGammas::Type::kNamed_Type; | 314 return SkGammas::Type::kNamed_Type; |
315 } | 315 } |
316 | 316 |
317 const uint16_t* table = (const uint16_t*) (src + 12); | 317 const uint16_t* table = (const uint16_t*) (src + 12); |
318 if (1 == count) { | 318 if (1 == count) { |
319 // The table entry is the gamma (with a bias of 256). | 319 // The table entry is the gamma (with a bias of 256). |
320 float value = (read_big_endian_u16((const uint8_t*) table)) / 25
6.0f; | 320 float value = (read_big_endian_u16((const uint8_t*) table)) / 25
6.0f; |
321 SkColorSpacePrintf("gamma %g\n", value); | 321 SkColorSpacePrintf("gamma %g\n", value); |
322 | 322 |
323 return set_gamma_value(outData, value); | 323 return set_gamma_value(outData, value); |
324 } | 324 } |
325 | 325 |
326 // Check for frequently occurring sRGB curves. | 326 // Check for frequently occurring sRGB curves. |
327 // We do this by sampling a few values and see if they match our exp
ectation. | 327 // We do this by sampling a few values and see if they match our exp
ectation. |
328 // A more robust solution would be to compare each value in this cur
ve against | 328 // A more robust solution would be to compare each value in this cur
ve against |
329 // an sRGB curve to see if we remain below an error threshold. At t
his time, | 329 // an sRGB curve to see if we remain below an error threshold. At t
his time, |
330 // we haven't seen any images in the wild that make this kind of | 330 // we haven't seen any images in the wild that make this kind of |
331 // calculation necessary. We encounter identical gamma curves over
and | 331 // calculation necessary. We encounter identical gamma curves over
and |
332 // over again, but relatively few variations. | 332 // over again, but relatively few variations. |
333 if (1024 == count) { | 333 if (1024 == count) { |
334 // The magic values were chosen because they match both the very
common | 334 // The magic values were chosen because they match both the very
common |
335 // HP sRGB gamma table and the less common Canon sRGB gamma tabl
e (which use | 335 // HP sRGB gamma table and the less common Canon sRGB gamma tabl
e (which use |
336 // different rounding rules). | 336 // different rounding rules). |
337 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && | 337 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && |
338 3366 == read_big_endian_u16((const uint8_t*) &table[257]
) && | 338 3366 == read_big_endian_u16((const uint8_t*) &table[257]
) && |
339 14116 == read_big_endian_u16((const uint8_t*) &table[513
]) && | 339 14116 == read_big_endian_u16((const uint8_t*) &table[513
]) && |
340 34318 == read_big_endian_u16((const uint8_t*) &table[768
]) && | 340 34318 == read_big_endian_u16((const uint8_t*) &table[768
]) && |
341 65535 == read_big_endian_u16((const uint8_t*) &table[102
3])) { | 341 65535 == read_big_endian_u16((const uint8_t*) &table[102
3])) { |
342 outData->fNamed = SkColorSpace::kSRGB_GammaNamed; | 342 outData->fNamed = kSRGB_SkGammaNamed; |
343 return SkGammas::Type::kNamed_Type; | 343 return SkGammas::Type::kNamed_Type; |
344 } | 344 } |
345 } | 345 } |
346 | 346 |
347 if (26 == count) { | 347 if (26 == count) { |
348 // The magic values were chosen because they match a very common
LCMS sRGB | 348 // The magic values were chosen because they match a very common
LCMS sRGB |
349 // gamma table. | 349 // gamma table. |
350 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && | 350 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && |
351 3062 == read_big_endian_u16((const uint8_t*) &table[6])
&& | 351 3062 == read_big_endian_u16((const uint8_t*) &table[6])
&& |
352 12824 == read_big_endian_u16((const uint8_t*) &table[12]
) && | 352 12824 == read_big_endian_u16((const uint8_t*) &table[12]
) && |
353 31237 == read_big_endian_u16((const uint8_t*) &table[18]
) && | 353 31237 == read_big_endian_u16((const uint8_t*) &table[18]
) && |
354 65535 == read_big_endian_u16((const uint8_t*) &table[25]
)) { | 354 65535 == read_big_endian_u16((const uint8_t*) &table[25]
)) { |
355 outData->fNamed = SkColorSpace::kSRGB_GammaNamed; | 355 outData->fNamed = kSRGB_SkGammaNamed; |
356 return SkGammas::Type::kNamed_Type; | 356 return SkGammas::Type::kNamed_Type; |
357 } | 357 } |
358 } | 358 } |
359 | 359 |
360 if (4096 == count) { | 360 if (4096 == count) { |
361 // The magic values were chosen because they match Nikon, Epson,
and | 361 // The magic values were chosen because they match Nikon, Epson,
and |
362 // LCMS sRGB gamma tables (all of which use different rounding r
ules). | 362 // LCMS sRGB gamma tables (all of which use different rounding r
ules). |
363 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && | 363 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && |
364 950 == read_big_endian_u16((const uint8_t*) &table[515])
&& | 364 950 == read_big_endian_u16((const uint8_t*) &table[515])
&& |
365 3342 == read_big_endian_u16((const uint8_t*) &table[1025
]) && | 365 3342 == read_big_endian_u16((const uint8_t*) &table[1025
]) && |
366 14079 == read_big_endian_u16((const uint8_t*) &table[205
1]) && | 366 14079 == read_big_endian_u16((const uint8_t*) &table[205
1]) && |
367 65535 == read_big_endian_u16((const uint8_t*) &table[409
5])) { | 367 65535 == read_big_endian_u16((const uint8_t*) &table[409
5])) { |
368 outData->fNamed = SkColorSpace::kSRGB_GammaNamed; | 368 outData->fNamed = kSRGB_SkGammaNamed; |
369 return SkGammas::Type::kNamed_Type; | 369 return SkGammas::Type::kNamed_Type; |
370 } | 370 } |
371 } | 371 } |
372 | 372 |
373 // Otherwise, we will represent gamma with a table. | 373 // Otherwise, we will represent gamma with a table. |
374 outData->fTable.fSize = count; | 374 outData->fTable.fSize = count; |
375 return SkGammas::Type::kTable_Type; | 375 return SkGammas::Type::kTable_Type; |
376 } | 376 } |
377 case kTAG_ParaCurveType: { | 377 case kTAG_ParaCurveType: { |
378 enum ParaCurveType { | 378 enum ParaCurveType { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 } | 479 } |
480 | 480 |
481 // Recognize and simplify a very common parametric representation of
sRGB gamma. | 481 // Recognize and simplify a very common parametric representation of
sRGB gamma. |
482 if (color_space_almost_equal(0.9479f, a) && | 482 if (color_space_almost_equal(0.9479f, a) && |
483 color_space_almost_equal(0.0521f, b) && | 483 color_space_almost_equal(0.0521f, b) && |
484 color_space_almost_equal(0.0000f, c) && | 484 color_space_almost_equal(0.0000f, c) && |
485 color_space_almost_equal(0.0405f, d) && | 485 color_space_almost_equal(0.0405f, d) && |
486 color_space_almost_equal(0.0774f, e) && | 486 color_space_almost_equal(0.0774f, e) && |
487 color_space_almost_equal(0.0000f, f) && | 487 color_space_almost_equal(0.0000f, f) && |
488 color_space_almost_equal(2.4000f, g)) { | 488 color_space_almost_equal(2.4000f, g)) { |
489 outData->fNamed = SkColorSpace::kSRGB_GammaNamed; | 489 outData->fNamed = kSRGB_SkGammaNamed; |
490 return SkGammas::Type::kNamed_Type; | 490 return SkGammas::Type::kNamed_Type; |
491 } | 491 } |
492 | 492 |
493 // Fail on invalid gammas. | 493 // Fail on invalid gammas. |
494 if (SkScalarIsNaN(d)) { | 494 if (SkScalarIsNaN(d)) { |
495 return SkGammas::Type::kNone_Type; | 495 return SkGammas::Type::kNone_Type; |
496 } | 496 } |
497 | 497 |
498 if (d <= 0.0f) { | 498 if (d <= 0.0f) { |
499 // Y = (aX + b)^g + c for always | 499 // Y = (aX + b)^g + c for always |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 } | 555 } |
556 | 556 |
557 /** | 557 /** |
558 * Sets invalid gamma to the default value. | 558 * Sets invalid gamma to the default value. |
559 */ | 559 */ |
560 static void handle_invalid_gamma(SkGammas::Type* type, SkGammas::Data* data) { | 560 static void handle_invalid_gamma(SkGammas::Type* type, SkGammas::Data* data) { |
561 if (SkGammas::Type::kNone_Type == *type) { | 561 if (SkGammas::Type::kNone_Type == *type) { |
562 *type = SkGammas::Type::kNamed_Type; | 562 *type = SkGammas::Type::kNamed_Type; |
563 | 563 |
564 // Guess sRGB in the case of a malformed transfer function. | 564 // Guess sRGB in the case of a malformed transfer function. |
565 data->fNamed = SkColorSpace::kSRGB_GammaNamed; | 565 data->fNamed = kSRGB_SkGammaNamed; |
566 } | 566 } |
567 } | 567 } |
568 | 568 |
569 /** | 569 /** |
570 * Finish loading the gammas, now that we have allocated memory for the SkGamma
s struct. | 570 * Finish loading the gammas, now that we have allocated memory for the SkGamma
s struct. |
571 * | 571 * |
572 * There's nothing to do for the simple cases, but for table gammas we need to
actually | 572 * There's nothing to do for the simple cases, but for table gammas we need to
actually |
573 * read the table into heap memory. And for parametric gammas, we need to copy
over the | 573 * read the table into heap memory. And for parametric gammas, we need to copy
over the |
574 * parameter values. | 574 * parameter values. |
575 * | 575 * |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 array[10] = scale * SkFixedToFloat(read_big_endian_i32(src + 32)); | 711 array[10] = scale * SkFixedToFloat(read_big_endian_i32(src + 32)); |
712 array[11] = scale * SkFixedToFloat(read_big_endian_i32(src + 44)); // transl
ate B | 712 array[11] = scale * SkFixedToFloat(read_big_endian_i32(src + 44)); // transl
ate B |
713 array[12] = 0.0f; | 713 array[12] = 0.0f; |
714 array[13] = 0.0f; | 714 array[13] = 0.0f; |
715 array[14] = 0.0f; | 715 array[14] = 0.0f; |
716 array[15] = 1.0f; | 716 array[15] = 1.0f; |
717 toXYZ->setColMajorf(array); | 717 toXYZ->setColMajorf(array); |
718 return true; | 718 return true; |
719 } | 719 } |
720 | 720 |
721 static inline SkColorSpace::GammaNamed is_named(const sk_sp<SkGammas>& gammas) { | 721 static inline SkGammaNamed is_named(const sk_sp<SkGammas>& gammas) { |
722 if (gammas->isNamed(0) && gammas->isNamed(1) && gammas->isNamed(2) && | 722 if (gammas->isNamed(0) && gammas->isNamed(1) && gammas->isNamed(2) && |
723 gammas->fRedData.fNamed == gammas->fGreenData.fNamed && | 723 gammas->fRedData.fNamed == gammas->fGreenData.fNamed && |
724 gammas->fRedData.fNamed == gammas->fBlueData.fNamed) | 724 gammas->fRedData.fNamed == gammas->fBlueData.fNamed) |
725 { | 725 { |
726 return gammas->fRedData.fNamed; | 726 return gammas->fRedData.fNamed; |
727 } | 727 } |
728 | 728 |
729 return SkColorSpace::kNonStandard_GammaNamed; | 729 return kNonStandard_SkGammaNamed; |
730 } | 730 } |
731 | 731 |
732 | 732 |
733 static bool load_a2b0(sk_sp<SkColorLookUpTable>* colorLUT, SkColorSpace::GammaNa
med* gammaNamed, | 733 static bool load_a2b0(sk_sp<SkColorLookUpTable>* colorLUT, SkGammaNamed* gammaNa
med, |
734 sk_sp<SkGammas>* gammas, SkMatrix44* toXYZ, const uint8_t*
src, size_t len) { | 734 sk_sp<SkGammas>* gammas, SkMatrix44* toXYZ, const uint8_t*
src, size_t len) { |
735 if (len < 32) { | 735 if (len < 32) { |
736 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); | 736 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); |
737 return false; | 737 return false; |
738 } | 738 } |
739 | 739 |
740 uint32_t type = read_big_endian_u32(src); | 740 uint32_t type = read_big_endian_u32(src); |
741 if (kTAG_AtoBType != type) { | 741 if (kTAG_AtoBType != type) { |
742 // FIXME (msarett): Need to support lut8Type and lut16Type. | 742 // FIXME (msarett): Need to support lut8Type and lut16Type. |
743 SkColorSpacePrintf("Unsupported A to B tag type.\n"); | 743 SkColorSpacePrintf("Unsupported A to B tag type.\n"); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 | 854 |
855 (*gammas)->fBlueType = bType; | 855 (*gammas)->fBlueType = bType; |
856 load_gammas(memory, offset, bType, &bData, bParams, bTagPtr); | 856 load_gammas(memory, offset, bType, &bData, bParams, bTagPtr); |
857 | 857 |
858 (*gammas)->fRedData = rData; | 858 (*gammas)->fRedData = rData; |
859 (*gammas)->fGreenData = gData; | 859 (*gammas)->fGreenData = gData; |
860 (*gammas)->fBlueData = bData; | 860 (*gammas)->fBlueData = bData; |
861 } | 861 } |
862 } else { | 862 } else { |
863 // Guess sRGB if the chunk is missing a transfer function. | 863 // Guess sRGB if the chunk is missing a transfer function. |
864 *gammaNamed = SkColorSpace::kSRGB_GammaNamed; | 864 *gammaNamed = kSRGB_SkGammaNamed; |
865 } | 865 } |
866 | 866 |
867 if (SkColorSpace::kNonStandard_GammaNamed == *gammaNamed) { | 867 if (kNonStandard_SkGammaNamed == *gammaNamed) { |
868 *gammaNamed = is_named(*gammas); | 868 *gammaNamed = is_named(*gammas); |
869 if (SkColorSpace::kNonStandard_GammaNamed != *gammaNamed) { | 869 if (kNonStandard_SkGammaNamed != *gammaNamed) { |
870 // No need to keep the gammas struct, the enum is enough. | 870 // No need to keep the gammas struct, the enum is enough. |
871 *gammas = nullptr; | 871 *gammas = nullptr; |
872 } | 872 } |
873 } | 873 } |
874 | 874 |
875 uint32_t offsetToMatrix = read_big_endian_i32(src + 16); | 875 uint32_t offsetToMatrix = read_big_endian_i32(src + 16); |
876 if (0 != offsetToMatrix && offsetToMatrix < len) { | 876 if (0 != offsetToMatrix && offsetToMatrix < len) { |
877 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) { | 877 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) { |
878 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); | 878 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); |
879 toXYZ->setIdentity(); | 879 toXYZ->setIdentity(); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 | 978 |
979 if (!g) { | 979 if (!g) { |
980 g = r ? r : b; | 980 g = r ? r : b; |
981 } | 981 } |
982 | 982 |
983 if (!b) { | 983 if (!b) { |
984 b = r ? r : g; | 984 b = r ? r : g; |
985 } | 985 } |
986 } | 986 } |
987 | 987 |
988 GammaNamed gammaNamed = kNonStandard_GammaNamed; | 988 SkGammaNamed gammaNamed = kNonStandard_SkGammaNamed; |
989 sk_sp<SkGammas> gammas = nullptr; | 989 sk_sp<SkGammas> gammas = nullptr; |
990 size_t tagBytes; | 990 size_t tagBytes; |
991 if (r && g && b) { | 991 if (r && g && b) { |
992 if (tag_equals(r, g, base) && tag_equals(g, b, base)) { | 992 if (tag_equals(r, g, base) && tag_equals(g, b, base)) { |
993 SkGammas::Data data; | 993 SkGammas::Data data; |
994 SkGammas::Params params; | 994 SkGammas::Params params; |
995 SkGammas::Type type = | 995 SkGammas::Type type = |
996 parse_gamma(&data, ¶ms, &tagBytes, r->addr(b
ase), r->fLength); | 996 parse_gamma(&data, ¶ms, &tagBytes, r->addr(b
ase), r->fLength); |
997 handle_invalid_gamma(&type, &data); | 997 handle_invalid_gamma(&type, &data); |
998 | 998 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 | 1055 |
1056 gammas->fBlueType = bType; | 1056 gammas->fBlueType = bType; |
1057 load_gammas(memory, offset, bType, &bData, bParams, b->a
ddr(base)); | 1057 load_gammas(memory, offset, bType, &bData, bParams, b->a
ddr(base)); |
1058 | 1058 |
1059 gammas->fRedData = rData; | 1059 gammas->fRedData = rData; |
1060 gammas->fGreenData = gData; | 1060 gammas->fGreenData = gData; |
1061 gammas->fBlueData = bData; | 1061 gammas->fBlueData = bData; |
1062 } | 1062 } |
1063 } else { | 1063 } else { |
1064 // Guess sRGB if the profile is missing transfer functions. | 1064 // Guess sRGB if the profile is missing transfer functions. |
1065 gammaNamed = kSRGB_GammaNamed; | 1065 gammaNamed = kSRGB_SkGammaNamed; |
1066 } | 1066 } |
1067 | 1067 |
1068 if (kNonStandard_GammaNamed == gammaNamed) { | 1068 if (kNonStandard_SkGammaNamed == gammaNamed) { |
1069 // It's possible that we'll initially detect non-matching ga
mmas, only for | 1069 // It's possible that we'll initially detect non-matching ga
mmas, only for |
1070 // them to evaluate to the same named gamma curve. | 1070 // them to evaluate to the same named gamma curve. |
1071 gammaNamed = is_named(gammas); | 1071 gammaNamed = is_named(gammas); |
1072 if (kNonStandard_GammaNamed == gammaNamed) { | 1072 if (kNonStandard_SkGammaNamed == gammaNamed) { |
1073 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr
, gammaNamed, | 1073 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr
, gammaNamed, |
1074 std::mo
ve(gammas), mat, | 1074 std::mo
ve(gammas), mat, |
1075 std::mo
ve(data))); | 1075 std::mo
ve(data))); |
1076 } | 1076 } |
1077 } | 1077 } |
1078 | 1078 |
1079 return SkColorSpace_Base::NewRGB(gammaNamed, mat); | 1079 return SkColorSpace_Base::NewRGB(gammaNamed, mat); |
1080 } | 1080 } |
1081 | 1081 |
1082 // Recognize color profile specified by A2B0 tag. | 1082 // Recognize color profile specified by A2B0 tag. |
1083 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); | 1083 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); |
1084 if (a2b0) { | 1084 if (a2b0) { |
1085 GammaNamed gammaNamed = kNonStandard_GammaNamed; | 1085 SkGammaNamed gammaNamed = kNonStandard_SkGammaNamed; |
1086 sk_sp<SkGammas> gammas = nullptr; | 1086 sk_sp<SkGammas> gammas = nullptr; |
1087 sk_sp<SkColorLookUpTable> colorLUT = nullptr; | 1087 sk_sp<SkColorLookUpTable> colorLUT = nullptr; |
1088 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); | 1088 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); |
1089 if (!load_a2b0(&colorLUT, &gammaNamed, &gammas, &toXYZ, a2b0->ad
dr(base), | 1089 if (!load_a2b0(&colorLUT, &gammaNamed, &gammas, &toXYZ, a2b0->ad
dr(base), |
1090 a2b0->fLength)) { | 1090 a2b0->fLength)) { |
1091 return_null("Failed to parse A2B0 tag"); | 1091 return_null("Failed to parse A2B0 tag"); |
1092 } | 1092 } |
1093 | 1093 |
1094 if (colorLUT || kNonStandard_GammaNamed == gammaNamed) { | 1094 if (colorLUT || kNonStandard_SkGammaNamed == gammaNamed) { |
1095 return sk_sp<SkColorSpace>(new SkColorSpace_Base(std::move(c
olorLUT), | 1095 return sk_sp<SkColorSpace>(new SkColorSpace_Base(std::move(c
olorLUT), |
1096 gammaNamed,
std::move(gammas), | 1096 gammaNamed,
std::move(gammas), |
1097 toXYZ, std:
:move(data))); | 1097 toXYZ, std:
:move(data))); |
1098 } | 1098 } |
1099 | 1099 |
1100 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZ); | 1100 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZ); |
1101 } | 1101 } |
1102 } | 1102 } |
1103 default: | 1103 default: |
1104 break; | 1104 break; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1270 | 1270 |
1271 // Write XYZ tags | 1271 // Write XYZ tags |
1272 write_xyz_tag((uint32_t*) ptr, fToXYZD50, 0); | 1272 write_xyz_tag((uint32_t*) ptr, fToXYZD50, 0); |
1273 ptr += kTAG_XYZ_Bytes; | 1273 ptr += kTAG_XYZ_Bytes; |
1274 write_xyz_tag((uint32_t*) ptr, fToXYZD50, 1); | 1274 write_xyz_tag((uint32_t*) ptr, fToXYZD50, 1); |
1275 ptr += kTAG_XYZ_Bytes; | 1275 ptr += kTAG_XYZ_Bytes; |
1276 write_xyz_tag((uint32_t*) ptr, fToXYZD50, 2); | 1276 write_xyz_tag((uint32_t*) ptr, fToXYZD50, 2); |
1277 ptr += kTAG_XYZ_Bytes; | 1277 ptr += kTAG_XYZ_Bytes; |
1278 | 1278 |
1279 // Write TRC tags | 1279 // Write TRC tags |
1280 GammaNamed gammaNamed = this->gammaNamed(); | 1280 SkGammaNamed gammaNamed = this->gammaNamed(); |
1281 if (kNonStandard_GammaNamed == gammaNamed) { | 1281 if (kNonStandard_SkGammaNamed == gammaNamed) { |
1282 // FIXME (msarett): | 1282 // FIXME (msarett): |
1283 // Write the correct gamma representation rather than 2.2f. | 1283 // Write the correct gamma representation rather than 2.2f. |
1284 write_trc_tag((uint32_t*) ptr, 2.2f); | 1284 write_trc_tag((uint32_t*) ptr, 2.2f); |
1285 ptr += SkAlign4(kTAG_TRC_Bytes); | 1285 ptr += SkAlign4(kTAG_TRC_Bytes); |
1286 write_trc_tag((uint32_t*) ptr, 2.2f); | 1286 write_trc_tag((uint32_t*) ptr, 2.2f); |
1287 ptr += SkAlign4(kTAG_TRC_Bytes); | 1287 ptr += SkAlign4(kTAG_TRC_Bytes); |
1288 write_trc_tag((uint32_t*) ptr, 2.2f); | 1288 write_trc_tag((uint32_t*) ptr, 2.2f); |
1289 ptr += SkAlign4(kTAG_TRC_Bytes); | 1289 ptr += SkAlign4(kTAG_TRC_Bytes); |
1290 } else { | 1290 } else { |
1291 switch (gammaNamed) { | 1291 switch (gammaNamed) { |
1292 case SkColorSpace::kSRGB_GammaNamed: | 1292 case kSRGB_SkGammaNamed: |
1293 // FIXME (msarett): | 1293 // FIXME (msarett): |
1294 // kSRGB cannot be represented by a value. Here we fall through
to 2.2f, | 1294 // kSRGB cannot be represented by a value. Here we fall through
to 2.2f, |
1295 // which is a close guess. To be more accurate, we need to repr
esent sRGB | 1295 // which is a close guess. To be more accurate, we need to repr
esent sRGB |
1296 // gamma with a parametric curve. | 1296 // gamma with a parametric curve. |
1297 case SkColorSpace::k2Dot2Curve_GammaNamed: | 1297 case k2Dot2Curve_SkGammaNamed: |
1298 write_trc_tag((uint32_t*) ptr, 2.2f); | 1298 write_trc_tag((uint32_t*) ptr, 2.2f); |
1299 ptr += SkAlign4(kTAG_TRC_Bytes); | 1299 ptr += SkAlign4(kTAG_TRC_Bytes); |
1300 write_trc_tag((uint32_t*) ptr, 2.2f); | 1300 write_trc_tag((uint32_t*) ptr, 2.2f); |
1301 ptr += SkAlign4(kTAG_TRC_Bytes); | 1301 ptr += SkAlign4(kTAG_TRC_Bytes); |
1302 write_trc_tag((uint32_t*) ptr, 2.2f); | 1302 write_trc_tag((uint32_t*) ptr, 2.2f); |
1303 ptr += SkAlign4(kTAG_TRC_Bytes); | 1303 ptr += SkAlign4(kTAG_TRC_Bytes); |
1304 break; | 1304 break; |
1305 case SkColorSpace::kLinear_GammaNamed: | 1305 case kLinear_SkGammaNamed: |
1306 write_trc_tag((uint32_t*) ptr, 1.0f); | 1306 write_trc_tag((uint32_t*) ptr, 1.0f); |
1307 ptr += SkAlign4(kTAG_TRC_Bytes); | 1307 ptr += SkAlign4(kTAG_TRC_Bytes); |
1308 write_trc_tag((uint32_t*) ptr, 1.0f); | 1308 write_trc_tag((uint32_t*) ptr, 1.0f); |
1309 ptr += SkAlign4(kTAG_TRC_Bytes); | 1309 ptr += SkAlign4(kTAG_TRC_Bytes); |
1310 write_trc_tag((uint32_t*) ptr, 1.0f); | 1310 write_trc_tag((uint32_t*) ptr, 1.0f); |
1311 ptr += SkAlign4(kTAG_TRC_Bytes); | 1311 ptr += SkAlign4(kTAG_TRC_Bytes); |
1312 break; | 1312 break; |
1313 default: | 1313 default: |
1314 SkASSERT(false); | 1314 SkASSERT(false); |
1315 break; | 1315 break; |
(...skipping 11 matching lines...) Expand all Loading... |
1327 ptr32[4] = SkEndian_SwapBE32(0x000116cc); | 1327 ptr32[4] = SkEndian_SwapBE32(0x000116cc); |
1328 ptr += kTAG_XYZ_Bytes; | 1328 ptr += kTAG_XYZ_Bytes; |
1329 | 1329 |
1330 // Write copyright tag | 1330 // Write copyright tag |
1331 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); | 1331 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); |
1332 | 1332 |
1333 // TODO (msarett): Should we try to hold onto the data so we can return imme
diately if | 1333 // TODO (msarett): Should we try to hold onto the data so we can return imme
diately if |
1334 // the client calls again? | 1334 // the client calls again? |
1335 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); | 1335 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); |
1336 } | 1336 } |
OLD | NEW |