bool ICOImageDecoder::decodeAtIndex(size_t index)
{
    ASSERT(index < m_dirEntries.size());
    const IconDirectoryEntry& dirEntry = m_dirEntries[index];
    const ImageType imageType = imageTypeAtIndex(index);
    if (imageType == Unknown)
        return false; // Not enough data to determine image type yet.

    if (imageType == BMP) {
        if (!m_bmpReaders[index]) {
            // We need to have already sized m_frameBufferCache before this, and
            // we must not resize it again later (see caution in frameCount()).
            ASSERT(m_frameBufferCache.size() == m_dirEntries.size());
            m_bmpReaders[index].set(new BMPImageReader(this, dirEntry.m_imageOffset, 0, true));
            m_bmpReaders[index]->setData(m_data.get());
            m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]);
        }
        m_frameSize = dirEntry.m_size;
        bool result = m_bmpReaders[index]->decodeBMP(false);
        m_frameSize = IntSize();
        return result;
    }

    if (!m_pngDecoders[index]) {
        m_pngDecoders[index].set(new PNGImageDecoder(m_premultiplyAlpha, m_ignoreGammaAndColorProfile));
        setDataForPNGDecoderAtIndex(index);
    }
    // Fail if the size the PNGImageDecoder calculated does not match the size
    // in the directory.
    if (m_pngDecoders[index]->isSizeAvailable() && (m_pngDecoders[index]->size() != dirEntry.m_size))
        return setFailed();
    m_frameBufferCache[index] = *m_pngDecoders[index]->frameBufferAtIndex(0);
    return !m_pngDecoders[index]->failed() || setFailed();
}
Beispiel #2
0
bool ICOImageDecoder::decodeAtIndex(size_t index) {
  SECURITY_DCHECK(index < m_dirEntries.size());
  const IconDirectoryEntry& dirEntry = m_dirEntries[index];
  const ImageType imageType = imageTypeAtIndex(index);
  if (imageType == Unknown)
    return false;  // Not enough data to determine image type yet.

  if (imageType == BMP) {
    if (!m_bmpReaders[index]) {
      m_bmpReaders[index] =
          wrapUnique(new BMPImageReader(this, dirEntry.m_imageOffset, 0, true));
      m_bmpReaders[index]->setData(m_data.get());
    }
    // Update the pointer to the buffer as it could change after
    // m_frameBufferCache.resize().
    m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]);
    m_frameSize = dirEntry.m_size;
    bool result = m_bmpReaders[index]->decodeBMP(false);
    m_frameSize = IntSize();
    return result;
  }

  if (!m_pngDecoders[index]) {
    AlphaOption alphaOption =
        m_premultiplyAlpha ? AlphaPremultiplied : AlphaNotPremultiplied;
    m_pngDecoders[index] = wrapUnique(
        new PNGImageDecoder(alphaOption, m_colorSpaceOption, m_maxDecodedBytes,
                            dirEntry.m_imageOffset));
    setDataForPNGDecoderAtIndex(index);
  }
  // Fail if the size the PNGImageDecoder calculated does not match the size
  // in the directory.
  if (m_pngDecoders[index]->isSizeAvailable() &&
      (m_pngDecoders[index]->size() != dirEntry.m_size))
    return setFailed();
  m_frameBufferCache[index] = *m_pngDecoders[index]->frameBufferAtIndex(0);
  m_frameBufferCache[index].setPremultiplyAlpha(m_premultiplyAlpha);
  return !m_pngDecoders[index]->failed() || setFailed();
}