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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp

Issue 2523943002: Explicitly specify target color space to ImageDecoder at creation (Closed)
Patch Set: Rebase Created 4 years 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
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698