Chromium Code Reviews| Index: src/core/SkBitmap.cpp |
| diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp |
| index 63a760c4cf7672a15068f8b801efc7a36d7d530e..bad63bac18f5d25ba1445a06fbc2fef17f2ad68f 100644 |
| --- a/src/core/SkBitmap.cpp |
| +++ b/src/core/SkBitmap.cpp |
| @@ -143,6 +143,7 @@ void SkBitmap::swap(SkBitmap& other) { |
| SkTSwap(fWidth, other.fWidth); |
| SkTSwap(fHeight, other.fHeight); |
| SkTSwap(fConfig, other.fConfig); |
| + SkTSwap(fAlphaType, other.fAlphaType); |
| SkTSwap(fFlags, other.fFlags); |
| SkTSwap(fBytesPerPixel, other.fBytesPerPixel); |
| @@ -266,33 +267,76 @@ void SkBitmap::getBounds(SkIRect* bounds) const { |
| /////////////////////////////////////////////////////////////////////////////// |
| -void SkBitmap::setConfig(Config c, int width, int height, size_t rowBytes) { |
| - this->freePixels(); |
| +static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType, |
| + SkAlphaType* canonical) { |
| + switch (config) { |
| + case SkBitmap::kNo_Config: |
| + alphaType = kIgnore_SkAlphaType; |
| + break; |
| + case SkBitmap::kA1_Config: |
| + case SkBitmap::kA8_Config: |
| + if (kUnpremul_SkAlphaType == alphaType) { |
| + alphaType = kPremul_SkAlphaType; |
|
scroggo
2014/06/10 20:11:59
Looking back at this as I write tests for Android.
|
| + } |
| + // fall-through |
| + case SkBitmap::kIndex8_Config: |
| + case SkBitmap::kARGB_4444_Config: |
| + case SkBitmap::kARGB_8888_Config: |
| + if (kIgnore_SkAlphaType == alphaType) { |
| + return false; |
| + } |
| + break; |
| + case SkBitmap::kRGB_565_Config: |
| + alphaType = kOpaque_SkAlphaType; |
| + break; |
| + } |
| + if (canonical) { |
| + *canonical = alphaType; |
| + } |
| + return true; |
| +} |
| +bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, |
| + SkAlphaType alphaType) { |
| if ((width | height) < 0) { |
| - goto err; |
| + goto ERROR; |
| } |
| - |
| if (rowBytes == 0) { |
| - rowBytes = SkBitmap::ComputeRowBytes(c, width); |
| - if (0 == rowBytes && kNo_Config != c) { |
| - goto err; |
| + rowBytes = SkBitmap::ComputeRowBytes(config, width); |
| + if (0 == rowBytes && kNo_Config != config) { |
| + goto ERROR; |
| } |
| } |
| - fConfig = SkToU8(c); |
| + if (!validate_alphaType(config, alphaType, &alphaType)) { |
| + goto ERROR; |
| + } |
| + |
| + this->freePixels(); |
| + |
| + fConfig = SkToU8(config); |
| + fAlphaType = SkToU8(alphaType); |
| fWidth = width; |
| fHeight = height; |
| fRowBytes = SkToU32(rowBytes); |
| - fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(c); |
| + fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config); |
| SkDEBUGCODE(this->validate();) |
| - return; |
| + return true; |
| // if we got here, we had an error, so we reset the bitmap to empty |
| -err: |
| +ERROR: |
| this->reset(); |
| + return false; |
| +} |
| + |
| +bool SkBitmap::setAlphaType(SkAlphaType alphaType) { |
| + if (!validate_alphaType(this->config(), alphaType, &alphaType)) { |
| + return false; |
| + } |
| + fAlphaType = SkToU8(alphaType); |
| + return true; |
| } |
| void SkBitmap::updatePixelsFromRef() const { |
| @@ -524,46 +568,6 @@ void SkBitmap::setImmutable() { |
| } |
| } |
| -bool SkBitmap::isOpaque() const { |
| - switch (fConfig) { |
| - case kNo_Config: |
| - return true; |
| - |
| - case kA1_Config: |
| - case kA8_Config: |
| - case kARGB_4444_Config: |
| - case kARGB_8888_Config: |
| - return (fFlags & kImageIsOpaque_Flag) != 0; |
| - |
| - case kIndex8_Config: { |
| - bool isOpaque; |
| - |
| - this->lockPixels(); |
| - isOpaque = fColorTable && fColorTable->isOpaque(); |
| - this->unlockPixels(); |
| - return isOpaque; |
| - } |
| - |
| - case kRGB_565_Config: |
| - return true; |
| - |
| - default: |
| - SkDEBUGFAIL("unknown bitmap config pased to isOpaque"); |
| - return false; |
| - } |
| -} |
| - |
| -void SkBitmap::setIsOpaque(bool isOpaque) { |
| - /* we record this regardless of fConfig, though it is ignored in |
| - isOpaque() for configs that can't support per-pixel alpha. |
| - */ |
| - if (isOpaque) { |
| - fFlags |= kImageIsOpaque_Flag; |
| - } else { |
| - fFlags &= ~kImageIsOpaque_Flag; |
| - } |
| -} |
| - |
| bool SkBitmap::isVolatile() const { |
| return (fFlags & kImageIsVolatile_Flag) != 0; |
| } |
| @@ -958,9 +962,9 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { |
| SkPixelRef* pixelRef = fPixelRef->deepCopy(this->config(), &subset); |
| if (pixelRef != NULL) { |
| SkBitmap dst; |
| - dst.setConfig(this->config(), subset.width(), subset.height()); |
| + dst.setConfig(this->config(), subset.width(), subset.height(), 0, |
| + this->alphaType()); |
| dst.setIsVolatile(this->isVolatile()); |
| - dst.setIsOpaque(this->isOpaque()); |
| dst.setPixelRef(pixelRef)->unref(); |
| SkDEBUGCODE(dst.validate()); |
| result->swap(dst); |
| @@ -979,9 +983,9 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { |
| } |
| SkBitmap dst; |
| - dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes()); |
| + dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(), |
| + this->alphaType()); |
| dst.setIsVolatile(this->isVolatile()); |
| - dst.setIsOpaque(this->isOpaque()); |
| if (fPixelRef) { |
| // share the pixelref with a custom offset |
| @@ -1070,7 +1074,8 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { |
| } |
| SkBitmap tmpDst; |
| - tmpDst.setConfig(dstConfig, src->width(), src->height()); |
| + tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, |
| + src->alphaType()); |
| // allocate colortable if srcConfig == kIndex8_Config |
| SkColorTable* ctable = (dstConfig == kIndex8_Config) ? |
| @@ -1130,8 +1135,6 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { |
| canvas.drawBitmap(*src, 0, 0, &paint); |
| } |
| - tmpDst.setIsOpaque(src->isOpaque()); |
| - |
| dst->swap(tmpDst); |
| return true; |
| } |
| @@ -1579,7 +1582,7 @@ void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const { |
| buffer.writeInt(fHeight); |
| buffer.writeInt(fRowBytes); |
| buffer.writeInt(fConfig); |
| - buffer.writeBool(this->isOpaque()); |
| + buffer.writeInt(fAlphaType); |
| if (fPixelRef) { |
| if (fPixelRef->getFactory()) { |
| @@ -1602,9 +1605,9 @@ void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) { |
| int height = buffer.readInt(); |
| int rowBytes = buffer.readInt(); |
| int config = buffer.readInt(); |
| + int alphaType = buffer.readInt(); |
| - this->setConfig((Config)config, width, height, rowBytes); |
| - this->setIsOpaque(buffer.readBool()); |
| + this->setConfig((Config)config, width, height, rowBytes, (SkAlphaType)alphaType); |
| int reftype = buffer.readInt(); |
| switch (reftype) { |