Bitmap.cpp revision 10219fb261606fcc71c607167b28295b4578a10d
194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define LOG_TAG "Bitmap" 294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "Bitmap.h" 394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkBitmap.h" 5d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkPixelRef.h" 6d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkImageEncoder.h" 794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "SkImageInfo.h" 8d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkColorPriv.h" 994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "GraphicsJNI.h" 10d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkDither.h" 11d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkUnPreMultiply.h" 12d93707342a61e66bc3eb2145628158452f577f42Dave Allison#include "SkStream.h" 13d93707342a61e66bc3eb2145628158452f577f42Dave Allison 1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <binder/Parcel.h> 1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "android_os_Parcel.h" 1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "android_util_Binder.h" 1741ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey#include "android_nio_utils.h" 1841ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey#include "CreateJavaOutputStreamAdaptor.h" 19e4ec9eb7b4c452493589983970ba5ccc501728d1Elliott Hughes#include <hwui/Paint.h> 20e4ec9eb7b4c452493589983970ba5ccc501728d1Elliott Hughes#include <hwui/Bitmap.h> 210378aaf257aee92539d30543914a50c4481c6a18Brian Carlstrom#include <renderthread/RenderProxy.h> 2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 23e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey#include "core_jni_helpers.h" 249e87a8014055606b514b1c72b21915e17db7d513Igor Murashkin 25e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey#include <jni.h> 26e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey#include <memory> 27e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey#include <string> 28e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 29e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey#define DEBUG_PARCEL 0 30e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey#define ASHMEM_BITMAP_MIN_SIZE (128 * (1 << 10)) 3141ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey 3241ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkeystatic jclass gBitmap_class; 3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic jfieldID gBitmap_nativePtr; 3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic jmethodID gBitmap_constructorMethodID; 3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic jmethodID gBitmap_reinitMethodID; 3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic jmethodID gBitmap_getAllocationByteCountMethodID; 3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodnamespace android { 3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodclass BitmapWrapper { 41e23a13299a4f6f2488935b4786cdbb46f46e3d3cJeff Sharkeypublic: 4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood BitmapWrapper(Bitmap* bitmap) 4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood : mBitmap(bitmap) { } 44e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 45e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey void freePixels() { 46c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey mInfo = mBitmap->info(); 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mHasHardwareMipMap = mBitmap->hasHardwareMipMap(); 4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mAllocationSize = mBitmap->getAllocationByteCount(); 4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mRowBytes = mBitmap->rowBytes(); 5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mGenerationId = mBitmap->getGenerationID(); 5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mBitmap.reset(); 5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 53d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 54c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey bool valid() { 5594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmap; 56a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich } 5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood Bitmap& bitmap() { 5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood assertValid(); 60a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich return *mBitmap; 6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 6294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void assertValid() { 6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood LOG_ALWAYS_FATAL_IF(!valid(), "Error, cannot access an invalid/free'd bitmap here!"); 6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 6626288202e7bdf2e897a11bf31a15685d7c20945fStephen Smalley 6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void getSkBitmap(SkBitmap* outBitmap) { 6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood assertValid(); 6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mBitmap->getSkBitmap(outBitmap); 7094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bool hasHardwareMipMap() { 7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mBitmap) { 7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmap->hasHardwareMipMap(); 7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mHasHardwareMipMap; 7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void setHasHardwareMipMap(bool hasMipMap) { 8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood assertValid(); 81c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey mBitmap->setHasHardwareMipMap(hasMipMap); 8294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 83d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 84c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey void setAlphaType(SkAlphaType alphaType) { 8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood assertValid(); 8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood mBitmap->setAlphaType(alphaType); 8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkImageInfo& info() { 9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mBitmap) { 9194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmap->info(); 9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 9394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mInfo; 9494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 9694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size_t getAllocationByteCount() const { 9794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mBitmap) { 9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmap->getAllocationByteCount(); 9994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mAllocationSize; 10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size_t rowBytes() const { 10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mBitmap) { 10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmap->rowBytes(); 10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 107c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey return mRowBytes; 10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t getGenerationID() const { 11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mBitmap) { 11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmap->getGenerationID(); 11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mGenerationId; 11594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 116d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 117c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey ~BitmapWrapper() { } 11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodprivate: 12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood sk_sp<Bitmap> mBitmap; 12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkImageInfo mInfo; 12292dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn bool mHasHardwareMipMap; 12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size_t mAllocationSize; 12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size_t mRowBytes; 12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t mGenerationId; 12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Convenience class that does not take a global ref on the pixels, relying 12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// on the caller already having a local JNI ref 13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodclass LocalScopedBitmap { 13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodpublic: 13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood explicit LocalScopedBitmap(jlong bitmapHandle) 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood : mBitmapWrapper(reinterpret_cast<BitmapWrapper*>(bitmapHandle)) {} 13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood BitmapWrapper* operator->() { 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmapWrapper; 13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void* pixels() { 140c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey return mBitmapWrapper->bitmap().pixels(); 14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 142d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 143c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey bool valid() { 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return mBitmapWrapper && mBitmapWrapper->valid(); 1453316fe472fd68377eba9983c43dfce4281209103Jeff Sharkey } 14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodprivate: 148c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey BitmapWrapper* mBitmapWrapper; 14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 150d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 151c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkeynamespace bitmap { 15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 153a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich// Assert that bitmap's SkAlphaType is consistent with isPremultiplied. 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied) { 15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is 15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // irrelevant. This just tests to ensure that the SkAlphaType is not 157a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich // opposite of isPremultiplied. 15894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (isPremultiplied) { 15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(info.alphaType() != kUnpremul_SkAlphaType); 16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(info.alphaType() != kPremul_SkAlphaType); 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16326288202e7bdf2e897a11bf31a15685d7c20945fStephen Smalley} 16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, 16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bool isPremultiplied) 16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // The caller needs to have already set the alpha type properly, so the 16994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // native SkBitmap stays in sync with the Java Bitmap. 17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood assert_premultiplied(info, isPremultiplied); 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID, 17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood info.width(), info.height(), isPremultiplied); 17494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap) 17794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 17831f08986f83fa6f2dcf55523b2cf706460aeed7cJeff Sharkey return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID); 179d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 180d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 181e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeyjobject createBitmap(JNIEnv* env, Bitmap* bitmap, 182e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, 183d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey int density) { 184d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; 185d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied; 186d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey // The caller needs to have already set the alpha type properly, so the 187d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey // native SkBitmap stays in sync with the Java Bitmap. 188d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey assert_premultiplied(bitmap->info(), isPremultiplied); 189d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey BitmapWrapper* bitmapWrapper = new BitmapWrapper(bitmap); 190d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, 191d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density, 192d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey isMutable, isPremultiplied, ninePatchChunk, ninePatchInsets); 193d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 194d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey if (env->ExceptionCheck() != 0) { 195d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey ALOGE("*** Uncaught exception returned from Java call!\n"); 196d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey env->ExceptionDescribe(); 197d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 198d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return obj; 199d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 200d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 201d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkeyvoid toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap) { 202d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey LocalScopedBitmap bitmap(bitmapHandle); 203d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey bitmap->getSkBitmap(outBitmap); 204d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 205d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 206d792118c493806eeb24a8203f508e6e18fe93bd7Jeff SharkeyBitmap& toBitmap(JNIEnv* env, jobject bitmap) { 207d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkASSERT(env); 208d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkASSERT(bitmap); 209d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 210d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 211d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey LocalScopedBitmap localBitmap(bitmapHandle); 212d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return localBitmap->bitmap(); 213d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 214d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 215d792118c493806eeb24a8203f508e6e18fe93bd7Jeff SharkeyBitmap& toBitmap(JNIEnv* env, jlong bitmapHandle) { 216e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey SkASSERT(env); 217d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey LocalScopedBitmap localBitmap(bitmapHandle); 218d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return localBitmap->bitmap(); 219d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 220e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 221e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey} // namespace bitmap 222e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 223e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey} // namespace android 224e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 225e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeyusing namespace android; 226e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeyusing namespace android::bitmap; 227e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 228e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey/////////////////////////////////////////////////////////////////////////////// 229e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey// Conversions to/from SkColor, for get/setPixels, and the create method, which 230e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey// is basically like setPixels 231e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 232e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeytypedef void (*FromColorProc)(void* dst, const SkColor src[], int width, 233e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey int x, int y); 234e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 235e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeystatic void FromColor_D32(void* dst, const SkColor src[], int width, 236e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey int, int) { 237e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey SkPMColor* d = (SkPMColor*)dst; 238e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 239e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey for (int i = 0; i < width; i++) { 240e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey *d++ = SkPreMultiplyColor(*src++); 241e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey } 242e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey} 243e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 244e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeystatic void FromColor_D32_Raw(void* dst, const SkColor src[], int width, 245e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey int, int) { 246e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey // Needed to thwart the unreachable code detection from clang. 247d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey static const bool sk_color_ne_zero = SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER; 248e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 249e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey // SkColor's ordering may be different from SkPMColor 250e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey if (sk_color_ne_zero) { 251e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey memcpy(dst, src, width * sizeof(SkColor)); 252e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey return; 253e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey } 254e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 255e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey // order isn't same, repack each pixel manually 256e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey SkPMColor* d = (SkPMColor*)dst; 257e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey for (int i = 0; i < width; i++) { 258a2307aefd06f1310660ef1d35ce01bcfc72c9633Jeff Sharkey SkColor c = *src++; 259e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 260a2307aefd06f1310660ef1d35ce01bcfc72c9633Jeff Sharkey SkColorGetG(c), SkColorGetB(c)); 261a2307aefd06f1310660ef1d35ce01bcfc72c9633Jeff Sharkey } 262a2307aefd06f1310660ef1d35ce01bcfc72c9633Jeff Sharkey} 263e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 264e36372423000a906bafae68844ebc6c42d09335aJeff Sharkeystatic void FromColor_D565(void* dst, const SkColor src[], int width, 26531f08986f83fa6f2dcf55523b2cf706460aeed7cJeff Sharkey int x, int y) { 26631f08986f83fa6f2dcf55523b2cf706460aeed7cJeff Sharkey uint16_t* d = (uint16_t*)dst; 26731f08986f83fa6f2dcf55523b2cf706460aeed7cJeff Sharkey 268e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey DITHER_565_SCAN(y); 269e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey for (int stop = x + width; x < stop; x++) { 270e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey SkColor c = *src++; 271e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), 272d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey DITHER_VALUE(x)); 273d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 274d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 275d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 276d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkeystatic void FromColor_D4444(void* dst, const SkColor src[], int width, 277d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey int x, int y) { 278e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey SkPMColor16* d = (SkPMColor16*)dst; 279d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 280e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey DITHER_4444_SCAN(y); 281e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey for (int stop = x + width; x < stop; x++) { 282e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey SkPMColor pmc = SkPreMultiplyColor(*src++); 283e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 284e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey// *d++ = SkPixel32ToPixel4444(pmc); 285e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey } 286e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey} 2877c8bec01790087748ec7afa69a31789828b751f9Robin Lee 28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void FromColor_D4444_Raw(void* dst, const SkColor src[], int width, 289095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee int x, int y) { 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkPMColor16* d = (SkPMColor16*)dst; 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 292095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee DITHER_4444_SCAN(y); 293095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee for (int stop = x + width; x < stop; x++) { 294095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee SkColor c = *src++; 295095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 29641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied 297095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 298095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee SkColorGetG(c), SkColorGetB(c)); 299095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 30041ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey// *d++ = SkPixel32ToPixel4444(pmc); 30141ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey } 302095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee} 30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void FromColor_DA8(void* dst, const SkColor src[], int width, int x, int y) { 30541ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey uint8_t* d = (uint8_t*)dst; 30641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey 307095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee for (int stop = x + width; x < stop; x++) { 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *d++ = SkColorGetA(*src++); 309095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 31041ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey} 31141ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey 31241ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey// can return NULL 31341ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkeystatic FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) { 31441ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey switch (bitmap.colorType()) { 31541ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey case kN32_SkColorType: 31641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D32 : FromColor_D32_Raw; 31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kARGB_4444_SkColorType: 31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D4444 : 319095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee FromColor_D4444_Raw; 32094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kRGB_565_SkColorType: 32194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return FromColor_D565; 322c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey case kAlpha_8_SkColorType: 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return FromColor_DA8; 324c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey default: 325d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey break; 326c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey } 32794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return NULL; 328c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey} 3293aee2c5c749dc2589f001b26fae1ec958ec89524Narayan Kamath 33094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodbool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride, 33194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int x, int y, int width, int height, const SkBitmap& dstBitmap) { 332c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey SkAutoLockPixels alp(dstBitmap); 333c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey void* dst = dstBitmap.getPixels(); 334c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey FromColorProc proc = ChooseFromColorProc(dstBitmap); 335a2ccb9e43db52a18d088c1d440676335cb4b9e68Daichi Hirono 336c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey if (NULL == dst || NULL == proc) { 337c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey return false; 338c03de09173f98506e73e7cf7df21fe11795d4b24Jeff Sharkey } 339c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey 340770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey const jint* array = env->GetIntArrayElements(srcColors, NULL); 341770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey const SkColor* src = (const SkColor*)array + srcOffset; 342770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey 343770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey // reset to to actual choice from caller 344770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey dst = dstBitmap.getAddr(x, y); 345c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey // now copy/convert each scanline 346c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey for (int y = 0; y < height; y++) { 347c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey proc(dst, src, width, x, y); 348c796b681e52fbb792da9a5b4f30e935cc927c1d7Jeff Sharkey src += srcStride; 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood dst = (char*)dst + dstBitmap.rowBytes(); 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood dstBitmap.notifyPixelsChanged(); 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood JNI_ABORT); 35641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey return true; 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//////////////////// ToColor procs 36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodtypedef void (*ToColorProc)(SkColor dst[], const void* src, int width, 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*); 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width, 36541ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey SkColorTable*) { 36641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey SkASSERT(width > 0); 36741ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey const SkPMColor* s = (const SkPMColor*)src; 36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkUnPreMultiply::PMColorToColor(*s++); 37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width, 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*) { 37541ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey SkASSERT(width > 0); 37641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey const SkPMColor* s = (const SkPMColor*)src; 37741ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey do { 37841ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey SkPMColor c = *s++; 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkGetPackedG32(c), SkGetPackedB32(c)); 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 38241ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey} 38341ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey 38441ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkeystatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width, 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*) { 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(width > 0); 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkPMColor* s = (const SkPMColor*)src; 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkPMColor c = *s++; 39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkGetPackedB32(c)); 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width, 39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*) { 39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(width > 0); 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkPMColor16* s = (const SkPMColor16*)src; 39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++)); 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width, 40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*) { 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(width > 0); 40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkPMColor16* s = (const SkPMColor16*)src; 40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 40994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkPMColor c = SkPixel4444ToPixel32(*s++); 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkGetPackedG32(c), SkGetPackedB32(c)); 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width, 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*) { 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(width > 0); 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkPMColor16* s = (const SkPMColor16*)src; 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkPMColor c = SkPixel4444ToPixel32(*s++); 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkGetPackedB32(c)); 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_S565(SkColor dst[], const void* src, int width, 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable*) { 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(width > 0); 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const uint16_t* s = (const uint16_t*)src; 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t c = *s++; 43294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), 43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkPacked16ToB32(c)); 43494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 43641ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable* ctable) { 43941ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey SkASSERT(width > 0); 44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const uint8_t* s = (const uint8_t*)src; 44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkPMColor* colors = ctable->readColors(); 4421b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath do { 44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); 44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } while (--width != 0); 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 447770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkeystatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, 448770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey SkColorTable* ctable) { 449770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey SkASSERT(width > 0); 450770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey const uint8_t* s = (const uint8_t*)src; 451770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey const SkPMColor* colors = ctable->readColors(); 452770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey do { 453770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey SkPMColor c = colors[*s++]; 454770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkGetPackedG32(c), SkGetPackedB32(c)); 4561b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath } while (--width != 0); 4571b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath} 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable* ctable) { 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkASSERT(width > 0); 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const uint8_t* s = (const uint8_t*)src; 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const SkPMColor* colors = ctable->readColors(); 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood do { 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkPMColor c = colors[*s++]; 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkGetPackedB32(c)); 4681b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath } while (--width != 0); 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) { 472770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey SkASSERT(width > 0); 473770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey const uint8_t* s = (const uint8_t*)src; 474770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey do { 475770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey uint8_t c = *s++; 476770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey *dst++ = SkColorSetARGB(c, c, c, c); 4771b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath } while (--width != 0); 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// can return NULL 481770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkeystatic ToColorProc ChooseToColorProc(const SkBitmap& src) { 482770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey switch (src.colorType()) { 483770180a4dd86f8bda6af2e6db4676e99a5bb1548Jeff Sharkey case kN32_SkColorType: 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch (src.alphaType()) { 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kOpaque_SkAlphaType: 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ToColor_S32_Opaque; 48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kPremul_SkAlphaType: 48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ToColor_S32_Alpha; 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kUnpremul_SkAlphaType: 490d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ToColor_S32_Raw; 4918b41780d73930b37b6254cc1dac5607c843839c0Dianne Hackborn default: 4921b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return NULL; 4931b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath } 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kARGB_4444_SkColorType: 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch (src.alphaType()) { 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kOpaque_SkAlphaType: 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ToColor_S4444_Opaque; 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kPremul_SkAlphaType: 49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ToColor_S4444_Alpha; 50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kUnpremul_SkAlphaType: 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ToColor_S4444_Raw; 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return NULL; 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kRGB_565_SkColorType: 506d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ToColor_S565; 507d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey case kIndex_8_SkColorType: 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (src.getColorTable() == NULL) { 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return NULL; 51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch (src.alphaType()) { 512d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey case kOpaque_SkAlphaType: 513d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ToColor_SI8_Opaque; 514d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey case kPremul_SkAlphaType: 515d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ToColor_SI8_Alpha; 516d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey case kUnpremul_SkAlphaType: 517d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ToColor_SI8_Raw; 518d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey default: 519d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return NULL; 52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case kAlpha_8_SkColorType: 522d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ToColor_SA8; 523d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey default: 52494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 52594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return NULL; 52794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 52894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 529d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey/////////////////////////////////////////////////////////////////////////////// 530d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey/////////////////////////////////////////////////////////////////////////////// 5311b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath 53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int getPremulBitmapCreateFlags(bool isMutable) { 53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int flags = android::bitmap::kBitmapCreateFlag_Premultiplied; 53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (isMutable) flags |= android::bitmap::kBitmapCreateFlag_Mutable; 53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return flags; 53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 537d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 5388b41780d73930b37b6254cc1dac5607c843839c0Dianne Hackbornstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 5398b41780d73930b37b6254cc1dac5607c843839c0Dianne Hackborn jint offset, jint stride, jint width, jint height, 54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood jint configHandle, jboolean isMutable) { 54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (NULL != jColors) { 54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size_t n = env->GetArrayLength(jColors); 54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n < SkAbs32(stride) * (size_t)height) { 54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood doThrowAIOOBE(env); 54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return NULL; 547d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // ARGB_4444 is a deprecated format, convert automatically to 8888 55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (colorType == kARGB_4444_SkColorType) { 55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood colorType = kN32_SkColorType; 55394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 554d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 555d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkBitmap bitmap; 556d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType, 557d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey GraphicsJNI::defaultColorSpace())); 558d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL); 56094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!nativeBitmap) { 561d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return NULL; 562d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 563d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 56494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (jColors != NULL) { 565d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey GraphicsJNI::SetPixels(env, jColors, offset, stride, 566d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 0, 0, width, height, bitmap); 567d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 568d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 569d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable)); 570d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 571d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 572d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkeystatic jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, 573d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey jint dstConfigHandle, jboolean isMutable) { 574d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkBitmap src; 575d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 576d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 577d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkBitmap result; 578d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey HeapAllocator allocator; 579d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 580d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey if (!src.copyTo(&result, dstCT, &allocator)) { 581d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return NULL; 582d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 583d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey auto bitmap = allocator.getStorageObjAndReset(); 584d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return createBitmap(env, bitmap, getPremulBitmapCreateFlags(isMutable)); 585d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 586d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 587d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkeystatic Bitmap* Bitmap_copyAshmemImpl(JNIEnv* env, SkBitmap& src, SkColorType& dstCT) { 588d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkBitmap result; 589d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 590d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey AshmemPixelAllocator allocator(env); 591d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey if (!src.copyTo(&result, dstCT, &allocator)) { 592d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return NULL; 593d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey } 594d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey auto bitmap = allocator.getStorageObjAndReset(); 595d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey bitmap->setImmutable(); 596d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return bitmap; 597d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 598d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 599d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkeystatic jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) { 600d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkBitmap src; 601d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 602d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkColorType dstCT = src.colorType(); 603d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 604d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 605d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey return ret; 606d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 607d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey 608d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkeystatic jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle) { 60994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkBitmap src; 610d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 611d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 612d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 61394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 61494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ret; 615d792118c493806eeb24a8203f508e6e18fe93bd7Jeff Sharkey} 61694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void Bitmap_destruct(BitmapWrapper* bitmap) { 61894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood delete bitmap; 61994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 62094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic jlong Bitmap_getNativeFinalizer(JNIEnv*, jobject) { 62294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct)); 62394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 6241b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath 62594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { 62694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood LocalScopedBitmap bitmap(bitmapHandle); 62794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bitmap->freePixels(); 62894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return JNI_TRUE; 62994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 63094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 63194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, 63294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood jint width, jint height, jint configHandle, jboolean requestPremul) { 63394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood LocalScopedBitmap bitmap(bitmapHandle); 63494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bitmap->assertValid(); 63594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 63694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 63794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // ARGB_4444 is a deprecated format, convert automatically to 8888 63894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (colorType == kARGB_4444_SkColorType) { 63994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood colorType = kN32_SkColorType; 64094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 641d93707342a61e66bc3eb2145628158452f577f42Dave Allison size_t requestedSize = width * height * SkColorTypeBytesPerPixel(colorType); 6421b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath if (requestedSize > bitmap->getAllocationByteCount()) { 6431b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath // done in native as there's no way to get BytesPerPixel in Java 644d93707342a61e66bc3eb2145628158452f577f42Dave Allison doThrowIAE(env, "Bitmap not large enough to support new configuration"); 64594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 64694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 64794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkAlphaType alphaType; 64894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bitmap->info().colorType() != kRGB_565_SkColorType 6491b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath && bitmap->info().alphaType() == kOpaque_SkAlphaType) { 65094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // If the original bitmap was set to opaque, keep that setting, unless it 6511b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath // was 565, which is required to be opaque. 65294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood alphaType = kOpaque_SkAlphaType; 65394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 654d93707342a61e66bc3eb2145628158452f577f42Dave Allison // Otherwise respect the premultiplied request. 6551b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 65694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 65794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bitmap->bitmap().reconfigure(SkImageInfo::Make(width, height, colorType, alphaType, 65894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood sk_ref_sp(bitmap->info().colorSpace()))); 65994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 66094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 66194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// These must match the int values in Bitmap.java 66294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodenum JavaEncodeFormat { 66394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood kJPEG_JavaEncodeFormat = 0, 664b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban kPNG_JavaEncodeFormat = 1, 665b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban kWEBP_JavaEncodeFormat = 2 666b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban}; 667b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban 668b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Roubanstatic jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, 669b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban jint format, jint quality, 670b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban jobject jstream, jbyteArray jstorage) { 671b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban SkEncodedImageFormat fm; 672b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban switch (format) { 673b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban case kJPEG_JavaEncodeFormat: 674b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban fm = SkEncodedImageFormat::kJPEG; 675b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban break; 676b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban case kPNG_JavaEncodeFormat: 677b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban fm = SkEncodedImageFormat::kPNG; 678b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban break; 679b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban case kWEBP_JavaEncodeFormat: 680b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban fm = SkEncodedImageFormat::kWEBP; 68114e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae break; 682b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban default: 683b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban return JNI_FALSE; 684b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban } 685b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban 686b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban LocalScopedBitmap bitmap(bitmapHandle); 687b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban if (!bitmap.valid()) { 688b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban return JNI_FALSE; 689b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban } 690b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban 691b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban std::unique_ptr<SkWStream> strm(CreateJavaOutputStreamAdaptor(env, jstream, jstorage)); 692b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban if (!strm.get()) { 693b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban return JNI_FALSE; 694b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban } 695b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban 6967365a10689df23334d245b211ce272502ad20669Alex Light SkBitmap skbitmap; 69799d9fb15b4a1eb534261ae81b2cf25aec4447bd0Chih-Hung Hsieh bitmap->getSkBitmap(&skbitmap); 6987365a10689df23334d245b211ce272502ad20669Alex Light return SkEncodeImage(strm.get(), skbitmap, fm, quality) ? JNI_TRUE : JNI_FALSE; 6997365a10689df23334d245b211ce272502ad20669Alex Light} 7008fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle 7017365a10689df23334d245b211ce272502ad20669Alex Lightstatic void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { 7027365a10689df23334d245b211ce272502ad20669Alex Light LocalScopedBitmap bitmap(bitmapHandle); 7037365a10689df23334d245b211ce272502ad20669Alex Light SkBitmap skBitmap; 7047365a10689df23334d245b211ce272502ad20669Alex Light bitmap->getSkBitmap(&skBitmap); 7057365a10689df23334d245b211ce272502ad20669Alex Light skBitmap.eraseColor(color); 7067365a10689df23334d245b211ce272502ad20669Alex Light} 7077365a10689df23334d245b211ce272502ad20669Alex Light 7087365a10689df23334d245b211ce272502ad20669Alex Lightstatic jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { 7097365a10689df23334d245b211ce272502ad20669Alex Light LocalScopedBitmap bitmap(bitmapHandle); 7107365a10689df23334d245b211ce272502ad20669Alex Light return static_cast<jint>(bitmap->rowBytes()); 7117365a10689df23334d245b211ce272502ad20669Alex Light} 7127365a10689df23334d245b211ce272502ad20669Alex Light 7137365a10689df23334d245b211ce272502ad20669Alex Lightstatic jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { 7147365a10689df23334d245b211ce272502ad20669Alex Light LocalScopedBitmap bitmap(bitmapHandle); 7157365a10689df23334d245b211ce272502ad20669Alex Light return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->info().colorType()); 7167365a10689df23334d245b211ce272502ad20669Alex Light} 7177365a10689df23334d245b211ce272502ad20669Alex Light 7187365a10689df23334d245b211ce272502ad20669Alex Lightstatic jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { 719a7915d437c3971943f82dfc2370fe7a5df522801Alex Light LocalScopedBitmap bitmap(bitmapHandle); 7207365a10689df23334d245b211ce272502ad20669Alex Light return static_cast<jint>(bitmap->getGenerationID()); 7217365a10689df23334d245b211ce272502ad20669Alex Light} 7227365a10689df23334d245b211ce272502ad20669Alex Light 7237365a10689df23334d245b211ce272502ad20669Alex Lightstatic jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) { 7247365a10689df23334d245b211ce272502ad20669Alex Light LocalScopedBitmap bitmap(bitmapHandle); 7257365a10689df23334d245b211ce272502ad20669Alex Light if (bitmap->info().alphaType() == kPremul_SkAlphaType) { 7267365a10689df23334d245b211ce272502ad20669Alex Light return JNI_TRUE; 7277365a10689df23334d245b211ce272502ad20669Alex Light } 7287365a10689df23334d245b211ce272502ad20669Alex Light return JNI_FALSE; 7297365a10689df23334d245b211ce272502ad20669Alex Light} 7307365a10689df23334d245b211ce272502ad20669Alex Light 7317365a10689df23334d245b211ce272502ad20669Alex Lightstatic jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { 7327365a10689df23334d245b211ce272502ad20669Alex Light LocalScopedBitmap bitmap(bitmapHandle); 7337365a10689df23334d245b211ce272502ad20669Alex Light return !bitmap->info().isOpaque() ? JNI_TRUE : JNI_FALSE; 7347365a10689df23334d245b211ce272502ad20669Alex Light} 7357365a10689df23334d245b211ce272502ad20669Alex Light 7363822b8b79cf533ee8573794176838406c32a1c20Andreas Gampestatic void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle, 7373822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe jboolean hasAlpha, jboolean requestPremul) { 7383822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe LocalScopedBitmap bitmap(bitmapHandle); 7393822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe if (hasAlpha) { 7403822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe bitmap->setAlphaType( 7413822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); 7423822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe } else { 7433822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe bitmap->setAlphaType(kOpaque_SkAlphaType); 7443822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe } 7451705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom} 746df9dadd5e5c287110d837c38aaec12bcf5e5d151Calin Juravle 74712434f8cce66a753ef49c07b503f9625e01366c8Todd Kennedystatic void Bitmap_setPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, 7481705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom jboolean isPremul) { 7498fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle LocalScopedBitmap bitmap(bitmapHandle); 7508fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle if (!bitmap->info().isOpaque()) { 7518fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle if (isPremul) { 7528fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle bitmap->setAlphaType(kPremul_SkAlphaType); 7538fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle } else { 7548fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle bitmap->setAlphaType(kUnpremul_SkAlphaType); 7558fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle } 7568fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle } 757e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom} 758e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom 759e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstromstatic jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { 760e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom LocalScopedBitmap bitmap(bitmapHandle); 761e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; 762e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom} 763cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom 764cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstromstatic void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, 765cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom jboolean hasMipMap) { 766cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom LocalScopedBitmap bitmap(bitmapHandle); 7678d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe bitmap->setHasHardwareMipMap(hasMipMap); 768919461cbeef3e9f35388fc099a5fcdae1cb79cc6Andreas Gampe} 769919461cbeef3e9f35388fc099a5fcdae1cb79cc6Andreas Gampe 770919461cbeef3e9f35388fc099a5fcdae1cb79cc6Andreas Gampe/////////////////////////////////////////////////////////////////////////////// 771919461cbeef3e9f35388fc099a5fcdae1cb79cc6Andreas Gampe 772919461cbeef3e9f35388fc099a5fcdae1cb79cc6Andreas Gampestatic jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 7738d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe if (parcel == NULL) { 7748d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe SkDebugf("-------- unparcel parcel is NULL\n"); 7758d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe return NULL; 7768d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe } 7778d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe 7788fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle android::Parcel* p = android::parcelForJavaObject(env, parcel); 7798fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle 7808fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle const bool isMutable = p->readInt32() != 0; 7818fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle const SkColorType colorType = (SkColorType)p->readInt32(); 7828fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); 7838fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle const bool isSRGB = p->readInt32() != 0; 78416a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers const int width = p->readInt32(); 78516a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers const int height = p->readInt32(); 78616a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers const int rowBytes = p->readInt32(); 78716a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers const int density = p->readInt32(); 78816a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers 78916a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers if (kN32_SkColorType != colorType && 79014e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae kRGB_565_SkColorType != colorType && 79114e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae kARGB_4444_SkColorType != colorType && 79214e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae kIndex_8_SkColorType != colorType && 7930ae8e39ebcc26836ba55a5ee4481825a0f473a9eBrian Carlstrom kAlpha_8_SkColorType != colorType) { 794b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban SkDebugf("Bitmap_createFromParcel unknown colortype: %d\n", colorType); 795b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban return NULL; 7960ae8e39ebcc26836ba55a5ee4481825a0f473a9eBrian Carlstrom } 7970ae8e39ebcc26836ba55a5ee4481825a0f473a9eBrian Carlstrom 798538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom std::unique_ptr<SkBitmap> bitmap(new SkBitmap); 799538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom 800538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType, 801538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom isSRGB ? SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : nullptr), rowBytes)) { 802538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom return NULL; 803538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom } 804538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom 805528c8ddc60df7b3d291b389117e4db878a20ad48David Srbecky SkColorTable* ctable = NULL; 806d4a7b459f4f383988440c0512513b321ce03fc22Mathieu Chartier if (colorType == kIndex_8_SkColorType) { 8071705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom int count = p->readInt32(); 80853e0776d967324e2908e3be56b80cddb2c9d9e03Brian Carlstrom if (count < 0 || count > 256) { 80953e0776d967324e2908e3be56b80cddb2c9d9e03Brian Carlstrom // The data is corrupt, since SkColorTable enforces a value between 0 and 256, 81053e0776d967324e2908e3be56b80cddb2c9d9e03Brian Carlstrom // inclusive. 8111705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom return NULL; 8121b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath } 8131705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom if (count > 0) { 8141705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom size_t size = count * sizeof(SkPMColor); 8151705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom const SkPMColor* src = (const SkPMColor*)p->readInplace(size); 8167195fcc2185c35b45a8f28c79fde4999b38850e8Brian Carlstrom if (src == NULL) { 8171b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return NULL; 81816a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers } 8198fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle ctable = new SkColorTable(src, count); 820e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom } 821e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom } 822cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom 823e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe // Read the bitmap blob. 824e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe size_t size = bitmap->getSize(); 8251705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom android::Parcel::ReadableBlob blob; 8261705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom android::status_t status = p->readBlob(size, &blob); 8271705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom if (status) { 8281705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom SkSafeUnref(ctable); 8291705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom doThrowRE(env, "Could not read bitmap blob."); 8301b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return NULL; 83116a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers } 8328fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle 833e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe // Map the bitmap in place from the ashmem region if possible otherwise copy. 834e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe sk_sp<Bitmap> nativeBitmap; 835e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (blob.fd() >= 0 && (blob.isMutable() || !isMutable) && (size >= ASHMEM_BITMAP_MIN_SIZE)) { 836e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe#if DEBUG_PARCEL 83757c69c39640a7d6a08b3afb56361d76f7ecf1250Calin Juravle ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob " 83812434f8cce66a753ef49c07b503f9625e01366c8Todd Kennedy "(fds %s)", 83912434f8cce66a753ef49c07b503f9625e01366c8Todd Kennedy isMutable ? "mutable" : "immutable", 840e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom blob.isMutable() ? "mutable" : "immutable", 841e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom p->allowFds() ? "allowed" : "forbidden"); 842e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom#endif 843e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom // Dup the file descriptor so we can keep a reference to it after the Parcel 844e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom // is disposed. 845e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom int dupFd = dup(blob.fd()); 846538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom if (dupFd < 0) { 847e18987efb5e39ca1bed15527b7b82bde55c99669Brian Carlstrom ALOGE("Error allocating dup fd. Error:%d", errno); 848538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom blob.release(); 84914e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae SkSafeUnref(ctable); 850b1efac103523efccbe671e76cc0eaaeab810415bCalin Juravle doThrowRE(env, "Could not allocate dup blob fd."); 851b1efac103523efccbe671e76cc0eaaeab810415bCalin Juravle return NULL; 85297477d203eaf0c3235bbe2415356f20a0431cadaCalin Juravle } 853d4a7b459f4f383988440c0512513b321ce03fc22Mathieu Chartier 854d4a7b459f4f383988440c0512513b321ce03fc22Mathieu Chartier // Map the pixels in place and take ownership of the ashmem region. 855d4a7b459f4f383988440c0512513b321ce03fc22Mathieu Chartier nativeBitmap = sk_sp<Bitmap>(GraphicsJNI::mapAshmemBitmap(env, bitmap.get(), 856538998f204d1e542e235de9e7ce18ef4dc68c9ccBrian Carlstrom ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable)); 857cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom SkSafeUnref(ctable); 858cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom if (!nativeBitmap) { 859e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom close(dupFd); 860598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe blob.release(); 861598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe doThrowRE(env, "Could not allocate ashmem pixel ref."); 862df9dadd5e5c287110d837c38aaec12bcf5e5d151Calin Juravle return NULL; 863598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe } 864598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe 865598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe // Clear the blob handle, don't release it. 866598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe blob.clear(); 867598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe } else { 8681705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom#if DEBUG_PARCEL 8694fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle if (blob.fd() >= 0) { 87014e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae ALOGD("Bitmap.createFromParcel: copied contents of mutable bitmap " 87114e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae "from immutable blob (fds %s)", 87214e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae p->allowFds() ? "allowed" : "forbidden"); 87314e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae } else { 87414e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae ALOGD("Bitmap.createFromParcel: copied contents from %s blob " 87514e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae "(fds %s)", 8768d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe blob.isMutable() ? "mutable" : "immutable", 87714e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae p->allowFds() ? "allowed" : "forbidden"); 87814e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae } 879528c8ddc60df7b3d291b389117e4db878a20ad48David Srbecky#endif 880598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe 88114e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae // Copy the pixels into a new buffer. 8824fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle nativeBitmap = Bitmap::allocateHeapBitmap(bitmap.get(), ctable); 88314e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae SkSafeUnref(ctable); 8844fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle if (!nativeBitmap) { 8854fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle blob.release(); 8864fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle doThrowRE(env, "Could not allocate java pixel ref."); 8874fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle return NULL; 8884fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle } 88916a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers bitmap->lockPixels(); 89016a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers memcpy(bitmap->getPixels(), blob.data(), size); 89116a95b267ac6aac75453f65f1bc382ce65c0741eIan Rogers bitmap->unlockPixels(); 8928fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle 8938fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle // Release the blob handle. 8948fc7315a67fdbf9b56cc6fa061f0773be2223a81Calin Juravle blob.release(); 895e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom } 89614e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae 897e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom return createBitmap(env, nativeBitmap.release(), 898e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); 899e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom} 90014e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae 901e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstromstatic jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 902e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom jlong bitmapHandle, 903cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom jboolean isMutable, jint density, 904cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom jobject parcel) { 905cf51ba1360ee13459830a0502b0d454d0145544fBrian Carlstrom if (parcel == NULL) { 9068d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe SkDebugf("------- writeToParcel null parcel\n"); 9078d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe return JNI_FALSE; 9088d7af8b2418cc5e7e59746f0cb359a75ed0bdfd1Andreas Gampe } 909e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe 910e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe android::Parcel* p = android::parcelForJavaObject(env, parcel); 911e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe SkBitmap bitmap; 912528c8ddc60df7b3d291b389117e4db878a20ad48David Srbecky 913528c8ddc60df7b3d291b389117e4db878a20ad48David Srbecky auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle); 9143822b8b79cf533ee8573794176838406c32a1c20Andreas Gampe bitmapWrapper->getSkBitmap(&bitmap); 915598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe 916598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); 917598c25e23f7c97470e09a2316513ddf2efdfb670Andreas Gampe bool isSRGB = bitmap.colorSpace() == sRGB.get(); 918b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban 919b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban p->writeInt32(isMutable); 9204fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle p->writeInt32(bitmap.colorType()); 92114e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae p->writeInt32(bitmap.alphaType()); 92214e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae p->writeInt32(isSRGB); // TODO: We should write the color space (b/32072280) 92314e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae p->writeInt32(bitmap.width()); 92414e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae p->writeInt32(bitmap.height()); 925e46a75a0f6007967cd0d161959af844772cdc330Brian Carlstrom p->writeInt32(bitmap.rowBytes()); 9264fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle p->writeInt32(density); 9274fdff4616699708e58d875273c3c1a85ba4c63bdCalin Juravle 92814e084d39ac44e9d4d0a0143bf1f111011343d34neo.chae if (bitmap.colorType() == kIndex_8_SkColorType) { 929b0d8d00b2916aef7b01ad42f6d441f5b46b7731aYevgeny Rouban // The bitmap needs to be locked to access its color table. 9301705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom SkAutoLockPixels alp(bitmap); 9311705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom SkColorTable* ctable = bitmap.getColorTable(); 93263568b1430d741f40ca008391c854ef1cc880138Mårten Kongstad if (ctable != NULL) { 93394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int count = ctable->count(); 93494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood p->writeInt32(count); 93594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(p->writeInplace(count * sizeof(SkPMColor)), 93694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ctable->readColors(), count * sizeof(SkPMColor)); 93794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 93894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood p->writeInt32(0); // indicate no ctable 93994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 94094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 94194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 94294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Transfer the underlying ashmem region if we have one and it's immutable. 94394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::status_t status; 94494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int fd = bitmapWrapper->bitmap().getAshmemFd(); 94594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fd >= 0 && !isMutable && p->allowFds()) { 94694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if DEBUG_PARCEL 94794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " 94894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "immutable blob (fds %s)", 94994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood p->allowFds() ? "allowed" : "forbidden"); 95094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 95194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 95294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood status = p->writeDupImmutableBlobFileDescriptor(fd); 95394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (status) { 95494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood doThrowRE(env, "Could not write bitmap blob file descriptor."); 95594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return JNI_FALSE; 95694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 95794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return JNI_TRUE; 958e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 959c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe 960c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe // Copy the bitmap to a new blob. 961c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe bool mutableCopy = isMutable; 962c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe#if DEBUG_PARCEL 963c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe ALOGD("Bitmap.writeToParcel: copying %s bitmap into new %s blob (fds %s)", 964c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe isMutable ? "mutable" : "immutable", 965c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe mutableCopy ? "mutable" : "immutable", 966c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe p->allowFds() ? "allowed" : "forbidden"); 967c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe#endif 968c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe 969e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe size_t size = bitmap.getSize(); 970c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe android::Parcel::WritableBlob blob; 971c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe status = p->writeBlob(size, mutableCopy, &blob); 972e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (status) { 973e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe doThrowRE(env, "Could not copy bitmap to parcel blob."); 974e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe return JNI_FALSE; 975e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 976e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe 977e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe bitmap.lockPixels(); 978c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe const void* pSrc = bitmap.getPixels(); 979c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe if (pSrc == NULL) { 980c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe memset(blob.data(), 0, size); 981c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe } else { 982c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe memcpy(blob.data(), pSrc, size); 983c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe } 984c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe bitmap.unlockPixels(); 985c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe 986c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe blob.release(); 987c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe return JNI_TRUE; 988c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe} 989c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe 990c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampestatic jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, 991c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe jlong srcHandle, jlong paintHandle, 992c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe jintArray offsetXY) { 993c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe SkBitmap src; 994c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 995c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle); 996c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe SkIPoint offset; 997c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe SkBitmap dst; 998c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe HeapAllocator allocator; 999c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe 1000c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe src.extractAlpha(&dst, paint, &allocator, &offset); 1001c968c0175e967e39e72f557b5e014b9575ba4727Andreas Gampe // If Skia can't allocate pixels for destination bitmap, it resets 1002e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe // it, that is set its pixels buffer to NULL, and zero width and height. 1003e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (dst.getPixels() == NULL && src.getPixels() != NULL) { 1004009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler doThrowOOME(env, "failed to allocate pixels for alpha"); 1005009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler return NULL; 1006009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler } 1007009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) { 1008009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler int* array = env->GetIntArrayElements(offsetXY, NULL); 1009009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler array[0] = offset.fX; 1010009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler array[1] = offset.fY; 1011009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler env->ReleaseIntArrayElements(offsetXY, array, 0); 1012009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler } 1013009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler 1014009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler return createBitmap(env, allocator.getStorageObjAndReset(), 1015009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler getPremulBitmapCreateFlags(true)); 1016009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler} 1017009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler 1018009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler/////////////////////////////////////////////////////////////////////////////// 1019009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler 1020009b8771323ce69658c1ac0254c3259186107fb6Richard Uhlerstatic jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, 1021009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler jint x, jint y) { 1022009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler SkBitmap bitmap; 1023009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1024009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler SkAutoLockPixels alp(bitmap); 1025009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler 1026009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler ToColorProc proc = ChooseToColorProc(bitmap); 1027009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler if (NULL == proc) { 1028009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler return 0; 1029009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler } 1030009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler const void* src = bitmap.getAddr(x, y); 1031009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler if (NULL == src) { 1032009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler return 0; 1033009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler } 1034009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler 1035009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler SkColor dst[1]; 1036009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler proc(dst, src, 1, bitmap.getColorTable()); 1037009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler return static_cast<jint>(dst[0]); 1038009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler} 1039009b8771323ce69658c1ac0254c3259186107fb6Richard Uhler 104094dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampestatic void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, 104194dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe jintArray pixelArray, jint offset, jint stride, 104294dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe jint x, jint y, jint width, jint height) { 104394dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe SkBitmap bitmap; 104494dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 104594dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe SkAutoLockPixels alp(bitmap); 104694dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe 104794dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe ToColorProc proc = ChooseToColorProc(bitmap); 104894dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe if (NULL == proc) { 104994dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe return; 105094dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe } 105194dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe const void* src = bitmap.getAddr(x, y); 105294dd3d3c5be4de57278ee668218a3464585795c0Andreas Gampe if (NULL == src) { 105376e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy return; 105476e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy } 105594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 105694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkColorTable* ctable = bitmap.getColorTable(); 105726ff93c1a783d02c177a47f0a80249070fe43682Fyodor Kupolov jint* dst = env->GetIntArrayElements(pixelArray, NULL); 10581705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom SkColor* d = (SkColor*)dst + offset; 1059e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe while (--height >= 0) { 10607365a10689df23334d245b211ce272502ad20669Alex Light proc(d, src, width, ctable); 10617365a10689df23334d245b211ce272502ad20669Alex Light d += stride; 1062e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe src = (void*)((const char*)src + bitmap.rowBytes()); 106376e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy } 106476e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy env->ReleaseIntArrayElements(pixelArray, dst, 0); 106576e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy} 106676e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy 106712434f8cce66a753ef49c07b503f9625e01366c8Todd Kennedy/////////////////////////////////////////////////////////////////////////////// 106876e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy 1069e296e00df65461629a20cd03b5b041a59935d00fTodd Kennedystatic void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, 107076e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy jint x, jint y, jint colorHandle) { 107176e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy SkBitmap bitmap; 107294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1073e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe SkColor color = static_cast<SkColor>(colorHandle); 1074e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe SkAutoLockPixels alp(bitmap); 1075e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (NULL == bitmap.getPixels()) { 107694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 107788ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov } 107894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 107994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood FromColorProc proc = ChooseFromColorProc(bitmap); 108094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (NULL == proc) { 108188ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return; 108288ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov } 108388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 108488ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov proc(bitmap.getAddr(x, y), &color, 1, x, y); 108588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov bitmap.notifyPixelsChanged(); 108688ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov} 108788ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 108888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolovstatic void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, 108988ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov jintArray pixelArray, jint offset, jint stride, 109088ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov jint x, jint y, jint width, jint height) { 109188ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov SkBitmap bitmap; 10920e8ae16f084e3d4772ea6dd33a9b72925d7b40d5Chih-Wei Huang reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 109394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood GraphicsJNI::SetPixels(env, pixelArray, offset, stride, 109494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood x, y, width, height, bitmap); 1095c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler} 1096c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1097c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhlerstatic void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, 1098c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler jlong bitmapHandle, jobject jbuffer) { 1099c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler SkBitmap bitmap; 1100c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1101c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler SkAutoLockPixels alp(bitmap); 1102c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler const void* src = bitmap.getPixels(); 1103c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1104c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler if (NULL != src) { 1105c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); 1106c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1107c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler // the java side has already checked that buffer is large enough 1108c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler memcpy(abp.pointer(), src, bitmap.getSize()); 1109c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler } 1110c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler} 1111c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1112c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhlerstatic void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, 1113c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler jlong bitmapHandle, jobject jbuffer) { 11147365a10689df23334d245b211ce272502ad20669Alex Light SkBitmap bitmap; 11157365a10689df23334d245b211ce272502ad20669Alex Light reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 11167365a10689df23334d245b211ce272502ad20669Alex Light SkAutoLockPixels alp(bitmap); 11177365a10689df23334d245b211ce272502ad20669Alex Light void* dst = bitmap.getPixels(); 111894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11197365a10689df23334d245b211ce272502ad20669Alex Light if (NULL != dst) { 11207365a10689df23334d245b211ce272502ad20669Alex Light android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); 11217365a10689df23334d245b211ce272502ad20669Alex Light // the java side has already checked that buffer is large enough 112294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(dst, abp.pointer(), bitmap.getSize()); 112394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bitmap.notifyPixelsChanged(); 112494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11251705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom} 11261705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom 11271705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstromstatic jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, 11281705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom jlong bm1Handle) { 112994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkBitmap bm0; 113094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkBitmap bm1; 11311705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom reinterpret_cast<BitmapWrapper*>(bm0Handle)->getSkBitmap(&bm0); 113294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reinterpret_cast<BitmapWrapper*>(bm1Handle)->getSkBitmap(&bm1); 113394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bm0.width() != bm1.width() || 11341705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom bm0.height() != bm1.height() || 113594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bm0.colorType() != bm1.colorType() || 113694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bm0.alphaType() != bm1.alphaType() || 11371705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom bm0.colorSpace() != bm1.colorSpace()) { 11381705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom return JNI_FALSE; 113994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 114094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 114194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood SkAutoLockPixels alp0(bm0); 1142e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe SkAutoLockPixels alp1(bm1); 1143c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1144e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe // if we can't load the pixels, return false 1145e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) { 1146e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe return JNI_FALSE; 1147e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 1148e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe 1149e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (bm0.colorType() == kIndex_8_SkColorType) { 1150e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe SkColorTable* ct0 = bm0.getColorTable(); 1151e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe SkColorTable* ct1 = bm1.getColorTable(); 1152e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (NULL == ct0 || NULL == ct1) { 1153e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe return JNI_FALSE; 1154e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 1155e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (ct0->count() != ct1->count()) { 1156e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe return JNI_FALSE; 1157e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 1158e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe 1159e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe const size_t size = ct0->count() * sizeof(SkPMColor); 1160e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe if (memcmp(ct0->readColors(), ct1->readColors(), size) != 0) { 1161e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe return JNI_FALSE; 1162e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 1163e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe } 1164d93707342a61e66bc3eb2145628158452f577f42Dave Allison 11657365a10689df23334d245b211ce272502ad20669Alex Light // now compare each scanline. We can't do the entire buffer at once, 116694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // since we don't care about the pixel values that might extend beyond 116794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // the width (since the scanline might be larger than the logical width) 116894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const int h = bm0.height(); 116994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const size_t size = bm0.width() * bm0.bytesPerPixel(); 117094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (int y = 0; y < h; y++) { 117194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config 11721705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0 117394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // and bm1 both have pixel data() (have passed NULL == getPixels() check), 117494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE 117594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // to warn user those 2 unrecognized config bitmaps may be different. 11761705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom void *bm0Addr = bm0.getAddr(0, y); 117794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *bm1Addr = bm1.getAddr(0, y); 117894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 117994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if(bm0Addr == NULL || bm1Addr == NULL) { 118094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return JNI_FALSE; 118194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 118294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 118394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (memcmp(bm0Addr, bm1Addr, size) != 0) { 118494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return JNI_FALSE; 118594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 118694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 118794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return JNI_TRUE; 118894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 118913f141910ba383404145924df64ad6626fe5b42fAndreas Gampe 11901705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstromstatic void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) { 11911705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom LocalScopedBitmap bitmapHandle(bitmapPtr); 119294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!bitmapHandle.valid()) return; 119394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmapHandle->bitmap()); 119494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 1195c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1196c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhlerstatic jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) { 1197bd872e49561282682793ab526616d609f7fbb274Andreas Gampe LocalScopedBitmap bitmapHandle(bitmapPtr); 1198c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler return static_cast<jint>(bitmapHandle->getAllocationByteCount()); 119988ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov} 120088ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 120188ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov/////////////////////////////////////////////////////////////////////////////// 120288ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolovstatic jclass make_globalref(JNIEnv* env, const char classname[]) 120388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 120488ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov jclass c = env->FindClass(classname); 1205df9dadd5e5c287110d837c38aaec12bcf5e5d151Calin Juravle SkASSERT(c); 120612434f8cce66a753ef49c07b503f9625e01366c8Todd Kennedy return (jclass) env->NewGlobalRef(c); 1207c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler} 1208c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhler 1209c92fb6247d4c4fbc34c0a5deb26ccf538ca9ec81Richard Uhlerstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz, 12101705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom const char fieldname[], const char type[]) 121194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 121294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood jfieldID id = env->GetFieldID(clazz, fieldname, type); 121363568b1430d741f40ca008391c854ef1cc880138Mårten Kongstad SkASSERT(id); 121463568b1430d741f40ca008391c854ef1cc880138Mårten Kongstad return id; 12157365a10689df23334d245b211ce272502ad20669Alex Light} 121663568b1430d741f40ca008391c854ef1cc880138Mårten Kongstad 12177365a10689df23334d245b211ce272502ad20669Alex Lightstatic const JNINativeMethod gBitmapMethods[] = { 121894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;", 121994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood (void*)Bitmap_creator }, 122094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;", 122194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood (void*)Bitmap_copy }, 12227365a10689df23334d245b211ce272502ad20669Alex Light { "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;", 12237365a10689df23334d245b211ce272502ad20669Alex Light (void*)Bitmap_copyAshmem }, 12241705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;", 12251705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom (void*)Bitmap_copyAshmemConfig }, 12261705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom { "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer }, 12277365a10689df23334d245b211ce272502ad20669Alex Light { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle }, 1228e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure }, 1229e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z", 1230e1c01353c4dc6058a384eea9853238d2a87040dbAndreas Gampe (void*)Bitmap_compress }, 123194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeErase", "(JI)V", (void*)Bitmap_erase }, 123294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes }, 123394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeConfig", "(J)I", (void*)Bitmap_config }, 12341705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha }, 12351705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom { "nativeIsPremultiplied", "(J)Z", (void*)Bitmap_isPremultiplied}, 12361705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom { "nativeSetHasAlpha", "(JZZ)V", (void*)Bitmap_setHasAlpha}, 123794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeSetPremultiplied", "(JZ)V", (void*)Bitmap_setPremultiplied}, 12387365a10689df23334d245b211ce272502ad20669Alex Light { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap }, 12397365a10689df23334d245b211ce272502ad20669Alex Light { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap }, 124094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeCreateFromParcel", 124194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;", 124294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood (void*)Bitmap_createFromParcel }, 124394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z", 1244091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath (void*)Bitmap_writeToParcel }, 1245091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;", 1246091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath (void*)Bitmap_extractAlpha }, 1247091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId }, 1248091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeGetPixel", "(JII)I", (void*)Bitmap_getPixel }, 1249091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeGetPixels", "(J[IIIIIII)V", (void*)Bitmap_getPixels }, 1250091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeSetPixel", "(JIII)V", (void*)Bitmap_setPixel }, 1251091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeSetPixels", "(J[IIIIIII)V", (void*)Bitmap_setPixels }, 1252091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V", 1253091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath (void*)Bitmap_copyPixelsToBuffer }, 1254091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", 1255091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath (void*)Bitmap_copyPixelsFromBuffer }, 1256091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, 1257091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, 1258091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount }, 125994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 126094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 126194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint register_android_graphics_Bitmap(JNIEnv* env) 126294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 126394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood gBitmap_class = make_globalref(env, "android/graphics/Bitmap"); 126494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J"); 126594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V"); 126694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V"); 126794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); 126894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, 126994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NELEM(gBitmapMethods)); 127094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 127194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood