Exemplo n.º 1
0
bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
{
    if (!m_image)
        return false;
    m_skiaImage = m_image->nativeImageForCurrentFrame();
    m_alphaOp = AlphaDoNothing;
    bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true;
    if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
        // Attempt to get raw unpremultiplied image data.
        OwnPtr<ImageDecoder> decoder(ImageDecoder::create(
            *(m_image->data()), ImageSource::AlphaNotPremultiplied,
            ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied));
        if (!decoder)
            return false;
        decoder->setData(m_image->data(), true);
        if (!decoder->frameCount())
            return false;
        ImageFrame* frame = decoder->frameBufferAtIndex(0);
        if (!frame || frame->status() != ImageFrame::FrameComplete)
            return false;
        hasAlpha = frame->hasAlpha();
        m_nativeImage = adoptPtr(frame->asNewNativeImage());
        if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativeImage->bitmap().width() || !m_nativeImage->bitmap().height())
            return false;
        SkBitmap::Config skiaConfig = m_nativeImage->bitmap().config();
        if (skiaConfig != SkBitmap::kARGB_8888_Config)
            return false;
        m_skiaImage = m_nativeImage.get();
        if (hasAlpha && premultiplyAlpha)
            m_alphaOp = AlphaDoPremultiply;
    } else if (!premultiplyAlpha && hasAlpha) {
        // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value for each pixel is 0xFF
        // which is true at present and may be changed in the future and needs adjustment accordingly.
        // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port,
        // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
        if (m_imageHtmlDomSource != HtmlDomVideo)
            m_alphaOp = AlphaDoUnmultiply;
    }
    if (!m_skiaImage)
        return false;

    m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8;
    m_imageWidth = m_skiaImage->bitmap().width();
    m_imageHeight = m_skiaImage->bitmap().height();
    if (!m_imageWidth || !m_imageHeight)
        return false;
    m_imageSourceUnpackAlignment = 0;
    m_skiaImage->bitmap().lockPixels();
    m_imagePixelData = m_skiaImage->bitmap().getPixels();
    return true;
}
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
    if (!m_decoder)
        return 0;

    ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
        return 0;

    // Zero-height images can cause problems for some ports.  If we have an
    // empty image dimension, just bail.
    if (size().isEmpty())
        return 0;

    // Return the buffer contents as a native image.  For some ports, the data
    // is already in a native container, and this just increments its refcount.
    return buffer->asNewNativeImage();
}
Exemplo n.º 3
0
WebImage WebImage::fromData(const WebData& data, const WebSize& desiredSize)
{
    RefPtr<SharedBuffer> buffer = PassRefPtr<SharedBuffer>(data);
    OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*buffer.get(), ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileIgnored));
    if (!decoder)
        return WebImage();

    decoder->setData(buffer.get(), true);
    if (!decoder->isSizeAvailable())
        return WebImage();

    // Frames are arranged by decreasing size, then decreasing bit depth.
    // Pick the frame closest to |desiredSize|'s area without being smaller,
    // which has the highest bit depth.
    const size_t frameCount = decoder->frameCount();
    size_t index = 0; // Default to first frame if none are large enough.
    int frameAreaAtIndex = 0;
    for (size_t i = 0; i < frameCount; ++i) {
        const IntSize frameSize = decoder->frameSizeAtIndex(i);
        if (WebSize(frameSize) == desiredSize) {
            index = i;
            break; // Perfect match.
        }

        const int frameArea = frameSize.width() * frameSize.height();
        if (frameArea < (desiredSize.width * desiredSize.height))
            break; // No more frames that are large enough.

        if (!i || (frameArea < frameAreaAtIndex)) {
            index = i; // Closer to desired area than previous best match.
            frameAreaAtIndex = frameArea;
        }
    }

    ImageFrame* frame = decoder->frameBufferAtIndex(index);
    if (!frame)
        return WebImage();

    RefPtr<NativeImageSkia> image = frame->asNewNativeImage();
    if (!image)
        return WebImage();

    return WebImage(image->bitmap());
}
Exemplo n.º 4
0
WebVector<WebImage> WebImage::framesFromData(const WebData& data)
{
    // This is to protect from malicious images. It should be big enough that it's never hit in pracice.
    const size_t maxFrameCount = 8;

    RefPtr<SharedBuffer> buffer = PassRefPtr<SharedBuffer>(data);
    OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*buffer.get(), ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileIgnored));
    if (!decoder)
        return WebVector<WebImage>();

    decoder->setData(buffer.get(), true);
    if (!decoder->isSizeAvailable())
        return WebVector<WebImage>();

    // Frames are arranged by decreasing size, then decreasing bit depth.
    // Keep the first frame at every size, has the highest bit depth.
    const size_t frameCount = decoder->frameCount();
    IntSize lastSize;

    Vector<WebImage> frames;
    for (size_t i = 0; i < std::min(frameCount, maxFrameCount); ++i) {
        const IntSize frameSize = decoder->frameSizeAtIndex(i);
        if (frameSize == lastSize)
            continue;
        lastSize = frameSize;

        ImageFrame* frame = decoder->frameBufferAtIndex(i);
        if (!frame)
            continue;

        RefPtr<NativeImageSkia> image = frame->asNewNativeImage();
        if (image && image->isDataComplete())
            frames.append(WebImage(image->bitmap()));
    }

    return frames;
}