1f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#define LOG_TAG "Bitmap"
2f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include "Bitmap.h"
3f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
40a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv#include "GraphicBuffer.h"
532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkBitmap.h"
632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkPixelRef.h"
732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkImageEncoder.h"
857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III#include "SkImageInfo.h"
99505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkColor.h"
1032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkColorPriv.h"
11ce217faddb4b40c1b3e698944da1951027080427Romain Guy#include "SkColorSpace.h"
12ce217faddb4b40c1b3e698944da1951027080427Romain Guy#include "SkColorSpaceXform.h"
139505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkHalf.h"
14efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy#include "SkMatrix44.h"
159505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkPM4f.h"
169505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkPM4fPriv.h"
1732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "GraphicsJNI.h"
1832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkDither.h"
1932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkUnPreMultiply.h"
2032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkStream.h"
2132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
2232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <binder/Parcel.h>
2332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_os_Parcel.h"
2432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_util_Binder.h"
2532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_nio_utils.h"
2632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "CreateJavaOutputStreamAdaptor.h"
27dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h>
28c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv#include <hwui/Bitmap.h>
294387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck#include <renderthread/RenderProxy.h>
3032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
31ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
32ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
3332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <jni.h>
34ce217faddb4b40c1b3e698944da1951027080427Romain Guy#include <string.h>
3539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <memory>
3639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <string>
3732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
38a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#define DEBUG_PARCEL 0
398cee7c17119b204be88860feb812f2374d0de732Riley Andrews#define ASHMEM_BITMAP_MIN_SIZE (128 * (1 << 10))
40a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown
41c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass   gBitmap_class;
42c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID gBitmap_nativePtr;
43c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_constructorMethodID;
44c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_reinitMethodID;
45c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_getAllocationByteCountMethodID;
46c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
47f29ed28c7b878ef28058bc730715d0d32445bc57John Recknamespace android {
48f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
49c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvclass BitmapWrapper {
50f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic:
51c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    BitmapWrapper(Bitmap* bitmap)
52c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        : mBitmap(bitmap) { }
53c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
54c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    void freePixels() {
55c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mInfo = mBitmap->info();
56c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mHasHardwareMipMap = mBitmap->hasHardwareMipMap();
57c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mAllocationSize = mBitmap->getAllocationByteCount();
58c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mRowBytes = mBitmap->rowBytes();
59c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mGenerationId = mBitmap->getGenerationID();
6015a108550e3d74b406927d85c8e69018761adf49sergeyv        mIsHardware = mBitmap->isHardware();
61c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mBitmap.reset();
62f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
63f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
64c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    bool valid() {
65fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return mBitmap;
66f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
67f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
68aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    Bitmap& bitmap() {
69aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv        assertValid();
70aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv        return *mBitmap;
71aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    }
72c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
73c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    void assertValid() {
74c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        LOG_ALWAYS_FATAL_IF(!valid(), "Error, cannot access an invalid/free'd bitmap here!");
75c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    }
76c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
77c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    void getSkBitmap(SkBitmap* outBitmap) {
78c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        assertValid();
79c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mBitmap->getSkBitmap(outBitmap);
80c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    }
810781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck
82c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    bool hasHardwareMipMap() {
83c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        if (mBitmap) {
84c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            return mBitmap->hasHardwareMipMap();
85c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        }
86f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        return mHasHardwareMipMap;
87f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
88f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
89f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void setHasHardwareMipMap(bool hasMipMap) {
90c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        assertValid();
91c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mBitmap->setHasHardwareMipMap(hasMipMap);
92f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
93f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
94c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    void setAlphaType(SkAlphaType alphaType) {
95c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        assertValid();
96c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        mBitmap->setAlphaType(alphaType);
97f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
98f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
99c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    const SkImageInfo& info() {
100c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        if (mBitmap) {
101c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            return mBitmap->info();
102c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        }
103c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        return mInfo;
104f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
105f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
106c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    size_t getAllocationByteCount() const {
107c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        if (mBitmap) {
108c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            return mBitmap->getAllocationByteCount();
109c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        }
110c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        return mAllocationSize;
111f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
112f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
113c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    size_t rowBytes() const {
114c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        if (mBitmap) {
115c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            return mBitmap->rowBytes();
116c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        }
117c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        return mRowBytes;
118c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    }
119f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
120c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    uint32_t getGenerationID() const {
121c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        if (mBitmap) {
122c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            return mBitmap->getGenerationID();
123c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        }
124c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        return mGenerationId;
125f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
126c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
12715a108550e3d74b406927d85c8e69018761adf49sergeyv    bool isHardware() {
12815a108550e3d74b406927d85c8e69018761adf49sergeyv        if (mBitmap) {
12915a108550e3d74b406927d85c8e69018761adf49sergeyv            return mBitmap->isHardware();
13015a108550e3d74b406927d85c8e69018761adf49sergeyv        }
13115a108550e3d74b406927d85c8e69018761adf49sergeyv        return mIsHardware;
13215a108550e3d74b406927d85c8e69018761adf49sergeyv    }
13315a108550e3d74b406927d85c8e69018761adf49sergeyv
134c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    ~BitmapWrapper() { }
135c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
136c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvprivate:
137c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    sk_sp<Bitmap> mBitmap;
138c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    SkImageInfo mInfo;
139c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    bool mHasHardwareMipMap;
140c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    size_t mAllocationSize;
141c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    size_t mRowBytes;
142c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    uint32_t mGenerationId;
14315a108550e3d74b406927d85c8e69018761adf49sergeyv    bool mIsHardware;
144f29ed28c7b878ef28058bc730715d0d32445bc57John Reck};
145f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
146f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// Convenience class that does not take a global ref on the pixels, relying
147f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// on the caller already having a local JNI ref
148f29ed28c7b878ef28058bc730715d0d32445bc57John Reckclass LocalScopedBitmap {
149f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic:
150c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh    explicit LocalScopedBitmap(jlong bitmapHandle)
151c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            : mBitmapWrapper(reinterpret_cast<BitmapWrapper*>(bitmapHandle)) {}
152f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
153c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    BitmapWrapper* operator->() {
154c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        return mBitmapWrapper;
155f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
156f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
157f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void* pixels() {
158aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv        return mBitmapWrapper->bitmap().pixels();
159f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
160f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
161f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    bool valid() {
162c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        return mBitmapWrapper && mBitmapWrapper->valid();
163f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
164f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
165f29ed28c7b878ef28058bc730715d0d32445bc57John Reckprivate:
166c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    BitmapWrapper* mBitmapWrapper;
167f29ed28c7b878ef28058bc730715d0d32445bc57John Reck};
168f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
169c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvnamespace bitmap {
170c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
171c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv// Assert that bitmap's SkAlphaType is consistent with isPremultiplied.
172c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied) {
173c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is
174c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // irrelevant. This just tests to ensure that the SkAlphaType is not
175c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // opposite of isPremultiplied.
176c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    if (isPremultiplied) {
177c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        SkASSERT(info.alphaType() != kUnpremul_SkAlphaType);
178c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    } else {
179c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        SkASSERT(info.alphaType() != kPremul_SkAlphaType);
180c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    }
181c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}
182c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
183c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
184c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        bool isPremultiplied)
185c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{
186c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // The caller needs to have already set the alpha type properly, so the
187c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // native SkBitmap stays in sync with the Java Bitmap.
188c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    assert_premultiplied(info, isPremultiplied);
189c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
190c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
191c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv            info.width(), info.height(), isPremultiplied);
192c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}
193c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
194c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvint getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap)
195c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{
196c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID);
197c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}
198c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
199c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvjobject createBitmap(JNIEnv* env, Bitmap* bitmap,
200c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets,
201c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        int density) {
202c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
203c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
204c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // The caller needs to have already set the alpha type properly, so the
205c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    // native SkBitmap stays in sync with the Java Bitmap.
206c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    assert_premultiplied(bitmap->info(), isPremultiplied);
207c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    BitmapWrapper* bitmapWrapper = new BitmapWrapper(bitmap);
208c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
209c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density,
210c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv            isMutable, isPremultiplied, ninePatchChunk, ninePatchInsets);
211c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
212c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    if (env->ExceptionCheck() != 0) {
213c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        ALOGE("*** Uncaught exception returned from Java call!\n");
214c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv        env->ExceptionDescribe();
215c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    }
216c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    return obj;
217c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}
218c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
219c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap) {
220c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    LocalScopedBitmap bitmap(bitmapHandle);
221c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    bitmap->getSkBitmap(outBitmap);
222c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}
223c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
224aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvBitmap& toBitmap(JNIEnv* env, jobject bitmap) {
225c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    SkASSERT(env);
226c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    SkASSERT(bitmap);
227c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
228c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
229c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    LocalScopedBitmap localBitmap(bitmapHandle);
230c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return localBitmap->bitmap();
231c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}
232c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
2335fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyvBitmap& toBitmap(JNIEnv* env, jlong bitmapHandle) {
2345fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    SkASSERT(env);
2355fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    LocalScopedBitmap localBitmap(bitmapHandle);
2365fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv    return localBitmap->bitmap();
2375fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv}
2385fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv
23900799f760d6956fc54ee1763427f8196fcb3696dJohn Reckvoid imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info) {
24000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(info);
24100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(env);
24200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(bitmap);
24300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
24400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
24500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    LocalScopedBitmap localBitmap(bitmapHandle);
24600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
24700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    const SkImageInfo& imageInfo = localBitmap->info();
24800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    info->width = imageInfo.width();
24900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    info->height = imageInfo.height();
25000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    info->stride = localBitmap->rowBytes();
25100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    info->flags = 0;
25200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    switch (imageInfo.colorType()) {
25300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        case kN32_SkColorType:
25400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            info->format = ANDROID_BITMAP_FORMAT_RGBA_8888;
25500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            break;
25600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        case kRGB_565_SkColorType:
25700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            info->format = ANDROID_BITMAP_FORMAT_RGB_565;
25800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            break;
25900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        case kARGB_4444_SkColorType:
26000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            info->format = ANDROID_BITMAP_FORMAT_RGBA_4444;
26100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            break;
26200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        case kAlpha_8_SkColorType:
26300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            info->format = ANDROID_BITMAP_FORMAT_A_8;
26400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            break;
26500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        default:
26600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            info->format = ANDROID_BITMAP_FORMAT_NONE;
26700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck            break;
26800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    }
26900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck}
27000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
27100799f760d6956fc54ee1763427f8196fcb3696dJohn Reckvoid* lockPixels(JNIEnv* env, jobject bitmap) {
27200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(env);
27300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(bitmap);
27400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
27500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
27600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
27700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    LocalScopedBitmap localBitmap(bitmapHandle);
27800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    if (!localBitmap->valid()) return nullptr;
27900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
28000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkPixelRef& pixelRef = localBitmap->bitmap();
28100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    pixelRef.lockPixels();
28200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    if (!pixelRef.pixels()) {
28300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        pixelRef.unlockPixels();
28400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck        return nullptr;
28500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    }
28600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    pixelRef.ref();
28700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    return pixelRef.pixels();
28800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck}
28900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
29000799f760d6956fc54ee1763427f8196fcb3696dJohn Reckbool unlockPixels(JNIEnv* env, jobject bitmap) {
29100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(env);
29200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(bitmap);
29300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
29400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
29500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
29600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    LocalScopedBitmap localBitmap(bitmapHandle);
29700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    if (!localBitmap->valid()) return false;
29800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
29900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    SkPixelRef& pixelRef = localBitmap->bitmap();
30000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    pixelRef.notifyPixelsChanged();
30100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    pixelRef.unlockPixels();
30200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    pixelRef.unref();
30300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck    return true;
30400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck}
30500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck
306c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace bitmap
307c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
308c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace android
309c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
310c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android;
311c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android::bitmap;
312c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv
31332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik///////////////////////////////////////////////////////////////////////////////
31432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// Conversions to/from SkColor, for get/setPixels, and the create method, which
31532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// is basically like setPixels
31632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
31732054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*FromColorProc)(void* dst, const SkColor src[], int width,
31832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                              int x, int y);
31932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
3209505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void FromColor_F16(void* dst, const SkColor src[], int width,
3219505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                          int, int) {
3229505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    uint64_t* d = (uint64_t*)dst;
3239505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
3249505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    for (int i = 0; i < width; i++) {
3259505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        *d++ = SkColor4f::FromColor(*src++).premul().toF16();
3269505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    }
3279505a6552764461c22ce48f1ac13d025d23e1579Romain Guy}
3289505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
3299505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void FromColor_F16_Raw(void* dst, const SkColor src[], int width,
3309505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                          int, int) {
3319505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    uint64_t* d = (uint64_t*)dst;
3329505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
3339505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    for (int i = 0; i < width; i++) {
3349505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        const float* color = SkColor4f::FromColor(*src++).vec();
3359505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        uint16_t* scratch = reinterpret_cast<uint16_t*>(d++);
3369505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        for (int i = 0; i < 4; ++i) {
3379505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            scratch[i] = SkFloatToHalf(color[i]);
3389505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        }
3399505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    }
3409505a6552764461c22ce48f1ac13d025d23e1579Romain Guy}
3419505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
34232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32(void* dst, const SkColor src[], int width,
34332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                          int, int) {
34432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkPMColor* d = (SkPMColor*)dst;
34532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
34632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    for (int i = 0; i < width; i++) {
34732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *d++ = SkPreMultiplyColor(*src++);
34832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
34932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
35032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
35132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32_Raw(void* dst, const SkColor src[], int width,
35232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                          int, int) {
35346d8444631b4b1253a76bfcc78a29d26014d022fDan Albert    // Needed to thwart the unreachable code detection from clang.
35446d8444631b4b1253a76bfcc78a29d26014d022fDan Albert    static const bool sk_color_ne_zero = SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER;
35546d8444631b4b1253a76bfcc78a29d26014d022fDan Albert
35632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    // SkColor's ordering may be different from SkPMColor
35746d8444631b4b1253a76bfcc78a29d26014d022fDan Albert    if (sk_color_ne_zero) {
35832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        memcpy(dst, src, width * sizeof(SkColor));
35932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        return;
36032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
36132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
36232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    // order isn't same, repack each pixel manually
36332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkPMColor* d = (SkPMColor*)dst;
36432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    for (int i = 0; i < width; i++) {
36532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkColor c = *src++;
36632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
36732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                   SkColorGetG(c), SkColorGetB(c));
36832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
36932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
37032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
37132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D565(void* dst, const SkColor src[], int width,
37232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                           int x, int y) {
37332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    uint16_t* d = (uint16_t*)dst;
37432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
37532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    DITHER_565_SCAN(y);
37632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    for (int stop = x + width; x < stop; x++) {
37732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkColor c = *src++;
37832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c),
37932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                DITHER_VALUE(x));
38032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
38132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
38232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
38332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444(void* dst, const SkColor src[], int width,
38432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                            int x, int y) {
38532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkPMColor16* d = (SkPMColor16*)dst;
38632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
38732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    DITHER_4444_SCAN(y);
38832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    for (int stop = x + width; x < stop; x++) {
38932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor pmc = SkPreMultiplyColor(*src++);
39032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
39132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//        *d++ = SkPixel32ToPixel4444(pmc);
39232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
39332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
39432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
39532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444_Raw(void* dst, const SkColor src[], int width,
39632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                            int x, int y) {
39732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkPMColor16* d = (SkPMColor16*)dst;
39832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
39932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    DITHER_4444_SCAN(y);
40032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    for (int stop = x + width; x < stop; x++) {
40132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkColor c = *src++;
40232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
40332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied
40432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
40532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                            SkColorGetG(c), SkColorGetB(c));
40632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
40732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//        *d++ = SkPixel32ToPixel4444(pmc);
40832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
40932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
41032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
4116260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void FromColor_DA8(void* dst, const SkColor src[], int width, int x, int y) {
4126260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    uint8_t* d = (uint8_t*)dst;
4136260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik
4146260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    for (int stop = x + width; x < stop; x++) {
4156260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik        *d++ = SkColorGetA(*src++);
4166260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    }
4176260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik}
4186260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik
41932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL
42057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) {
42157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    switch (bitmap.colorType()) {
42257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        case kN32_SkColorType:
42357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D32 : FromColor_D32_Raw;
42457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        case kARGB_4444_SkColorType:
42557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D4444 :
42657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    FromColor_D4444_Raw;
42757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        case kRGB_565_SkColorType:
42832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            return FromColor_D565;
4296260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik        case kAlpha_8_SkColorType:
4306260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik            return FromColor_DA8;
4319505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        case kRGBA_F16_SkColorType:
4329505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_F16 : FromColor_F16_Raw;
43332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        default:
43432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            break;
43532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
43632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    return NULL;
43732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
43832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
43932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikbool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,
44057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        int x, int y, int width, int height, const SkBitmap& dstBitmap) {
44132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkAutoLockPixels alp(dstBitmap);
44232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    void* dst = dstBitmap.getPixels();
44357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    FromColorProc proc = ChooseFromColorProc(dstBitmap);
44432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
44532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    if (NULL == dst || NULL == proc) {
44632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        return false;
44732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
44832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
44932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const jint* array = env->GetIntArrayElements(srcColors, NULL);
45032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkColor* src = (const SkColor*)array + srcOffset;
45132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
45232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    // reset to to actual choice from caller
45332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    dst = dstBitmap.getAddr(x, y);
454ce217faddb4b40c1b3e698944da1951027080427Romain Guy
455ce217faddb4b40c1b3e698944da1951027080427Romain Guy    SkColorSpace* colorSpace = dstBitmap.colorSpace();
456d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy    if (dstBitmap.colorType() == kRGBA_F16_SkColorType ||
457d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy            GraphicsJNI::isColorSpaceSRGB(colorSpace)) {
458ce217faddb4b40c1b3e698944da1951027080427Romain Guy        // now copy/convert each scanline
459ce217faddb4b40c1b3e698944da1951027080427Romain Guy        for (int y = 0; y < height; y++) {
460ce217faddb4b40c1b3e698944da1951027080427Romain Guy            proc(dst, src, width, x, y);
461ce217faddb4b40c1b3e698944da1951027080427Romain Guy            src += srcStride;
462ce217faddb4b40c1b3e698944da1951027080427Romain Guy            dst = (char*)dst + dstBitmap.rowBytes();
463ce217faddb4b40c1b3e698944da1951027080427Romain Guy        }
464ce217faddb4b40c1b3e698944da1951027080427Romain Guy    } else {
465ce217faddb4b40c1b3e698944da1951027080427Romain Guy        auto sRGB = SkColorSpace::MakeSRGB();
466ce217faddb4b40c1b3e698944da1951027080427Romain Guy        auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace);
467ce217faddb4b40c1b3e698944da1951027080427Romain Guy
468ce217faddb4b40c1b3e698944da1951027080427Romain Guy        std::unique_ptr<SkColor[]> row(new SkColor[width]);
469ce217faddb4b40c1b3e698944da1951027080427Romain Guy
470ce217faddb4b40c1b3e698944da1951027080427Romain Guy        // now copy/convert each scanline
471ce217faddb4b40c1b3e698944da1951027080427Romain Guy        for (int y = 0; y < height; y++) {
472ce217faddb4b40c1b3e698944da1951027080427Romain Guy            memcpy(row.get(), src, sizeof(SkColor) * width);
473ce217faddb4b40c1b3e698944da1951027080427Romain Guy            xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(),
474ce217faddb4b40c1b3e698944da1951027080427Romain Guy                    SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(), width,
475ce217faddb4b40c1b3e698944da1951027080427Romain Guy                    SkAlphaType::kUnpremul_SkAlphaType);
476ce217faddb4b40c1b3e698944da1951027080427Romain Guy
477ce217faddb4b40c1b3e698944da1951027080427Romain Guy            proc(dst, row.get(), width, x, y);
478ce217faddb4b40c1b3e698944da1951027080427Romain Guy            src += srcStride;
479ce217faddb4b40c1b3e698944da1951027080427Romain Guy            dst = (char*)dst + dstBitmap.rowBytes();
480ce217faddb4b40c1b3e698944da1951027080427Romain Guy        }
48132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
48232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
48332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    dstBitmap.notifyPixelsChanged();
48432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
4859505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), JNI_ABORT);
48632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    return true;
48732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
48832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
48932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//////////////////// ToColor procs
49032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
49132054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*ToColorProc)(SkColor dst[], const void* src, int width,
49232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                            SkColorTable*);
49332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
4949505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void ToColor_F16_Alpha(SkColor dst[], const void* src, int width,
4959505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                              SkColorTable*) {
4969505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    SkASSERT(width > 0);
4979505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    uint64_t* s = (uint64_t*)src;
4989505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    do {
4999505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        *dst++ = SkPM4f::FromF16((const uint16_t*) s++).unpremul().toSkColor();
5009505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    } while (--width != 0);
5019505a6552764461c22ce48f1ac13d025d23e1579Romain Guy}
5029505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
5039505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void ToColor_F16_Raw(SkColor dst[], const void* src, int width,
5049505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                            SkColorTable*) {
5059505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    SkASSERT(width > 0);
5069505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    uint64_t* s = (uint64_t*)src;
5079505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    do {
5089505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        *dst++ = Sk4f_toS32(swizzle_rb(SkHalfToFloat_finite_ftz(*s++)));
5099505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    } while (--width != 0);
5109505a6552764461c22ce48f1ac13d025d23e1579Romain Guy}
5119505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
51232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width,
51332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                              SkColorTable*) {
51432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
51532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkPMColor* s = (const SkPMColor*)src;
51632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
51732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkUnPreMultiply::PMColorToColor(*s++);
51832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
51932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
52032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
52132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width,
52232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                              SkColorTable*) {
52332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
52432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkPMColor* s = (const SkPMColor*)src;
52532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
52632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor c = *s++;
52732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
52832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                SkGetPackedG32(c), SkGetPackedB32(c));
52932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
53032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
53132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
53232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width,
53332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                               SkColorTable*) {
53432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
53532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkPMColor* s = (const SkPMColor*)src;
53632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
53732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor c = *s++;
53832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
53932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                               SkGetPackedB32(c));
54032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
54132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
54232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
54332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width,
54432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                SkColorTable*) {
54532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
54632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkPMColor16* s = (const SkPMColor16*)src;
54732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
54832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++));
54932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
55032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
55132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
55232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width,
55332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                SkColorTable*) {
55432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
55532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkPMColor16* s = (const SkPMColor16*)src;
55632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
55732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor c = SkPixel4444ToPixel32(*s++);
55832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
55932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                SkGetPackedG32(c), SkGetPackedB32(c));
56032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
56132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
56232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
56332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,
56432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                 SkColorTable*) {
56532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
56632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const SkPMColor16* s = (const SkPMColor16*)src;
56732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
56832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor c = SkPixel4444ToPixel32(*s++);
56932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
57032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                               SkGetPackedB32(c));
57132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
57232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
57332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
57432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S565(SkColor dst[], const void* src, int width,
57532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                         SkColorTable*) {
57632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
57732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const uint16_t* s = (const uint16_t*)src;
57832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
57932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        uint16_t c = *s++;
58032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ =  SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c),
58132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                SkPacked16ToB32(c));
58232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
58332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
58432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
58532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
58632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                              SkColorTable* ctable) {
58732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
58832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const uint8_t* s = (const uint8_t*)src;
58971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed    const SkPMColor* colors = ctable->readColors();
59032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
59132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
59232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
59332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
59432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
59532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
59632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                              SkColorTable* ctable) {
59732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
59832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const uint8_t* s = (const uint8_t*)src;
59971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed    const SkPMColor* colors = ctable->readColors();
60032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
60132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor c = colors[*s++];
60232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
60332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                                SkGetPackedG32(c), SkGetPackedB32(c));
60432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
60532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
60632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
60732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
60832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                               SkColorTable* ctable) {
60932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkASSERT(width > 0);
61032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    const uint8_t* s = (const uint8_t*)src;
61171487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed    const SkPMColor* colors = ctable->readColors();
61232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    do {
61332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        SkPMColor c = colors[*s++];
61432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
61532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                               SkGetPackedB32(c));
61632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    } while (--width != 0);
61732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
61832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
6196260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) {
6206260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    SkASSERT(width > 0);
6216260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    const uint8_t* s = (const uint8_t*)src;
6226260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    do {
6236260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik        uint8_t c = *s++;
6245320a72a882f505682f47978d2e38778113900faMatt Sarett        *dst++ = SkColorSetARGB(c, 0, 0, 0);
6256260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik    } while (--width != 0);
6266260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik}
6276260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik
62832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL
62957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic ToColorProc ChooseToColorProc(const SkBitmap& src) {
630b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed    switch (src.colorType()) {
631b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed        case kN32_SkColorType:
63257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            switch (src.alphaType()) {
63357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kOpaque_SkAlphaType:
63457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_S32_Opaque;
63557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kPremul_SkAlphaType:
63657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_S32_Alpha;
63757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kUnpremul_SkAlphaType:
63857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_S32_Raw;
63957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                default:
64057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return NULL;
64157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            }
642b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed        case kARGB_4444_SkColorType:
64357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            switch (src.alphaType()) {
64457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kOpaque_SkAlphaType:
64557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_S4444_Opaque;
64657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kPremul_SkAlphaType:
64757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_S4444_Alpha;
64857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kUnpremul_SkAlphaType:
64957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_S4444_Raw;
65057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                default:
65157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return NULL;
65257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            }
653b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed        case kRGB_565_SkColorType:
65432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            return ToColor_S565;
655b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed        case kIndex_8_SkColorType:
65632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            if (src.getColorTable() == NULL) {
65732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                return NULL;
65832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            }
65957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            switch (src.alphaType()) {
66057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kOpaque_SkAlphaType:
66157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_SI8_Opaque;
66257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kPremul_SkAlphaType:
66357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_SI8_Alpha;
66457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                case kUnpremul_SkAlphaType:
66557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return ToColor_SI8_Raw;
66657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                default:
66757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                    return NULL;
66857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            }
6696260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik        case kAlpha_8_SkColorType:
6706260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik            return ToColor_SA8;
6719505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        case kRGBA_F16_SkColorType:
6729505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            switch (src.alphaType()) {
6739505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                case kOpaque_SkAlphaType:
6749505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    return ToColor_F16_Raw;
6759505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                case kPremul_SkAlphaType:
6769505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    return ToColor_F16_Alpha;
6779505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                case kUnpremul_SkAlphaType:
6789505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    return ToColor_F16_Raw;
6799505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                default:
6809505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    return NULL;
6819505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            }
68232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        default:
68332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            break;
68432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
68532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    return NULL;
68632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
68732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
6888242656f495847c50c9ceaea92839dce78218a75Romain Guystatic void ToF16_SA8(void* dst, const void* src, int width) {
6898242656f495847c50c9ceaea92839dce78218a75Romain Guy    SkASSERT(width > 0);
6908242656f495847c50c9ceaea92839dce78218a75Romain Guy    uint64_t* d = (uint64_t*)dst;
6918242656f495847c50c9ceaea92839dce78218a75Romain Guy    const uint8_t* s = (const uint8_t*)src;
6928242656f495847c50c9ceaea92839dce78218a75Romain Guy
6938242656f495847c50c9ceaea92839dce78218a75Romain Guy    for (int i = 0; i < width; i++) {
6948242656f495847c50c9ceaea92839dce78218a75Romain Guy        uint8_t c = *s++;
6958242656f495847c50c9ceaea92839dce78218a75Romain Guy        SkPM4f a;
6968242656f495847c50c9ceaea92839dce78218a75Romain Guy        a.fVec[SkPM4f::R] = 0.0f;
6978242656f495847c50c9ceaea92839dce78218a75Romain Guy        a.fVec[SkPM4f::G] = 0.0f;
6988242656f495847c50c9ceaea92839dce78218a75Romain Guy        a.fVec[SkPM4f::B] = 0.0f;
6998242656f495847c50c9ceaea92839dce78218a75Romain Guy        a.fVec[SkPM4f::A] = c / 255.0f;
7008242656f495847c50c9ceaea92839dce78218a75Romain Guy        *d++ = a.toF16();
7018242656f495847c50c9ceaea92839dce78218a75Romain Guy    }
7028242656f495847c50c9ceaea92839dce78218a75Romain Guy}
7038242656f495847c50c9ceaea92839dce78218a75Romain Guy
70432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik///////////////////////////////////////////////////////////////////////////////
70532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik///////////////////////////////////////////////////////////////////////////////
70632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
70732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic int getPremulBitmapCreateFlags(bool isMutable) {
708c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    int flags = android::bitmap::kBitmapCreateFlag_Premultiplied;
709c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    if (isMutable) flags |= android::bitmap::kBitmapCreateFlag_Mutable;
71032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    return flags;
71132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
71232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
71332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
71432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik                              jint offset, jint stride, jint width, jint height,
7158242656f495847c50c9ceaea92839dce78218a75Romain Guy                              jint configHandle, jboolean isMutable,
7168242656f495847c50c9ceaea92839dce78218a75Romain Guy                              jfloatArray xyzD50, jobject transferParameters) {
7171103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle);
71832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    if (NULL != jColors) {
71932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        size_t n = env->GetArrayLength(jColors);
72032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        if (n < SkAbs32(stride) * (size_t)height) {
72132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            doThrowAIOOBE(env);
72232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik            return NULL;
72332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        }
72432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
72532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
72632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    // ARGB_4444 is a deprecated format, convert automatically to 8888
727b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed    if (colorType == kARGB_4444_SkColorType) {
728b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed        colorType = kN32_SkColorType;
72932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
73032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
73132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    SkBitmap bitmap;
7328242656f495847c50c9ceaea92839dce78218a75Romain Guy    sk_sp<SkColorSpace> colorSpace;
7338242656f495847c50c9ceaea92839dce78218a75Romain Guy
7348242656f495847c50c9ceaea92839dce78218a75Romain Guy    if (colorType != kN32_SkColorType || xyzD50 == nullptr || transferParameters == nullptr) {
7358242656f495847c50c9ceaea92839dce78218a75Romain Guy        colorSpace = GraphicsJNI::colorSpaceForType(colorType);
7368242656f495847c50c9ceaea92839dce78218a75Romain Guy    } else {
73795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        SkColorSpaceTransferFn p = GraphicsJNI::getNativeTransferParameters(env, transferParameters);
73895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        SkMatrix44 xyzMatrix = GraphicsJNI::getNativeXYZMatrix(env, xyzD50);
7398242656f495847c50c9ceaea92839dce78218a75Romain Guy        colorSpace = SkColorSpace::MakeRGB(p, xyzMatrix);
7408242656f495847c50c9ceaea92839dce78218a75Romain Guy    }
7418242656f495847c50c9ceaea92839dce78218a75Romain Guy
7428242656f495847c50c9ceaea92839dce78218a75Romain Guy    bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType, colorSpace));
74332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
744c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
745f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    if (!nativeBitmap) {
74632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik        return NULL;
74732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
74832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
74932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    if (jColors != NULL) {
7509505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap);
75132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik    }
75232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
753c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable));
75432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}
75532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik
7565320a72a882f505682f47978d2e38778113900faMatt Sarettstatic bool bitmapCopyTo(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src,
7575320a72a882f505682f47978d2e38778113900faMatt Sarett        SkBitmap::Allocator* alloc) {
7585320a72a882f505682f47978d2e38778113900faMatt Sarett    // Skia does not support copying from kAlpha8 to types that are not alpha only.
7595320a72a882f505682f47978d2e38778113900faMatt Sarett    // We will handle this case here.
7605320a72a882f505682f47978d2e38778113900faMatt Sarett    if (kAlpha_8_SkColorType == src.colorType() && kAlpha_8_SkColorType != dstCT) {
7615320a72a882f505682f47978d2e38778113900faMatt Sarett        SkAutoPixmapUnlock srcUnlocker;
7625320a72a882f505682f47978d2e38778113900faMatt Sarett        if (!src.requestLock(&srcUnlocker)) {
7635320a72a882f505682f47978d2e38778113900faMatt Sarett            return false;
7645320a72a882f505682f47978d2e38778113900faMatt Sarett        }
7655320a72a882f505682f47978d2e38778113900faMatt Sarett        SkPixmap srcPixmap = srcUnlocker.pixmap();
7665320a72a882f505682f47978d2e38778113900faMatt Sarett
7675320a72a882f505682f47978d2e38778113900faMatt Sarett        SkImageInfo dstInfo = src.info().makeColorType(dstCT);
7688242656f495847c50c9ceaea92839dce78218a75Romain Guy        if (dstCT == kRGBA_F16_SkColorType) {
7698242656f495847c50c9ceaea92839dce78218a75Romain Guy             dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
7708242656f495847c50c9ceaea92839dce78218a75Romain Guy        }
7715320a72a882f505682f47978d2e38778113900faMatt Sarett        if (!dst->setInfo(dstInfo)) {
7725320a72a882f505682f47978d2e38778113900faMatt Sarett            return false;
7735320a72a882f505682f47978d2e38778113900faMatt Sarett        }
7745320a72a882f505682f47978d2e38778113900faMatt Sarett        if (!dst->tryAllocPixels(alloc, nullptr)) {
7755320a72a882f505682f47978d2e38778113900faMatt Sarett            return false;
7765320a72a882f505682f47978d2e38778113900faMatt Sarett        }
7775320a72a882f505682f47978d2e38778113900faMatt Sarett
7785320a72a882f505682f47978d2e38778113900faMatt Sarett        switch (dstCT) {
7795320a72a882f505682f47978d2e38778113900faMatt Sarett            case kRGBA_8888_SkColorType:
7805320a72a882f505682f47978d2e38778113900faMatt Sarett            case kBGRA_8888_SkColorType: {
7815320a72a882f505682f47978d2e38778113900faMatt Sarett                for (int y = 0; y < src.height(); y++) {
7825320a72a882f505682f47978d2e38778113900faMatt Sarett                    const uint8_t* srcRow = srcPixmap.addr8(0, y);
7835320a72a882f505682f47978d2e38778113900faMatt Sarett                    uint32_t* dstRow = dst->getAddr32(0, y);
7845320a72a882f505682f47978d2e38778113900faMatt Sarett                    ToColor_SA8(dstRow, srcRow, src.width(), nullptr);
7855320a72a882f505682f47978d2e38778113900faMatt Sarett                }
7865320a72a882f505682f47978d2e38778113900faMatt Sarett                return true;
7875320a72a882f505682f47978d2e38778113900faMatt Sarett            }
788