| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 inline bool matchesCURSignature(const char* contents) | 76 inline bool matchesCURSignature(const char* contents) |
| 77 { | 77 { |
| 78 return !memcmp(contents, "\x00\x00\x02\x00", 4); | 78 return !memcmp(contents, "\x00\x00\x02\x00", 4); |
| 79 } | 79 } |
| 80 | 80 |
| 81 inline bool matchesBMPSignature(const char* contents) | 81 inline bool matchesBMPSignature(const char* contents) |
| 82 { | 82 { |
| 83 return !memcmp(contents, "BM", 2); | 83 return !memcmp(contents, "BM", 2); |
| 84 } | 84 } |
| 85 | 85 |
| 86 std::unique_ptr<ImageDecoder> ImageDecoder::create(SniffResult sniffResult, Alph
aOption alphaOption, GammaAndColorProfileOption colorOptions) | 86 // This needs to be updated if we ever add a matches*Signature() which requires
more characters. |
| 87 static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; |
| 88 |
| 89 std::unique_ptr<ImageDecoder> ImageDecoder::create(PassRefPtr<SegmentReader> pas
sData, bool dataComplete, |
| 90 AlphaOption alphaOption, GammaAndColorProfileOption colorOptions) |
| 87 { | 91 { |
| 88 size_t maxDecodedBytes = Platform::current() ? Platform::current()->maxDecod
edImageBytes() : noDecodedImageByteLimit; | 92 RefPtr<SegmentReader> data = passData; |
| 89 | 93 |
| 94 // We need at least kLongestSignatureLength bytes to run the signature match
er. |
| 95 if (data->size() < kLongestSignatureLength) |
| 96 return nullptr; |
| 97 |
| 98 const size_t maxDecodedBytes = Platform::current() |
| 99 ? Platform::current()->maxDecodedImageBytes() |
| 100 : noDecodedImageByteLimit; |
| 101 |
| 102 // Access the first kLongestSignatureLength chars to sniff the signature. |
| 103 // (note: FastSharedBufferReader only makes a copy if the bytes are segmente
d) |
| 104 char buffer[kLongestSignatureLength]; |
| 105 const FastSharedBufferReader fastReader(data); |
| 106 const ImageDecoder::SniffResult sniffResult = determineImageType( |
| 107 fastReader.getConsecutiveData(0, kLongestSignatureLength, buffer), kLong
estSignatureLength); |
| 108 |
| 109 std::unique_ptr<ImageDecoder> decoder; |
| 90 switch (sniffResult) { | 110 switch (sniffResult) { |
| 91 case SniffResult::JPEG: | 111 case SniffResult::JPEG: |
| 92 return wrapUnique(new JPEGImageDecoder(alphaOption, colorOptions, maxDec
odedBytes)); | 112 decoder.reset(new JPEGImageDecoder(alphaOption, colorOptions, maxDecoded
Bytes)); |
| 113 break; |
| 93 case SniffResult::PNG: | 114 case SniffResult::PNG: |
| 94 return wrapUnique(new PNGImageDecoder(alphaOption, colorOptions, maxDeco
dedBytes)); | 115 decoder.reset(new PNGImageDecoder(alphaOption, colorOptions, maxDecodedB
ytes)); |
| 116 break; |
| 95 case SniffResult::GIF: | 117 case SniffResult::GIF: |
| 96 return wrapUnique(new GIFImageDecoder(alphaOption, colorOptions, maxDeco
dedBytes)); | 118 decoder.reset(new GIFImageDecoder(alphaOption, colorOptions, maxDecodedB
ytes)); |
| 119 break; |
| 97 case SniffResult::WEBP: | 120 case SniffResult::WEBP: |
| 98 return wrapUnique(new WEBPImageDecoder(alphaOption, colorOptions, maxDec
odedBytes)); | 121 decoder.reset(new WEBPImageDecoder(alphaOption, colorOptions, maxDecoded
Bytes)); |
| 122 break; |
| 99 case SniffResult::ICO: | 123 case SniffResult::ICO: |
| 100 return wrapUnique(new ICOImageDecoder(alphaOption, colorOptions, maxDeco
dedBytes)); | 124 decoder.reset(new ICOImageDecoder(alphaOption, colorOptions, maxDecodedB
ytes)); |
| 125 break; |
| 101 case SniffResult::BMP: | 126 case SniffResult::BMP: |
| 102 return wrapUnique(new BMPImageDecoder(alphaOption, colorOptions, maxDeco
dedBytes)); | 127 decoder.reset(new BMPImageDecoder(alphaOption, colorOptions, maxDecodedB
ytes)); |
| 103 case SniffResult::InsufficientData: | 128 break; |
| 104 case SniffResult::Invalid: | 129 case SniffResult::Invalid: |
| 105 return nullptr; | 130 break; |
| 106 } | 131 } |
| 107 NOTREACHED(); | 132 |
| 108 return nullptr; | 133 if (decoder) |
| 134 decoder->setData(data.release(), dataComplete); |
| 135 |
| 136 return decoder; |
| 109 } | 137 } |
| 110 | 138 |
| 111 namespace { | 139 bool ImageDecoder::hasSufficientDataToSniffImageType(const SharedBuffer& data) |
| 112 | 140 { |
| 113 // This needs to be updated if we ever add a matches*Signature() which requires
more characters. | 141 return data.size() >= kLongestSignatureLength; |
| 114 constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; | 142 } |
| 115 | |
| 116 } // anonymous ns | |
| 117 | 143 |
| 118 ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents,
size_t length) | 144 ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents,
size_t length) |
| 119 { | 145 { |
| 120 if (length < kLongestSignatureLength) | 146 DCHECK_GE(length, kLongestSignatureLength); |
| 121 return SniffResult::InsufficientData; | 147 |
| 122 if (matchesJPEGSignature(contents)) | 148 if (matchesJPEGSignature(contents)) |
| 123 return SniffResult::JPEG; | 149 return SniffResult::JPEG; |
| 124 if (matchesPNGSignature(contents)) | 150 if (matchesPNGSignature(contents)) |
| 125 return SniffResult::PNG; | 151 return SniffResult::PNG; |
| 126 if (matchesGIFSignature(contents)) | 152 if (matchesGIFSignature(contents)) |
| 127 return SniffResult::GIF; | 153 return SniffResult::GIF; |
| 128 if (matchesWebPSignature(contents)) | 154 if (matchesWebPSignature(contents)) |
| 129 return SniffResult::WEBP; | 155 return SniffResult::WEBP; |
| 130 if (matchesICOSignature(contents) || matchesCURSignature(contents)) | 156 if (matchesICOSignature(contents) || matchesCURSignature(contents)) |
| 131 return SniffResult::ICO; | 157 return SniffResult::ICO; |
| 132 if (matchesBMPSignature(contents)) | 158 if (matchesBMPSignature(contents)) |
| 133 return SniffResult::BMP; | 159 return SniffResult::BMP; |
| 134 return SniffResult::Invalid; | 160 return SniffResult::Invalid; |
| 135 } | 161 } |
| 136 | 162 |
| 137 ImageDecoder::SniffResult ImageDecoder::determineImageType(const SharedBuffer& d
ata) | |
| 138 { | |
| 139 // TODO(fmalita): refactor the method signature to avoid casting. | |
| 140 RefPtr<SegmentReader> reader = SegmentReader::createFromSharedBuffer(const_c
ast<SharedBuffer*>(&data)); | |
| 141 | |
| 142 return determineImageType(*reader); | |
| 143 } | |
| 144 | |
| 145 ImageDecoder::SniffResult ImageDecoder::determineImageType(const SegmentReader&
data) | |
| 146 { | |
| 147 // TODO(fmalita): refactor the method signature to avoid casting. | |
| 148 const FastSharedBufferReader fastReader(const_cast<SegmentReader*>(&data)); | |
| 149 char buffer[kLongestSignatureLength]; | |
| 150 const size_t len = std::min(kLongestSignatureLength, data.size()); | |
| 151 | |
| 152 return determineImageType(fastReader.getConsecutiveData(0, len, buffer), len
); | |
| 153 } | |
| 154 | |
| 155 size_t ImageDecoder::frameCount() | 163 size_t ImageDecoder::frameCount() |
| 156 { | 164 { |
| 157 const size_t oldSize = m_frameBufferCache.size(); | 165 const size_t oldSize = m_frameBufferCache.size(); |
| 158 const size_t newSize = decodeFrameCount(); | 166 const size_t newSize = decodeFrameCount(); |
| 159 if (oldSize != newSize) { | 167 if (oldSize != newSize) { |
| 160 m_frameBufferCache.resize(newSize); | 168 m_frameBufferCache.resize(newSize); |
| 161 for (size_t i = oldSize; i < newSize; ++i) { | 169 for (size_t i = oldSize; i < newSize; ++i) { |
| 162 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); | 170 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); |
| 163 initializeNewFrame(i); | 171 initializeNewFrame(i); |
| 164 } | 172 } |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 return; | 422 return; |
| 415 | 423 |
| 416 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8; | 424 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8; |
| 417 | 425 |
| 418 // FIXME: Don't force perceptual intent if the image profile contains an int
ent. | 426 // FIXME: Don't force perceptual intent if the image profile contains an int
ent. |
| 419 m_sourceToOutputDeviceColorTransform.reset(qcms_transform_create(inputProfil
e.get(), dataFormat, gTargetColorProfile, QCMS_DATA_RGBA_8, QCMS_INTENT_PERCEPTU
AL)); | 427 m_sourceToOutputDeviceColorTransform.reset(qcms_transform_create(inputProfil
e.get(), dataFormat, gTargetColorProfile, QCMS_DATA_RGBA_8, QCMS_INTENT_PERCEPTU
AL)); |
| 420 #endif // USE(QCMSLIB) | 428 #endif // USE(QCMSLIB) |
| 421 } | 429 } |
| 422 | 430 |
| 423 } // namespace blink | 431 } // namespace blink |
| OLD | NEW |