| 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 "SkAtomics.h" | 8 #include "SkAtomics.h" |
| 9 #include "SkColorSpace.h" | 9 #include "SkColorSpace.h" |
| 10 #include "SkColorSpacePriv.h" | 10 #include "SkColorSpacePriv.h" |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 switch (type) { | 355 switch (type) { |
| 356 case kTAG_CurveType: { | 356 case kTAG_CurveType: { |
| 357 uint32_t count = read_big_endian_uint(src + 8); | 357 uint32_t count = read_big_endian_uint(src + 8); |
| 358 tagBytes = 12 + count * 2; | 358 tagBytes = 12 + count * 2; |
| 359 if (0 == count) { | 359 if (0 == count) { |
| 360 // Some tags require a gamma curve, but the author doesn't a
ctually want | 360 // Some tags require a gamma curve, but the author doesn't a
ctually want |
| 361 // to transform the data. In this case, it is common to see
a curve with | 361 // to transform the data. In this case, it is common to see
a curve with |
| 362 // a count of 0. | 362 // a count of 0. |
| 363 gammas[i].fValue = 1.0f; | 363 gammas[i].fValue = 1.0f; |
| 364 break; | 364 break; |
| 365 } else if (len < 12 + 2 * count) { | 365 } else if (len < tagBytes) { |
| 366 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len)
; | 366 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len)
; |
| 367 return false; | 367 return false; |
| 368 } | 368 } |
| 369 | 369 |
| 370 const uint16_t* table = (const uint16_t*) (src + 12); | 370 const uint16_t* table = (const uint16_t*) (src + 12); |
| 371 if (1 == count) { | 371 if (1 == count) { |
| 372 // The table entry is the gamma (with a bias of 256). | 372 // The table entry is the gamma (with a bias of 256). |
| 373 uint16_t value = read_big_endian_short((const uint8_t*) tabl
e); | 373 uint16_t value = read_big_endian_short((const uint8_t*) tabl
e); |
| 374 gammas[i].fValue = value / 256.0f; | 374 gammas[i].fValue = value / 256.0f; |
| 375 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue)
; | 375 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue)
; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 // Otherwise, fill in the interpolation table. | 422 // Otherwise, fill in the interpolation table. |
| 423 gammas[i].fTableSize = count; | 423 gammas[i].fTableSize = count; |
| 424 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]); | 424 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]); |
| 425 for (uint32_t j = 0; j < count; j++) { | 425 for (uint32_t j = 0; j < count; j++) { |
| 426 gammas[i].fTable[j] = | 426 gammas[i].fTable[j] = |
| 427 (read_big_endian_short((const uint8_t*) &table[j]))
/ 65535.0f; | 427 (read_big_endian_short((const uint8_t*) &table[j]))
/ 65535.0f; |
| 428 } | 428 } |
| 429 break; | 429 break; |
| 430 } | 430 } |
| 431 case kTAG_ParaCurveType: | 431 case kTAG_ParaCurveType: |
| 432 // Guess 2.2f. | 432 // Determine the format of the parametric curve tag. |
| 433 // FIXME (msarett): Handle parametric curves. | 433 switch(read_big_endian_short(src + 8)) { |
| 434 SkColorSpacePrintf("parametric curve\n"); | 434 case 0: { |
| 435 gammas[i].fValue = 2.2f; | 435 tagBytes = 12 + 4; |
| 436 if (len < tagBytes) { |
| 437 SkColorSpacePrintf("gamma tag is too small (%d bytes
)", len); |
| 438 return false; |
| 439 } |
| 436 | 440 |
| 437 // Determine the size of the parametric curve tag. | 441 // Y = X^g |
| 438 switch(read_big_endian_short(src + 8)) { | 442 int32_t g = read_big_endian_int(src + 12); |
| 439 case 0: | 443 gammas[i].fValue = SkFixedToFloat(g); |
| 440 tagBytes = 12 + 4; | |
| 441 break; | 444 break; |
| 442 case 1: | 445 } |
| 446 |
| 447 // Here's where the real parametric gammas start. There are
many |
| 448 // permutations of the same equations. |
| 449 // |
| 450 // Y = (aX + b)^g + c for X >= d |
| 451 // Y = eX + f otherwise |
| 452 // |
| 453 // We will fill in with zeros as necessary to always match t
he above form. |
| 454 // Note that there is no need to actually write zero, since
the struct is |
| 455 // zero initialized. |
| 456 case 1: { |
| 443 tagBytes = 12 + 12; | 457 tagBytes = 12 + 12; |
| 458 if (len < tagBytes) { |
| 459 SkColorSpacePrintf("gamma tag is too small (%d bytes
)", len); |
| 460 return false; |
| 461 } |
| 462 |
| 463 // Y = (aX + b)^g for X >= -b/a |
| 464 // Y = 0 otherwise |
| 465 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src +
12)); |
| 466 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src +
16)); |
| 467 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src +
20)); |
| 468 gammas[i].fD = -gammas[i].fB / gammas[i].fA; |
| 444 break; | 469 break; |
| 470 } |
| 445 case 2: | 471 case 2: |
| 446 tagBytes = 12 + 16; | 472 tagBytes = 12 + 16; |
| 473 if (len < tagBytes) { |
| 474 SkColorSpacePrintf("gamma tag is too small (%d bytes
)", len); |
| 475 return false; |
| 476 } |
| 477 |
| 478 // Y = (aX + b)^g + c for X >= -b/a |
| 479 // Y = c otherwise |
| 480 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src +
12)); |
| 481 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src +
16)); |
| 482 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src +
20)); |
| 483 gammas[i].fC = SkFixedToFloat(read_big_endian_int(src +
24)); |
| 484 gammas[i].fD = -gammas[i].fB / gammas[i].fA; |
| 485 gammas[i].fF = gammas[i].fC; |
| 447 break; | 486 break; |
| 448 case 3: | 487 case 3: |
| 449 tagBytes = 12 + 20; | 488 tagBytes = 12 + 20; |
| 489 if (len < tagBytes) { |
| 490 SkColorSpacePrintf("gamma tag is too small (%d bytes
)", len); |
| 491 return false; |
| 492 } |
| 493 |
| 494 // Y = (aX + b)^g for X >= d |
| 495 // Y = cX otherwise |
| 496 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src +
12)); |
| 497 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src +
16)); |
| 498 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src +
20)); |
| 499 gammas[i].fD = SkFixedToFloat(read_big_endian_int(src +
28)); |
| 500 gammas[i].fE = SkFixedToFloat(read_big_endian_int(src +
24)); |
| 450 break; | 501 break; |
| 451 case 4: | 502 case 4: |
| 452 tagBytes = 12 + 28; | 503 tagBytes = 12 + 28; |
| 504 if (len < tagBytes) { |
| 505 SkColorSpacePrintf("gamma tag is too small (%d bytes
)", len); |
| 506 return false; |
| 507 } |
| 508 |
| 509 // Y = (aX + b)^g + c for X >= d |
| 510 // Y = eX + f otherwise |
| 511 // NOTE: The ICC spec writes "cX" instead of "eX" but I
think it's a typo. |
| 512 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src +
12)); |
| 513 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src +
16)); |
| 514 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src +
20)); |
| 515 gammas[i].fC = SkFixedToFloat(read_big_endian_int(src +
24)); |
| 516 gammas[i].fD = SkFixedToFloat(read_big_endian_int(src +
28)); |
| 517 gammas[i].fE = SkFixedToFloat(read_big_endian_int(src +
32)); |
| 518 gammas[i].fF = SkFixedToFloat(read_big_endian_int(src +
36)); |
| 453 break; | 519 break; |
| 454 default: | 520 default: |
| 455 SkColorSpacePrintf("Invalid parametric curve type\n"); | 521 SkColorSpacePrintf("Invalid parametric curve type\n"); |
| 456 return false; | 522 return false; |
| 457 } | 523 } |
| 458 break; | 524 break; |
| 459 default: | 525 default: |
| 460 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type); | 526 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type); |
| 461 return false; | 527 return false; |
| 462 } | 528 } |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 } | 808 } |
| 743 } | 809 } |
| 744 | 810 |
| 745 } | 811 } |
| 746 default: | 812 default: |
| 747 break; | 813 break; |
| 748 } | 814 } |
| 749 | 815 |
| 750 return_null("ICC profile contains unsupported colorspace"); | 816 return_null("ICC profile contains unsupported colorspace"); |
| 751 } | 817 } |
| OLD | NEW |