aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-24 18:53:42 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-24 18:53:42 +0000
commit9ebcac54635cde63110d73ad7c43d70772e7872f (patch)
tree59ed546835d806d958e25892d79097724efbf983
parentbde4ba2ce6994a57f1b4e820ac83e9d27caf75de (diff)
add installPixels
BUG=skia: R=halcanary@google.com Review URL: https://codereview.chromium.org/143073008 git-svn-id: http://skia.googlecode.com/svn/trunk@13174 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkBitmap.h32
-rw-r--r--include/core/SkMallocPixelRef.h6
-rw-r--r--include/core/SkPixelRef.h11
-rw-r--r--src/core/SkBitmap.cpp56
-rw-r--r--src/core/SkBitmapDevice.cpp6
-rw-r--r--src/core/SkDevice.cpp5
-rw-r--r--src/core/SkMallocPixelRef.cpp8
-rw-r--r--src/core/SkOrderedReadBuffer.cpp3
-rw-r--r--src/effects/SkAlphaThresholdFilter.cpp3
-rw-r--r--src/effects/SkBicubicImageFilter.cpp3
-rw-r--r--src/effects/SkBlurImageFilter.cpp3
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp3
-rw-r--r--src/effects/SkLightingImageFilter.cpp3
-rw-r--r--src/effects/SkPerlinNoiseShader.cpp6
-rw-r--r--src/effects/SkTableColorFilter.cpp3
-rw-r--r--src/gpu/GrSWMaskHelper.cpp3
-rw-r--r--src/gpu/GrSurface.cpp6
-rw-r--r--src/gpu/SkGrPixelRef.cpp3
-rw-r--r--src/images/SkMovie_gif.cpp6
-rw-r--r--src/lazy/SkDiscardablePixelRef.cpp2
-rw-r--r--src/pdf/SkPDFDevice.cpp12
-rw-r--r--src/utils/SkPDFRasterizer.cpp3
-rw-r--r--src/utils/debugger/SkDebugCanvas.cpp3
-rw-r--r--src/utils/mac/SkCreateCGImageRef.cpp5
24 files changed, 143 insertions, 51 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index f53a0a7e45..af0c8b87e7 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -18,6 +18,7 @@ struct SkIRect;
struct SkRect;
class SkPaint;
class SkPixelRef;
+class SkPixelRefFactory;
class SkRegion;
class SkString;
@@ -250,6 +251,35 @@ public:
bool setConfig(const SkImageInfo& info, size_t rowBytes = 0);
/**
+ * Allocate a pixelref to match the specified image info. If the Factory
+ * is non-null, call it to allcoate the pixelref. If the ImageInfo requires
+ * a colortable, then ColorTable must be non-null, and will be ref'd.
+ * On failure, the bitmap will be set to empty and return false.
+ */
+ bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
+
+ /**
+ * Allocate a pixelref to match the specified image info, using the default
+ * allocator.
+ * On success, the bitmap's pixels will be "locked", and return true.
+ * On failure, the bitmap will be set to empty and return false.
+ */
+ bool allocPixels(const SkImageInfo& info) {
+ return this->allocPixels(info, NULL, NULL);
+ }
+
+ /**
+ * Install a pixelref that wraps the specified pixels and rowBytes, and
+ * optional ReleaseProc and context. When the pixels are no longer
+ * referenced, if ReleaseProc is not null, it will be called with the
+ * pixels and context as parameters.
+ * On failure, the bitmap will be set to empty and return false.
+ */
+ bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes,
+ void (*ReleaseProc)(void* addr, void* context),
+ void* context);
+
+ /**
* If the bitmap's config can be represented as SkImageInfo, return true,
* and if info is not-null, set it to the bitmap's info. If it cannot be
* represented as SkImageInfo, return false and ignore the info parameter.
@@ -637,7 +667,7 @@ public:
*/
class HeapAllocator : public Allocator {
public:
- virtual bool allocPixelRef(SkBitmap*, SkColorTable*);
+ virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
};
class RLEPixels {
diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h
index 6642af57bb..4607fa2843 100644
--- a/include/core/SkMallocPixelRef.h
+++ b/include/core/SkMallocPixelRef.h
@@ -79,6 +79,12 @@ public:
void* getAddr() const { return fStorage; }
+ class PRFactory : public SkPixelRefFactory {
+ public:
+ virtual SkPixelRef* create(const SkImageInfo&,
+ SkColorTable*) SK_OVERRIDE;
+ };
+
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
protected:
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index fc0feb042a..e65f4a04c5 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -364,4 +364,15 @@ private:
typedef SkFlattenable INHERITED;
};
+class SkPixelRefFactory : public SkRefCnt {
+public:
+ /**
+ * Allocate a new pixelref matching the specified ImageInfo, allocating
+ * the memory for the pixels. If the ImageInfo requires a ColorTable,
+ * the pixelref will ref() the colortable.
+ * On failure return NULL.
+ */
+ virtual SkPixelRef* create(const SkImageInfo&, SkColorTable*) = 0;
+};
+
#endif
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 2464d5d596..9227906eab 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -488,13 +488,67 @@ void SkBitmap::setPixels(void* p, SkColorTable* ctable) {
bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) {
HeapAllocator stdalloc;
-
+
if (NULL == allocator) {
allocator = &stdalloc;
}
return allocator->allocPixelRef(this, ctable);
}
+///////////////////////////////////////////////////////////////////////////////
+
+static bool reset_return_false(SkBitmap* bm) {
+ bm->reset();
+ return false;
+}
+
+bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory,
+ SkColorTable* ctable) {
+ if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) {
+ return reset_return_false(this);
+ }
+ if (!this->setConfig(info)) {
+ return reset_return_false(this);
+ }
+
+ SkMallocPixelRef::PRFactory defaultFactory;
+ if (NULL == factory) {
+ factory = &defaultFactory;
+ }
+
+ SkPixelRef* pr = factory->create(info, ctable);
+ if (NULL == pr) {
+ return reset_return_false(this);
+ }
+ this->setPixelRef(pr)->unref();
+
+ // TODO: lockPixels could/should return bool or void*/NULL
+ this->lockPixels();
+ if (NULL == this->getPixels()) {
+ return reset_return_false(this);
+ }
+ return true;
+}
+
+bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb,
+ void (*releaseProc)(void* addr, void* context),
+ void* context) {
+ if (!this->setConfig(info)) {
+ this->reset();
+ return false;
+ }
+
+ SkPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rb, NULL, pixels,
+ releaseProc, context);
+ if (!pr) {
+ this->reset();
+ return false;
+ }
+
+ this->setPixelRef(pr)->unref();
+ return true;
+}
+
void SkBitmap::freePixels() {
// if we're gonna free the pixels, we certainly need to free the mipmap
this->freeMipMap();
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 0570fd9afd..4b4f45317f 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -164,10 +164,8 @@ void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
drawSprite = false;
} else {
// we convert to a temporary bitmap and draw that as a sprite
- dstBmp.setConfig(SkBitmap::kARGB_8888_Config,
- spriteRect.width(),
- spriteRect.height());
- if (!dstBmp.allocPixels()) {
+ if (!dstBmp.allocPixels(SkImageInfo::MakeN32Premul(spriteRect.width(),
+ spriteRect.height()))) {
return;
}
drawSprite = true;
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 0c9e9d66b6..c08ae26159 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -92,9 +92,8 @@ bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y,
SkBitmap tmp;
SkBitmap* bmp;
if (bitmap->isNull()) {
- tmp.setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(),
- bitmap->height());
- if (!tmp.allocPixels()) {
+ if (!tmp.allocPixels(SkImageInfo::MakeN32Premul(bitmap->width(),
+ bitmap->height()))) {
return false;
}
bmp = &tmp;
diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp
index 50357e469b..c591ffb37d 100644
--- a/src/core/SkMallocPixelRef.cpp
+++ b/src/core/SkMallocPixelRef.cpp
@@ -238,3 +238,11 @@ SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer)
this->setPreLocked(fStorage, fRB, fCTable);
}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkPixelRef* SkMallocPixelRef::PRFactory::create(const SkImageInfo& info,
+ SkColorTable* ctable) {
+ return SkMallocPixelRef::NewAllocate(info, info.minRowBytes(), ctable);
+}
+
diff --git a/src/core/SkOrderedReadBuffer.cpp b/src/core/SkOrderedReadBuffer.cpp
index 69c60cbe09..1ebaac4da8 100644
--- a/src/core/SkOrderedReadBuffer.cpp
+++ b/src/core/SkOrderedReadBuffer.cpp
@@ -252,8 +252,7 @@ void SkOrderedReadBuffer::readBitmap(SkBitmap* bitmap) {
}
}
// Could not read the SkBitmap. Use a placeholder bitmap.
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
- bitmap->allocPixels();
+ bitmap->allocPixels(SkImageInfo::MakeN32Premul(width, height));
bitmap->eraseColor(SK_ColorRED);
}
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index f15a13dd8b..4bcb32031b 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -323,8 +323,7 @@ bool SkAlphaThresholdFilterImpl::onFilterImage(Proxy*, const SkBitmap& src,
}
dst->setConfig(src.config(), src.width(), src.height());
- dst->allocPixels();
- if (!dst->getPixels()) {
+ if (!dst->allocPixels()) {
return false;
}
diff --git a/src/effects/SkBicubicImageFilter.cpp b/src/effects/SkBicubicImageFilter.cpp
index 96d46aa7ce..8b89a343d0 100644
--- a/src/effects/SkBicubicImageFilter.cpp
+++ b/src/effects/SkBicubicImageFilter.cpp
@@ -108,8 +108,7 @@ bool SkBicubicImageFilter::onFilterImage(Proxy* proxy,
return false;
}
result->setConfig(src.config(), dstIRect.width(), dstIRect.height());
- result->allocPixels();
- if (!result->getPixels()) {
+ if (!result->allocPixels()) {
return false;
}
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index 7f3f532079..3e60c9bb87 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -160,8 +160,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
dst->setConfig(src.config(), srcBounds.width(), srcBounds.height());
dst->getBounds(&dstBounds);
- dst->allocPixels();
- if (!dst->getPixels()) {
+ if (!dst->allocPixels()) {
return false;
}
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 8264ec8e06..6ad46badb9 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -229,8 +229,7 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy,
}
dst->setConfig(color.config(), bounds.width(), bounds.height());
- dst->allocPixels();
- if (!dst->getPixels()) {
+ if (!dst->allocPixels()) {
return false;
}
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index b24a91eb44..81c62fe6dc 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -952,8 +952,7 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy* proxy,
}
dst->setConfig(src.config(), bounds.width(), bounds.height());
- dst->allocPixels();
- if (!dst->getPixels()) {
+ if (!dst->allocPixels()) {
return false;
}
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index 77ce9cb348..cdf8baf682 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -241,8 +241,7 @@ public:
{
if (!fPermutationsBitmap) {
fPermutationsBitmap = SkNEW(SkBitmap);
- fPermutationsBitmap->setConfig(SkBitmap::kA8_Config, kBlockSize, 1);
- fPermutationsBitmap->allocPixels();
+ fPermutationsBitmap->allocPixels(SkImageInfo::MakeA8(kBlockSize, 1));
uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0);
memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize);
}
@@ -253,8 +252,7 @@ public:
{
if (!fNoiseBitmap) {
fNoiseBitmap = SkNEW(SkBitmap);
- fNoiseBitmap->setConfig(SkBitmap::kARGB_8888_Config, kBlockSize, 4);
- fNoiseBitmap->allocPixels();
+ fNoiseBitmap->allocPixels(SkImageInfo::MakeN32Premul(kBlockSize, 4));
uint32_t* bitmapPixels = fNoiseBitmap->getAddr32(0, 0);
memcpy(bitmapPixels, fNoise[0][0], sizeof(uint16_t) * kBlockSize * 4 * 2);
}
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 203f058364..2872ed14b0 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -203,8 +203,7 @@ bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
if (table) {
if (NULL == fBitmap) {
SkBitmap* bmp = SkNEW(SkBitmap);
- bmp->setConfig(SkBitmap::kA8_Config, 256, 4, 256);
- bmp->allocPixels();
+ bmp->allocPixels(SkImageInfo::MakeA8(256, 4));
uint8_t* bitmapPixels = bmp->getAddr8(0, 0);
int offset = 0;
static const unsigned kFlags[] = { kA_Flag, kR_Flag, kG_Flag, kB_Flag };
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index eefc951e7e..504f5a0a35 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -99,8 +99,7 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds,
SkIRect bounds = SkIRect::MakeWH(resultBounds.width(),
resultBounds.height());
- fBM.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom);
- if (!fBM.allocPixels()) {
+ if (!fBM.allocPixels(SkImageInfo::MakeA8(bounds.fRight, bounds.fBottom))) {
return false;
}
sk_bzero(fBM.getPixels(), fBM.getSafeSize());
diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp
index 1fcc4ff18b..66ebe3b1e1 100644
--- a/src/gpu/GrSurface.cpp
+++ b/src/gpu/GrSurface.cpp
@@ -23,8 +23,10 @@ void GrSurface::asImageInfo(SkImageInfo* info) const {
bool GrSurface::savePixels(const char* filename) {
SkBitmap bm;
- bm.setConfig(SkBitmap::kARGB_8888_Config, this->width(), this->height());
- bm.allocPixels();
+ if (!bm.allocPixels(SkImageInfo::MakeN32Premul(this->width(),
+ this->height()))) {
+ return false;
+ }
bool result = readPixels(0, 0, this->width(), this->height(), kSkia8888_GrPixelConfig,
bm.getPixels());
diff --git a/src/gpu/SkGrPixelRef.cpp b/src/gpu/SkGrPixelRef.cpp
index 8a16437780..fdf94870cc 100644
--- a/src/gpu/SkGrPixelRef.cpp
+++ b/src/gpu/SkGrPixelRef.cpp
@@ -178,8 +178,7 @@ bool SkGrPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
top = 0;
height = fSurface->height();
}
- dst->setConfig(SkBitmap::kARGB_8888_Config, width, height);
- if (!dst->allocPixels()) {
+ if (!dst->allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
SkDebugf("SkGrPixelRef::onReadPixels failed to alloc bitmap for result!\n");
return false;
}
diff --git a/src/images/SkMovie_gif.cpp b/src/images/SkMovie_gif.cpp
index b6d068a391..decefd5acc 100644
--- a/src/images/SkMovie_gif.cpp
+++ b/src/images/SkMovie_gif.cpp
@@ -364,13 +364,11 @@ bool SkGIFMovie::onGetBitmap(SkBitmap* bm)
startIndex = 0;
// create bitmap
- bm->setConfig(SkBitmap::kARGB_8888_Config, width, height, 0);
- if (!bm->allocPixels(NULL)) {
+ if (!bm->allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
return false;
}
// create bitmap for backup
- fBackup.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0);
- if (!fBackup.allocPixels(NULL)) {
+ if (!fBackup.allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
return false;
}
} else if (startIndex > fCurrIndex) {
diff --git a/src/lazy/SkDiscardablePixelRef.cpp b/src/lazy/SkDiscardablePixelRef.cpp
index abd80f2e0a..0878d00335 100644
--- a/src/lazy/SkDiscardablePixelRef.cpp
+++ b/src/lazy/SkDiscardablePixelRef.cpp
@@ -89,7 +89,7 @@ bool SkInstallDiscardablePixelRef(SkImageGenerator* generator,
}
SkASSERT(dst->config() != SkBitmap::kNo_Config);
if (dst->empty()) { // Use a normal pixelref.
- return dst->allocPixels(NULL, NULL);
+ return dst->allocPixels();
}
SkAutoTUnref<SkDiscardablePixelRef> ref(
SkNEW_ARGS(SkDiscardablePixelRef,
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index a9ad49e9ee..ff83aadeee 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -2250,13 +2250,11 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix,
// the image. Avoiding alpha will reduce the pdf size and generation
// CPU time some.
- perspectiveBitmap.setConfig(
- SkBitmap::kARGB_8888_Config,
- SkScalarCeilToInt(
- physicalPerspectiveOutline.getBounds().width()),
- SkScalarCeilToInt(
- physicalPerspectiveOutline.getBounds().height()));
- perspectiveBitmap.allocPixels();
+ const int w = SkScalarCeilToInt(physicalPerspectiveOutline.getBounds().width());
+ const int h = SkScalarCeilToInt(physicalPerspectiveOutline.getBounds().height());
+ if (!perspectiveBitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) {
+ return;
+ }
perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT);
SkBitmapDevice device(perspectiveBitmap);
diff --git a/src/utils/SkPDFRasterizer.cpp b/src/utils/SkPDFRasterizer.cpp
index 68a31196ec..66634804bc 100644
--- a/src/utils/SkPDFRasterizer.cpp
+++ b/src/utils/SkPDFRasterizer.cpp
@@ -50,8 +50,7 @@ bool SkPopplerRasterizePDF(SkStream* pdf, SkBitmap* output) {
char *imgData = image.data();
SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
- if (!bitmap.allocPixels()) {
+ if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
return false;
}
bitmap.eraseColor(SK_ColorWHITE);
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index e491f3b8a7..1c3e26e643 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -74,8 +74,7 @@ void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
- bitmap.allocPixels();
+ bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
SkCanvas canvas(bitmap);
canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y));
diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp
index 0677b7bc30..1b52ba31a6 100644
--- a/src/utils/mac/SkCreateCGImageRef.cpp
+++ b/src/utils/mac/SkCreateCGImageRef.cpp
@@ -209,8 +209,9 @@ bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
int h = (int)CGRectGetHeight(bounds);
SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
- bitmap.allocPixels();
+ if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) {
+ return false;
+ }
bitmap.eraseColor(SK_ColorWHITE);
size_t bitsPerComponent;