From bae704b050491a8a98c67cb23eaccb10852d2bd5 Mon Sep 17 00:00:00 2001 From: reed Date: Sat, 28 Jun 2014 14:26:35 -0700 Subject: [PATCH] add rowbytes option to allocPixels TBR= Author: reed@google.com Review URL: https://codereview.chromium.org/345263005 --- bench/BitmapBench.cpp | 6 ++---- include/core/SkBitmap.h | 14 ++++++++++++-- src/animator/SkDrawBitmap.cpp | 4 ++-- src/core/SkBitmap.cpp | 30 ++++++++++++++++++++++++++++++ src/lazy/SkCachingPixelRef.cpp | 2 +- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/bench/BitmapBench.cpp b/bench/BitmapBench.cpp index a269e90..e9ba1dc 100644 --- a/bench/BitmapBench.cpp +++ b/bench/BitmapBench.cpp @@ -107,12 +107,10 @@ protected: SkBitmap bm; if (kIndex_8_SkColorType == fColorType) { - bm.setInfo(SkImageInfo::MakeN32(W, H, fAlphaType)); + bm.allocPixels(SkImageInfo::MakeN32(W, H, fAlphaType)); } else { - bm.setInfo(SkImageInfo::Make(W, H, fColorType, fAlphaType)); + bm.allocPixels(SkImageInfo::Make(W, H, fColorType, fAlphaType)); } - - bm.allocPixels(); bm.eraseColor(kOpaque_SkAlphaType == fAlphaType ? SK_ColorBLACK : 0); onDrawIntoBitmap(bm); diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h index d3a20c0..6728308 100644 --- a/include/core/SkBitmap.h +++ b/include/core/SkBitmap.h @@ -290,7 +290,7 @@ public: #endif /** - * Allocate a pixelref to match the specified image info. If the Factory + * Allocate the bitmap's pixels to match the requested 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. @@ -298,13 +298,23 @@ public: bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*); /** + * Allocate the bitmap's pixels to match the requested image info and + * rowBytes. If the request cannot be met (e.g. the info is invalid or + * the requested rowBytes are not compatible with the info + * (e.g. rowBytes < info.minRowBytes() or rowBytes is not aligned with + * the pixel size specified by info.colorType()) then false is returned + * and the bitmap is set to empty. + */ + bool allocPixels(const SkImageInfo& info, size_t rowBytes); + + /** * 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); + return this->allocPixels(info, info.minRowBytes()); } bool allocN32Pixels(int width, int height, bool isOpaque = false) { diff --git a/src/animator/SkDrawBitmap.cpp b/src/animator/SkDrawBitmap.cpp index f481ee7..5349774 100644 --- a/src/animator/SkDrawBitmap.cpp +++ b/src/animator/SkDrawBitmap.cpp @@ -89,8 +89,8 @@ void SkDrawBitmap::onEndElement(SkAnimateMaker&) { SkASSERT(height != -1); SkASSERT(rowBytes >= 0); SkColorType colorType = SkColorType(format); - fBitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType), rowBytes); - fBitmap.allocPixels(); + fBitmap.allocPixels(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType), + rowBytes); if (fColorSet) fBitmap.eraseColor(fColor); } diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 789bf11..38df07c 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -366,6 +366,36 @@ bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) { /////////////////////////////////////////////////////////////////////////////// +bool SkBitmap::allocPixels(const SkImageInfo& requestedInfo, size_t rowBytes) { + if (kIndex_8_SkColorType == requestedInfo.colorType()) { + return reset_return_false(this); + } + if (!this->setInfo(requestedInfo)) { + return reset_return_false(this); + } + + // setInfo may have corrected info (e.g. 565 is always opaque). + const SkImageInfo& correctedInfo = this->info(); + if (!correctedInfo.validRowBytes(rowBytes)) { + return reset_return_false(this); + } + + SkMallocPixelRef::PRFactory defaultFactory; + + SkPixelRef* pr = defaultFactory.create(correctedInfo, NULL); + 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::allocPixels(const SkImageInfo& requestedInfo, SkPixelRefFactory* factory, SkColorTable* ctable) { if (kIndex_8_SkColorType == requestedInfo.fColorType && NULL == ctable) { diff --git a/src/lazy/SkCachingPixelRef.cpp b/src/lazy/SkCachingPixelRef.cpp index 76510f6..97503e5 100644 --- a/src/lazy/SkCachingPixelRef.cpp +++ b/src/lazy/SkCachingPixelRef.cpp @@ -54,7 +54,7 @@ bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) { &bitmap); if (NULL == fScaledCacheId) { // Cache has been purged, must re-decode. - if ((!bitmap.setInfo(info, fRowBytes)) || !bitmap.allocPixels()) { + if (!bitmap.allocPixels(info, fRowBytes)) { fErrorInDecoding = true; return false; } -- 2.7.4