Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 return (index && (index < m_dirEntries.size())) ? m_dirEntries[index].m_size : size(); | 76 return (index && (index < m_dirEntries.size())) ? m_dirEntries[index].m_size : size(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 bool ICOImageDecoder::setSize(unsigned width, unsigned height) | 79 bool ICOImageDecoder::setSize(unsigned width, unsigned height) |
| 80 { | 80 { |
| 81 // The size calculated inside the BMPImageReader had better match the one in | 81 // The size calculated inside the BMPImageReader had better match the one in |
| 82 // the icon directory. | 82 // the icon directory. |
| 83 return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntS ize(width, height) == m_frameSize) || setFailed()); | 83 return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntS ize(width, height) == m_frameSize) || setFailed()); |
| 84 } | 84 } |
| 85 | 85 |
| 86 bool ICOImageDecoder::frameIsCompleteAtIndex(size_t index) const | |
| 87 { | |
| 88 if (index >= m_dirEntries.size()) | |
| 89 return false; | |
| 90 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; | |
| 91 return (dirEntry.m_imageOffset + dirEntry.m_byteSize) <= m_data->size(); | |
| 92 } | |
| 93 | |
| 86 bool ICOImageDecoder::setFailed() | 94 bool ICOImageDecoder::setFailed() |
| 87 { | 95 { |
| 88 m_bmpReaders.clear(); | 96 m_bmpReaders.clear(); |
| 89 m_pngDecoders.clear(); | 97 m_pngDecoders.clear(); |
| 90 return ImageDecoder::setFailed(); | 98 return ImageDecoder::setFailed(); |
| 91 } | 99 } |
| 92 | 100 |
| 93 bool ICOImageDecoder::hotSpot(IntPoint& hotSpot) const | 101 bool ICOImageDecoder::hotSpot(IntPoint& hotSpot) const |
| 94 { | 102 { |
| 95 // When unspecified, the default frame is always frame 0. This is consistent with | 103 // When unspecified, the default frame is always frame 0. This is consistent with |
| 96 // BitmapImage where currentFrame() starts at 0 and only increases when anim ation is | 104 // BitmapImage where currentFrame() starts at 0 and only increases when anim ation is |
| 97 // requested. | 105 // requested. |
| 98 return hotSpotAtIndex(0, hotSpot); | 106 return hotSpotAtIndex(0, hotSpot); |
| 99 } | 107 } |
| 100 | 108 |
| 101 bool ICOImageDecoder::hotSpotAtIndex(size_t index, IntPoint& hotSpot) const | 109 bool ICOImageDecoder::hotSpotAtIndex(size_t index, IntPoint& hotSpot) const |
| 102 { | 110 { |
| 103 if (index >= m_dirEntries.size() || m_fileType != CURSOR) | 111 if (index >= m_dirEntries.size() || m_fileType != CURSOR) |
| 104 return false; | 112 return false; |
| 105 | 113 |
| 106 hotSpot = m_dirEntries[index].m_hotSpot; | 114 hotSpot = m_dirEntries[index].m_hotSpot; |
| 107 return true; | 115 return true; |
| 108 } | 116 } |
| 109 | 117 |
| 110 | |
|
Peter Kasting
2016/06/08 23:16:13
Nit: Don't remove this
aleksandar.stojiljkovic
2016/06/09 20:34:07
Done.
| |
| 111 // static | 118 // static |
| 112 bool ICOImageDecoder::compareEntries(const IconDirectoryEntry& a, const IconDire ctoryEntry& b) | 119 bool ICOImageDecoder::compareEntries(const IconDirectoryEntry& a, const IconDire ctoryEntry& b) |
| 113 { | 120 { |
| 114 // Larger icons are better. After that, higher bit-depth icons are better. | 121 // Larger icons are better. After that, higher bit-depth icons are better. |
| 115 const int aEntryArea = a.m_size.width() * a.m_size.height(); | 122 const int aEntryArea = a.m_size.width() * a.m_size.height(); |
| 116 const int bEntryArea = b.m_size.width() * b.m_size.height(); | 123 const int bEntryArea = b.m_size.width() * b.m_size.height(); |
| 117 return (aEntryArea == bEntryArea) ? (a.m_bitCount > b.m_bitCount) : (aEntryA rea > bEntryArea); | 124 return (aEntryArea == bEntryArea) ? (a.m_bitCount > b.m_bitCount) : (aEntryA rea > bEntryArea); |
| 118 } | 125 } |
| 119 | 126 |
| 120 size_t ICOImageDecoder::decodeFrameCount() | 127 size_t ICOImageDecoder::decodeFrameCount() |
| 121 { | 128 { |
| 122 decodeSize(); | 129 decodeSize(); |
| 130 | |
| 131 // Length of sequence of completely received frames. | |
| 132 for (size_t i = 0; i < m_dirEntries.size(); ++i) { | |
| 133 const IconDirectoryEntry& dirEntry = m_dirEntries[i]; | |
| 134 if ((dirEntry.m_imageOffset + dirEntry.m_byteSize) > m_data->size()) | |
| 135 return i; | |
| 136 } | |
| 123 return m_dirEntries.size(); | 137 return m_dirEntries.size(); |
| 124 } | 138 } |
| 125 | 139 |
| 126 void ICOImageDecoder::setDataForPNGDecoderAtIndex(size_t index) | 140 void ICOImageDecoder::setDataForPNGDecoderAtIndex(size_t index) |
| 127 { | 141 { |
| 128 if (!m_pngDecoders[index]) | 142 if (!m_pngDecoders[index]) |
| 129 return; | 143 return; |
| 130 | 144 |
| 131 m_pngDecoders[index]->setData(m_data.get(), isAllDataReceived()); | 145 m_pngDecoders[index]->setData(m_data.get(), isAllDataReceived()); |
| 132 } | 146 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 bool ICOImageDecoder::decodeAtIndex(size_t index) | 180 bool ICOImageDecoder::decodeAtIndex(size_t index) |
| 167 { | 181 { |
| 168 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); | 182 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); |
| 169 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; | 183 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; |
| 170 const ImageType imageType = imageTypeAtIndex(index); | 184 const ImageType imageType = imageTypeAtIndex(index); |
| 171 if (imageType == Unknown) | 185 if (imageType == Unknown) |
| 172 return false; // Not enough data to determine image type yet. | 186 return false; // Not enough data to determine image type yet. |
| 173 | 187 |
| 174 if (imageType == BMP) { | 188 if (imageType == BMP) { |
| 175 if (!m_bmpReaders[index]) { | 189 if (!m_bmpReaders[index]) { |
| 176 // We need to have already sized m_frameBufferCache before this, and | |
| 177 // we must not resize it again later (see caution in frameCount()). | |
| 178 ASSERT(m_frameBufferCache.size() == m_dirEntries.size()); | |
| 179 m_bmpReaders[index] = adoptPtr(new BMPImageReader(this, dirEntry.m_i mageOffset, 0, true)); | 190 m_bmpReaders[index] = adoptPtr(new BMPImageReader(this, dirEntry.m_i mageOffset, 0, true)); |
| 180 m_bmpReaders[index]->setData(m_data.get()); | 191 m_bmpReaders[index]->setData(m_data.get()); |
| 181 m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); | |
| 182 } | 192 } |
| 193 // Update the pointer to the buffer as it could change after | |
| 194 // m_frameBufferCache.resize(). | |
| 195 m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); | |
| 183 m_frameSize = dirEntry.m_size; | 196 m_frameSize = dirEntry.m_size; |
| 184 bool result = m_bmpReaders[index]->decodeBMP(false); | 197 bool result = m_bmpReaders[index]->decodeBMP(false); |
| 185 m_frameSize = IntSize(); | 198 m_frameSize = IntSize(); |
| 186 return result; | 199 return result; |
| 187 } | 200 } |
| 188 | 201 |
| 189 if (!m_pngDecoders[index]) { | 202 if (!m_pngDecoders[index]) { |
| 190 AlphaOption alphaOption = m_premultiplyAlpha ? AlphaPremultiplied : Alph aNotPremultiplied; | 203 AlphaOption alphaOption = m_premultiplyAlpha ? AlphaPremultiplied : Alph aNotPremultiplied; |
| 191 GammaAndColorProfileOption colorOptions = m_ignoreGammaAndColorProfile ? GammaAndColorProfileIgnored : GammaAndColorProfileApplied; | 204 GammaAndColorProfileOption colorOptions = m_ignoreGammaAndColorProfile ? GammaAndColorProfileIgnored : GammaAndColorProfileApplied; |
| 192 m_pngDecoders[index] = adoptPtr(new PNGImageDecoder(alphaOption, colorOp tions, m_maxDecodedBytes, dirEntry.m_imageOffset)); | 205 m_pngDecoders[index] = adoptPtr(new PNGImageDecoder(alphaOption, colorOp tions, m_maxDecodedBytes, dirEntry.m_imageOffset)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 height = 256; | 279 height = 256; |
| 267 IconDirectoryEntry entry; | 280 IconDirectoryEntry entry; |
| 268 entry.m_size = IntSize(width, height); | 281 entry.m_size = IntSize(width, height); |
| 269 if (m_fileType == CURSOR) { | 282 if (m_fileType == CURSOR) { |
| 270 entry.m_bitCount = 0; | 283 entry.m_bitCount = 0; |
| 271 entry.m_hotSpot = IntPoint(readUint16(4), readUint16(6)); | 284 entry.m_hotSpot = IntPoint(readUint16(4), readUint16(6)); |
| 272 } else { | 285 } else { |
| 273 entry.m_bitCount = readUint16(6); | 286 entry.m_bitCount = readUint16(6); |
| 274 entry.m_hotSpot = IntPoint(); | 287 entry.m_hotSpot = IntPoint(); |
| 275 } | 288 } |
| 289 entry.m_byteSize = readUint32(8); | |
| 276 entry.m_imageOffset = readUint32(12); | 290 entry.m_imageOffset = readUint32(12); |
| 277 | 291 |
| 278 // Some icons don't have a bit depth, only a color count. Convert the | 292 // Some icons don't have a bit depth, only a color count. Convert the |
| 279 // color count to the minimum necessary bit depth. It doesn't matter if | 293 // color count to the minimum necessary bit depth. It doesn't matter if |
| 280 // this isn't quite what the bitmap info header says later, as we only use | 294 // this isn't quite what the bitmap info header says later, as we only use |
| 281 // this value to determine which icon entry is best. | 295 // this value to determine which icon entry is best. |
| 282 if (!entry.m_bitCount) { | 296 if (!entry.m_bitCount) { |
| 283 int colorCount = readUint8(2); | 297 int colorCount = readUint8(2); |
| 284 if (!colorCount) | 298 if (!colorCount) |
| 285 colorCount = 256; // Vague in the spec, needed by real-world icons. | 299 colorCount = 256; // Vague in the spec, needed by real-world icons. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 298 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); | 312 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); |
| 299 const uint32_t imageOffset = m_dirEntries[index].m_imageOffset; | 313 const uint32_t imageOffset = m_dirEntries[index].m_imageOffset; |
| 300 if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4)) | 314 if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4)) |
| 301 return Unknown; | 315 return Unknown; |
| 302 char buffer[4]; | 316 char buffer[4]; |
| 303 const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer); | 317 const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer); |
| 304 return strncmp(data, "\x89PNG", 4) ? BMP : PNG; | 318 return strncmp(data, "\x89PNG", 4) ? BMP : PNG; |
| 305 } | 319 } |
| 306 | 320 |
| 307 } // namespace blink | 321 } // namespace blink |
| OLD | NEW |