Bitmap.cpp revision ce217faddb4b40c1b3e698944da1951027080427
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(); 456ce217faddb4b40c1b3e698944da1951027080427Romain Guy if (GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 457ce217faddb4b40c1b3e698944da1951027080427Romain Guy // now copy/convert each scanline 458ce217faddb4b40c1b3e698944da1951027080427Romain Guy for (int y = 0; y < height; y++) { 459ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(dst, src, width, x, y); 460ce217faddb4b40c1b3e698944da1951027080427Romain Guy src += srcStride; 461ce217faddb4b40c1b3e698944da1951027080427Romain Guy dst = (char*)dst + dstBitmap.rowBytes(); 462ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 463ce217faddb4b40c1b3e698944da1951027080427Romain Guy } else { 464ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 465ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace); 466ce217faddb4b40c1b3e698944da1951027080427Romain Guy 467ce217faddb4b40c1b3e698944da1951027080427Romain Guy std::unique_ptr<SkColor[]> row(new SkColor[width]); 468ce217faddb4b40c1b3e698944da1951027080427Romain Guy 469ce217faddb4b40c1b3e698944da1951027080427Romain Guy // now copy/convert each scanline 470ce217faddb4b40c1b3e698944da1951027080427Romain Guy for (int y = 0; y < height; y++) { 471ce217faddb4b40c1b3e698944da1951027080427Romain Guy memcpy(row.get(), src, sizeof(SkColor) * width); 472ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(), 473ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(), width, 474ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 475ce217faddb4b40c1b3e698944da1951027080427Romain Guy 476ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(dst, row.get(), width, x, y); 477ce217faddb4b40c1b3e698944da1951027080427Romain Guy src += srcStride; 478ce217faddb4b40c1b3e698944da1951027080427Romain Guy dst = (char*)dst + dstBitmap.rowBytes(); 479ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 48032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 48132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dstBitmap.notifyPixelsChanged(); 48332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4849505a6552764461c22ce48f1ac13d025d23e1579Romain Guy env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), JNI_ABORT); 48532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return true; 48632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 48732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//////////////////// ToColor procs 48932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 49032054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*ToColorProc)(SkColor dst[], const void* src, int width, 49132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*); 49232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4939505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void ToColor_F16_Alpha(SkColor dst[], const void* src, int width, 4949505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkColorTable*) { 4959505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkASSERT(width > 0); 4969505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint64_t* s = (uint64_t*)src; 4979505a6552764461c22ce48f1ac13d025d23e1579Romain Guy do { 4989505a6552764461c22ce48f1ac13d025d23e1579Romain Guy *dst++ = SkPM4f::FromF16((const uint16_t*) s++).unpremul().toSkColor(); 4999505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } while (--width != 0); 5009505a6552764461c22ce48f1ac13d025d23e1579Romain Guy} 5019505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 5029505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void ToColor_F16_Raw(SkColor dst[], const void* src, int width, 5039505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkColorTable*) { 5049505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkASSERT(width > 0); 5059505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint64_t* s = (uint64_t*)src; 5069505a6552764461c22ce48f1ac13d025d23e1579Romain Guy do { 5079505a6552764461c22ce48f1ac13d025d23e1579Romain Guy *dst++ = Sk4f_toS32(swizzle_rb(SkHalfToFloat_finite_ftz(*s++))); 5089505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } while (--width != 0); 5099505a6552764461c22ce48f1ac13d025d23e1579Romain Guy} 5109505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 51132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width, 51232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 51332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 51432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 51532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 51632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(*s++); 51732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 51832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 51932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 52032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width, 52132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 52232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 52332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 52432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 52532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 52632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 52732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 52832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 52932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 53032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width, 53232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 53332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 53432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 53532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 53632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 53732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 53832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 53932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 54032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 54132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 54232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width, 54332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 54432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 54532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 54632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 54732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++)); 54832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 54932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 55032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width, 55232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 55332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 55432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 55532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 55632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 55732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 55832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 55932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 56032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 56132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 56232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width, 56332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 56432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 56532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 56632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 56732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 56832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 56932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 57032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 57132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 57232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S565(SkColor dst[], const void* src, int width, 57432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 57532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 57632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint16_t* s = (const uint16_t*)src; 57732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 57832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t c = *s++; 57932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), 58032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPacked16ToB32(c)); 58132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 58232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 58332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 58432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 58532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 58632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 58732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 58871487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 58932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 59032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); 59132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 59232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 59332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 59432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, 59532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 59632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 59732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 59871487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 59932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 60032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 60132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 60232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 60332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 60432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 60532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 60632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, 60732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 60832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 60932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 61071487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 61132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 61232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 61332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 61432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 61532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 61632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 61732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 6186260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) { 6196260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik SkASSERT(width > 0); 6206260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik const uint8_t* s = (const uint8_t*)src; 6216260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik do { 6226260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t c = *s++; 6236260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *dst++ = SkColorSetARGB(c, c, c, c); 6246260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } while (--width != 0); 6256260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 6266260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 62732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 62857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic ToColorProc ChooseToColorProc(const SkBitmap& src) { 629b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed switch (src.colorType()) { 630b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kN32_SkColorType: 63157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 63257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 63357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Opaque; 63457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 63557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Alpha; 63657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 63757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Raw; 63857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 63957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 64057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 641b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kARGB_4444_SkColorType: 64257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 64357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 64457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Opaque; 64557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 64657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Alpha; 64757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 64857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Raw; 64957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 65057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 65157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 652b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kRGB_565_SkColorType: 65332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return ToColor_S565; 654b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kIndex_8_SkColorType: 65532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.getColorTable() == NULL) { 65632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 65732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 65857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 65957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 66057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Opaque; 66157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 66257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Alpha; 66357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 66457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Raw; 66557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 66657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 66757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 6686260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 6696260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return ToColor_SA8; 6709505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kRGBA_F16_SkColorType: 6719505a6552764461c22ce48f1ac13d025d23e1579Romain Guy switch (src.alphaType()) { 6729505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kOpaque_SkAlphaType: 6739505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return ToColor_F16_Raw; 6749505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kPremul_SkAlphaType: 6759505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return ToColor_F16_Alpha; 6769505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kUnpremul_SkAlphaType: 6779505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return ToColor_F16_Raw; 6789505a6552764461c22ce48f1ac13d025d23e1579Romain Guy default: 6799505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return NULL; 6809505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } 68132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 68232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 68332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 68432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 68532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 68632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 68732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 68832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 68932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic int getPremulBitmapCreateFlags(bool isMutable) { 691c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int flags = android::bitmap::kBitmapCreateFlag_Premultiplied; 692c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isMutable) flags |= android::bitmap::kBitmapCreateFlag_Mutable; 69332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return flags; 69432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 69532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 69732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint offset, jint stride, jint width, jint height, 69832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint configHandle, jboolean isMutable) { 6991103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 70032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != jColors) { 70132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t n = env->GetArrayLength(jColors); 70232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (n < SkAbs32(stride) * (size_t)height) { 70332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowAIOOBE(env); 70432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 70532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 70832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // ARGB_4444 is a deprecated format, convert automatically to 8888 709b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kARGB_4444_SkColorType) { 710b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed colorType = kN32_SkColorType; 71132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 71232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 71332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap bitmap; 714253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType, 7159505a6552764461c22ce48f1ac13d025d23e1579Romain Guy GraphicsJNI::colorSpaceForType(colorType))); 71632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 717c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL); 718f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!nativeBitmap) { 71932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 72032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 72132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (jColors != NULL) { 7239505a6552764461c22ce48f1ac13d025d23e1579Romain Guy GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap); 72432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 72532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 726c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable)); 72732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 72832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, 73032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint dstConfigHandle, jboolean isMutable) { 731f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 732c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 73305126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv if (dstConfigHandle == GraphicsJNI::hardwareLegacyBitmapConfig()) { 73405126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv sk_sp<Bitmap> bitmap(Bitmap::allocateHardwareBitmap(src)); 73505126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv if (!bitmap.get()) { 73605126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv return NULL; 73705126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv } 738656117bed2fc1937bcebd615898924ed57c48979sergeyv return createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(isMutable)); 73905126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv } 74005126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv 7411103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 7424508218850faedea95371188da587b6734f5f3dasergeyv SkBitmap result; 7434508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 74432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 745f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!src.copyTo(&result, dstCT, &allocator)) { 74632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 74732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 748c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = allocator.getStorageObjAndReset(); 749c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return createBitmap(env, bitmap, getPremulBitmapCreateFlags(isMutable)); 75032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 75132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 752c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic Bitmap* Bitmap_copyAshmemImpl(JNIEnv* env, SkBitmap& src, SkColorType& dstCT) { 753721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews SkBitmap result; 754721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 755721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews AshmemPixelAllocator allocator(env); 756a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson if (!src.copyTo(&result, dstCT, &allocator)) { 757721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return NULL; 758721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews } 759c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = allocator.getStorageObjAndReset(); 760c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv bitmap->setImmutable(); 761c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return bitmap; 762a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 763a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 764a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) { 765a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 766c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 767a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = src.colorType(); 768c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 769c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 770a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson return ret; 771a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 772a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 773a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle) { 774a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 775c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 776a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 777c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 778c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 779721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return ret; 780721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews} 781721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 782c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic void Bitmap_destruct(BitmapWrapper* bitmap) { 783c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv delete bitmap; 78432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 78532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 786775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic jlong Bitmap_getNativeFinalizer(JNIEnv*, jobject) { 787775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct)); 788775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler} 789775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler 79032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { 791f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 792f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->freePixels(); 79332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 79432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 79532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 79632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, 7974508218850faedea95371188da587b6734f5f3dasergeyv jint width, jint height, jint configHandle, jboolean requestPremul) { 798f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 799c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->assertValid(); 8001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 80117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III 80217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // ARGB_4444 is a deprecated format, convert automatically to 8888 80317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (colorType == kARGB_4444_SkColorType) { 80417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III colorType = kN32_SkColorType; 80517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 8064508218850faedea95371188da587b6734f5f3dasergeyv size_t requestedSize = width * height * SkColorTypeBytesPerPixel(colorType); 8074508218850faedea95371188da587b6734f5f3dasergeyv if (requestedSize > bitmap->getAllocationByteCount()) { 80832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // done in native as there's no way to get BytesPerPixel in Java 80932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowIAE(env, "Bitmap not large enough to support new configuration"); 81032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 81132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 81217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkAlphaType alphaType; 813f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().colorType() != kRGB_565_SkColorType 814f29ed28c7b878ef28058bc730715d0d32445bc57John Reck && bitmap->info().alphaType() == kOpaque_SkAlphaType) { 81517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // If the original bitmap was set to opaque, keep that setting, unless it 81617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // was 565, which is required to be opaque. 81717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = kOpaque_SkAlphaType; 81817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } else { 81917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // Otherwise respect the premultiplied request. 82017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 82117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 822aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv bitmap->bitmap().reconfigure(SkImageInfo::Make(width, height, colorType, alphaType, 8237d5219fb505ff1b178910cda25a40154e7d4d09asergeyv sk_ref_sp(bitmap->info().colorSpace()))); 82432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 82532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 82632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// These must match the int values in Bitmap.java 82732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikenum JavaEncodeFormat { 82832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kJPEG_JavaEncodeFormat = 0, 82932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kPNG_JavaEncodeFormat = 1, 83032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kWEBP_JavaEncodeFormat = 2 83132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 83232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 83332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, 83432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint format, jint quality, 83532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject jstream, jbyteArray jstorage) { 83610219fb261606fcc71c607167b28295b4578a10dHal Canary SkEncodedImageFormat fm; 83732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik switch (format) { 83832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kJPEG_JavaEncodeFormat: 83910219fb261606fcc71c607167b28295b4578a10dHal Canary fm = SkEncodedImageFormat::kJPEG; 84032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 84132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kPNG_JavaEncodeFormat: 84210219fb261606fcc71c607167b28295b4578a10dHal Canary fm = SkEncodedImageFormat::kPNG; 84332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 84432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kWEBP_JavaEncodeFormat: 84510219fb261606fcc71c607167b28295b4578a10dHal Canary fm = SkEncodedImageFormat::kWEBP; 84632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 84732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 84832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 84932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 85032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 85110219fb261606fcc71c607167b28295b4578a10dHal Canary LocalScopedBitmap bitmap(bitmapHandle); 852f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap.valid()) { 853f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 854f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 85532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 856f29ed28c7b878ef28058bc730715d0d32445bc57John Reck std::unique_ptr<SkWStream> strm(CreateJavaOutputStreamAdaptor(env, jstream, jstorage)); 857f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!strm.get()) { 858f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 859f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 86032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86110219fb261606fcc71c607167b28295b4578a10dHal Canary SkBitmap skbitmap; 86210219fb261606fcc71c607167b28295b4578a10dHal Canary bitmap->getSkBitmap(&skbitmap); 86310219fb261606fcc71c607167b28295b4578a10dHal Canary return SkEncodeImage(strm.get(), skbitmap, fm, quality) ? JNI_TRUE : JNI_FALSE; 86432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 86532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { 867f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 868f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap skBitmap; 869f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->getSkBitmap(&skBitmap); 870f29ed28c7b878ef28058bc730715d0d32445bc57John Reck skBitmap.eraseColor(color); 87132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 87232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 87332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { 874f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 87532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->rowBytes()); 87632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 87732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 87832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { 879f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 88015a108550e3d74b406927d85c8e69018761adf49sergeyv if (bitmap->isHardware()) { 88119b4b019169424d62bf3edc40b9560984206cf80sergeyv return GraphicsJNI::hardwareLegacyBitmapConfig(); 88219b4b019169424d62bf3edc40b9560984206cf80sergeyv } 883f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->info().colorType()); 88432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 88532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 88632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { 887f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 888c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return static_cast<jint>(bitmap->getGenerationID()); 88932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 89032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 89157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) { 892f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 893f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().alphaType() == kPremul_SkAlphaType) { 89457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_TRUE; 89557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 89657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_FALSE; 89757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 89857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 89932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { 900f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 901f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return !bitmap->info().isOpaque() ? JNI_TRUE : JNI_FALSE; 90232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 90332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 90457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle, 90557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean hasAlpha, jboolean requestPremul) { 906f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 90757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (hasAlpha) { 9080781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType( 909f29ed28c7b878ef28058bc730715d0d32445bc57John Reck requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); 91032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 9110781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kOpaque_SkAlphaType); 91257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 91357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 91457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 91557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, 91657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean isPremul) { 917f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 918f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap->info().isOpaque()) { 91957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (isPremul) { 9200781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kPremul_SkAlphaType); 92157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } else { 9220781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kUnpremul_SkAlphaType); 92357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 92432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 92532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 92632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 92732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { 928f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 92932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; 93032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 93132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 93232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, 93332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean hasMipMap) { 934f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 93532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setHasHardwareMipMap(hasMipMap); 93632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 93732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 93832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 93932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 94032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 94132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 94232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("-------- unparcel parcel is NULL\n"); 94332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 94432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 94532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 94632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 94732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 948b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const bool isMutable = p->readInt32() != 0; 949b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkColorType colorType = (SkColorType)p->readInt32(); 950b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); 9515acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy const uint32_t colorSpaceSize = p->readUint32(); 9525acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy sk_sp<SkColorSpace> colorSpace; 9535acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy if (kRGBA_F16_SkColorType == colorType) { 9545acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy colorSpace = SkColorSpace::MakeSRGBLinear(); 9555acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } else if (colorSpaceSize > 0) { 9565acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy colorSpace = SkColorSpace::Deserialize(p->readInplace(colorSpaceSize), colorSpaceSize); 9575acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } 958b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int width = p->readInt32(); 959b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int height = p->readInt32(); 960b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int rowBytes = p->readInt32(); 961b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int density = p->readInt32(); 962b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed 963b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (kN32_SkColorType != colorType && 9649505a6552764461c22ce48f1ac13d025d23e1579Romain Guy kRGBA_F16_SkColorType != colorType && 965b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kRGB_565_SkColorType != colorType && 966b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kARGB_4444_SkColorType != colorType && 967b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kIndex_8_SkColorType != colorType && 968b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kAlpha_8_SkColorType != colorType) { 969b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed SkDebugf("Bitmap_createFromParcel unknown colortype: %d\n", colorType); 97032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 97132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 97232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 973ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III std::unique_ptr<SkBitmap> bitmap(new SkBitmap); 9749505a6552764461c22ce48f1ac13d025d23e1579Romain Guy if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType, colorSpace), 9759505a6552764461c22ce48f1ac13d025d23e1579Romain Guy rowBytes)) { 976ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 977ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 97832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 97932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = NULL; 980b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kIndex_8_SkColorType) { 98132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = p->readInt32(); 982ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (count < 0 || count > 256) { 983ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // The data is corrupt, since SkColorTable enforces a value between 0 and 256, 984ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // inclusive. 985ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 986ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 98732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (count > 0) { 98832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = count * sizeof(SkPMColor); 98932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* src = (const SkPMColor*)p->readInplace(size); 990ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (src == NULL) { 991ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 992ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 99332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable = new SkColorTable(src, count); 99432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 99532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 99632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 997a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Read the bitmap blob. 998a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap->getSize(); 999a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::ReadableBlob blob; 1000a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status = p->readBlob(size, &blob); 1001a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 100232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkSafeUnref(ctable); 1003a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not read bitmap blob."); 100432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 100532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 100632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1007a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the bitmap in place from the ashmem region if possible otherwise copy. 1008c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> nativeBitmap; 10098cee7c17119b204be88860feb812f2374d0de732Riley Andrews if (blob.fd() >= 0 && (blob.isMutable() || !isMutable) && (size >= ASHMEM_BITMAP_MIN_SIZE)) { 1010a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1011a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob " 1012a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 1013a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 1014a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 1015a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1016a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1017a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Dup the file descriptor so we can keep a reference to it after the Parcel 1018a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // is disposed. 1019a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown int dupFd = dup(blob.fd()); 1020a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (dupFd < 0) { 1021211abad3b92b70dd094949c79f67e686c940fa0cErik Wolsheimer ALOGE("Error allocating dup fd. Error:%d", errno); 1022a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1023a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1024a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate dup blob fd."); 1025a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 102639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1027a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1028a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the pixels in place and take ownership of the ashmem region. 1029c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv nativeBitmap = sk_sp<Bitmap>(GraphicsJNI::mapAshmemBitmap(env, bitmap.get(), 1030c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable)); 1031a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1032a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 1033a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown close(dupFd); 1034a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1035a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate ashmem pixel ref."); 1036a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 103739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1038a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1039a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Clear the blob handle, don't release it. 1040a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.clear(); 1041a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1042a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1043a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (blob.fd() >= 0) { 1044a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents of mutable bitmap " 1045a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "from immutable blob (fds %s)", 1046a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1047a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1048a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents from %s blob " 1049a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 1050a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 1051a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 105239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1053a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1054a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1055a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the pixels into a new buffer. 1056c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv nativeBitmap = Bitmap::allocateHeapBitmap(bitmap.get(), ctable); 1057a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1058a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 1059a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1060a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate java pixel ref."); 1061a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 106239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1063a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->lockPixels(); 1064a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(bitmap->getPixels(), blob.data(), size); 1065a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->unlockPixels(); 1066a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1067a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Release the blob handle. 1068a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 106939d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1070a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1071c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return createBitmap(env, nativeBitmap.release(), 1072a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); 1073a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown} 107439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 107532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 107632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, 107732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean isMutable, jint density, 107832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject parcel) { 107932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 108032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("------- writeToParcel null parcel\n"); 108132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 108232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 108332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 108432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 1085f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 108639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 1087c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle); 1088c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv bitmapWrapper->getSkBitmap(&bitmap); 108932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 109032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(isMutable); 1091f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.colorType()); 1092f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.alphaType()); 10935acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 10945acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy if (colorSpace != nullptr && bitmap.colorType() != kRGBA_F16_SkColorType) { 10955acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy sk_sp<SkData> data = colorSpace->serialize(); 10965acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy size_t size = data->size(); 10975acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy p->writeUint32(size); 10985acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy if (size > 0) { 10995acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy p->write(data->data(), size); 11005acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } 11015acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } else { 11025acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy p->writeUint32(0); 11035acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } 1104f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.width()); 1105f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.height()); 1106f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.rowBytes()); 110732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(density); 110832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1109f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap.colorType() == kIndex_8_SkColorType) { 111066ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III // The bitmap needs to be locked to access its color table. 111166ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III SkAutoLockPixels alp(bitmap); 1112f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 111332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ctable != NULL) { 111432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = ctable->count(); 111532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(count); 111632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(p->writeInplace(count * sizeof(SkPMColor)), 111771487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed ctable->readColors(), count * sizeof(SkPMColor)); 111832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 111932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(0); // indicate no ctable 112032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 112132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 112232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1123a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Transfer the underlying ashmem region if we have one and it's immutable. 1124a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status; 1125aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv int fd = bitmapWrapper->bitmap().getAshmemFd(); 1126a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (fd >= 0 && !isMutable && p->allowFds()) { 1127a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1128a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " 1129a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "immutable blob (fds %s)", 1130a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1131a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1132a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1133a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeDupImmutableBlobFileDescriptor(fd); 1134a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 1135a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not write bitmap blob file descriptor."); 113639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews return JNI_FALSE; 113739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1138a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_TRUE; 1139a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 114032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1141a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the bitmap to a new blob. 1142a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bool mutableCopy = isMutable; 1143a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1144a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: copying %s bitmap into new %s blob (fds %s)", 1145a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 1146a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown mutableCopy ? "mutable" : "immutable", 1147a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1148a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1149a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1150a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap.getSize(); 1151a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::WritableBlob blob; 1152a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeBlob(size, mutableCopy, &blob); 1153a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 1154a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not copy bitmap to parcel blob."); 1155a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_FALSE; 115639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1157a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1158a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.lockPixels(); 1159a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown const void* pSrc = bitmap.getPixels(); 1160a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (pSrc == NULL) { 1161a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memset(blob.data(), 0, size); 1162a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1163a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(blob.data(), pSrc, size); 1164a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 1165a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.unlockPixels(); 1166a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1167a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 116832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 116932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 117032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 117132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, 117232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong srcHandle, jlong paintHandle, 117332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray offsetXY) { 1174f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 1175c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 11766ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle); 117732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkIPoint offset; 1178f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap dst; 11794508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 118032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1181f29ed28c7b878ef28058bc730715d0d32445bc57John Reck src.extractAlpha(&dst, paint, &allocator, &offset); 118232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // If Skia can't allocate pixels for destination bitmap, it resets 118332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // it, that is set its pixels buffer to NULL, and zero width and height. 1184f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (dst.getPixels() == NULL && src.getPixels() != NULL) { 118532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowOOME(env, "failed to allocate pixels for alpha"); 118632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 118732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 118832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) { 118932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int* array = env->GetIntArrayElements(offsetXY, NULL); 119032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[0] = offset.fX; 119132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[1] = offset.fY; 119232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(offsetXY, array, 0); 119332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 119432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1195c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, allocator.getStorageObjAndReset(), 1196f29ed28c7b878ef28058bc730715d0d32445bc57John Reck getPremulBitmapCreateFlags(true)); 119732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 119832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 119932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 120032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1201efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guystatic jboolean Bitmap_isSRGB(JNIEnv* env, jobject, jlong bitmapHandle) { 1202efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy LocalScopedBitmap bitmapHolder(bitmapHandle); 1203efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!bitmapHolder.valid()) return JNI_TRUE; 1204efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1205efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkColorSpace* colorSpace = bitmapHolder->info().colorSpace(); 1206ce217faddb4b40c1b3e698944da1951027080427Romain Guy return GraphicsJNI::isColorSpaceSRGB(colorSpace); 1207efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy} 1208efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1209efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guystatic jboolean Bitmap_getColorSpace(JNIEnv* env, jobject, jlong bitmapHandle, 1210efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy jfloatArray xyzArray, jfloatArray paramsArray) { 1211efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1212efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy LocalScopedBitmap bitmapHolder(bitmapHandle); 1213efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!bitmapHolder.valid()) return JNI_FALSE; 1214efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1215efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkColorSpace* colorSpace = bitmapHolder->info().colorSpace(); 1216efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (colorSpace == nullptr) return JNI_FALSE; 1217efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1218efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor); 1219efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!colorSpace->toXYZD50(&xyzMatrix)) return JNI_FALSE; 1220efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1221efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy jfloat* xyz = env->GetFloatArrayElements(xyzArray, NULL); 1222efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[0] = xyzMatrix.getFloat(0, 0); 1223efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[1] = xyzMatrix.getFloat(1, 0); 1224efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[2] = xyzMatrix.getFloat(2, 0); 1225efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[3] = xyzMatrix.getFloat(0, 1); 1226efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[4] = xyzMatrix.getFloat(1, 1); 1227efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[5] = xyzMatrix.getFloat(2, 1); 1228efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[6] = xyzMatrix.getFloat(0, 2); 1229efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[7] = xyzMatrix.getFloat(1, 2); 1230efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[8] = xyzMatrix.getFloat(2, 2); 1231efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy env->ReleaseFloatArrayElements(xyzArray, xyz, 0); 1232efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1233efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkColorSpaceTransferFn transferParams; 1234efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!colorSpace->isNumericalTransferFn(&transferParams)) return JNI_FALSE; 1235efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1236efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy jfloat* params = env->GetFloatArrayElements(paramsArray, NULL); 1237efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[0] = transferParams.fA; 1238efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[1] = transferParams.fB; 1239efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[2] = transferParams.fC; 1240efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[3] = transferParams.fD; 1241efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[4] = transferParams.fE; 1242efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[5] = transferParams.fF; 1243efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[6] = transferParams.fG; 1244efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy env->ReleaseFloatArrayElements(paramsArray, params, 0); 1245efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1246efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy return JNI_TRUE; 1247efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy} 1248efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1249efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy/////////////////////////////////////////////////////////////////////////////// 1250efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 125132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, 125257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y) { 1253f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1254c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1255f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 125632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1257f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 125832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 125932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 126032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1261f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 126232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 126332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 126432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 126532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 126632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor dst[1]; 1267f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(dst, src, 1, bitmap.getColorTable()); 1268ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1269ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 1270ce217faddb4b40c1b3e698944da1951027080427Romain Guy if (!GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 1271ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 1272ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get()); 1273ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0], 1274ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0], 1, 1275ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 1276ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 1277ce217faddb4b40c1b3e698944da1951027080427Romain Guy 127832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(dst[0]); 127932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 128032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 128132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, 128232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 128357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1284f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1285c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1286f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 128732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1288f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 128932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 129032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 129132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1292f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 129332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 129432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 129532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 129632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1297f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 129832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint* dst = env->GetIntArrayElements(pixelArray, NULL); 129932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor* d = (SkColor*)dst + offset; 1300ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1301ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 1302ce217faddb4b40c1b3e698944da1951027080427Romain Guy if (GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 1303ce217faddb4b40c1b3e698944da1951027080427Romain Guy while (--height >= 0) { 1304ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(d, src, width, ctable); 1305ce217faddb4b40c1b3e698944da1951027080427Romain Guy d += stride; 1306ce217faddb4b40c1b3e698944da1951027080427Romain Guy src = (void*)((const char*)src + bitmap.rowBytes()); 1307ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 1308ce217faddb4b40c1b3e698944da1951027080427Romain Guy } else { 1309ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 1310ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get()); 1311ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1312ce217faddb4b40c1b3e698944da1951027080427Romain Guy while (--height >= 0) { 1313ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(d, src, width, ctable); 1314ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1315ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, d, 1316ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, d, width, 1317ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 1318ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1319ce217faddb4b40c1b3e698944da1951027080427Romain Guy d += stride; 1320ce217faddb4b40c1b3e698944da1951027080427Romain Guy src = (void*)((const char*)src + bitmap.rowBytes()); 1321ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 132232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1323ce217faddb4b40c1b3e698944da1951027080427Romain Guy 132432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(pixelArray, dst, 0); 132532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 132632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 132732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 132832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 132932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, 133057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint colorHandle) { 1331f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1332c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 133332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor color = static_cast<SkColor>(colorHandle); 1334f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1335f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bitmap.getPixels()) { 133632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 133732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 133832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1339f29ed28c7b878ef28058bc730715d0d32445bc57John Reck FromColorProc proc = ChooseFromColorProc(bitmap); 134032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 134132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 134232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 134332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1344ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 1345ce217faddb4b40c1b3e698944da1951027080427Romain Guy if (!GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 1346ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 1347ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace); 1348ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &color, 1349ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, &color, 1, 1350ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 1351ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 1352ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1353f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(bitmap.getAddr(x, y), &color, 1, x, y); 1354f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 135532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 135632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 135732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, 135832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 135957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1360f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1361c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 136232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, pixelArray, offset, stride, 1363f29ed28c7b878ef28058bc730715d0d32445bc57John Reck x, y, width, height, bitmap); 136432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 136532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 136632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, 136732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1368f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1369c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1370f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1371f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getPixels(); 137232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 137332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != src) { 137432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); 137532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 137632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1377f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(abp.pointer(), src, bitmap.getSize()); 137832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 137932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 138032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 138132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, 138232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1383f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1384c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1385f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1386f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* dst = bitmap.getPixels(); 138732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 138832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != dst) { 138932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); 139032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1391f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(dst, abp.pointer(), bitmap.getSize()); 1392f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 139332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 139432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 139532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1396795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craikstatic jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, jlong bm1Handle) { 1397f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm0; 1398f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm1; 13991eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv 14001eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv LocalScopedBitmap bitmap0(bm0Handle); 14011eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv LocalScopedBitmap bitmap1(bm1Handle); 14021eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv 14031eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv // Paying the price for making Hardware Bitmap as Config: 14041eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv // later check for colorType will pass successfully, 14051eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv // because Hardware Config internally may be RGBA8888 or smth like that. 140615a108550e3d74b406927d85c8e69018761adf49sergeyv if (bitmap0->isHardware() != bitmap1->isHardware()) { 14071eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv return JNI_FALSE; 14081eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv } 14091eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv 14101eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv bitmap0->bitmap().getSkBitmap(&bm0); 14111eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv bitmap1->bitmap().getSkBitmap(&bm1); 1412795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik if (bm0.width() != bm1.width() 1413795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || bm0.height() != bm1.height() 1414795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || bm0.colorType() != bm1.colorType() 1415795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || bm0.alphaType() != bm1.alphaType() 1416795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || !SkColorSpace::Equals(bm0.colorSpace(), bm1.colorSpace())) { 141732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 141832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 141932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1420f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp0(bm0); 1421f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp1(bm1); 142232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 142332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // if we can't load the pixels, return false 1424f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) { 142532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 142632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 142732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1428f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bm0.colorType() == kIndex_8_SkColorType) { 1429f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct0 = bm0.getColorTable(); 1430f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct1 = bm1.getColorTable(); 143132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == ct0 || NULL == ct1) { 143232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 143332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 143432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ct0->count() != ct1->count()) { 143532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 143632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 143732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 143832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const size_t size = ct0->count() * sizeof(SkPMColor); 143971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed if (memcmp(ct0->readColors(), ct1->readColors(), size) != 0) { 144032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 144132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 144232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 144332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 144432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now compare each scanline. We can't do the entire buffer at once, 144532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // since we don't care about the pixel values that might extend beyond 144632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the width (since the scanline might be larger than the logical width) 1447f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const int h = bm0.height(); 1448f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const size_t size = bm0.width() * bm0.bytesPerPixel(); 144932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < h; y++) { 145053001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config 145153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0 145253001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // and bm1 both have pixel data() (have passed NULL == getPixels() check), 145353001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE 145453001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // to warn user those 2 unrecognized config bitmaps may be different. 1455f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm0Addr = bm0.getAddr(0, y); 1456f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm1Addr = bm1.getAddr(0, y); 145753001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 145853001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if(bm0Addr == NULL || bm1Addr == NULL) { 145953001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen return JNI_FALSE; 146053001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen } 146153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 146253001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if (memcmp(bm0Addr, bm1Addr, size) != 0) { 146332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 146432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 146532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 146632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 146732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 146832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 14694387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reckstatic void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) { 14704387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck LocalScopedBitmap bitmapHandle(bitmapPtr); 14714387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck if (!bitmapHandle.valid()) return; 1472ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmapHandle->bitmap()); 14734387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck} 14744387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck 14754508218850faedea95371188da587b6734f5f3dasergeyvstatic jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) { 14764508218850faedea95371188da587b6734f5f3dasergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 14774508218850faedea95371188da587b6734f5f3dasergeyv return static_cast<jint>(bitmapHandle->getAllocationByteCount()); 14784508218850faedea95371188da587b6734f5f3dasergeyv} 14794508218850faedea95371188da587b6734f5f3dasergeyv 14806e3658a63843096058ed444d073fbcd191fd7e1bsergeyvstatic jobject Bitmap_copyPreserveInternalConfig(JNIEnv* env, jobject, jlong bitmapPtr) { 148181f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 148281f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(), 148381f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv "Hardware config is only supported config in Bitmap_nativeCopyPreserveInternalConfig"); 148481f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv Bitmap& hwuiBitmap = bitmapHandle->bitmap(); 148581f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv SkBitmap src; 148681f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv hwuiBitmap.getSkBitmap(&src); 148781f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv 148881f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv SkBitmap result; 148981f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv HeapAllocator allocator; 149081f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv if (!src.copyTo(&result, hwuiBitmap.info().colorType(), &allocator)) { 149181f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv doThrowRE(env, "Could not copy a hardware bitmap."); 149281f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv return NULL; 149381f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv } 1494656117bed2fc1937bcebd615898924ed57c48979sergeyv return createBitmap(env, allocator.getStorageObjAndReset(), getPremulBitmapCreateFlags(false)); 149581f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv} 149681f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv 14970a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyvstatic jobject Bitmap_createHardwareBitmap(JNIEnv* env, jobject, jobject graphicBuffer) { 14980a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer)); 14990a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer); 15000a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv if (!bitmap.get()) { 15010a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv ALOGW("failed to create hardware bitmap from graphic buffer"); 15020a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv return NULL; 15030a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv } 1504656117bed2fc1937bcebd615898924ed57c48979sergeyv return bitmap::createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(false)); 15050a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv} 15060a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv 15076e3658a63843096058ed444d073fbcd191fd7e1bsergeyvstatic jobject Bitmap_createGraphicBufferHandle(JNIEnv* env, jobject, jlong bitmapPtr) { 15086e3658a63843096058ed444d073fbcd191fd7e1bsergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 15096e3658a63843096058ed444d073fbcd191fd7e1bsergeyv LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(), 15106e3658a63843096058ed444d073fbcd191fd7e1bsergeyv "Hardware config is only supported config in Bitmap_getGraphicBuffer"); 15116e3658a63843096058ed444d073fbcd191fd7e1bsergeyv 15126e3658a63843096058ed444d073fbcd191fd7e1bsergeyv Bitmap& hwuiBitmap = bitmapHandle->bitmap(); 15136e3658a63843096058ed444d073fbcd191fd7e1bsergeyv sp<GraphicBuffer> buffer(hwuiBitmap.graphicBuffer()); 15146e3658a63843096058ed444d073fbcd191fd7e1bsergeyv return createJavaGraphicBuffer(env, buffer); 15156e3658a63843096058ed444d073fbcd191fd7e1bsergeyv} 15166e3658a63843096058ed444d073fbcd191fd7e1bsergeyv 151732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 1518c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass make_globalref(JNIEnv* env, const char classname[]) 1519c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1520c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jclass c = env->FindClass(classname); 1521c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(c); 1522c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return (jclass) env->NewGlobalRef(c); 1523c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 1524c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 1525c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz, 1526c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const char fieldname[], const char type[]) 1527c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1528c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jfieldID id = env->GetFieldID(clazz, fieldname, type); 1529c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(id); 1530c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return id; 1531c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 153232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 153376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBitmapMethods[] = { 153432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;", 153532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_creator }, 153632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;", 153732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copy }, 1538721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews { "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;", 1539721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews (void*)Bitmap_copyAshmem }, 1540a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;", 1541a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson (void*)Bitmap_copyAshmemConfig }, 1542775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler { "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer }, 154332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle }, 15444508218850faedea95371188da587b6734f5f3dasergeyv { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure }, 154532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z", 154632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_compress }, 154732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeErase", "(JI)V", (void*)Bitmap_erase }, 154832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes }, 154932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeConfig", "(J)I", (void*)Bitmap_config }, 155032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha }, 155157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeIsPremultiplied", "(J)Z", (void*)Bitmap_isPremultiplied}, 155257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetHasAlpha", "(JZZ)V", (void*)Bitmap_setHasAlpha}, 155357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPremultiplied", "(JZ)V", (void*)Bitmap_setPremultiplied}, 155432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap }, 155532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap }, 155632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreateFromParcel", 155732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;", 155832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_createFromParcel }, 155932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z", 156032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_writeToParcel }, 156132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;", 156232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_extractAlpha }, 156332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId }, 156457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixel", "(JII)I", (void*)Bitmap_getPixel }, 156557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixels", "(J[IIIIIII)V", (void*)Bitmap_getPixels }, 156657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixel", "(JIII)V", (void*)Bitmap_setPixel }, 156757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixels", "(J[IIIIIII)V", (void*)Bitmap_setPixels }, 156832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V", 156932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsToBuffer }, 157032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", 157132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsFromBuffer }, 157232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, 15734387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, 15744508218850faedea95371188da587b6734f5f3dasergeyv { "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount }, 157581f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv { "nativeCopyPreserveInternalConfig", "(J)Landroid/graphics/Bitmap;", 15766e3658a63843096058ed444d073fbcd191fd7e1bsergeyv (void*)Bitmap_copyPreserveInternalConfig }, 15770a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv { "nativeCreateHardwareBitmap", "(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;", 15786e3658a63843096058ed444d073fbcd191fd7e1bsergeyv (void*) Bitmap_createHardwareBitmap }, 15796e3658a63843096058ed444d073fbcd191fd7e1bsergeyv { "nativeCreateGraphicBufferHandle", "(J)Landroid/graphics/GraphicBuffer;", 1580efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy (void*) Bitmap_createGraphicBufferHandle }, 1581efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy { "nativeGetColorSpace", "(J[F[F)Z", (void*)Bitmap_getColorSpace }, 1582efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy { "nativeIsSRGB", "(J)Z", (void*)Bitmap_isSRGB }, 158332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 158432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 158532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikint register_android_graphics_Bitmap(JNIEnv* env) 158632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik{ 1587c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_class = make_globalref(env, "android/graphics/Bitmap"); 1588c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J"); 1589c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V"); 1590c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V"); 1591c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); 1592ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, 1593ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe NELEM(gBitmapMethods)); 15949192d5e8d78b826a665ce048c007e6eaf0f5b003John Reck} 1595