OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 } | 64 } |
65 | 65 |
66 // This needs to be updated if we ever add a matches*Signature() which requires | 66 // This needs to be updated if we ever add a matches*Signature() which requires |
67 // more characters. | 67 // more characters. |
68 static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; | 68 static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; |
69 | 69 |
70 std::unique_ptr<ImageDecoder> ImageDecoder::create( | 70 std::unique_ptr<ImageDecoder> ImageDecoder::create( |
71 PassRefPtr<SegmentReader> passData, | 71 PassRefPtr<SegmentReader> passData, |
72 bool dataComplete, | 72 bool dataComplete, |
73 AlphaOption alphaOption, | 73 AlphaOption alphaOption, |
74 ColorSpaceOption colorOptions) { | 74 ColorSpaceOption colorOptions, |
| 75 sk_sp<SkColorSpace> targetColorSpace) { |
75 RefPtr<SegmentReader> data = passData; | 76 RefPtr<SegmentReader> data = passData; |
76 | 77 |
| 78 // Ensure that the color space options are consistent. |
| 79 if (colorOptions == ColorSpaceTransformed) |
| 80 DCHECK(targetColorSpace); |
| 81 else |
| 82 DCHECK(!targetColorSpace); |
| 83 |
77 // We need at least kLongestSignatureLength bytes to run the signature | 84 // We need at least kLongestSignatureLength bytes to run the signature |
78 // matcher. | 85 // matcher. |
79 if (data->size() < kLongestSignatureLength) | 86 if (data->size() < kLongestSignatureLength) |
80 return nullptr; | 87 return nullptr; |
81 | 88 |
82 const size_t maxDecodedBytes = | 89 const size_t maxDecodedBytes = |
83 Platform::current() ? Platform::current()->maxDecodedImageBytes() | 90 Platform::current() ? Platform::current()->maxDecodedImageBytes() |
84 : noDecodedImageByteLimit; | 91 : noDecodedImageByteLimit; |
85 | 92 |
86 // Access the first kLongestSignatureLength chars to sniff the signature. | 93 // Access the first kLongestSignatureLength chars to sniff the signature. |
87 // (note: FastSharedBufferReader only makes a copy if the bytes are segmented) | 94 // (note: FastSharedBufferReader only makes a copy if the bytes are segmented) |
88 char buffer[kLongestSignatureLength]; | 95 char buffer[kLongestSignatureLength]; |
89 const FastSharedBufferReader fastReader(data); | 96 const FastSharedBufferReader fastReader(data); |
90 const ImageDecoder::SniffResult sniffResult = determineImageType( | 97 const ImageDecoder::SniffResult sniffResult = determineImageType( |
91 fastReader.getConsecutiveData(0, kLongestSignatureLength, buffer), | 98 fastReader.getConsecutiveData(0, kLongestSignatureLength, buffer), |
92 kLongestSignatureLength); | 99 kLongestSignatureLength); |
93 | 100 |
94 std::unique_ptr<ImageDecoder> decoder; | 101 std::unique_ptr<ImageDecoder> decoder; |
95 switch (sniffResult) { | 102 switch (sniffResult) { |
96 case SniffResult::JPEG: | 103 case SniffResult::JPEG: |
97 decoder.reset( | 104 decoder.reset(new JPEGImageDecoder(alphaOption, colorOptions, |
98 new JPEGImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); | 105 std::move(targetColorSpace), |
| 106 maxDecodedBytes)); |
99 break; | 107 break; |
100 case SniffResult::PNG: | 108 case SniffResult::PNG: |
101 decoder.reset( | 109 decoder.reset(new PNGImageDecoder(alphaOption, colorOptions, |
102 new PNGImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); | 110 std::move(targetColorSpace), |
| 111 maxDecodedBytes)); |
103 break; | 112 break; |
104 case SniffResult::GIF: | 113 case SniffResult::GIF: |
105 decoder.reset( | 114 decoder.reset(new GIFImageDecoder(alphaOption, colorOptions, |
106 new GIFImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); | 115 std::move(targetColorSpace), |
| 116 maxDecodedBytes)); |
107 break; | 117 break; |
108 case SniffResult::WEBP: | 118 case SniffResult::WEBP: |
109 decoder.reset( | 119 decoder.reset(new WEBPImageDecoder(alphaOption, colorOptions, |
110 new WEBPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); | 120 std::move(targetColorSpace), |
| 121 maxDecodedBytes)); |
111 break; | 122 break; |
112 case SniffResult::ICO: | 123 case SniffResult::ICO: |
113 decoder.reset( | 124 decoder.reset(new ICOImageDecoder(alphaOption, colorOptions, |
114 new ICOImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); | 125 std::move(targetColorSpace), |
| 126 maxDecodedBytes)); |
115 break; | 127 break; |
116 case SniffResult::BMP: | 128 case SniffResult::BMP: |
117 decoder.reset( | 129 decoder.reset(new BMPImageDecoder(alphaOption, colorOptions, |
118 new BMPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); | 130 std::move(targetColorSpace), |
| 131 maxDecodedBytes)); |
119 break; | 132 break; |
120 case SniffResult::Invalid: | 133 case SniffResult::Invalid: |
121 break; | 134 break; |
122 } | 135 } |
123 | 136 |
124 if (decoder) { | 137 if (decoder) |
125 decoder->setData(data.release(), dataComplete); | 138 decoder->setData(data.release(), dataComplete); |
126 decoder->m_targetColorSpace = globalTargetColorSpace(); | |
127 } | |
128 | 139 |
129 return decoder; | 140 return decoder; |
130 } | 141 } |
131 | 142 |
132 bool ImageDecoder::hasSufficientDataToSniffImageType(const SharedBuffer& data) { | 143 bool ImageDecoder::hasSufficientDataToSniffImageType(const SharedBuffer& data) { |
133 return data.size() >= kLongestSignatureLength; | 144 return data.size() >= kLongestSignatureLength; |
134 } | 145 } |
135 | 146 |
136 ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents, | 147 ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents, |
137 size_t length) { | 148 size_t length) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; | 277 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; |
267 | 278 |
268 // If the frame is already initialized, return true. | 279 // If the frame is already initialized, return true. |
269 if (buffer->getStatus() != ImageFrame::FrameEmpty) | 280 if (buffer->getStatus() != ImageFrame::FrameEmpty) |
270 return true; | 281 return true; |
271 | 282 |
272 size_t requiredPreviousFrameIndex = buffer->requiredPreviousFrameIndex(); | 283 size_t requiredPreviousFrameIndex = buffer->requiredPreviousFrameIndex(); |
273 if (requiredPreviousFrameIndex == kNotFound) { | 284 if (requiredPreviousFrameIndex == kNotFound) { |
274 // This frame doesn't rely on any previous data. | 285 // This frame doesn't rely on any previous data. |
275 if (!buffer->setSizeAndColorSpace(size().width(), size().height(), | 286 if (!buffer->setSizeAndColorSpace(size().width(), size().height(), |
276 colorSpace())) { | 287 colorSpaceForSkImages())) { |
277 return setFailed(); | 288 return setFailed(); |
278 } | 289 } |
279 } else { | 290 } else { |
280 ImageFrame* const prevBuffer = | 291 ImageFrame* const prevBuffer = |
281 &m_frameBufferCache[requiredPreviousFrameIndex]; | 292 &m_frameBufferCache[requiredPreviousFrameIndex]; |
282 DCHECK(prevBuffer->getStatus() == ImageFrame::FrameComplete); | 293 DCHECK(prevBuffer->getStatus() == ImageFrame::FrameComplete); |
283 | 294 |
284 // We try to reuse |prevBuffer| as starting state to avoid copying. | 295 // We try to reuse |prevBuffer| as starting state to avoid copying. |
285 // If canReusePreviousFrameBuffer returns false, we must copy the data since | 296 // If canReusePreviousFrameBuffer returns false, we must copy the data since |
286 // |prevBuffer| is necessary to decode this or later frames. In that case, | 297 // |prevBuffer| is necessary to decode this or later frames. In that case, |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 // initialized. | 463 // initialized. |
453 if (!gTargetColorSpace) { | 464 if (!gTargetColorSpace) { |
454 gTargetColorSpace = | 465 gTargetColorSpace = |
455 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).release(); | 466 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).release(); |
456 } | 467 } |
457 | 468 |
458 gTargetColorSpace->ref(); | 469 gTargetColorSpace->ref(); |
459 return sk_sp<SkColorSpace>(gTargetColorSpace); | 470 return sk_sp<SkColorSpace>(gTargetColorSpace); |
460 } | 471 } |
461 | 472 |
462 sk_sp<SkColorSpace> ImageDecoder::colorSpace() const { | 473 // static |
463 // TODO(ccameron): This should always return a non-null SkColorSpace. This is | 474 sk_sp<SkColorSpace> ImageDecoder::targetColorSpaceForTesting() { |
464 // disabled for now because specifying a non-renderable color space results in | 475 return globalTargetColorSpace(); |
465 // errors. | 476 } |
466 // https://bugs.chromium.org/p/skia/issues/detail?id=5907 | 477 |
467 if (!RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) | 478 sk_sp<SkColorSpace> ImageDecoder::colorSpaceForSkImages() const { |
| 479 if (m_colorSpaceOption != ColorSpaceTagged) |
468 return nullptr; | 480 return nullptr; |
469 | 481 |
470 if (m_embeddedColorSpace) | 482 if (m_embeddedColorSpace) |
471 return m_embeddedColorSpace; | 483 return m_embeddedColorSpace; |
472 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); | 484 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); |
473 } | 485 } |
474 | 486 |
475 void ImageDecoder::setEmbeddedColorProfile(const char* iccData, | 487 void ImageDecoder::setEmbeddedColorProfile(const char* iccData, |
476 unsigned iccLength) { | 488 unsigned iccLength) { |
477 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(iccData, iccLength); | 489 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(iccData, iccLength); |
478 if (!colorSpace) | 490 if (!colorSpace) |
479 DLOG(ERROR) << "Failed to parse image ICC profile"; | 491 DLOG(ERROR) << "Failed to parse image ICC profile"; |
480 setEmbeddedColorSpace(std::move(colorSpace)); | 492 setEmbeddedColorSpace(std::move(colorSpace)); |
481 } | 493 } |
482 | 494 |
483 void ImageDecoder::setEmbeddedColorSpace(sk_sp<SkColorSpace> colorSpace) { | 495 void ImageDecoder::setEmbeddedColorSpace(sk_sp<SkColorSpace> colorSpace) { |
484 DCHECK(!m_ignoreColorSpace); | 496 DCHECK(!ignoresColorSpace()); |
485 DCHECK(!m_hasHistogrammedColorSpace); | 497 DCHECK(!m_hasHistogrammedColorSpace); |
486 | 498 |
487 m_embeddedColorSpace = colorSpace; | 499 m_embeddedColorSpace = colorSpace; |
488 m_sourceToTargetColorTransformNeedsUpdate = true; | 500 m_sourceToTargetColorTransformNeedsUpdate = true; |
489 } | 501 } |
490 | 502 |
491 SkColorSpaceXform* ImageDecoder::colorTransform() { | 503 SkColorSpaceXform* ImageDecoder::colorTransform() { |
492 if (!m_sourceToTargetColorTransformNeedsUpdate) | 504 if (!m_sourceToTargetColorTransformNeedsUpdate) |
493 return m_sourceToTargetColorTransform.get(); | 505 return m_sourceToTargetColorTransform.get(); |
494 m_sourceToTargetColorTransformNeedsUpdate = false; | 506 m_sourceToTargetColorTransformNeedsUpdate = false; |
(...skipping 12 matching lines...) Expand all Loading... |
507 m_targetColorSpace.get())) { | 519 m_targetColorSpace.get())) { |
508 return nullptr; | 520 return nullptr; |
509 } | 521 } |
510 | 522 |
511 m_sourceToTargetColorTransform = SkColorSpaceXform::New( | 523 m_sourceToTargetColorTransform = SkColorSpaceXform::New( |
512 m_embeddedColorSpace.get(), m_targetColorSpace.get()); | 524 m_embeddedColorSpace.get(), m_targetColorSpace.get()); |
513 return m_sourceToTargetColorTransform.get(); | 525 return m_sourceToTargetColorTransform.get(); |
514 } | 526 } |
515 | 527 |
516 } // namespace blink | 528 } // namespace blink |
OLD | NEW |