Exemple #1
0
static inline void test_premul(skiatest::Reporter* reporter) {
    for (int a = 0; a <= 255; a++) {
        for (int x = 0; x <= 255; x++) {
            SkColor c0 = SkColorSetARGB(a, x, x, x);
            SkPMColor p0 = SkPreMultiplyColor(c0);

            SkColor c1 = SkUnPreMultiply::PMColorToColor(p0);
            SkPMColor p1 = SkPreMultiplyColor(c1);

            // we can't promise that c0 == c1, since c0 -> p0 is a many to one
            // function, however, we can promise that p0 -> c1 -> p1 : p0 == p1
            REPORTER_ASSERT(reporter, p0 == p1);

            {
                int ax = SkMulDiv255Ceiling(x, a);
                REPORTER_ASSERT(reporter, ax <= a);
            }
        }
    }
}
void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint,
                  SkDevice* dstDevice, const IntSize& size)
{
    ASSERT(sourceRect.width() > 0);
    ASSERT(sourceRect.height() > 0);

    int originX = sourceRect.x();
    int destX = destPoint.x() + sourceRect.x();
    ASSERT(destX >= 0);
    ASSERT(destX < size.width());
    ASSERT(originX >= 0);
    ASSERT(originX < sourceRect.maxX());

    int endX = destPoint.x() + sourceRect.maxX();
    ASSERT(endX <= size.width());

    int numColumns = endX - destX;

    int originY = sourceRect.y();
    int destY = destPoint.y() + sourceRect.y();
    ASSERT(destY >= 0);
    ASSERT(destY < size.height());
    ASSERT(originY >= 0);
    ASSERT(originY < sourceRect.maxY());

    int endY = destPoint.y() + sourceRect.maxY();
    ASSERT(endY <= size.height());
    int numRows = endY - destY;

    unsigned srcBytesPerRow = 4 * sourceSize.width();

    SkBitmap deviceBitmap = dstDevice->accessBitmap(true);
    SkAutoLockPixels deviceAutoLock(deviceBitmap);

    // If the device's bitmap doesn't have pixels we will make a temp and call writePixels on the device.
    bool temporaryBitmap = !deviceBitmap.getPixels();
    SkBitmap destBitmap;

    if (temporaryBitmap) {
        destBitmap.setConfig(SkBitmap::kARGB_8888_Config, numColumns, numRows, srcBytesPerRow);
        if (!destBitmap.allocPixels())
            CRASH();
    } else
        deviceBitmap.extractSubset(&destBitmap, SkIRect::MakeXYWH(destX, destY, numColumns, numRows));

    // Whether we made a temporary or not destBitmap is always configured to be written at 0,0
    SkAutoLockPixels destAutoLock(destBitmap);
    const unsigned char* srcRow = source->data() + originY * srcBytesPerRow + originX * 4;
    for (int y = 0; y < numRows; ++y) {
        SkPMColor* destRow = destBitmap.getAddr32(0, y);
        for (int x = 0; x < numColumns; ++x) {
            const unsigned char* srcPixel = &srcRow[x * 4];
            if (multiplied == Unmultiplied) {
                unsigned char alpha = srcPixel[3];
                unsigned char r = SkMulDiv255Ceiling(srcPixel[0], alpha);
                unsigned char g = SkMulDiv255Ceiling(srcPixel[1], alpha);
                unsigned char b = SkMulDiv255Ceiling(srcPixel[2], alpha);
                destRow[x] = SkPackARGB32(alpha, r, g, b);
            } else
                destRow[x] = SkPackARGB32(srcPixel[3], srcPixel[0], srcPixel[1], srcPixel[2]);
        }
        srcRow += srcBytesPerRow;
    }

    // If we used a temporary then write it to the device
    if (temporaryBitmap)
        dstDevice->writePixels(destBitmap, destX, destY);
}