Fix reconfigure & setPremult alpha handling
Bug: 20948129
Change-Id: Ifba35e5d87772a304fd3655e4a2363b293a6d8ac
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 04b9a95..832f92f 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -46,8 +46,8 @@
SkSafeUnref(mColorTable);
}
- void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) {
- if (kIndex_8_SkColorType != info.colorType()) {
+ void reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
+ if (kIndex_8_SkColorType != newInfo.colorType()) {
ctable = nullptr;
}
mRowBytes = rowBytes;
@@ -56,13 +56,22 @@
mColorTable = ctable;
SkSafeRef(mColorTable);
}
+
+ // Need to validate the alpha type to filter against the color type
+ // to prevent things like a non-opaque RGB565 bitmap
+ SkAlphaType alphaType;
+ LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
+ newInfo.colorType(), newInfo.alphaType(), &alphaType),
+ "Failed to validate alpha type!");
+
// Dirty hack is dirty
// TODO: Figure something out here, Skia's current design makes this
// really hard to work with. Skia really, really wants immutable objects,
// but with the nested-ref-count hackery going on that's just not
// feasible without going insane trying to figure it out
SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
- *myInfo = info;
+ *myInfo = newInfo;
+ changeAlphaType(alphaType);
// Docs say to only call this in the ctor, but we're going to call
// it anyway even if this isn't always the ctor.
@@ -254,6 +263,14 @@
reconfigure(info, info.minRowBytes(), nullptr);
}
+void Bitmap::setAlphaType(SkAlphaType alphaType) {
+ if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) {
+ return;
+ }
+
+ mPixelRef->changeAlphaType(alphaType);
+}
+
void Bitmap::detachFromJava() {
bool disposeSelf;
{
@@ -861,10 +878,10 @@
jboolean hasAlpha, jboolean requestPremul) {
LocalScopedBitmap bitmap(bitmapHandle);
if (hasAlpha) {
- bitmap->peekAtPixelRef()->changeAlphaType(
+ bitmap->setAlphaType(
requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
} else {
- bitmap->peekAtPixelRef()->changeAlphaType(kOpaque_SkAlphaType);
+ bitmap->setAlphaType(kOpaque_SkAlphaType);
}
}
@@ -873,9 +890,9 @@
LocalScopedBitmap bitmap(bitmapHandle);
if (!bitmap->info().isOpaque()) {
if (isPremul) {
- bitmap->peekAtPixelRef()->changeAlphaType(kPremul_SkAlphaType);
+ bitmap->setAlphaType(kPremul_SkAlphaType);
} else {
- bitmap->peekAtPixelRef()->changeAlphaType(kUnpremul_SkAlphaType);
+ bitmap->setAlphaType(kUnpremul_SkAlphaType);
}
}
}