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