| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 return (index && (index < m_dirEntries.size())) ? m_dirEntries[index].m_size
: size(); | 78 return (index && (index < m_dirEntries.size())) ? m_dirEntries[index].m_size
: size(); |
| 79 } | 79 } |
| 80 | 80 |
| 81 bool ICOImageDecoder::setSize(unsigned width, unsigned height) | 81 bool ICOImageDecoder::setSize(unsigned width, unsigned height) |
| 82 { | 82 { |
| 83 // The size calculated inside the BMPImageReader had better match the one in | 83 // The size calculated inside the BMPImageReader had better match the one in |
| 84 // the icon directory. | 84 // the icon directory. |
| 85 return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntS
ize(width, height) == m_frameSize) || setFailed()); | 85 return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntS
ize(width, height) == m_frameSize) || setFailed()); |
| 86 } | 86 } |
| 87 | 87 |
| 88 bool ICOImageDecoder::frameIsCompleteAtIndex(size_t index) const | |
| 89 { | |
| 90 if (index >= m_dirEntries.size()) | |
| 91 return false; | |
| 92 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; | |
| 93 return (dirEntry.m_imageOffset + dirEntry.m_byteSize) <= m_data->size(); | |
| 94 } | |
| 95 | |
| 96 bool ICOImageDecoder::setFailed() | 88 bool ICOImageDecoder::setFailed() |
| 97 { | 89 { |
| 98 m_bmpReaders.clear(); | 90 m_bmpReaders.clear(); |
| 99 m_pngDecoders.clear(); | 91 m_pngDecoders.clear(); |
| 100 return ImageDecoder::setFailed(); | 92 return ImageDecoder::setFailed(); |
| 101 } | 93 } |
| 102 | 94 |
| 103 bool ICOImageDecoder::hotSpot(IntPoint& hotSpot) const | 95 bool ICOImageDecoder::hotSpot(IntPoint& hotSpot) const |
| 104 { | 96 { |
| 105 // When unspecified, the default frame is always frame 0. This is consistent
with | 97 // When unspecified, the default frame is always frame 0. This is consistent
with |
| (...skipping 17 matching lines...) Expand all Loading... |
| 123 { | 115 { |
| 124 // Larger icons are better. After that, higher bit-depth icons are better. | 116 // Larger icons are better. After that, higher bit-depth icons are better. |
| 125 const int aEntryArea = a.m_size.width() * a.m_size.height(); | 117 const int aEntryArea = a.m_size.width() * a.m_size.height(); |
| 126 const int bEntryArea = b.m_size.width() * b.m_size.height(); | 118 const int bEntryArea = b.m_size.width() * b.m_size.height(); |
| 127 return (aEntryArea == bEntryArea) ? (a.m_bitCount > b.m_bitCount) : (aEntryA
rea > bEntryArea); | 119 return (aEntryArea == bEntryArea) ? (a.m_bitCount > b.m_bitCount) : (aEntryA
rea > bEntryArea); |
| 128 } | 120 } |
| 129 | 121 |
| 130 size_t ICOImageDecoder::decodeFrameCount() | 122 size_t ICOImageDecoder::decodeFrameCount() |
| 131 { | 123 { |
| 132 decodeSize(); | 124 decodeSize(); |
| 133 | |
| 134 // Length of sequence of completely received frames. | |
| 135 for (size_t i = 0; i < m_dirEntries.size(); ++i) { | |
| 136 const IconDirectoryEntry& dirEntry = m_dirEntries[i]; | |
| 137 if ((dirEntry.m_imageOffset + dirEntry.m_byteSize) > m_data->size()) | |
| 138 return i; | |
| 139 } | |
| 140 return m_dirEntries.size(); | 125 return m_dirEntries.size(); |
| 141 } | 126 } |
| 142 | 127 |
| 143 void ICOImageDecoder::setDataForPNGDecoderAtIndex(size_t index) | 128 void ICOImageDecoder::setDataForPNGDecoderAtIndex(size_t index) |
| 144 { | 129 { |
| 145 if (!m_pngDecoders[index]) | 130 if (!m_pngDecoders[index]) |
| 146 return; | 131 return; |
| 147 | 132 |
| 148 m_pngDecoders[index]->setData(m_data.get(), isAllDataReceived()); | 133 m_pngDecoders[index]->setData(m_data.get(), isAllDataReceived()); |
| 149 } | 134 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 bool ICOImageDecoder::decodeAtIndex(size_t index) | 168 bool ICOImageDecoder::decodeAtIndex(size_t index) |
| 184 { | 169 { |
| 185 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); | 170 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); |
| 186 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; | 171 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; |
| 187 const ImageType imageType = imageTypeAtIndex(index); | 172 const ImageType imageType = imageTypeAtIndex(index); |
| 188 if (imageType == Unknown) | 173 if (imageType == Unknown) |
| 189 return false; // Not enough data to determine image type yet. | 174 return false; // Not enough data to determine image type yet. |
| 190 | 175 |
| 191 if (imageType == BMP) { | 176 if (imageType == BMP) { |
| 192 if (!m_bmpReaders[index]) { | 177 if (!m_bmpReaders[index]) { |
| 178 // We need to have already sized m_frameBufferCache before this, and |
| 179 // we must not resize it again later (see caution in frameCount()). |
| 180 ASSERT(m_frameBufferCache.size() == m_dirEntries.size()); |
| 193 m_bmpReaders[index] = adoptPtr(new BMPImageReader(this, dirEntry.m_i
mageOffset, 0, true)); | 181 m_bmpReaders[index] = adoptPtr(new BMPImageReader(this, dirEntry.m_i
mageOffset, 0, true)); |
| 194 m_bmpReaders[index]->setData(m_data.get()); | 182 m_bmpReaders[index]->setData(m_data.get()); |
| 183 m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); |
| 195 } | 184 } |
| 196 // Update the pointer to the buffer as it could change after | |
| 197 // m_frameBufferCache.resize(). | |
| 198 m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); | |
| 199 m_frameSize = dirEntry.m_size; | 185 m_frameSize = dirEntry.m_size; |
| 200 bool result = m_bmpReaders[index]->decodeBMP(false); | 186 bool result = m_bmpReaders[index]->decodeBMP(false); |
| 201 m_frameSize = IntSize(); | 187 m_frameSize = IntSize(); |
| 202 return result; | 188 return result; |
| 203 } | 189 } |
| 204 | 190 |
| 205 if (!m_pngDecoders[index]) { | 191 if (!m_pngDecoders[index]) { |
| 206 AlphaOption alphaOption = m_premultiplyAlpha ? AlphaPremultiplied : Alph
aNotPremultiplied; | 192 AlphaOption alphaOption = m_premultiplyAlpha ? AlphaPremultiplied : Alph
aNotPremultiplied; |
| 207 GammaAndColorProfileOption colorOptions = m_ignoreGammaAndColorProfile ?
GammaAndColorProfileIgnored : GammaAndColorProfileApplied; | 193 GammaAndColorProfileOption colorOptions = m_ignoreGammaAndColorProfile ?
GammaAndColorProfileIgnored : GammaAndColorProfileApplied; |
| 208 m_pngDecoders[index] = adoptPtr(new PNGImageDecoder(alphaOption, colorOp
tions, m_maxDecodedBytes, dirEntry.m_imageOffset)); | 194 m_pngDecoders[index] = adoptPtr(new PNGImageDecoder(alphaOption, colorOp
tions, m_maxDecodedBytes, dirEntry.m_imageOffset)); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 height = 256; | 273 height = 256; |
| 288 IconDirectoryEntry entry; | 274 IconDirectoryEntry entry; |
| 289 entry.m_size = IntSize(width, height); | 275 entry.m_size = IntSize(width, height); |
| 290 if (m_fileType == CURSOR) { | 276 if (m_fileType == CURSOR) { |
| 291 entry.m_bitCount = 0; | 277 entry.m_bitCount = 0; |
| 292 entry.m_hotSpot = IntPoint(readUint16(4), readUint16(6)); | 278 entry.m_hotSpot = IntPoint(readUint16(4), readUint16(6)); |
| 293 } else { | 279 } else { |
| 294 entry.m_bitCount = readUint16(6); | 280 entry.m_bitCount = readUint16(6); |
| 295 entry.m_hotSpot = IntPoint(); | 281 entry.m_hotSpot = IntPoint(); |
| 296 } | 282 } |
| 297 entry.m_byteSize = readUint32(8); | |
| 298 entry.m_imageOffset = readUint32(12); | 283 entry.m_imageOffset = readUint32(12); |
| 299 | 284 |
| 300 // Some icons don't have a bit depth, only a color count. Convert the | 285 // Some icons don't have a bit depth, only a color count. Convert the |
| 301 // color count to the minimum necessary bit depth. It doesn't matter if | 286 // color count to the minimum necessary bit depth. It doesn't matter if |
| 302 // this isn't quite what the bitmap info header says later, as we only use | 287 // this isn't quite what the bitmap info header says later, as we only use |
| 303 // this value to determine which icon entry is best. | 288 // this value to determine which icon entry is best. |
| 304 if (!entry.m_bitCount) { | 289 if (!entry.m_bitCount) { |
| 305 int colorCount = readUint8(2); | 290 int colorCount = readUint8(2); |
| 306 if (!colorCount) | 291 if (!colorCount) |
| 307 colorCount = 256; // Vague in the spec, needed by real-world icons. | 292 colorCount = 256; // Vague in the spec, needed by real-world icons. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 320 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); | 305 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); |
| 321 const uint32_t imageOffset = m_dirEntries[index].m_imageOffset; | 306 const uint32_t imageOffset = m_dirEntries[index].m_imageOffset; |
| 322 if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4)) | 307 if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4)) |
| 323 return Unknown; | 308 return Unknown; |
| 324 char buffer[4]; | 309 char buffer[4]; |
| 325 const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer); | 310 const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer); |
| 326 return strncmp(data, "\x89PNG", 4) ? BMP : PNG; | 311 return strncmp(data, "\x89PNG", 4) ? BMP : PNG; |
| 327 } | 312 } |
| 328 | 313 |
| 329 } // namespace blink | 314 } // namespace blink |
| OLD | NEW |