Index: src/core/SkBitmap.cpp |
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp |
index 07f6f177deb16bc5df445381ae61d78e019fc404..ec324964ea899e4eda410080fc25df2321b4bf98 100644 |
--- a/src/core/SkBitmap.cpp |
+++ b/src/core/SkBitmap.cpp |
@@ -413,21 +413,24 @@ bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) { |
/////////////////////////////////////////////////////////////////////////////// |
-bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, |
+bool SkBitmap::allocPixels(const SkImageInfo& requestedInfo, SkPixelRefFactory* factory, |
SkColorTable* ctable) { |
- if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { |
+ if (kIndex_8_SkColorType == requestedInfo.fColorType && NULL == ctable) { |
return reset_return_false(this); |
} |
- if (!this->setInfo(info)) { |
+ 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(); |
+ |
SkMallocPixelRef::PRFactory defaultFactory; |
if (NULL == factory) { |
factory = &defaultFactory; |
} |
- SkPixelRef* pr = factory->create(info, ctable); |
+ SkPixelRef* pr = factory->create(correctedInfo, ctable); |
if (NULL == pr) { |
return reset_return_false(this); |
} |
@@ -441,14 +444,19 @@ bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, |
return true; |
} |
-bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb, SkColorTable* ct, |
- void (*releaseProc)(void* addr, void* context), void* context) { |
- if (!this->setInfo(info, rb)) { |
+bool SkBitmap::installPixels(const SkImageInfo& requestedInfo, void* pixels, size_t rb, |
+ SkColorTable* ct, void (*releaseProc)(void* addr, void* context), |
+ void* context) { |
+ if (!this->setInfo(requestedInfo, rb)) { |
this->reset(); |
return false; |
} |
- SkPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rb, ct, pixels, releaseProc, context); |
+ // setInfo may have corrected info (e.g. 565 is always opaque). |
+ const SkImageInfo& correctedInfo = this->info(); |
+ |
+ SkPixelRef* pr = SkMallocPixelRef::NewWithProc(correctedInfo, rb, ct, pixels, releaseProc, |
+ context); |
if (!pr) { |
this->reset(); |
return false; |
@@ -962,6 +970,11 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, |
subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, |
fInfo.width(), fInfo.height()); |
if (fPixelRef->readPixels(&tmpSrc, &subset)) { |
+ if (fPixelRef->info().alphaType() == kUnpremul_SkAlphaType) { |
+ // FIXME: The only meaningful implementation of readPixels |
+ // (GrPixelRef) assumes premultiplied pixels. |
+ return false; |
+ } |
SkASSERT(tmpSrc.width() == this->width()); |
SkASSERT(tmpSrc.height() == this->height()); |
@@ -1021,23 +1034,10 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, |
if (src->colorType() == dstColorType) { |
if (tmpDst.getSize() == src->getSize()) { |
memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); |
- SkPixelRef* pixelRef = tmpDst.pixelRef(); |
- |
- // In order to reach this point, we know that the width, config and |
- // rowbytes of the SkPixelRefs are the same, but it is possible for |
- // the heights to differ, if this SkBitmap's height is a subset of |
- // fPixelRef. Only if the SkPixelRefs' heights match are we |
- // guaranteed that this is an exact copy, meaning we should clone |
- // the genID. |
- if (pixelRef->info().fHeight == fPixelRef->info().fHeight) { |
- // TODO: what to do if the two infos match, BUT |
- // fPixelRef is premul and pixelRef is opaque? |
- // skipping assert for now |
- // https://code.google.com/p/skia/issues/detail?id=2012 |
-// SkASSERT(pixelRef->info() == fPixelRef->info()); |
- SkASSERT(pixelRef->info().fWidth == fPixelRef->info().fWidth); |
- SkASSERT(pixelRef->info().fColorType == fPixelRef->info().fColorType); |
- pixelRef->cloneGenID(*fPixelRef); |
+ |
+ SkPixelRef* dstPixelRef = tmpDst.pixelRef(); |
+ if (dstPixelRef->info() == fPixelRef->info()) { |
+ dstPixelRef->cloneGenID(*fPixelRef); |
} |
} else { |
const char* srcP = reinterpret_cast<const char*>(src->getPixels()); |
@@ -1052,6 +1052,10 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, |
} |
} else if (kARGB_4444_SkColorType == dstColorType |
&& kN32_SkColorType == src->colorType()) { |
+ if (src->alphaType() == kUnpremul_SkAlphaType) { |
+ // Our method for converting to 4444 assumes premultiplied. |
+ return false; |
+ } |
SkASSERT(src->height() == tmpDst.height()); |
SkASSERT(src->width() == tmpDst.width()); |
for (int y = 0; y < src->height(); ++y) { |
@@ -1064,6 +1068,11 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, |
} |
} |
} else { |
+ if (tmpDst.alphaType() == kUnpremul_SkAlphaType) { |
+ // We do not support drawing to unpremultiplied bitmaps. |
+ return false; |
+ } |
+ |
// Always clear the dest in case one of the blitters accesses it |
// TODO: switch the allocation of tmpDst to call sk_calloc_throw |
tmpDst.eraseColor(SK_ColorTRANSPARENT); |