virtual Result onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options&, SkPMColor ctableEntries[], int* ctableCount) override { SkMemoryStream stream(fData->data(), fData->size(), false); SkAutoTUnref<BareMemoryAllocator> allocator(SkNEW_ARGS(BareMemoryAllocator, (info, pixels, rowBytes))); fDecoder->setAllocator(allocator); fDecoder->setRequireUnpremultipliedColors(kUnpremul_SkAlphaType == info.alphaType()); SkBitmap bm; const SkImageDecoder::Result result = fDecoder->decode(&stream, &bm, info.colorType(), SkImageDecoder::kDecodePixels_Mode); if (SkImageDecoder::kFailure == result) { return kInvalidInput; } SkASSERT(info.colorType() == bm.info().colorType()); if (kIndex_8_SkColorType == info.colorType()) { SkASSERT(ctableEntries); SkColorTable* ctable = bm.getColorTable(); if (NULL == ctable) { return kInvalidConversion; } const int count = ctable->count(); memcpy(ctableEntries, ctable->readColors(), count * sizeof(SkPMColor)); *ctableCount = count; } if (SkImageDecoder::kPartialSuccess == result) { return kIncompleteInput; } return kSuccess; }
void DecodingBench::onDraw(const int n, SkCanvas* canvas) { SkBitmap bitmap; // Declare the allocator before the decoder, so it will outlive the // decoder, which will unref it. UseExistingAllocator allocator(fBitmap.pixelRef()); SkAutoTDelete<SkImageDecoder> decoder; SkAutoTDelete<SkStreamRewindable> stream; for (int i = 0; i < n; i++) { // create a new stream and a new decoder to mimic the behavior of // CodecBench. stream.reset(new SkMemoryStream(fData)); decoder.reset(SkImageDecoder::Factory(stream)); decoder->setAllocator(&allocator); decoder->decode(stream, &bitmap, fColorType, SkImageDecoder::kDecodePixels_Mode); } }