Index: src/ports/SkImageGenerator_skia.cpp |
diff --git a/src/ports/SkImageGenerator_skia.cpp b/src/ports/SkImageGenerator_skia.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cd02ae25673a86c6c632a9e3b2be5c5e283e1ce0 |
--- /dev/null |
+++ b/src/ports/SkImageGenerator_skia.cpp |
@@ -0,0 +1,116 @@ |
+/* |
+ * Copyright 2015 The Android Open Source Project |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkData.h" |
+#include "SkImageDecoder.h" |
+#include "SkImageGenerator.h" |
+#include "SkStream.h" |
+ |
+class BareMemoryAllocator : public SkBitmap::Allocator { |
+ const SkImageInfo fInfo; |
+ void* const fMemory; |
+ const size_t fRowBytes; |
+ |
+public: |
+ BareMemoryAllocator(const SkImageInfo& info, void* memory, size_t rowBytes) |
+ : fInfo(info), fMemory(memory), fRowBytes(rowBytes) |
+ {} |
+ |
+protected: |
+ bool allocPixelRef(SkBitmap* bm, SkColorTable* ctable) SK_OVERRIDE { |
+ const SkImageInfo bmi = bm->info(); |
+ if (bmi.width() != fInfo.width() || bmi.height() != fInfo.height() || |
+ bmi.colorType() != fInfo.colorType()) |
+ { |
+ return false; |
+ } |
+ return bm->installPixels(bmi, fMemory, fRowBytes, ctable, NULL, NULL); |
+ } |
+}; |
+ |
+class SkImageDecoderGenerator : public SkImageGenerator { |
+ const SkImageInfo fInfo; |
+ SkAutoTDelete<SkImageDecoder> fDecoder; |
+ SkAutoTUnref<SkData> fData; |
+ |
+public: |
+ SkImageDecoderGenerator(const SkImageInfo& info, SkImageDecoder* decoder, SkData* data) |
+ : fInfo(info), fDecoder(decoder), fData(SkRef(data)) |
+ {} |
+ |
+protected: |
+ SkData* onRefEncodedData() SK_OVERRIDE { |
+ return SkRef(fData.get()); |
+ } |
+ |
+ virtual bool onGetInfo(SkImageInfo* info) { |
+ *info = fInfo; |
+ return true; |
+ } |
+ |
+ virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, |
+ SkPMColor ctableEntries[], int* ctableCount) { |
+ 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; |
+ SkImageDecoder::Result result = fDecoder->decode(&stream, &bm, info.colorType(), |
+ SkImageDecoder::kDecodePixels_Mode); |
+ switch (result) { |
+ case SkImageDecoder::kSuccess: |
+ break; |
+ default: |
+ return false; |
+ } |
+ |
+ SkASSERT(info.colorType() == bm.info().colorType()); |
+ |
+ if (kIndex_8_SkColorType == info.colorType()) { |
+ SkASSERT(ctableEntries); |
+ |
+ SkColorTable* ctable = bm.getColorTable(); |
+ if (NULL == ctable) { |
+ return false; |
+ } |
+ const int count = ctable->count(); |
+ memcpy(ctableEntries, ctable->readColors(), count * sizeof(SkPMColor)); |
+ *ctableCount = count; |
+ } |
+ return true; |
+ } |
+ |
+ bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], |
+ SkYUVColorSpace* colorSpace) SK_OVERRIDE { |
+ SkMemoryStream stream(fData->data(), fData->size(), false); |
+ return fDecoder->decodeYUV8Planes(&stream, sizes, planes, rowBytes, colorSpace); |
+ } |
+ |
+}; |
+ |
+SkImageGenerator* SkImageGenerator::NewFromData(SkData* data) { |
+ if (NULL == data) { |
+ return NULL; |
+ } |
+ |
+ SkMemoryStream stream(data->data(), data->size(), false); |
+ SkImageDecoder* decoder = SkImageDecoder::Factory(&stream); |
+ if (NULL == decoder) { |
+ return NULL; |
+ } |
+ |
+ SkBitmap bm; |
+ stream.rewind(); |
+ if (!decoder->decode(&stream, &bm, kUnknown_SkColorType, SkImageDecoder::kDecodeBounds_Mode)) { |
+ SkDELETE(decoder); |
+ return NULL; |
+ } |
+ |
+ return SkNEW_ARGS(SkImageDecoderGenerator, (bm.info(), decoder, data)); |
+} |