PassOwnPtr<Vector<char>> PictureSnapshot::replay(unsigned fromStep, unsigned toStep, double scale) const
{
    const SkIRect bounds = m_picture->cullRect().roundOut();

    // TODO(fmalita): convert this to SkSurface/SkImage, drop the intermediate SkBitmap.
    SkBitmap bitmap;
    bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()));
    bitmap.eraseARGB(0, 0, 0, 0);
    {
        ReplayingCanvas canvas(bitmap, fromStep, toStep);
        canvas.scale(scale, scale);
        canvas.resetStepCount();
        m_picture->playback(&canvas, &canvas);
    }
    OwnPtr<Vector<char>> base64Data = adoptPtr(new Vector<char>());
    Vector<char> encodedImage;

    RefPtr<SkImage> image = adoptRef(SkImage::NewFromBitmap(bitmap));
    if (!image)
        return nullptr;

    ImagePixelLocker pixelLocker(image, kUnpremul_SkAlphaType);
    ImageDataBuffer imageData(IntSize(image->width(), image->height()),
        static_cast<const unsigned char*>(pixelLocker.pixels()));
    if (!PNGImageEncoder::encode(imageData, reinterpret_cast<Vector<unsigned char>*>(&encodedImage)))
        return nullptr;

    base64Encode(encodedImage, *base64Data);
    return base64Data.release();
}
PassOwnPtr<Vector<char>> PictureSnapshot::replay(unsigned fromStep, unsigned toStep, double scale) const
{
    const SkIRect bounds = m_picture->cullRect().roundOut();

    // TODO(fmalita): convert this to SkSurface/SkImage, drop the intermediate SkBitmap.
    SkBitmap bitmap;
    bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()));
    bitmap.eraseARGB(0, 0, 0, 0);
    {
        ReplayingCanvas canvas(bitmap, fromStep, toStep);
        // Disable LCD text preemptively, because the picture opacity is unknown.
        // The canonical API involves SkSurface props, but since we're not SkSurface-based
        // at this point (see TODO above) we (ab)use saveLayer for this purpose.
        SkAutoCanvasRestore autoRestore(&canvas, false);
        canvas.saveLayer(nullptr, nullptr);

        canvas.scale(scale, scale);
        canvas.resetStepCount();
        m_picture->playback(&canvas, &canvas);
    }
    OwnPtr<Vector<char>> base64Data = adoptPtr(new Vector<char>());
    Vector<char> encodedImage;

    RefPtr<SkImage> image = adoptRef(SkImage::NewFromBitmap(bitmap));
    if (!image)
        return nullptr;

    ImagePixelLocker pixelLocker(image, kUnpremul_SkAlphaType, kRGBA_8888_SkColorType);
    ImageDataBuffer imageData(IntSize(image->width(), image->height()),
        static_cast<const unsigned char*>(pixelLocker.pixels()));
    if (!PNGImageEncoder::encode(imageData, reinterpret_cast<Vector<unsigned char>*>(&encodedImage)))
        return nullptr;

    base64Encode(encodedImage, *base64Data);
    return base64Data.release();
}