PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
    GraphicsContext* gc = this->context();
    if (!gc) {
        return 0;
    }

    const SkBitmap& src = imageBufferCanvas(this)->getDevice()->accessBitmap(false);
    SkAutoLockPixels alp(src);
    if (!src.getPixels()) {
        return 0;
    }

    RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
    unsigned char* data = result->data();

    if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > m_size.width() || rect.maxY() > m_size.height())
        memset(data, 0, result->length());

    int originx = rect.x();
    int destx = 0;
    if (originx < 0) {
        destx = -originx;
        originx = 0;
    }
    int endx = rect.x() + rect.width();
    if (endx > m_size.width())
        endx = m_size.width();
    int numColumns = endx - originx;

    int originy = rect.y();
    int desty = 0;
    if (originy < 0) {
        desty = -originy;
        originy = 0;
    }
    int endy = rect.y() + rect.height();
    if (endy > m_size.height())
        endy = m_size.height();
    int numRows = endy - originy;

    unsigned srcPixelsPerRow = src.rowBytesAsPixels();
    unsigned destBytesPerRow = 4 * rect.width();

    /// M: change process to read pixel @{
    /* fix w3c pixel manipulation relative test case */
    SkBitmap destBitmap;
    destBitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height(), destBytesPerRow);
    destBitmap.setPixels(data);

    SkCanvas* canvas = imageBufferCanvas(this);
    canvas->readPixels(&destBitmap, rect.x(), rect.y(), SkCanvas::kRGBA_Unpremul_Config8888);
    return result.release();
    /// @}
}
void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
    GraphicsContext* gc = this->context();
    if (!gc) {
        return;
    }

    const SkBitmap& dst = imageBufferCanvas(this)->getDevice()->accessBitmap(true);
    SkAutoLockPixels alp(dst);
    if (!dst.getPixels()) {
        return;
    }

    ASSERT(sourceRect.width() > 0);
    ASSERT(sourceRect.height() > 0);

    int originx = sourceRect.x();
    int destx = destPoint.x() + sourceRect.x();
    ASSERT(destx >= 0);
    ASSERT(destx < m_size.width());
    ASSERT(originx >= 0);
    ASSERT(originx <= sourceRect.maxX());

    int endx = destPoint.x() + sourceRect.maxX();
    ASSERT(endx <= m_size.width());

    int numColumns = endx - destx;

    int originy = sourceRect.y();
    int desty = destPoint.y() + sourceRect.y();
    ASSERT(desty >= 0);
    ASSERT(desty < m_size.height());
    ASSERT(originy >= 0);
    ASSERT(originy <= sourceRect.maxY());

    int endy = destPoint.y() + sourceRect.maxY();
    ASSERT(endy <= m_size.height());
    int numRows = endy - desty;

    unsigned srcBytesPerRow = 4 * sourceSize.width();
    unsigned dstPixelsPerRow = dst.rowBytesAsPixels();

    unsigned char* srcRows = source->data() + originy * srcBytesPerRow + originx * 4;
    SkPMColor* dstRows = dst.getAddr32(destx, desty);
    for (int y = 0; y < numRows; ++y) {
        for (int x = 0; x < numColumns; x++) {
            int basex = x * 4;
            dstRows[x] = SkPackARGB32(srcRows[basex + 3],
                                      srcRows[basex + 0],
                                      srcRows[basex + 1],
                                      srcRows[basex + 2]);
        }
        dstRows += dstPixelsPerRow;
        srcRows += srcBytesPerRow;
    }
}
/// M: added for HTML5-benchmark performance @{
PassRefPtr<Image> ImageBuffer::getContextImageRef() const
{
    SkCanvas* canvas = imageBufferCanvas(this);
    if (!canvas)
        return 0;
    SkDevice* device = canvas->getDevice();
    const SkBitmap& orig = device->accessBitmap(false);

    SkBitmapRef* ref = new SkBitmapRef(orig);
    RefPtr<Image> image = BitmapImage::create(ref, 0);
    ref->unref();

    return image;
}
void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
    GraphicsContext* gc = this->context();
    if (!gc) {
        return;
    }

    ASSERT(sourceRect.width() > 0);
    ASSERT(sourceRect.height() > 0);

    int originx = sourceRect.x();
    int destx = destPoint.x() + sourceRect.x();
    ASSERT(destx >= 0);
    ASSERT(destx < m_size.width());
    ASSERT(originx >= 0);
    ASSERT(originx <= sourceRect.maxX());

    int endx = destPoint.x() + sourceRect.maxX();
    ASSERT(endx <= m_size.width());

    int numColumns = endx - destx;

    int originy = sourceRect.y();
    int desty = destPoint.y() + sourceRect.y();
    ASSERT(desty >= 0);
    ASSERT(desty < m_size.height());
    ASSERT(originy >= 0);
    ASSERT(originy <= sourceRect.maxY());

    int endy = destPoint.y() + sourceRect.maxY();
    ASSERT(endy <= m_size.height());
    int numRows = endy - desty;

    unsigned srcBytesPerRow = 4 * sourceSize.width();

    SkBitmap srcBitmap;
    /// M: change process to write pixel @{
    /* fix w3c pixel manipulation relative test case */
    srcBitmap.setConfig(SkBitmap::kARGB_8888_Config, numColumns, numRows, srcBytesPerRow);
    srcBitmap.setPixels(source->data() + originy * srcBytesPerRow + originx * 4);

    SkCanvas* canvas = imageBufferCanvas(this);
    canvas->writePixels(srcBitmap, destx, desty, SkCanvas::kRGBA_Unpremul_Config8888);
    /// @}
}
示例#5
0
bool CanvasTexture::uploadImageBuffer(ImageBuffer* imageBuffer)
{
    m_hasValidTexture = false;
    SurfaceTextureClient* anw = nativeWindow();
    if (!anw || ! imageBuffer) // CAPPFIX_WEB_NULL_CHECK_CANVASTEXTURE
        return false;
    // Size mismatch, early abort (will fall back to software)
    if (imageBuffer->size() != m_size)
        return false;
    SkCanvas* canvas = imageBufferCanvas(imageBuffer);
    if (!canvas)
        return false;
    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
    if (!GLUtils::updateSharedSurfaceTextureWithBitmap(anw, bitmap))
        return false;
    m_hasValidTexture = true;
    return true;
}
PassRefPtr<Image> ImageBuffer::copyImage() const
{
    ASSERT(context());

    SkCanvas* canvas = imageBufferCanvas(this);
    if (!canvas)
      return 0;

    SkDevice* device = canvas->getDevice();
    const SkBitmap& orig = device->accessBitmap(false);

    SkBitmap copy;
    if (PlatformBridge::canSatisfyMemoryAllocation(orig.getSize()))
        orig.copyTo(&copy, orig.config());

    SkBitmapRef* ref = new SkBitmapRef(copy);
    RefPtr<Image> image = BitmapImage::create(ref, 0);
    ref->unref();
    return image;
}
String ImageBuffer::toDataURL(const String&, const double*) const
{
    // Encode the image into a vector.
    SkDynamicMemoryWStream pngStream;
    const SkBitmap& dst = imageBufferCanvas(this)->getDevice()->accessBitmap(true);
    SkImageEncoder::EncodeStream(&pngStream, dst, SkImageEncoder::kPNG_Type, 100);

    // Convert it into base64.
    Vector<char> pngEncodedData;
    SkData* streamData = pngStream.copyToData();
    pngEncodedData.append((char*)streamData->data(), streamData->size());
    streamData->unref();
    Vector<char> base64EncodedData;
    base64Encode(pngEncodedData, base64EncodedData);
    // Append with a \0 so that it's a valid string.
    base64EncodedData.append('\0');

    // And the resulting string.
    return String::format("data:image/png;base64,%s", base64EncodedData.data());
}
示例#8
0
String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
{
    ASSERT(context() && context()->platformContext());

    // Request for canvas bitmap; conversion required.
    if (context()->platformContext()->isRecording())
        context()->platformContext()->convertToNonRecording();
// CAPPFIX_WEB_WEBGL
     SkCanvas* canvas = imageBufferCanvas(this);
// CAPPFIX_WEB_WEBGL_END
     SkDevice* device = canvas->getDevice();
     SkBitmap bitmap = device->accessBitmap(false);
     // if we can't see the pixels directly, call readPixels() to get a copy.
     // this could happen if the device is backed by a GPU.
     bitmap.lockPixels(); // balanced by our destructor, or explicitly if getPixels() fails
     if (!bitmap.getPixels()) {
         bitmap.unlockPixels();
         SkIRect bounds = SkIRect::MakeWH(device->width(), device->height());
         if (!canvas->readPixels(bounds, &bitmap))
             return "data:,";
     }

     return ImageToDataURL(bitmap, mimeType, quality);
}
示例#9
0
PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
    ASSERT(context() && context()->platformContext());

    // Request for canvas bitmap; conversion required.
    if (context()->platformContext()->isRecording())
        context()->platformContext()->convertToNonRecording();

    GraphicsContext* gc = this->context();
    if (!gc) {
        return 0;
    }

    const SkBitmap& src = imageBufferCanvas(this)->getDevice()->accessBitmap(false);
    SkAutoLockPixels alp(src);
    if (!src.getPixels()) {
        return 0;
    }

    RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
    unsigned char* data = result->data();

    if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > m_size.width() || rect.maxY() > m_size.height())
        memset(data, 0, result->length());

    int originx = rect.x();
    int destx = 0;
    if (originx < 0) {
        destx = -originx;
        originx = 0;
    }
    int endx = rect.x() + rect.width();
    if (endx > m_size.width())
        endx = m_size.width();
    int numColumns = endx - originx;

    int originy = rect.y();
    int desty = 0;
    if (originy < 0) {
        desty = -originy;
        originy = 0;
    }
    int endy = rect.y() + rect.height();
    if (endy > m_size.height())
        endy = m_size.height();
    int numRows = endy - originy;

    unsigned srcPixelsPerRow = src.rowBytesAsPixels();
    unsigned destBytesPerRow = 4 * rect.width();

    const SkPMColor* srcRows = src.getAddr32(originx, originy);
    unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
    for (int y = 0; y < numRows; ++y) {
        for (int x = 0; x < numColumns; x++) {
            // ugh, it appears they want unpremultiplied pixels
            SkColor c = SkUnPreMultiply::PMColorToColor(srcRows[x]);
            int basex = x * 4;
            destRows[basex + 0] = SkColorGetR(c);
            destRows[basex + 1] = SkColorGetG(c);
            destRows[basex + 2] = SkColorGetB(c);
            destRows[basex + 3] = SkColorGetA(c);
        }
        srcRows += srcPixelsPerRow;
        destRows += destBytesPerRow;
    }
    return result.release();
}