Bitmap.cpp revision 5fd2a1cb2726afa7d40fe4750e9defd89c24ed37
1f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#define LOG_TAG "Bitmap" 2f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include "Bitmap.h" 3f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkBitmap.h" 532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkPixelRef.h" 632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkImageEncoder.h" 757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III#include "SkImageInfo.h" 832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkColorPriv.h" 932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "GraphicsJNI.h" 1032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkDither.h" 1132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkUnPreMultiply.h" 1232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkStream.h" 1332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <binder/Parcel.h> 1532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_os_Parcel.h" 1632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_util_Binder.h" 1732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_nio_utils.h" 1832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "CreateJavaOutputStreamAdaptor.h" 19dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h> 20c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv#include <hwui/Bitmap.h> 214387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck#include <renderthread/RenderProxy.h> 2232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 23ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 2532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <jni.h> 2639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <memory> 2739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <string> 2832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 29a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#define DEBUG_PARCEL 0 308cee7c17119b204be88860feb812f2374d0de732Riley Andrews#define ASHMEM_BITMAP_MIN_SIZE (128 * (1 << 10)) 31a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 32c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass gBitmap_class; 33c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID gBitmap_nativePtr; 34c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_constructorMethodID; 35c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_reinitMethodID; 36c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_getAllocationByteCountMethodID; 37c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 38f29ed28c7b878ef28058bc730715d0d32445bc57John Recknamespace android { 39f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 40c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvclass BitmapWrapper { 41f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic: 42c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper(Bitmap* bitmap) 43c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv : mBitmap(bitmap) { } 44c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 45c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void freePixels() { 46c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mInfo = mBitmap->info(); 47c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mHasHardwareMipMap = mBitmap->hasHardwareMipMap(); 48c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mAllocationSize = mBitmap->getAllocationByteCount(); 49c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mRowBytes = mBitmap->rowBytes(); 50c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mGenerationId = mBitmap->getGenerationID(); 51c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap.reset(); 52f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 53f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 54c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool valid() { 55fc9999505a36c66892d7ccce85187936105f4f36sergeyv return mBitmap; 56f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 57f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 58aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv Bitmap& bitmap() { 59aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv assertValid(); 60aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv return *mBitmap; 61aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv } 62c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 63c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void assertValid() { 64c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LOG_ALWAYS_FATAL_IF(!valid(), "Error, cannot access an invalid/free'd bitmap here!"); 65c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 66c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 67c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void getSkBitmap(SkBitmap* outBitmap) { 68c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 69c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap->getSkBitmap(outBitmap); 70c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 710781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck 72c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool hasHardwareMipMap() { 73c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 74c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->hasHardwareMipMap(); 75c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 76f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return mHasHardwareMipMap; 77f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 78f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 79f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void setHasHardwareMipMap(bool hasMipMap) { 80c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 81c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap->setHasHardwareMipMap(hasMipMap); 82f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 83f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 84c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void setAlphaType(SkAlphaType alphaType) { 85c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 86c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap->setAlphaType(alphaType); 87f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 88f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 89c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const SkImageInfo& info() { 90c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 91c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->info(); 92c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 93c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mInfo; 94f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 95f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 96c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t getAllocationByteCount() const { 97c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 98c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->getAllocationByteCount(); 99c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 100c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mAllocationSize; 101f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 102f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 103c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t rowBytes() const { 104c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 105c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->rowBytes(); 106c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 107c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mRowBytes; 108c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 109f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 110c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv uint32_t getGenerationID() const { 111c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 112c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->getGenerationID(); 113c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 114c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mGenerationId; 115f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 116c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 117c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv ~BitmapWrapper() { } 118c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 119c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvprivate: 120c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> mBitmap; 121c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkImageInfo mInfo; 122c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool mHasHardwareMipMap; 123c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t mAllocationSize; 124c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t mRowBytes; 125c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv uint32_t mGenerationId; 126f29ed28c7b878ef28058bc730715d0d32445bc57John Reck}; 127f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 128f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// Convenience class that does not take a global ref on the pixels, relying 129f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// on the caller already having a local JNI ref 130f29ed28c7b878ef28058bc730715d0d32445bc57John Reckclass LocalScopedBitmap { 131f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic: 132c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit LocalScopedBitmap(jlong bitmapHandle) 133c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv : mBitmapWrapper(reinterpret_cast<BitmapWrapper*>(bitmapHandle)) {} 134f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 135c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper* operator->() { 136c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmapWrapper; 137f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 138f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 139f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* pixels() { 140aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv return mBitmapWrapper->bitmap().pixels(); 141f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 142f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 143f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bool valid() { 144c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmapWrapper && mBitmapWrapper->valid(); 145f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 146f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 147f29ed28c7b878ef28058bc730715d0d32445bc57John Reckprivate: 148c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper* mBitmapWrapper; 149f29ed28c7b878ef28058bc730715d0d32445bc57John Reck}; 150f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 151c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvnamespace bitmap { 152c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 153c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv// Assert that bitmap's SkAlphaType is consistent with isPremultiplied. 154c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied) { 155c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is 156c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // irrelevant. This just tests to ensure that the SkAlphaType is not 157c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // opposite of isPremultiplied. 158c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isPremultiplied) { 159c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(info.alphaType() != kUnpremul_SkAlphaType); 160c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } else { 161c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(info.alphaType() != kPremul_SkAlphaType); 162c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 163c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 164c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 165c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, 166c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isPremultiplied) 167c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 168c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // The caller needs to have already set the alpha type properly, so the 169c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // native SkBitmap stays in sync with the Java Bitmap. 170c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assert_premultiplied(info, isPremultiplied); 171c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 172c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID, 173c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv info.width(), info.height(), isPremultiplied); 174c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 175c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 176c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvint getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap) 177c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 178c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID); 179c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 180c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 181c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvjobject createBitmap(JNIEnv* env, Bitmap* bitmap, 182c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, 183c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int density) { 184c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; 185c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied; 186c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // The caller needs to have already set the alpha type properly, so the 187c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // native SkBitmap stays in sync with the Java Bitmap. 188c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv assert_premultiplied(bitmap->info(), isPremultiplied); 189c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper* bitmapWrapper = new BitmapWrapper(bitmap); 190c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, 191c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density, 192c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv isMutable, isPremultiplied, ninePatchChunk, ninePatchInsets); 193c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 194c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (env->ExceptionCheck() != 0) { 195c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv ALOGE("*** Uncaught exception returned from Java call!\n"); 196c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv env->ExceptionDescribe(); 197c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 198c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return obj; 199c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 200c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 201c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap) { 202c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LocalScopedBitmap bitmap(bitmapHandle); 203c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->getSkBitmap(outBitmap); 204c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 205c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 206aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvBitmap& toBitmap(JNIEnv* env, jobject bitmap) { 207c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(env); 208c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(bitmap); 209c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 210c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 211c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LocalScopedBitmap localBitmap(bitmapHandle); 212c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return localBitmap->bitmap(); 213c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 214c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 2155fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyvBitmap& toBitmap(JNIEnv* env, jlong bitmapHandle) { 2165fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv SkASSERT(env); 2175fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv LocalScopedBitmap localBitmap(bitmapHandle); 2185fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv return localBitmap->bitmap(); 2195fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv} 2205fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv 221c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace bitmap 222c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 223c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace android 224c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 225c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android; 226c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android::bitmap; 227c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 22832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 22932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// Conversions to/from SkColor, for get/setPixels, and the create method, which 23032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// is basically like setPixels 23132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 23232054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*FromColorProc)(void* dst, const SkColor src[], int width, 23332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y); 23432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 23532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32(void* dst, const SkColor src[], int width, 23632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 23732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 23832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 23932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 24032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPreMultiplyColor(*src++); 24132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 24232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 24332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 24432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32_Raw(void* dst, const SkColor src[], int width, 24532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 24646d8444631b4b1253a76bfcc78a29d26014d022fDan Albert // Needed to thwart the unreachable code detection from clang. 24746d8444631b4b1253a76bfcc78a29d26014d022fDan Albert static const bool sk_color_ne_zero = SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER; 24846d8444631b4b1253a76bfcc78a29d26014d022fDan Albert 24932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkColor's ordering may be different from SkPMColor 25046d8444631b4b1253a76bfcc78a29d26014d022fDan Albert if (sk_color_ne_zero) { 25132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(dst, src, width * sizeof(SkColor)); 25232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 25332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 25432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 25532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // order isn't same, repack each pixel manually 25632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 25732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 25832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 25932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 26032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 26132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 26232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 26332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 26432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D565(void* dst, const SkColor src[], int width, 26532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 26632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t* d = (uint16_t*)dst; 26732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 26832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_565_SCAN(y); 26932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 27032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 27132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), 27232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_VALUE(x)); 27332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 27432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 27532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 27632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444(void* dst, const SkColor src[], int width, 27732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 27832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 27932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 28032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 28132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 28232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPreMultiplyColor(*src++); 28332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 28432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 28532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 28632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 28732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 28832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444_Raw(void* dst, const SkColor src[], int width, 28932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 29032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 29132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 29232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 29332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 29432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 29532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 29632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied 29732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 29832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 29932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 30032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 30132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 30232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 30332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 3046260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void FromColor_DA8(void* dst, const SkColor src[], int width, int x, int y) { 3056260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t* d = (uint8_t*)dst; 3066260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 3076260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik for (int stop = x + width; x < stop; x++) { 3086260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *d++ = SkColorGetA(*src++); 3096260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } 3106260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 3116260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 31232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 31357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) { 31457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (bitmap.colorType()) { 31557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kN32_SkColorType: 31657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D32 : FromColor_D32_Raw; 31757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kARGB_4444_SkColorType: 31857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D4444 : 31957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III FromColor_D4444_Raw; 32057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kRGB_565_SkColorType: 32132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return FromColor_D565; 3226260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 3236260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return FromColor_DA8; 32432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 32532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 32632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 32732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 32832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 32932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 33032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikbool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride, 33157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III int x, int y, int width, int height, const SkBitmap& dstBitmap) { 33232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(dstBitmap); 33332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik void* dst = dstBitmap.getPixels(); 33457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III FromColorProc proc = ChooseFromColorProc(dstBitmap); 33532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 33632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == dst || NULL == proc) { 33732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return false; 33832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 33932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 34032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const jint* array = env->GetIntArrayElements(srcColors, NULL); 34132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkColor* src = (const SkColor*)array + srcOffset; 34232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 34332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // reset to to actual choice from caller 34432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = dstBitmap.getAddr(x, y); 34532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now copy/convert each scanline 34632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < height; y++) { 34732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(dst, src, width, x, y); 34832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik src += srcStride; 34932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = (char*)dst + dstBitmap.rowBytes(); 35032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 35132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 35232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dstBitmap.notifyPixelsChanged(); 35332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 35432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), 35532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik JNI_ABORT); 35632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return true; 35732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 35832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 35932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//////////////////// ToColor procs 36032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 36132054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*ToColorProc)(SkColor dst[], const void* src, int width, 36232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*); 36332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 36432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width, 36532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 36632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 36732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 36832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 36932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(*s++); 37032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 37132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 37232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 37332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width, 37432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 37532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 37632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 37732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 37832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 37932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 38032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 38132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 38232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 38332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 38432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width, 38532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 38632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 38732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 38832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 38932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 39032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 39132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 39232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 39332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 39432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 39532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width, 39632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 39732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 39832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 39932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 40032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++)); 40132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 40232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 40332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 40432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width, 40532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 40632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 40732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 40832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 40932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 41032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 41132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 41232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 41332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 41432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 41532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width, 41632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 41732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 41832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 41932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 42032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 42132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 42232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 42332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 42432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 42532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 42632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S565(SkColor dst[], const void* src, int width, 42732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 42832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 42932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint16_t* s = (const uint16_t*)src; 43032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 43132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t c = *s++; 43232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), 43332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPacked16ToB32(c)); 43432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 43532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 43632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 43732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 43832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 43932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 44032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 44171487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 44232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 44332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); 44432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 44532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 44632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 44732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, 44832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 44932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 45032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 45171487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 45232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 45332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 45432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 45532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 45632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 45732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 45832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 45932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, 46032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 46132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 46232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 46371487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 46432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 46532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 46632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 46732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 46832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 46932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 47032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4716260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) { 4726260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik SkASSERT(width > 0); 4736260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik const uint8_t* s = (const uint8_t*)src; 4746260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik do { 4756260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t c = *s++; 4766260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *dst++ = SkColorSetARGB(c, c, c, c); 4776260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } while (--width != 0); 4786260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 4796260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 48032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 48157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic ToColorProc ChooseToColorProc(const SkBitmap& src) { 482b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed switch (src.colorType()) { 483b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kN32_SkColorType: 48457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 48557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 48657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Opaque; 48757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 48857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Alpha; 48957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 49057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Raw; 49157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 49257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 49357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 494b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kARGB_4444_SkColorType: 49557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 49657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 49757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Opaque; 49857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 49957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Alpha; 50057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 50157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Raw; 50257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 50357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 50457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 505b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kRGB_565_SkColorType: 50632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return ToColor_S565; 507b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kIndex_8_SkColorType: 50832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.getColorTable() == NULL) { 50932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 51032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 51157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 51257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 51357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Opaque; 51457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 51557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Alpha; 51657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 51757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Raw; 51857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 51957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 52057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 5216260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 5226260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return ToColor_SA8; 52332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 52432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 52532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 52632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 52732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 52832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 52932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 53032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 53132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic int getPremulBitmapCreateFlags(bool isMutable) { 533c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int flags = android::bitmap::kBitmapCreateFlag_Premultiplied; 534c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isMutable) flags |= android::bitmap::kBitmapCreateFlag_Mutable; 53532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return flags; 53632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 53732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 53932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint offset, jint stride, jint width, jint height, 54032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint configHandle, jboolean isMutable) { 5411103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 54232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != jColors) { 54332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t n = env->GetArrayLength(jColors); 54432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (n < SkAbs32(stride) * (size_t)height) { 54532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowAIOOBE(env); 54632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 54732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 54832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 54932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // ARGB_4444 is a deprecated format, convert automatically to 8888 551b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kARGB_4444_SkColorType) { 552b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed colorType = kN32_SkColorType; 55332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 55432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap bitmap; 556253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType, 557253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy GraphicsJNI::defaultColorSpace())); 55832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 559c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL); 560f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!nativeBitmap) { 56132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 56232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 56332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 56432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (jColors != NULL) { 56532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, jColors, offset, stride, 56657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 0, 0, width, height, bitmap); 56732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 56832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 569c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable)); 57032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 57132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, 57332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint dstConfigHandle, jboolean isMutable) { 574f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 575c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 5761103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 5774508218850faedea95371188da587b6734f5f3dasergeyv SkBitmap result; 5784508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 57932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 580f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!src.copyTo(&result, dstCT, &allocator)) { 58132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 58232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 583c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = allocator.getStorageObjAndReset(); 584c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return createBitmap(env, bitmap, getPremulBitmapCreateFlags(isMutable)); 58532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 58632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 587c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic Bitmap* Bitmap_copyAshmemImpl(JNIEnv* env, SkBitmap& src, SkColorType& dstCT) { 588721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews SkBitmap result; 589721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 590721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews AshmemPixelAllocator allocator(env); 591a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson if (!src.copyTo(&result, dstCT, &allocator)) { 592721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return NULL; 593721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews } 594c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = allocator.getStorageObjAndReset(); 595c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv bitmap->setImmutable(); 596c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return bitmap; 597a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 598a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 599a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) { 600a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 601c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 602a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = src.colorType(); 603c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 604c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 605a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson return ret; 606a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 607a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 608a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle) { 609a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 610c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 611a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 612c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 613c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 614721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return ret; 615721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews} 616721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 617c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic void Bitmap_destruct(BitmapWrapper* bitmap) { 618c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv delete bitmap; 61932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 62032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 621775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic jlong Bitmap_getNativeFinalizer(JNIEnv*, jobject) { 622775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct)); 623775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler} 624775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler 62532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { 626f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 627f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->freePixels(); 62832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 62932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 63032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 63132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, 6324508218850faedea95371188da587b6734f5f3dasergeyv jint width, jint height, jint configHandle, jboolean requestPremul) { 633f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 634c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->assertValid(); 6351103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 63617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III 63717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // ARGB_4444 is a deprecated format, convert automatically to 8888 63817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (colorType == kARGB_4444_SkColorType) { 63917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III colorType = kN32_SkColorType; 64017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 6414508218850faedea95371188da587b6734f5f3dasergeyv size_t requestedSize = width * height * SkColorTypeBytesPerPixel(colorType); 6424508218850faedea95371188da587b6734f5f3dasergeyv if (requestedSize > bitmap->getAllocationByteCount()) { 64332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // done in native as there's no way to get BytesPerPixel in Java 64432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowIAE(env, "Bitmap not large enough to support new configuration"); 64532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 64632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 64717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkAlphaType alphaType; 648f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().colorType() != kRGB_565_SkColorType 649f29ed28c7b878ef28058bc730715d0d32445bc57John Reck && bitmap->info().alphaType() == kOpaque_SkAlphaType) { 65017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // If the original bitmap was set to opaque, keep that setting, unless it 65117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // was 565, which is required to be opaque. 65217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = kOpaque_SkAlphaType; 65317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } else { 65417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // Otherwise respect the premultiplied request. 65517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 65617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 657aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv bitmap->bitmap().reconfigure(SkImageInfo::Make(width, height, colorType, alphaType, 658253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy sk_sp<SkColorSpace>(bitmap->info().colorSpace()))); 65932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 66032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 66132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// These must match the int values in Bitmap.java 66232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikenum JavaEncodeFormat { 66332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kJPEG_JavaEncodeFormat = 0, 66432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kPNG_JavaEncodeFormat = 1, 66532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kWEBP_JavaEncodeFormat = 2 66632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 66732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 66832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, 66932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint format, jint quality, 67032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject jstream, jbyteArray jstorage) { 671f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 672f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 67332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkImageEncoder::Type fm; 67432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 67532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik switch (format) { 67632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kJPEG_JavaEncodeFormat: 67732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kJPEG_Type; 67832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 67932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kPNG_JavaEncodeFormat: 68032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kPNG_Type; 68132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 68232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kWEBP_JavaEncodeFormat: 68332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kWEBP_Type; 68432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 68532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 68632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 68732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 68832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 689f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap.valid()) { 690f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 691f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 69232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 693f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bool success = false; 69432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 695f29ed28c7b878ef28058bc730715d0d32445bc57John Reck std::unique_ptr<SkWStream> strm(CreateJavaOutputStreamAdaptor(env, jstream, jstorage)); 696f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!strm.get()) { 697f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 698f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 69932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 700f29ed28c7b878ef28058bc730715d0d32445bc57John Reck std::unique_ptr<SkImageEncoder> encoder(SkImageEncoder::Create(fm)); 701f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (encoder.get()) { 702f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap skbitmap; 703f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->getSkBitmap(&skbitmap); 704f29ed28c7b878ef28058bc730715d0d32445bc57John Reck success = encoder->encodeStream(strm.get(), skbitmap, quality); 70532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return success ? JNI_TRUE : JNI_FALSE; 70732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 70832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 70932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { 710f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 711f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap skBitmap; 712f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->getSkBitmap(&skBitmap); 713f29ed28c7b878ef28058bc730715d0d32445bc57John Reck skBitmap.eraseColor(color); 71432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 71532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 71632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { 717f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 71832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->rowBytes()); 71932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 72032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { 722f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 723f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->info().colorType()); 72432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 72532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { 727f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 728c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return static_cast<jint>(bitmap->getGenerationID()); 72932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 73032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 73157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) { 732f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 733f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().alphaType() == kPremul_SkAlphaType) { 73457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_TRUE; 73557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 73657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_FALSE; 73757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 73857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 73932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { 740f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 741f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return !bitmap->info().isOpaque() ? JNI_TRUE : JNI_FALSE; 74232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 74332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 74457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle, 74557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean hasAlpha, jboolean requestPremul) { 746f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 74757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (hasAlpha) { 7480781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType( 749f29ed28c7b878ef28058bc730715d0d32445bc57John Reck requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); 75032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 7510781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kOpaque_SkAlphaType); 75257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 75357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 75457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 75557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, 75657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean isPremul) { 757f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 758f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap->info().isOpaque()) { 75957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (isPremul) { 7600781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kPremul_SkAlphaType); 76157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } else { 7620781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kUnpremul_SkAlphaType); 76357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 76432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 76532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 76632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 76732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { 768f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 76932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; 77032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 77132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 77232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, 77332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean hasMipMap) { 774f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 77532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setHasHardwareMipMap(hasMipMap); 77632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 77732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 77832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 77932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 78032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 78132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 78232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("-------- unparcel parcel is NULL\n"); 78332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 78432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 78532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 78632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 78732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 788b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const bool isMutable = p->readInt32() != 0; 789b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkColorType colorType = (SkColorType)p->readInt32(); 790b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); 791253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy const bool isSRGB = p->readInt32() != 0; 792b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int width = p->readInt32(); 793b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int height = p->readInt32(); 794b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int rowBytes = p->readInt32(); 795b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int density = p->readInt32(); 796b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed 797b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (kN32_SkColorType != colorType && 798b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kRGB_565_SkColorType != colorType && 799b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kARGB_4444_SkColorType != colorType && 800b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kIndex_8_SkColorType != colorType && 801b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kAlpha_8_SkColorType != colorType) { 802b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed SkDebugf("Bitmap_createFromParcel unknown colortype: %d\n", colorType); 80332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 80432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 80532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 806ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III std::unique_ptr<SkBitmap> bitmap(new SkBitmap); 80732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 808253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType, 809253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy isSRGB ? SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named) : nullptr), rowBytes)) { 810ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 811ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 81232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 81332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = NULL; 814b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kIndex_8_SkColorType) { 81532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = p->readInt32(); 816ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (count < 0 || count > 256) { 817ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // The data is corrupt, since SkColorTable enforces a value between 0 and 256, 818ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // inclusive. 819ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 820ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 82132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (count > 0) { 82232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = count * sizeof(SkPMColor); 82332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* src = (const SkPMColor*)p->readInplace(size); 824ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (src == NULL) { 825ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 826ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 82732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable = new SkColorTable(src, count); 82832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 82932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 83032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 831a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Read the bitmap blob. 832a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap->getSize(); 833a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::ReadableBlob blob; 834a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status = p->readBlob(size, &blob); 835a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 83632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkSafeUnref(ctable); 837a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not read bitmap blob."); 83832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 83932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 84032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 841a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the bitmap in place from the ashmem region if possible otherwise copy. 842c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> nativeBitmap; 8438cee7c17119b204be88860feb812f2374d0de732Riley Andrews if (blob.fd() >= 0 && (blob.isMutable() || !isMutable) && (size >= ASHMEM_BITMAP_MIN_SIZE)) { 844a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 845a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob " 846a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 847a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 848a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 849a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 850a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 851a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Dup the file descriptor so we can keep a reference to it after the Parcel 852a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // is disposed. 853a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown int dupFd = dup(blob.fd()); 854a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (dupFd < 0) { 855211abad3b92b70dd094949c79f67e686c940fa0cErik Wolsheimer ALOGE("Error allocating dup fd. Error:%d", errno); 856a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 857a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 858a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate dup blob fd."); 859a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 86039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 861a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 862a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the pixels in place and take ownership of the ashmem region. 863c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv nativeBitmap = sk_sp<Bitmap>(GraphicsJNI::mapAshmemBitmap(env, bitmap.get(), 864c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable)); 865a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 866a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 867a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown close(dupFd); 868a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 869a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate ashmem pixel ref."); 870a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 87139d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 872a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 873a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Clear the blob handle, don't release it. 874a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.clear(); 875a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 876a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 877a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (blob.fd() >= 0) { 878a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents of mutable bitmap " 879a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "from immutable blob (fds %s)", 880a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 881a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 882a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents from %s blob " 883a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 884a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 885a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 88639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 887a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 888a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 889a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the pixels into a new buffer. 890c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv nativeBitmap = Bitmap::allocateHeapBitmap(bitmap.get(), ctable); 891a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 892a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 893a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 894a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate java pixel ref."); 895a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 89639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 897a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->lockPixels(); 898a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(bitmap->getPixels(), blob.data(), size); 899a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->unlockPixels(); 900a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 901a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Release the blob handle. 902a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 90339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 904a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 905c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return createBitmap(env, nativeBitmap.release(), 906a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); 907a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown} 90839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 90932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 91032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, 91132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean isMutable, jint density, 91232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject parcel) { 91332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 91432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("------- writeToParcel null parcel\n"); 91532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 91632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 91732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 91832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 919f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 92039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 921c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle); 922c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv bitmapWrapper->getSkBitmap(&bitmap); 92332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 924253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy sk_sp<SkColorSpace> sRGB = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); 925253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bool isSRGB = bitmap.colorSpace() == sRGB.get(); 926253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy 92732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(isMutable); 928f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.colorType()); 929f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.alphaType()); 930253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy p->writeInt32(isSRGB); // TODO: We should write the color space (b/32072280) 931f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.width()); 932f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.height()); 933f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.rowBytes()); 93432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(density); 93532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 936f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap.colorType() == kIndex_8_SkColorType) { 93766ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III // The bitmap needs to be locked to access its color table. 93866ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III SkAutoLockPixels alp(bitmap); 939f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 94032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ctable != NULL) { 94132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = ctable->count(); 94232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(count); 94332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(p->writeInplace(count * sizeof(SkPMColor)), 94471487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed ctable->readColors(), count * sizeof(SkPMColor)); 94532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 94632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(0); // indicate no ctable 94732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 94832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 94932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 950a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Transfer the underlying ashmem region if we have one and it's immutable. 951a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status; 952aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv int fd = bitmapWrapper->bitmap().getAshmemFd(); 953a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (fd >= 0 && !isMutable && p->allowFds()) { 954a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 955a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " 956a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "immutable blob (fds %s)", 957a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 958a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 959a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 960a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeDupImmutableBlobFileDescriptor(fd); 961a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 962a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not write bitmap blob file descriptor."); 96339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews return JNI_FALSE; 96439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 965a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_TRUE; 966a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 96732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 968a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the bitmap to a new blob. 969a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bool mutableCopy = isMutable; 970a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 971a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: copying %s bitmap into new %s blob (fds %s)", 972a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 973a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown mutableCopy ? "mutable" : "immutable", 974a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 975a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 976a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 977a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap.getSize(); 978a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::WritableBlob blob; 979a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeBlob(size, mutableCopy, &blob); 980a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 981a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not copy bitmap to parcel blob."); 982a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_FALSE; 98339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 984a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 985a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.lockPixels(); 986a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown const void* pSrc = bitmap.getPixels(); 987a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (pSrc == NULL) { 988a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memset(blob.data(), 0, size); 989a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 990a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(blob.data(), pSrc, size); 991a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 992a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.unlockPixels(); 993a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 994a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 99532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 99632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 99732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 99832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, 99932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong srcHandle, jlong paintHandle, 100032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray offsetXY) { 1001f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 1002c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 10036ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle); 100432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkIPoint offset; 1005f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap dst; 10064508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 100732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1008f29ed28c7b878ef28058bc730715d0d32445bc57John Reck src.extractAlpha(&dst, paint, &allocator, &offset); 100932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // If Skia can't allocate pixels for destination bitmap, it resets 101032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // it, that is set its pixels buffer to NULL, and zero width and height. 1011f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (dst.getPixels() == NULL && src.getPixels() != NULL) { 101232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowOOME(env, "failed to allocate pixels for alpha"); 101332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 101432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 101532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) { 101632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int* array = env->GetIntArrayElements(offsetXY, NULL); 101732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[0] = offset.fX; 101832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[1] = offset.fY; 101932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(offsetXY, array, 0); 102032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 102132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1022c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, allocator.getStorageObjAndReset(), 1023f29ed28c7b878ef28058bc730715d0d32445bc57John Reck getPremulBitmapCreateFlags(true)); 102432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 102532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 102632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 102732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 102832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, 102957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y) { 1030f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1031c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1032f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 103332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1034f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 103532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 103632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 103732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1038f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 103932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 104032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 104132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 104232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 104332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor dst[1]; 1044f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(dst, src, 1, bitmap.getColorTable()); 104532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(dst[0]); 104632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 104732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 104832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, 104932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 105057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1051f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1052c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1053f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 105432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1055f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 105632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 105732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 105832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1059f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 106032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 106132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 106232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 106332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1064f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 106532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint* dst = env->GetIntArrayElements(pixelArray, NULL); 106632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor* d = (SkColor*)dst + offset; 106732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik while (--height >= 0) { 106832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(d, src, width, ctable); 106932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik d += stride; 1070f29ed28c7b878ef28058bc730715d0d32445bc57John Reck src = (void*)((const char*)src + bitmap.rowBytes()); 107132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 107232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(pixelArray, dst, 0); 107332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 107432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 107532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 107632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 107732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, 107857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint colorHandle) { 1079f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1080c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 108132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor color = static_cast<SkColor>(colorHandle); 1082f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1083f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bitmap.getPixels()) { 108432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 108532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 108632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1087f29ed28c7b878ef28058bc730715d0d32445bc57John Reck FromColorProc proc = ChooseFromColorProc(bitmap); 108832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 108932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 109032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 109132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1092f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(bitmap.getAddr(x, y), &color, 1, x, y); 1093f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 109432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 109532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 109632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, 109732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 109857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1099f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1100c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 110132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, pixelArray, offset, stride, 1102f29ed28c7b878ef28058bc730715d0d32445bc57John Reck x, y, width, height, bitmap); 110332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 110432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 110532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, 110632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1107f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1108c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1109f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1110f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getPixels(); 111132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 111232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != src) { 111332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); 111432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 111532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1116f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(abp.pointer(), src, bitmap.getSize()); 111732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 111832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 111932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 112032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, 112132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1122f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1123c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1124f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1125f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* dst = bitmap.getPixels(); 112632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 112732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != dst) { 112832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); 112932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1130f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(dst, abp.pointer(), bitmap.getSize()); 1131f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 113232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 113332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 113432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 113532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, 113632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bm1Handle) { 1137f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm0; 1138f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm1; 1139c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bm0Handle)->getSkBitmap(&bm0); 1140c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bm1Handle)->getSkBitmap(&bm1); 1141f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bm0.width() != bm1.width() || 1142f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bm0.height() != bm1.height() || 1143253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bm0.colorType() != bm1.colorType() || 1144253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bm0.alphaType() != bm1.alphaType() || 1145253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bm0.colorSpace() != bm1.colorSpace()) { 114632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 114732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 114832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1149f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp0(bm0); 1150f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp1(bm1); 115132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 115232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // if we can't load the pixels, return false 1153f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) { 115432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 115532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 115632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1157f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bm0.colorType() == kIndex_8_SkColorType) { 1158f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct0 = bm0.getColorTable(); 1159f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct1 = bm1.getColorTable(); 116032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == ct0 || NULL == ct1) { 116132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 116232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 116332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ct0->count() != ct1->count()) { 116432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 116532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 116632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 116732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const size_t size = ct0->count() * sizeof(SkPMColor); 116871487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed if (memcmp(ct0->readColors(), ct1->readColors(), size) != 0) { 116932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 117032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 117132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 117232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 117332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now compare each scanline. We can't do the entire buffer at once, 117432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // since we don't care about the pixel values that might extend beyond 117532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the width (since the scanline might be larger than the logical width) 1176f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const int h = bm0.height(); 1177f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const size_t size = bm0.width() * bm0.bytesPerPixel(); 117832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < h; y++) { 117953001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config 118053001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0 118153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // and bm1 both have pixel data() (have passed NULL == getPixels() check), 118253001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE 118353001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // to warn user those 2 unrecognized config bitmaps may be different. 1184f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm0Addr = bm0.getAddr(0, y); 1185f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm1Addr = bm1.getAddr(0, y); 118653001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 118753001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if(bm0Addr == NULL || bm1Addr == NULL) { 118853001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen return JNI_FALSE; 118953001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen } 119053001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 119153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if (memcmp(bm0Addr, bm1Addr, size) != 0) { 119232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 119332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 119432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 119532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 119632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 119732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 11981158b6d4ee34707515d5af59a13e4999ba53563eRomain Guystatic jlong Bitmap_refPixelRef(JNIEnv* env, jobject, jlong bitmapHandle) { 11991158b6d4ee34707515d5af59a13e4999ba53563eRomain Guy LocalScopedBitmap bitmap(bitmapHandle); 1200aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv SkPixelRef& pixelRef = bitmap->bitmap(); 1201aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv pixelRef.ref(); 1202aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv return reinterpret_cast<jlong>(&pixelRef); 12031158b6d4ee34707515d5af59a13e4999ba53563eRomain Guy} 12041158b6d4ee34707515d5af59a13e4999ba53563eRomain Guy 12054387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reckstatic void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) { 12064387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck LocalScopedBitmap bitmapHandle(bitmapPtr); 12074387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck if (!bitmapHandle.valid()) return; 12084387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck SkBitmap bitmap; 12094387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck bitmapHandle->getSkBitmap(&bitmap); 12104387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmap); 12114387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck} 12124387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck 12134508218850faedea95371188da587b6734f5f3dasergeyvstatic jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) { 12144508218850faedea95371188da587b6734f5f3dasergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 12154508218850faedea95371188da587b6734f5f3dasergeyv return static_cast<jint>(bitmapHandle->getAllocationByteCount()); 12164508218850faedea95371188da587b6734f5f3dasergeyv} 12174508218850faedea95371188da587b6734f5f3dasergeyv 121832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 1219c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass make_globalref(JNIEnv* env, const char classname[]) 1220c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1221c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jclass c = env->FindClass(classname); 1222c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(c); 1223c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return (jclass) env->NewGlobalRef(c); 1224c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 1225c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 1226c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz, 1227c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const char fieldname[], const char type[]) 1228c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1229c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jfieldID id = env->GetFieldID(clazz, fieldname, type); 1230c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(id); 1231c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return id; 1232c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 123332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 123476f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBitmapMethods[] = { 123532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;", 123632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_creator }, 123732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;", 123832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copy }, 1239721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews { "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;", 1240721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews (void*)Bitmap_copyAshmem }, 1241a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;", 1242a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson (void*)Bitmap_copyAshmemConfig }, 1243775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler { "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer }, 124432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle }, 12454508218850faedea95371188da587b6734f5f3dasergeyv { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure }, 124632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z", 124732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_compress }, 124832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeErase", "(JI)V", (void*)Bitmap_erase }, 124932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes }, 125032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeConfig", "(J)I", (void*)Bitmap_config }, 125132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha }, 125257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeIsPremultiplied", "(J)Z", (void*)Bitmap_isPremultiplied}, 125357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetHasAlpha", "(JZZ)V", (void*)Bitmap_setHasAlpha}, 125457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPremultiplied", "(JZ)V", (void*)Bitmap_setPremultiplied}, 125532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap }, 125632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap }, 125732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreateFromParcel", 125832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;", 125932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_createFromParcel }, 126032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z", 126132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_writeToParcel }, 126232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;", 126332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_extractAlpha }, 126432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId }, 126557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixel", "(JII)I", (void*)Bitmap_getPixel }, 126657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixels", "(J[IIIIIII)V", (void*)Bitmap_getPixels }, 126757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixel", "(JIII)V", (void*)Bitmap_setPixel }, 126857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixels", "(J[IIIIIII)V", (void*)Bitmap_setPixels }, 126932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V", 127032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsToBuffer }, 127132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", 127232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsFromBuffer }, 127332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, 12741158b6d4ee34707515d5af59a13e4999ba53563eRomain Guy { "nativeRefPixelRef", "(J)J", (void*)Bitmap_refPixelRef }, 12754387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, 12764508218850faedea95371188da587b6734f5f3dasergeyv { "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount }, 127732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 127832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 127932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikint register_android_graphics_Bitmap(JNIEnv* env) 128032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik{ 1281c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_class = make_globalref(env, "android/graphics/Bitmap"); 1282c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J"); 1283c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V"); 1284c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V"); 1285c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); 1286ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, 1287ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe NELEM(gBitmapMethods)); 1288c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}