예제 #1
0
파일: factory.cpp 프로젝트: sheuan/skia
 void onOnceBeforeDraw() override {
     // Copyright-free file from http://openclipart.org/detail/29213/paper-plane-by-ddoo
     SkString pngFilename = GetResourcePath("plane.png");
     SkAutoDataUnref data(SkData::NewFromFileName(pngFilename.c_str()));
     if (data.get()) {
         // Create a cache which will boot the pixels out anytime the
         // bitmap is unlocked.
         SkAutoTUnref<SkDiscardableMemoryPool> pool(
             SkDiscardableMemoryPool::Create(1));
         SkAssertResult(SkInstallDiscardablePixelRef(SkImageGenerator::NewFromData(data),
                                                     NULL, &fBitmap, pool));
     }
 }
예제 #2
0
// example of how Android will do this inside their BitmapFactory
static SkPixelRef* install_pixel_ref(SkBitmap* bitmap,
                                     SkStreamRewindable* stream,
                                     int sampleSize, bool ditherImage) {
    SkASSERT(bitmap != NULL);
    SkASSERT(stream != NULL);
    SkASSERT(stream->rewind());
    SkColorType colorType = bitmap->colorType();
    SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType);
    if (SkInstallDiscardablePixelRef(
                SkDecodingImageGenerator::Create(stream, opts), bitmap)) {
        return bitmap->pixelRef();
    }
    return NULL;
}
예제 #3
0
    void onDraw(SkCanvas* canvas) override {
        SkBitmap bm;
        SkString filename = GetResourcePath("mandrill_128.");
        filename.append(this->fileExtension());
        SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str()));
        if (nullptr == fileData) {
            SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
            return;
        }

        if (!SkInstallDiscardablePixelRef(fileData, &bm)) {
            SkDebugf("Could not install discardable pixel ref.\n");
            return;
        }

        canvas->drawBitmap(bm, 0, 0);
    }
// Creates a SkBitmap that is backed by SkDiscardablePixelRef.
SkBitmap DeferredImageDecoder::createBitmap(size_t index)
{
    SkISize decodedSize = m_frameGenerator->getFullSize();
    ASSERT(decodedSize.width() > 0);
    ASSERT(decodedSize.height() > 0);

#if SK_B32_SHIFT // Little-endian RGBA pixels. (Android)
    const SkColorType colorType = kRGBA_8888_SkColorType;
#else
    const SkColorType colorType = kBGRA_8888_SkColorType;
#endif
    const SkImageInfo info = SkImageInfo::Make(decodedSize.width(), decodedSize.height(), colorType, kPremul_SkAlphaType);

    SkBitmap bitmap;
    DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, info, index);
    bool installed = SkInstallDiscardablePixelRef(generator, &bitmap);
    ASSERT_UNUSED(installed, installed);
    bitmap.pixelRef()->setURI(labelDiscardable);
    generator->setGenerationId(bitmap.getGenerationID());
    return bitmap;
}
예제 #5
0
//  Fits SkPicture::InstallPixelRefProc call signature.
//  Used in SkPictureData::CreateFromStream
bool sk_tools::LazyDecodeBitmap(const void* src,
                                size_t length,
                                SkBitmap* dst) {
    SkAutoDataUnref data(SkData::NewWithCopy(src, length));
    if (NULL == data.get()) {
        return false;
    }

    SkAutoTDelete<SkImageGenerator> gen(SkImageGenerator::NewFromData(data));
    SkImageInfo info;
    if ((NULL == gen.get()) || !gen->getInfo(&info)) {
        return false;
    }
    SkDiscardableMemory::Factory* pool = NULL;
    if ((!FLAGS_useVolatileCache) || (info.width() * info.height() < 32 * 1024)) {
        // how to do switching with SkDiscardableMemory.
        pool = SkGetGlobalDiscardableMemoryPool();
        // Only meaningful if platform has a default discardable
        // memory implementation that differs from the global DM pool.
    }
    return SkInstallDiscardablePixelRef(gen.detach(), dst, pool);
}
예제 #6
0
static void check_pixelref(TestImageGenerator::TestType type,
                           skiatest::Reporter* reporter,
                           PixelRefType pixelRefType,
                           SkDiscardableMemory::Factory* factory) {
    SkASSERT((pixelRefType >= 0) && (pixelRefType <= kLast_PixelRefType));
    SkAutoTDelete<SkImageGenerator> gen(SkNEW_ARGS(TestImageGenerator,
                                        (type, reporter)));
    REPORTER_ASSERT(reporter, gen.get() != NULL);
    SkBitmap lazy;
    bool success;
    if (kSkCaching_PixelRefType == pixelRefType) {
        // Ignore factory; use global cache.
        success = SkCachingPixelRef::Install(gen.detach(), &lazy);
    } else {
        success = SkInstallDiscardablePixelRef(gen.detach(), NULL, &lazy, factory);
    }
    REPORTER_ASSERT(reporter, success);
    if (TestImageGenerator::kSucceedGetPixels_TestType == type) {
        check_test_image_generator_bitmap(reporter, lazy);
    } else if (TestImageGenerator::kFailGetPixels_TestType == type) {
        SkAutoLockPixels autoLockPixels(lazy);
        REPORTER_ASSERT(reporter, NULL == lazy.getPixels());
    }
}
예제 #7
0
// This is the public API
bool SkInstallDiscardablePixelRef(SkImageGenerator* generator, SkBitmap* dst) {
    return SkInstallDiscardablePixelRef(generator, dst, NULL);
}
예제 #8
0
// Returned bitmap is lazy.  Only lazy bitmaps hold onto the original data.
static SkBitmap bitmap_from_data(SkData* data) {
    SkASSERT(data);
    SkBitmap bm;
    SkInstallDiscardablePixelRef(data, &bm);
    return bm;
}
예제 #9
0
static bool install_skDiscardablePixelRef(SkData* encoded, SkBitmap* dst) {
    // Use system-default discardable memory.
    return SkInstallDiscardablePixelRef(
        SkDecodingImageGenerator::Create(
            encoded, SkDecodingImageGenerator::Options()), dst);
}
예제 #10
0
static bool install_skDiscardablePixelRef(SkData* encoded, SkBitmap* dst) {
    // Use system-default discardable memory.
    return SkInstallDiscardablePixelRef(encoded, dst);
}
예제 #11
0
bool GetResourceAsBitmap(const char* resource, SkBitmap* dst) {
    SkString resourcePath = GetResourcePath(resource);
    SkAutoTUnref<SkData> resourceData(
            SkData::NewFromFileName(resourcePath.c_str()));
    return resourceData && SkInstallDiscardablePixelRef(resourceData, dst);
}
예제 #12
0
/**
 * Given either a SkStream or a SkData, try to decode the encoded
 * image using the specified options and report errors.
 */
static void test_options(skiatest::Reporter* reporter,
                         const SkDecodingImageGenerator::Options& opts,
                         SkStreamRewindable* encodedStream,
                         SkData* encodedData,
                         bool useData,
                         const SkString& path) {
    SkBitmap bm;
    bool success = false;
    if (useData) {
        if (NULL == encodedData) {
            return;
        }
        success = SkInstallDiscardablePixelRef(
            SkDecodingImageGenerator::Create(encodedData, opts), &bm);
    } else {
        if (NULL == encodedStream) {
            return;
        }
        success = SkInstallDiscardablePixelRef(
            SkDecodingImageGenerator::Create(encodedStream->duplicate(), opts), &bm);
    }
    if (!success) {
        if (opts.fUseRequestedColorType
            && (kARGB_4444_SkColorType == opts.fRequestedColorType)) {
            return;  // Ignore known conversion inabilities.
        }
        // If we get here, it's a failure and we will need more
        // information about why it failed.
        ERRORF(reporter, "Bounds decode failed [sampleSize=%d dither=%s "
               "colorType=%s %s]", opts.fSampleSize, yn(opts.fDitherImage),
               options_colorType(opts), path.c_str());
        return;
    }
    #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
    // Android is the only system that use Skia's image decoders in
    // production.  For now, we'll only verify that samplesize works
    // on systems where it already is known to work.
    REPORTER_ASSERT(reporter, check_rounding(bm.height(), kExpectedHeight,
                                             opts.fSampleSize));
    REPORTER_ASSERT(reporter, check_rounding(bm.width(), kExpectedWidth,
                                             opts.fSampleSize));
    // The ImageDecoder API doesn't guarantee that SampleSize does
    // anything at all, but the decoders that this test excercises all
    // produce an output size in the following range:
    //    (((sample_size * out_size) > (in_size - sample_size))
    //     && out_size <= SkNextPow2(((in_size - 1) / sample_size) + 1));
    #endif  // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX
    SkAutoLockPixels alp(bm);
    if (bm.getPixels() == NULL) {
        ERRORF(reporter, "Pixel decode failed [sampleSize=%d dither=%s "
               "colorType=%s %s]", opts.fSampleSize, yn(opts.fDitherImage),
               options_colorType(opts), path.c_str());
        return;
    }

    SkColorType requestedColorType = opts.fRequestedColorType;
    REPORTER_ASSERT(reporter,
                    (!opts.fUseRequestedColorType)
                    || (bm.colorType() == requestedColorType));

    // Condition under which we should check the decoding results:
    if ((kN32_SkColorType == bm.colorType())
        && (!path.endsWith(".jpg"))  // lossy
        && (opts.fSampleSize == 1)) {  // scaled
        const SkColor* correctPixels = kExpectedPixels;
        SkASSERT(bm.height() == kExpectedHeight);
        SkASSERT(bm.width() == kExpectedWidth);
        int pixelErrors = 0;
        for (int y = 0; y < bm.height(); ++y) {
            for (int x = 0; x < bm.width(); ++x) {
                if (*correctPixels != bm.getColor(x, y)) {
                    ++pixelErrors;
                }
                ++correctPixels;
            }
        }
        if (pixelErrors != 0) {
            ERRORF(reporter, "Pixel-level mismatch (%d of %d) "
                   "[sampleSize=%d dither=%s colorType=%s %s]",
                   pixelErrors, kExpectedHeight * kExpectedWidth,
                   opts.fSampleSize, yn(opts.fDitherImage),
                   options_colorType(opts), path.c_str());
        }
    }
}
예제 #13
0
bool SkInstallDiscardablePixelRef(SkData* encoded, SkBitmap* dst) {
    SkImageGenerator* generator = SkImageGenerator::NewFromEncoded(encoded);
    return generator ? SkInstallDiscardablePixelRef(generator, NULL, dst, NULL) : false;
}