Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: src/core/SkBitmap.cpp

Issue 25275004: store SkAlphaType inside SkBitmap, on road to support unpremul (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {

Powered by Google App Engine
This is Rietveld 408576698