Chromium Code Reviews| Index: third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp |
| diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp |
| index edf80d2fbbe5c151122cfbd9b8d4e7d5e5a82c46..96e83ac56c78ec7c3505884006ace8c79b1e6a53 100644 |
| --- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp |
| +++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp |
| @@ -83,42 +83,68 @@ inline bool matchesBMPSignature(const char* contents) |
| return !memcmp(contents, "BM", 2); |
| } |
| -std::unique_ptr<ImageDecoder> ImageDecoder::create(SniffResult sniffResult, AlphaOption alphaOption, GammaAndColorProfileOption colorOptions) |
| +// This needs to be updated if we ever add a matches*Signature() which requires more characters. |
| +static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; |
| + |
| +std::unique_ptr<ImageDecoder> ImageDecoder::create(PassRefPtr<SegmentReader> passData, bool dataComplete, |
| + AlphaOption alphaOption, GammaAndColorProfileOption colorOptions) |
| { |
| - size_t maxDecodedBytes = Platform::current() ? Platform::current()->maxDecodedImageBytes() : noDecodedImageByteLimit; |
| + RefPtr<SegmentReader> data = passData; |
| + |
| + // We need at least kLongestSignatureLength bytes to run the signature matcher. |
| + if (data->size() < kLongestSignatureLength) |
| + return nullptr; |
| + |
| + const size_t maxDecodedBytes = Platform::current() |
| + ? Platform::current()->maxDecodedImageBytes() |
| + : noDecodedImageByteLimit; |
| + |
| + // Access the first kLongestSignatureLength chars to sniff the signature. |
| + // (note: FastSharedBufferReader only makes a copy if the bytes are segmented) |
| + char buffer[kLongestSignatureLength]; |
| + const FastSharedBufferReader fastReader(data); |
| + const ImageDecoder::SniffResult sniffResult = determineImageType( |
| + fastReader.getConsecutiveData(0, kLongestSignatureLength, buffer), kLongestSignatureLength); |
| + std::unique_ptr<ImageDecoder> decoder; |
| switch (sniffResult) { |
| case SniffResult::JPEG: |
| - return wrapUnique(new JPEGImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + decoder = wrapUnique(new JPEGImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
|
Peter Kasting
2016/08/19 23:04:58
Nit: Do these wrapUnique() calls buy us anything a
f(malita)
2016/08/22 01:51:15
There's an assert in there that we're not trying t
|
| + break; |
| case SniffResult::PNG: |
| - return wrapUnique(new PNGImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + decoder = wrapUnique(new PNGImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + break; |
| case SniffResult::GIF: |
| - return wrapUnique(new GIFImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + decoder = wrapUnique(new GIFImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + break; |
| case SniffResult::WEBP: |
| - return wrapUnique(new WEBPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + decoder = wrapUnique(new WEBPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + break; |
| case SniffResult::ICO: |
| - return wrapUnique(new ICOImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + decoder = wrapUnique(new ICOImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + break; |
| case SniffResult::BMP: |
| - return wrapUnique(new BMPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| - case SniffResult::InsufficientData: |
| + decoder = wrapUnique(new BMPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); |
| + break; |
| case SniffResult::Invalid: |
| - return nullptr; |
| + break; |
| } |
| - NOTREACHED(); |
| - return nullptr; |
| -} |
| -namespace { |
| + if (decoder) |
| + decoder->setData(data.release(), dataComplete); |
| -// This needs to be updated if we ever add a matches*Signature() which requires more characters. |
| -constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; |
| + return decoder; |
| +} |
| -} // anonymous ns |
| +bool ImageDecoder::isSufficientData(const SharedBuffer& data) |
| +{ |
| + return data.size() >= kLongestSignatureLength; |
| +} |
| ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents, size_t length) |
| { |
| - if (length < kLongestSignatureLength) |
| - return SniffResult::InsufficientData; |
| + DCHECK_GE(length, kLongestSignatureLength); |
| + |
| if (matchesJPEGSignature(contents)) |
| return SniffResult::JPEG; |
| if (matchesPNGSignature(contents)) |
| @@ -134,24 +160,6 @@ ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents, |
| return SniffResult::Invalid; |
| } |
| -ImageDecoder::SniffResult ImageDecoder::determineImageType(const SharedBuffer& data) |
| -{ |
| - // TODO(fmalita): refactor the method signature to avoid casting. |
| - RefPtr<SegmentReader> reader = SegmentReader::createFromSharedBuffer(const_cast<SharedBuffer*>(&data)); |
| - |
| - return determineImageType(*reader); |
| -} |
| - |
| -ImageDecoder::SniffResult ImageDecoder::determineImageType(const SegmentReader& data) |
| -{ |
| - // TODO(fmalita): refactor the method signature to avoid casting. |
| - const FastSharedBufferReader fastReader(const_cast<SegmentReader*>(&data)); |
| - char buffer[kLongestSignatureLength]; |
| - const size_t len = std::min(kLongestSignatureLength, data.size()); |
| - |
| - return determineImageType(fastReader.getConsecutiveData(0, len, buffer), len); |
| -} |
| - |
| size_t ImageDecoder::frameCount() |
| { |
| const size_t oldSize = m_frameBufferCache.size(); |