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