示例#1
0
    void onDrawContent(SkCanvas* canvas) override {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setTextSize(SkIntToScalar(24));
        SkAutoTUnref<SkBlurDrawLooper> looper(
            SkBlurDrawLooper::Create(SK_ColorBLUE,
                                     SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(2)),
                                     0, 0));
        paint.setLooper(looper);
        SkScalar height = paint.getFontMetrics(nullptr);
        if (!fDecodeSucceeded) {
            SkString failure;
            if (fResPath.size() == 0) {
                failure.printf("resource path is required!");
            } else {
                failure.printf("Failed to decode %s", fCurrFile.c_str());
            }
            canvas->drawText(failure.c_str(), failure.size(), 0, height, paint);
            return;
        }

        // Name, size of the file, and whether or not it is premultiplied.
        SkString header(SkOSPath::Basename(fCurrFile.c_str()));
        header.appendf("     [%dx%d]     %s", fBitmap.width(), fBitmap.height(),
                       (fPremul ? "premultiplied" : "unpremultiplied"));
        canvas->drawText(header.c_str(), header.size(), 0, height, paint);
        canvas->translate(0, height);

        // Help messages
        header.printf("Press '%c' to move to the next image.'", fNextImageChar);
        canvas->drawText(header.c_str(), header.size(), 0, height, paint);
        canvas->translate(0, height);

        header.printf("Press '%c' to toggle premultiplied decode.", fTogglePremulChar);
        canvas->drawText(header.c_str(), header.size(), 0, height, paint);

        // Now draw the image itself.
        canvas->translate(height * 2, height * 2);
        if (!fPremul) {
            // A premultiplied bitmap cannot currently be drawn.
            SkAutoLockPixels alp(fBitmap);
            // Copy it to a bitmap which can be drawn, converting
            // to premultiplied:
            SkBitmap bm;
            bm.allocN32Pixels(fBitmap.width(), fBitmap.height());
            for (int i = 0; i < fBitmap.width(); ++i) {
                for (int j = 0; j < fBitmap.height(); ++j) {
                    *bm.getAddr32(i, j) = premultiply_unpmcolor(*fBitmap.getAddr32(i, j));
                }
            }
            canvas->drawBitmap(bm, 0, 0);
        } else {
            canvas->drawBitmap(fBitmap, 0, 0);
        }
    }
/**
 *  Test decoding an image in premultiplied mode and unpremultiplied mode and compare
 *  them.
 */
static void compare_unpremul(skiatest::Reporter* reporter, const SkString& filename) {
    // Decode a resource:
    SkBitmap bm8888;
    SkBitmap bm8888Unpremul;

    SkFILEStream stream(filename.c_str());

    SkImageDecoder::Format format = SkImageDecoder::GetStreamFormat(&stream);
    if (skip_image_format(format)) {
        return;
    }

    SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
    if (NULL == decoder.get()) {
        SkDebugf("couldn't decode %s\n", filename.c_str());
        return;
    }

    bool success = decoder->decode(&stream, &bm8888, SkBitmap::kARGB_8888_Config,
                                   SkImageDecoder::kDecodePixels_Mode);
    if (!success) {
        return;
    }

    success = stream.rewind();
    REPORTER_ASSERT(reporter, success);
    if (!success) {
        return;
    }

    decoder->setRequireUnpremultipliedColors(true);
    success = decoder->decode(&stream, &bm8888Unpremul, SkBitmap::kARGB_8888_Config,
                              SkImageDecoder::kDecodePixels_Mode);
    if (!success) {
        return;
    }

    bool dimensionsMatch = bm8888.width() == bm8888Unpremul.width()
                           && bm8888.height() == bm8888Unpremul.height();
    REPORTER_ASSERT(reporter, dimensionsMatch);
    if (!dimensionsMatch) {
        return;
    }

    // Only do the comparison if the two bitmaps are both 8888.
    if (bm8888.config() != SkBitmap::kARGB_8888_Config
        || bm8888Unpremul.config() != SkBitmap::kARGB_8888_Config) {
        return;
    }

    // Now compare the two bitmaps.
    for (int i = 0; i < bm8888.width(); ++i) {
        for (int j = 0; j < bm8888.height(); ++j) {
            // "c0" is the color of the premultiplied bitmap at (i, j).
            const SkPMColor c0 = *bm8888.getAddr32(i, j);
            // "c1" is the result of premultiplying the color of the unpremultiplied
            // bitmap at (i, j).
            const SkPMColor c1 = premultiply_unpmcolor(*bm8888Unpremul.getAddr32(i, j));
            // Compute the difference for each component.
            int da = SkAbs32(SkGetPackedA32(c0) - SkGetPackedA32(c1));
            int dr = SkAbs32(SkGetPackedR32(c0) - SkGetPackedR32(c1));
            int dg = SkAbs32(SkGetPackedG32(c0) - SkGetPackedG32(c1));
            int db = SkAbs32(SkGetPackedB32(c0) - SkGetPackedB32(c1));

            // Alpha component must be exactly the same.
            REPORTER_ASSERT(reporter, 0 == da);

            // Color components may not match exactly due to rounding error.
            REPORTER_ASSERT(reporter, dr <= 1);
            REPORTER_ASSERT(reporter, dg <= 1);
            REPORTER_ASSERT(reporter, db <= 1);
        }
    }
}