- Timestamp:
- 02/18/10 13:55:47 (7 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/BAL/ImageDecoder/WebCore/ICO/WK/BCICOImageDecoderWK.cpp
r1126 r1380 46 46 47 47 ICOImageDecoder::ICOImageDecoder() 48 : ImageDecoder() 49 , m_allDataReceived(false) 50 , m_decodedOffset(0) 48 : m_decodedOffset(0) 49 { 50 } 51 52 ICOImageDecoder::~ICOImageDecoder() 51 53 { 52 54 } … … 58 60 59 61 ImageDecoder::setData(data, allDataReceived); 60 m_allDataReceived = allDataReceived; 61 62 for (BMPReaders::iterator i(m_bmpReaders.begin()); 63 i != m_bmpReaders.end(); ++i) { 62 63 for (BMPReaders::iterator i(m_bmpReaders.begin()); i != m_bmpReaders.end(); ++i) { 64 64 if (*i) 65 65 (*i)->setData(data); … … 72 72 { 73 73 if (!ImageDecoder::isSizeAvailable()) 74 decode WithCheckForDataEnded(0, true);74 decode(0, true); 75 75 76 76 return ImageDecoder::isSizeAvailable(); … … 84 84 IntSize ICOImageDecoder::frameSizeAtIndex(size_t index) const 85 85 { 86 return (index && (index < m_dirEntries.size())) ? 87 m_dirEntries[index].m_size : size(); 86 return (index && (index < m_dirEntries.size())) ? m_dirEntries[index].m_size : size(); 88 87 } 89 88 … … 102 101 size_t ICOImageDecoder::frameCount() 103 102 { 104 decode WithCheckForDataEnded(0, true);103 decode(0, true); 105 104 if (m_frameBufferCache.isEmpty()) 106 105 m_frameBufferCache.resize(m_dirEntries.size()); … … 118 117 119 118 // Determine the image type, and if this is a BMP, decode. 120 decode WithCheckForDataEnded(index, false);119 decode(index, false); 121 120 122 121 // PNGs decode into their own framebuffers, so only use our internal cache … … 140 139 141 140 // static 142 bool ICOImageDecoder::compareEntries(const IconDirectoryEntry& a, 143 const IconDirectoryEntry& b) 144 { 145 // Larger icons are better. 141 bool ICOImageDecoder::compareEntries(const IconDirectoryEntry& a, const IconDirectoryEntry& b) 142 { 143 // Larger icons are better. After that, higher bit-depth icons are better. 146 144 const int aEntryArea = a.m_size.width() * a.m_size.height(); 147 145 const int bEntryArea = b.m_size.width() * b.m_size.height(); 148 if (aEntryArea != bEntryArea) 149 return (aEntryArea > bEntryArea); 150 151 // Higher bit-depth icons are better. 152 return (a.m_bitCount > b.m_bitCount); 146 return (aEntryArea == bEntryArea) ? (a.m_bitCount > b.m_bitCount) : (aEntryArea > bEntryArea); 153 147 } 154 148 … … 162 156 // FIXME: Save this copy by making the PNG decoder able to take an 163 157 // optional offset. 164 RefPtr<SharedBuffer> pngData( 165 SharedBuffer::create(&m_data->data()[dirEntry.m_imageOffset], 166 m_data->size() - dirEntry.m_imageOffset)); 167 m_pngDecoders[index]->setData(pngData.get(), m_allDataReceived); 168 } 169 170 void ICOImageDecoder::decodeWithCheckForDataEnded(size_t index, bool onlySize) 158 RefPtr<SharedBuffer> pngData(SharedBuffer::create(&m_data->data()[dirEntry.m_imageOffset], m_data->size() - dirEntry.m_imageOffset)); 159 m_pngDecoders[index]->setData(pngData.get(), isAllDataReceived()); 160 } 161 162 void ICOImageDecoder::decode(size_t index, bool onlySize) 171 163 { 172 164 if (failed()) … … 175 167 // If we couldn't decode the image but we've received all the data, decoding 176 168 // has failed. 177 if ((!decodeDirectory() || (!onlySize && !decodeAtIndex(index))) 178 && m_allDataReceived) 169 if ((!decodeDirectory() || (!onlySize && !decodeAtIndex(index))) && isAllDataReceived()) 179 170 setFailed(); 180 171 } … … 187 178 188 179 // Read and process directory entries. 189 return (m_decodedOffset >= 190 (sizeOfDirectory + (m_dirEntries.size() * sizeOfDirEntry))) 191 || processDirectoryEntries(); 180 return (m_decodedOffset >= (sizeOfDirectory + (m_dirEntries.size() * sizeOfDirEntry))) || processDirectoryEntries(); 192 181 } 193 182 … … 203 192 // we must not resize it again later (see caution in frameCount()). 204 193 ASSERT(m_frameBufferCache.size() == m_dirEntries.size()); 205 m_bmpReaders[index].set( 206 new BMPImageReader(this, dirEntry.m_imageOffset, 0, true)); 194 m_bmpReaders[index].set(new BMPImageReader(this, dirEntry.m_imageOffset, 0, true)); 207 195 m_bmpReaders[index]->setData(m_data.get()); 208 196 m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); … … 260 248 // Read directory entries. 261 249 ASSERT(m_decodedOffset == sizeOfDirectory); 262 if ((m_decodedOffset > m_data->size()) 263 || ((m_data->size() - m_decodedOffset) < 264 (m_dirEntries.size() * sizeOfDirEntry))) 250 if ((m_decodedOffset > m_data->size()) || ((m_data->size() - m_decodedOffset) < (m_dirEntries.size() * sizeOfDirEntry))) 265 251 return false; 266 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); 267 i != m_dirEntries.end(); ++i) 252 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntries.end(); ++i) 268 253 *i = readDirectoryEntry(); // Updates m_decodedOffset. 269 254 270 255 // Make sure the specified image offsets are past the end of the directory 271 256 // entries. 272 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); 273 i != m_dirEntries.end(); ++i) { 257 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntries.end(); ++i) { 274 258 if (i->m_imageOffset < m_decodedOffset) { 275 259 setFailed(); … … 310 294 // this value to determine which icon entry is best. 311 295 if (!entry.m_bitCount) { 312 int colorCount = 313 static_cast<uint8_t>(m_data->data()[m_decodedOffset + 2]); 296 int colorCount = static_cast<uint8_t>(m_data->data()[m_decodedOffset + 2]); 314 297 if (!colorCount) 315 298 colorCount = 256; // Vague in the spec, needed by real-world icons.
