Index: src/core/SkImageCacherator.cpp |
diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp |
index 82f36edfb378724757de4700f957396a8720886d..8c0e415770fb7539c50370f4541708c99bc9a519 100644 |
--- a/src/core/SkImageCacherator.cpp |
+++ b/src/core/SkImageCacherator.cpp |
@@ -70,36 +70,63 @@ static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) { |
return true; |
} |
-bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) { |
- const size_t rowBytes = fInfo.minRowBytes(); |
- if (!bitmap->tryAllocPixels(fInfo, rowBytes)) { |
+static void release_malloc_proc(void* pixels, void* ctx) { |
+ sk_free(pixels); |
+} |
+ |
+static bool generate_a_bitmap(SkBitmap* bitmap, SkImageGenerator* gen, const SkImageInfo& info) { |
+ const size_t rowBytes = info.minRowBytes(); |
+ const size_t pixelSize = info.getSafeSize(rowBytes); |
+ if (0 == pixelSize) { |
+ return false; |
+ } |
+ |
+ SkAutoFree pixelStorage(sk_malloc_flags(pixelSize, 0)); |
+ void* pixels = pixelStorage.get(); |
+ if (!pixels) { |
+ return false; |
+ } |
+ |
+ SkPMColor ctStorage[256]; |
+ int ctCount = 0; |
+ |
+ if (!gen->getPixels(info, pixels, rowBytes, ctStorage, &ctCount)) { |
return false; |
} |
- SkASSERT(bitmap->rowBytes() == rowBytes); |
+ SkAutoTUnref<SkColorTable> ctable; |
+ if (ctCount > 0) { |
+ SkASSERT(kIndex_8_SkColorType == info.colorType()); |
+ ctable.reset(new SkColorTable(ctStorage, ctCount)); |
+ } else { |
+ SkASSERT(kIndex_8_SkColorType != info.colorType()); |
+ } |
+ |
+ return bitmap->installPixels(info, pixelStorage.detach(), rowBytes, ctable, |
+ release_malloc_proc, nullptr); |
+} |
+ |
+bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) { |
ScopedGenerator generator(this); |
const SkImageInfo& genInfo = generator->getInfo(); |
if (fInfo.dimensions() == genInfo.dimensions()) { |
SkASSERT(fOrigin.x() == 0 && fOrigin.y() == 0); |
// fast-case, no copy needed |
- if (!generator->getPixels(bitmap->info(), bitmap->getPixels(), rowBytes)) { |
- bitmap->reset(); |
- return false; |
- } |
+ return generate_a_bitmap(bitmap, generator, fInfo); |
} else { |
- // need to handle subsetting |
+ // need to handle subsetting, so we first generate the full size version, and then |
+ // "read" from it to get our subset. See skbug.com/4213 |
+ |
SkBitmap full; |
- if (!full.tryAllocPixels(genInfo)) { |
+ if (!generate_a_bitmap(&full, generator, genInfo)) { |
return false; |
} |
- if (!generator->getPixels(full.info(), full.getPixels(), full.rowBytes())) { |
- bitmap->reset(); |
+ if (!bitmap->tryAllocPixels(fInfo, nullptr, full.getColorTable())) { |
return false; |
} |
- full.readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), |
- fOrigin.x(), fOrigin.y()); |
+ return full.readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), |
+ fOrigin.x(), fOrigin.y()); |
} |
- return true; |
} |
////////////////////////////////////////////////////////////////////////////////////////////////// |