From 76d1e01d5e65c4631c827831e98ad4e300d99eab Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Fri, 5 Mar 2010 17:42:30 -0500 Subject: [PATCH] hidden api sameAs() to compare the pixels of 2 bitmaps for equality --- core/jni/android/graphics/Bitmap.cpp | 50 +++++++++++++++++++++- graphics/java/android/graphics/Bitmap.java | 14 ++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index 0f1b8458f369b..88bbafd772c95 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -527,6 +527,53 @@ static void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, } } +static bool Bitmap_sameAs(JNIEnv* env, jobject, const SkBitmap* bm0, + const SkBitmap* bm1) { + if (bm0->width() != bm1->width() || + bm0->height() != bm1->height() || + bm0->config() != bm1->config()) { + return false; + } + + SkAutoLockPixels alp0(*bm0); + SkAutoLockPixels alp1(*bm1); + + // if we can't load the pixels, return false + if (NULL == bm0->getPixels() || NULL == bm1->getPixels()) { + return false; + } + + if (bm0->config() == SkBitmap::kIndex8_Config) { + SkColorTable* ct0 = bm0->getColorTable(); + SkColorTable* ct1 = bm1->getColorTable(); + if (NULL == ct0 || NULL == ct1) { + return false; + } + if (ct0->count() != ct1->count()) { + return false; + } + + SkAutoLockColors alc0(ct0); + SkAutoLockColors alc1(ct1); + const size_t size = ct0->count() * sizeof(SkPMColor); + if (memcmp(alc0.colors(), alc1.colors(), size) != 0) { + return false; + } + } + + // now compare each scanline. We can't do the entire buffer at once, + // since we don't care about the pixel values that might extend beyond + // the width (since the scanline might be larger than the logical width) + const int h = bm0->height(); + const size_t size = bm0->width() * bm0->bytesPerPixel(); + for (int y = 0; y < h; y++) { + if (memcmp(bm0->getAddr(0, y), bm1->getAddr(0, y), size) != 0) { + return false; + } + } + return true; +} + static void Bitmap_prepareToDraw(JNIEnv* env, jobject, SkBitmap* bitmap) { bitmap->lockPixels(); bitmap->unlockPixels(); @@ -567,7 +614,8 @@ static JNINativeMethod gBitmapMethods[] = { (void*)Bitmap_copyPixelsToBuffer }, { "nativeCopyPixelsFromBuffer", "(ILjava/nio/Buffer;)V", (void*)Bitmap_copyPixelsFromBuffer }, - { "nativePrepareToDraw", "(I)V", (void*)Bitmap_prepareToDraw } + { "nativeSameAs", "(II)Z", (void*)Bitmap_sameAs }, + { "nativePrepareToDraw", "(I)V", (void*)Bitmap_prepareToDraw }, }; #define kClassPathName "android/graphics/Bitmap" diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 5aa88b06840aa..7ca374164096b 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -971,6 +971,19 @@ public final class Bitmap implements Parcelable { return bm; } + /** + * Given another bitmap, return true if it has the same dimensions, config, + * and pixel data as this bitmap. If any of those differ, return false. + * If other is null, return false. + * + * @hide (just needed internally right now) + */ + public boolean sameAs(Bitmap other) { + return this == other || + (other != null && + nativeSameAs(mNativeBitmap, other.mNativeBitmap)); + } + /** * Rebuilds any caches associated with the bitmap that are used for * drawing it. In the case of purgeable bitmaps, this call will attempt to @@ -1042,6 +1055,7 @@ public final class Bitmap implements Parcelable { private static native void nativePrepareToDraw(int nativeBitmap); private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha); + private static native boolean nativeSameAs(int nb0, int nb1); /* package */ final int ni() { return mNativeBitmap;