Bitmap.cpp revision d70532d123b816e0f2ae482258b4e3af56fcdcb2
1f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#define LOG_TAG "Bitmap" 2f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include "Bitmap.h" 3f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 40a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv#include "GraphicBuffer.h" 532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkBitmap.h" 632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkPixelRef.h" 732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkImageEncoder.h" 857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III#include "SkImageInfo.h" 99505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkColor.h" 1032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkColorPriv.h" 11ce217faddb4b40c1b3e698944da1951027080427Romain Guy#include "SkColorSpace.h" 12ce217faddb4b40c1b3e698944da1951027080427Romain Guy#include "SkColorSpaceXform.h" 139505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkHalf.h" 14efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy#include "SkMatrix44.h" 159505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkPM4f.h" 169505a6552764461c22ce48f1ac13d025d23e1579Romain Guy#include "SkPM4fPriv.h" 1732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "GraphicsJNI.h" 1832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkDither.h" 1932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkUnPreMultiply.h" 2032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkStream.h" 2132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 2232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <binder/Parcel.h> 2332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_os_Parcel.h" 2432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_util_Binder.h" 2532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_nio_utils.h" 2632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "CreateJavaOutputStreamAdaptor.h" 27dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h> 28c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv#include <hwui/Bitmap.h> 294387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck#include <renderthread/RenderProxy.h> 3032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 31ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 32ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 3332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <jni.h> 34ce217faddb4b40c1b3e698944da1951027080427Romain Guy#include <string.h> 3539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <memory> 3639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <string> 3732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 38a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#define DEBUG_PARCEL 0 398cee7c17119b204be88860feb812f2374d0de732Riley Andrews#define ASHMEM_BITMAP_MIN_SIZE (128 * (1 << 10)) 40a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 41c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass gBitmap_class; 42c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID gBitmap_nativePtr; 43c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_constructorMethodID; 44c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_reinitMethodID; 45c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_getAllocationByteCountMethodID; 46c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 47f29ed28c7b878ef28058bc730715d0d32445bc57John Recknamespace android { 48f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 49c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvclass BitmapWrapper { 50f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic: 51c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper(Bitmap* bitmap) 52c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv : mBitmap(bitmap) { } 53c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 54c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void freePixels() { 55c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mInfo = mBitmap->info(); 56c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mHasHardwareMipMap = mBitmap->hasHardwareMipMap(); 57c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mAllocationSize = mBitmap->getAllocationByteCount(); 58c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mRowBytes = mBitmap->rowBytes(); 59c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mGenerationId = mBitmap->getGenerationID(); 6015a108550e3d74b406927d85c8e69018761adf49sergeyv mIsHardware = mBitmap->isHardware(); 61c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap.reset(); 62f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 63f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 64c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool valid() { 65fc9999505a36c66892d7ccce85187936105f4f36sergeyv return mBitmap; 66f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 67f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 68aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv Bitmap& bitmap() { 69aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv assertValid(); 70aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv return *mBitmap; 71aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv } 72c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 73c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void assertValid() { 74c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LOG_ALWAYS_FATAL_IF(!valid(), "Error, cannot access an invalid/free'd bitmap here!"); 75c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 76c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 77c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void getSkBitmap(SkBitmap* outBitmap) { 78c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 79c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap->getSkBitmap(outBitmap); 80c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 810781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck 82c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool hasHardwareMipMap() { 83c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 84c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->hasHardwareMipMap(); 85c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 86f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return mHasHardwareMipMap; 87f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 88f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 89f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void setHasHardwareMipMap(bool hasMipMap) { 90c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 91c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap->setHasHardwareMipMap(hasMipMap); 92f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 93f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 94c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void setAlphaType(SkAlphaType alphaType) { 95c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 96c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv mBitmap->setAlphaType(alphaType); 97f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 98f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 99c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const SkImageInfo& info() { 100c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 101c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->info(); 102c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 103c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mInfo; 104f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 105f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 106c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t getAllocationByteCount() const { 107c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 108c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->getAllocationByteCount(); 109c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 110c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mAllocationSize; 111f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 112f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 113c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t rowBytes() const { 114c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 115c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->rowBytes(); 116c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 117c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mRowBytes; 118c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 119f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 120c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv uint32_t getGenerationID() const { 121c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv if (mBitmap) { 122c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmap->getGenerationID(); 123c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 124c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mGenerationId; 125f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 126c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 12715a108550e3d74b406927d85c8e69018761adf49sergeyv bool isHardware() { 12815a108550e3d74b406927d85c8e69018761adf49sergeyv if (mBitmap) { 12915a108550e3d74b406927d85c8e69018761adf49sergeyv return mBitmap->isHardware(); 13015a108550e3d74b406927d85c8e69018761adf49sergeyv } 13115a108550e3d74b406927d85c8e69018761adf49sergeyv return mIsHardware; 13215a108550e3d74b406927d85c8e69018761adf49sergeyv } 13315a108550e3d74b406927d85c8e69018761adf49sergeyv 134c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv ~BitmapWrapper() { } 135c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 136c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvprivate: 137c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> mBitmap; 138c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkImageInfo mInfo; 139c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool mHasHardwareMipMap; 140c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t mAllocationSize; 141c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t mRowBytes; 142c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv uint32_t mGenerationId; 14315a108550e3d74b406927d85c8e69018761adf49sergeyv bool mIsHardware; 144f29ed28c7b878ef28058bc730715d0d32445bc57John Reck}; 145f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 146f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// Convenience class that does not take a global ref on the pixels, relying 147f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// on the caller already having a local JNI ref 148f29ed28c7b878ef28058bc730715d0d32445bc57John Reckclass LocalScopedBitmap { 149f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic: 150c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit LocalScopedBitmap(jlong bitmapHandle) 151c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv : mBitmapWrapper(reinterpret_cast<BitmapWrapper*>(bitmapHandle)) {} 152f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 153c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper* operator->() { 154c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmapWrapper; 155f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 156f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 157f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* pixels() { 158aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv return mBitmapWrapper->bitmap().pixels(); 159f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 160f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 161f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bool valid() { 162c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return mBitmapWrapper && mBitmapWrapper->valid(); 163f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 164f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 165f29ed28c7b878ef28058bc730715d0d32445bc57John Reckprivate: 166c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper* mBitmapWrapper; 167f29ed28c7b878ef28058bc730715d0d32445bc57John Reck}; 168f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 169c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvnamespace bitmap { 170c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 171c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv// Assert that bitmap's SkAlphaType is consistent with isPremultiplied. 172c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied) { 173c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is 174c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // irrelevant. This just tests to ensure that the SkAlphaType is not 175c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // opposite of isPremultiplied. 176c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isPremultiplied) { 177c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(info.alphaType() != kUnpremul_SkAlphaType); 178c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } else { 179c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(info.alphaType() != kPremul_SkAlphaType); 180c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 181c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 182c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 183c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, 184c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isPremultiplied) 185c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 186c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // The caller needs to have already set the alpha type properly, so the 187c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // native SkBitmap stays in sync with the Java Bitmap. 188c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assert_premultiplied(info, isPremultiplied); 189c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 190c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID, 191c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv info.width(), info.height(), isPremultiplied); 192c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 193c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 194c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvint getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap) 195c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 196c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID); 197c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 198c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 199c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvjobject createBitmap(JNIEnv* env, Bitmap* bitmap, 200c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, 201c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int density) { 202c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; 203c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied; 204c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // The caller needs to have already set the alpha type properly, so the 205c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // native SkBitmap stays in sync with the Java Bitmap. 206c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv assert_premultiplied(bitmap->info(), isPremultiplied); 207c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv BitmapWrapper* bitmapWrapper = new BitmapWrapper(bitmap); 208c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, 209c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density, 210c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv isMutable, isPremultiplied, ninePatchChunk, ninePatchInsets); 211c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 212c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (env->ExceptionCheck() != 0) { 213c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv ALOGE("*** Uncaught exception returned from Java call!\n"); 214c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv env->ExceptionDescribe(); 215c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 216c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return obj; 217c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 218c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 219c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap) { 220c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LocalScopedBitmap bitmap(bitmapHandle); 221c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->getSkBitmap(outBitmap); 222c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 223c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 224aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvBitmap& toBitmap(JNIEnv* env, jobject bitmap) { 225c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(env); 226c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(bitmap); 227c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 228c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 229c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LocalScopedBitmap localBitmap(bitmapHandle); 230c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return localBitmap->bitmap(); 231c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 232c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 2335fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyvBitmap& toBitmap(JNIEnv* env, jlong bitmapHandle) { 2345fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv SkASSERT(env); 2355fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv LocalScopedBitmap localBitmap(bitmapHandle); 2365fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv return localBitmap->bitmap(); 2375fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv} 2385fd2a1cb2726afa7d40fe4750e9defd89c24ed37sergeyv 23900799f760d6956fc54ee1763427f8196fcb3696dJohn Reckvoid imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info) { 24000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(info); 24100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(env); 24200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(bitmap); 24300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 24400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 24500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck LocalScopedBitmap localBitmap(bitmapHandle); 24600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 24700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck const SkImageInfo& imageInfo = localBitmap->info(); 24800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->width = imageInfo.width(); 24900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->height = imageInfo.height(); 25000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->stride = localBitmap->rowBytes(); 25100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->flags = 0; 25200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck switch (imageInfo.colorType()) { 25300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck case kN32_SkColorType: 25400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->format = ANDROID_BITMAP_FORMAT_RGBA_8888; 25500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck break; 25600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck case kRGB_565_SkColorType: 25700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->format = ANDROID_BITMAP_FORMAT_RGB_565; 25800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck break; 25900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck case kARGB_4444_SkColorType: 26000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->format = ANDROID_BITMAP_FORMAT_RGBA_4444; 26100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck break; 26200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck case kAlpha_8_SkColorType: 26300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->format = ANDROID_BITMAP_FORMAT_A_8; 26400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck break; 26500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck default: 26600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck info->format = ANDROID_BITMAP_FORMAT_NONE; 26700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck break; 26800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck } 26900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck} 27000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 27100799f760d6956fc54ee1763427f8196fcb3696dJohn Reckvoid* lockPixels(JNIEnv* env, jobject bitmap) { 27200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(env); 27300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(bitmap); 27400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 27500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 27600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 27700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck LocalScopedBitmap localBitmap(bitmapHandle); 27800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck if (!localBitmap->valid()) return nullptr; 27900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 28000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkPixelRef& pixelRef = localBitmap->bitmap(); 28100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck pixelRef.lockPixels(); 28200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck if (!pixelRef.pixels()) { 28300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck pixelRef.unlockPixels(); 28400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck return nullptr; 28500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck } 28600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck pixelRef.ref(); 28700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck return pixelRef.pixels(); 28800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck} 28900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 29000799f760d6956fc54ee1763427f8196fcb3696dJohn Reckbool unlockPixels(JNIEnv* env, jobject bitmap) { 29100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(env); 29200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(bitmap); 29300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 29400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 29500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 29600799f760d6956fc54ee1763427f8196fcb3696dJohn Reck LocalScopedBitmap localBitmap(bitmapHandle); 29700799f760d6956fc54ee1763427f8196fcb3696dJohn Reck if (!localBitmap->valid()) return false; 29800799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 29900799f760d6956fc54ee1763427f8196fcb3696dJohn Reck SkPixelRef& pixelRef = localBitmap->bitmap(); 30000799f760d6956fc54ee1763427f8196fcb3696dJohn Reck pixelRef.notifyPixelsChanged(); 30100799f760d6956fc54ee1763427f8196fcb3696dJohn Reck pixelRef.unlockPixels(); 30200799f760d6956fc54ee1763427f8196fcb3696dJohn Reck pixelRef.unref(); 30300799f760d6956fc54ee1763427f8196fcb3696dJohn Reck return true; 30400799f760d6956fc54ee1763427f8196fcb3696dJohn Reck} 30500799f760d6956fc54ee1763427f8196fcb3696dJohn Reck 306c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace bitmap 307c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 308c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace android 309c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 310c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android; 311c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android::bitmap; 312c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 31332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 31432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// Conversions to/from SkColor, for get/setPixels, and the create method, which 31532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// is basically like setPixels 31632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 31732054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*FromColorProc)(void* dst, const SkColor src[], int width, 31832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y); 31932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 3209505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void FromColor_F16(void* dst, const SkColor src[], int width, 3219505a6552764461c22ce48f1ac13d025d23e1579Romain Guy int, int) { 3229505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint64_t* d = (uint64_t*)dst; 3239505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 3249505a6552764461c22ce48f1ac13d025d23e1579Romain Guy for (int i = 0; i < width; i++) { 3259505a6552764461c22ce48f1ac13d025d23e1579Romain Guy *d++ = SkColor4f::FromColor(*src++).premul().toF16(); 3269505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } 3279505a6552764461c22ce48f1ac13d025d23e1579Romain Guy} 3289505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 3299505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void FromColor_F16_Raw(void* dst, const SkColor src[], int width, 3309505a6552764461c22ce48f1ac13d025d23e1579Romain Guy int, int) { 3319505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint64_t* d = (uint64_t*)dst; 3329505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 3339505a6552764461c22ce48f1ac13d025d23e1579Romain Guy for (int i = 0; i < width; i++) { 3349505a6552764461c22ce48f1ac13d025d23e1579Romain Guy const float* color = SkColor4f::FromColor(*src++).vec(); 3359505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint16_t* scratch = reinterpret_cast<uint16_t*>(d++); 3369505a6552764461c22ce48f1ac13d025d23e1579Romain Guy for (int i = 0; i < 4; ++i) { 3379505a6552764461c22ce48f1ac13d025d23e1579Romain Guy scratch[i] = SkFloatToHalf(color[i]); 3389505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } 3399505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } 3409505a6552764461c22ce48f1ac13d025d23e1579Romain Guy} 3419505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 34232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32(void* dst, const SkColor src[], int width, 34332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 34432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 34532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 34632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 34732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPreMultiplyColor(*src++); 34832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 34932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 35032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 35132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32_Raw(void* dst, const SkColor src[], int width, 35232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 35346d8444631b4b1253a76bfcc78a29d26014d022fDan Albert // Needed to thwart the unreachable code detection from clang. 35446d8444631b4b1253a76bfcc78a29d26014d022fDan Albert static const bool sk_color_ne_zero = SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER; 35546d8444631b4b1253a76bfcc78a29d26014d022fDan Albert 35632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkColor's ordering may be different from SkPMColor 35746d8444631b4b1253a76bfcc78a29d26014d022fDan Albert if (sk_color_ne_zero) { 35832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(dst, src, width * sizeof(SkColor)); 35932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 36032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 36132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 36232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // order isn't same, repack each pixel manually 36332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 36432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 36532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 36632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 36732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 36832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 36932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 37032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 37132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D565(void* dst, const SkColor src[], int width, 37232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 37332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t* d = (uint16_t*)dst; 37432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 37532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_565_SCAN(y); 37632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 37732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 37832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), 37932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_VALUE(x)); 38032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 38132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 38232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 38332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444(void* dst, const SkColor src[], int width, 38432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 38532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 38632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 38732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 38832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 38932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPreMultiplyColor(*src++); 39032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 39132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 39232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 39332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 39432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 39532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444_Raw(void* dst, const SkColor src[], int width, 39632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 39732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 39832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 39932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 40032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 40132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 40232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 40332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied 40432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 40532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 40632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 40732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 40832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 40932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 41032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4116260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void FromColor_DA8(void* dst, const SkColor src[], int width, int x, int y) { 4126260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t* d = (uint8_t*)dst; 4136260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 4146260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik for (int stop = x + width; x < stop; x++) { 4156260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *d++ = SkColorGetA(*src++); 4166260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } 4176260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 4186260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 41932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 42057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) { 42157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (bitmap.colorType()) { 42257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kN32_SkColorType: 42357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D32 : FromColor_D32_Raw; 42457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kARGB_4444_SkColorType: 42557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D4444 : 42657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III FromColor_D4444_Raw; 42757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kRGB_565_SkColorType: 42832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return FromColor_D565; 4296260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 4306260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return FromColor_DA8; 4319505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kRGBA_F16_SkColorType: 4329505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_F16 : FromColor_F16_Raw; 43332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 43432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 43532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 43632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 43732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 43832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 43932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikbool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride, 44057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III int x, int y, int width, int height, const SkBitmap& dstBitmap) { 44132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(dstBitmap); 44232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik void* dst = dstBitmap.getPixels(); 44357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III FromColorProc proc = ChooseFromColorProc(dstBitmap); 44432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 44532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == dst || NULL == proc) { 44632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return false; 44732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 44832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 44932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const jint* array = env->GetIntArrayElements(srcColors, NULL); 45032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkColor* src = (const SkColor*)array + srcOffset; 45132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 45232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // reset to to actual choice from caller 45332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = dstBitmap.getAddr(x, y); 454ce217faddb4b40c1b3e698944da1951027080427Romain Guy 455ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = dstBitmap.colorSpace(); 456d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy if (dstBitmap.colorType() == kRGBA_F16_SkColorType || 457d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 458ce217faddb4b40c1b3e698944da1951027080427Romain Guy // now copy/convert each scanline 459ce217faddb4b40c1b3e698944da1951027080427Romain Guy for (int y = 0; y < height; y++) { 460ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(dst, src, width, x, y); 461ce217faddb4b40c1b3e698944da1951027080427Romain Guy src += srcStride; 462ce217faddb4b40c1b3e698944da1951027080427Romain Guy dst = (char*)dst + dstBitmap.rowBytes(); 463ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 464ce217faddb4b40c1b3e698944da1951027080427Romain Guy } else { 465ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 466ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace); 467ce217faddb4b40c1b3e698944da1951027080427Romain Guy 468ce217faddb4b40c1b3e698944da1951027080427Romain Guy std::unique_ptr<SkColor[]> row(new SkColor[width]); 469ce217faddb4b40c1b3e698944da1951027080427Romain Guy 470ce217faddb4b40c1b3e698944da1951027080427Romain Guy // now copy/convert each scanline 471ce217faddb4b40c1b3e698944da1951027080427Romain Guy for (int y = 0; y < height; y++) { 472ce217faddb4b40c1b3e698944da1951027080427Romain Guy memcpy(row.get(), src, sizeof(SkColor) * width); 473ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(), 474ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(), width, 475ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 476ce217faddb4b40c1b3e698944da1951027080427Romain Guy 477ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(dst, row.get(), width, x, y); 478ce217faddb4b40c1b3e698944da1951027080427Romain Guy src += srcStride; 479ce217faddb4b40c1b3e698944da1951027080427Romain Guy dst = (char*)dst + dstBitmap.rowBytes(); 480ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 48132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 48232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dstBitmap.notifyPixelsChanged(); 48432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4859505a6552764461c22ce48f1ac13d025d23e1579Romain Guy env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), JNI_ABORT); 48632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return true; 48732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 48832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//////////////////// ToColor procs 49032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 49132054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*ToColorProc)(SkColor dst[], const void* src, int width, 49232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*); 49332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4949505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void ToColor_F16_Alpha(SkColor dst[], const void* src, int width, 4959505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkColorTable*) { 4969505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkASSERT(width > 0); 4979505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint64_t* s = (uint64_t*)src; 4989505a6552764461c22ce48f1ac13d025d23e1579Romain Guy do { 4999505a6552764461c22ce48f1ac13d025d23e1579Romain Guy *dst++ = SkPM4f::FromF16((const uint16_t*) s++).unpremul().toSkColor(); 5009505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } while (--width != 0); 5019505a6552764461c22ce48f1ac13d025d23e1579Romain Guy} 5029505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 5039505a6552764461c22ce48f1ac13d025d23e1579Romain Guystatic void ToColor_F16_Raw(SkColor dst[], const void* src, int width, 5049505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkColorTable*) { 5059505a6552764461c22ce48f1ac13d025d23e1579Romain Guy SkASSERT(width > 0); 5069505a6552764461c22ce48f1ac13d025d23e1579Romain Guy uint64_t* s = (uint64_t*)src; 5079505a6552764461c22ce48f1ac13d025d23e1579Romain Guy do { 5089505a6552764461c22ce48f1ac13d025d23e1579Romain Guy *dst++ = Sk4f_toS32(swizzle_rb(SkHalfToFloat_finite_ftz(*s++))); 5099505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } while (--width != 0); 5109505a6552764461c22ce48f1ac13d025d23e1579Romain Guy} 5119505a6552764461c22ce48f1ac13d025d23e1579Romain Guy 51232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width, 51332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 51432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 51532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 51632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 51732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(*s++); 51832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 51932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 52032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 52132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width, 52232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 52332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 52432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 52532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 52632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 52732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 52832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 52932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 53032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 53132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width, 53332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 53432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 53532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 53632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 53732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 53832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 53932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 54032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 54132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 54232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 54332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width, 54432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 54532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 54632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 54732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 54832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++)); 54932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 55032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 55132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width, 55332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 55432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 55532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 55632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 55732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 55832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 55932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 56032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 56132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 56232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 56332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width, 56432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 56532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 56632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 56732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 56832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 56932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 57032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 57132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 57232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 57332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S565(SkColor dst[], const void* src, int width, 57532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 57632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 57732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint16_t* s = (const uint16_t*)src; 57832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 57932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t c = *s++; 58032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), 58132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPacked16ToB32(c)); 58232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 58332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 58432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 58532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 58632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 58732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 58832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 58971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 59032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 59132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); 59232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 59332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 59432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 59532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, 59632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 59732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 59832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 59971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 60032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 60132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 60232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 60332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 60432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 60532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 60632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 60732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, 60832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 60932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 61032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 61171487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 61232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 61332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 61432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 61532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 61632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 61732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 61832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 6196260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) { 6206260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik SkASSERT(width > 0); 6216260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik const uint8_t* s = (const uint8_t*)src; 6226260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik do { 6236260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t c = *s++; 6246260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *dst++ = SkColorSetARGB(c, c, c, c); 6256260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } while (--width != 0); 6266260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 6276260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 62832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 62957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic ToColorProc ChooseToColorProc(const SkBitmap& src) { 630b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed switch (src.colorType()) { 631b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kN32_SkColorType: 63257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 63357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 63457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Opaque; 63557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 63657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Alpha; 63757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 63857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Raw; 63957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 64057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 64157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 642b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kARGB_4444_SkColorType: 64357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 64457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 64557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Opaque; 64657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 64757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Alpha; 64857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 64957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Raw; 65057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 65157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 65257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 653b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kRGB_565_SkColorType: 65432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return ToColor_S565; 655b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kIndex_8_SkColorType: 65632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.getColorTable() == NULL) { 65732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 65832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 65957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 66057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 66157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Opaque; 66257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 66357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Alpha; 66457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 66557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Raw; 66657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 66757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 66857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 6696260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 6706260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return ToColor_SA8; 6719505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kRGBA_F16_SkColorType: 6729505a6552764461c22ce48f1ac13d025d23e1579Romain Guy switch (src.alphaType()) { 6739505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kOpaque_SkAlphaType: 6749505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return ToColor_F16_Raw; 6759505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kPremul_SkAlphaType: 6769505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return ToColor_F16_Alpha; 6779505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case kUnpremul_SkAlphaType: 6789505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return ToColor_F16_Raw; 6799505a6552764461c22ce48f1ac13d025d23e1579Romain Guy default: 6809505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return NULL; 6819505a6552764461c22ce48f1ac13d025d23e1579Romain Guy } 68232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 68332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 68432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 68532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 68632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 68732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 68832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 68932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 69032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic int getPremulBitmapCreateFlags(bool isMutable) { 692c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int flags = android::bitmap::kBitmapCreateFlag_Premultiplied; 693c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isMutable) flags |= android::bitmap::kBitmapCreateFlag_Mutable; 69432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return flags; 69532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 69632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 69832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint offset, jint stride, jint width, jint height, 69932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint configHandle, jboolean isMutable) { 7001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 70132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != jColors) { 70232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t n = env->GetArrayLength(jColors); 70332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (n < SkAbs32(stride) * (size_t)height) { 70432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowAIOOBE(env); 70532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 70632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 70932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // ARGB_4444 is a deprecated format, convert automatically to 8888 710b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kARGB_4444_SkColorType) { 711b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed colorType = kN32_SkColorType; 71232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 71332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 71432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap bitmap; 715253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType, 7169505a6552764461c22ce48f1ac13d025d23e1579Romain Guy GraphicsJNI::colorSpaceForType(colorType))); 71732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 718c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL); 719f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!nativeBitmap) { 72032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 72132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 72232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (jColors != NULL) { 7249505a6552764461c22ce48f1ac13d025d23e1579Romain Guy GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap); 72532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 72632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 727c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable)); 72832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 72932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 73032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, 73132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint dstConfigHandle, jboolean isMutable) { 732f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 733c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 73405126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv if (dstConfigHandle == GraphicsJNI::hardwareLegacyBitmapConfig()) { 73505126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv sk_sp<Bitmap> bitmap(Bitmap::allocateHardwareBitmap(src)); 73605126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv if (!bitmap.get()) { 73705126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv return NULL; 73805126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv } 739656117bed2fc1937bcebd615898924ed57c48979sergeyv return createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(isMutable)); 74005126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv } 74105126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv 7421103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 7434508218850faedea95371188da587b6734f5f3dasergeyv SkBitmap result; 7444508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 74532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 746f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!src.copyTo(&result, dstCT, &allocator)) { 74732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 74832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 749c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = allocator.getStorageObjAndReset(); 750c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return createBitmap(env, bitmap, getPremulBitmapCreateFlags(isMutable)); 75132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 75232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 753c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic Bitmap* Bitmap_copyAshmemImpl(JNIEnv* env, SkBitmap& src, SkColorType& dstCT) { 754721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews SkBitmap result; 755721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 756721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews AshmemPixelAllocator allocator(env); 757a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson if (!src.copyTo(&result, dstCT, &allocator)) { 758721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return NULL; 759721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews } 760c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = allocator.getStorageObjAndReset(); 761c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv bitmap->setImmutable(); 762c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return bitmap; 763a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 764a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 765a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) { 766a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 767c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 768a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = src.colorType(); 769c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 770c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 771a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson return ret; 772a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 773a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 774a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle) { 775a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 776c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 777a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 778c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmap = Bitmap_copyAshmemImpl(env, src, dstCT); 779c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv jobject ret = createBitmap(env, bitmap, getPremulBitmapCreateFlags(false)); 780721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return ret; 781721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews} 782721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 783c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic void Bitmap_destruct(BitmapWrapper* bitmap) { 784c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv delete bitmap; 78532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 78632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 787775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic jlong Bitmap_getNativeFinalizer(JNIEnv*, jobject) { 788775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct)); 789775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler} 790775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler 79132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { 792f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 793f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->freePixels(); 79432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 79532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 79632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 79732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, 7984508218850faedea95371188da587b6734f5f3dasergeyv jint width, jint height, jint configHandle, jboolean requestPremul) { 799f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 800c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->assertValid(); 8011103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 80217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III 80317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // ARGB_4444 is a deprecated format, convert automatically to 8888 80417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (colorType == kARGB_4444_SkColorType) { 80517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III colorType = kN32_SkColorType; 80617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 8074508218850faedea95371188da587b6734f5f3dasergeyv size_t requestedSize = width * height * SkColorTypeBytesPerPixel(colorType); 8084508218850faedea95371188da587b6734f5f3dasergeyv if (requestedSize > bitmap->getAllocationByteCount()) { 80932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // done in native as there's no way to get BytesPerPixel in Java 81032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowIAE(env, "Bitmap not large enough to support new configuration"); 81132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 81232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 81317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkAlphaType alphaType; 814f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().colorType() != kRGB_565_SkColorType 815f29ed28c7b878ef28058bc730715d0d32445bc57John Reck && bitmap->info().alphaType() == kOpaque_SkAlphaType) { 81617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // If the original bitmap was set to opaque, keep that setting, unless it 81717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // was 565, which is required to be opaque. 81817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = kOpaque_SkAlphaType; 81917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } else { 82017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // Otherwise respect the premultiplied request. 82117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 82217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 823aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv bitmap->bitmap().reconfigure(SkImageInfo::Make(width, height, colorType, alphaType, 8247d5219fb505ff1b178910cda25a40154e7d4d09asergeyv sk_ref_sp(bitmap->info().colorSpace()))); 82532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 82632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 82732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// These must match the int values in Bitmap.java 82832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikenum JavaEncodeFormat { 82932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kJPEG_JavaEncodeFormat = 0, 83032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kPNG_JavaEncodeFormat = 1, 83132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kWEBP_JavaEncodeFormat = 2 83232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 83332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 83432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, 83532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint format, jint quality, 83632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject jstream, jbyteArray jstorage) { 83710219fb261606fcc71c607167b28295b4578a10dHal Canary SkEncodedImageFormat fm; 83832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik switch (format) { 83932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kJPEG_JavaEncodeFormat: 84010219fb261606fcc71c607167b28295b4578a10dHal Canary fm = SkEncodedImageFormat::kJPEG; 84132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 84232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kPNG_JavaEncodeFormat: 84310219fb261606fcc71c607167b28295b4578a10dHal Canary fm = SkEncodedImageFormat::kPNG; 84432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 84532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kWEBP_JavaEncodeFormat: 84610219fb261606fcc71c607167b28295b4578a10dHal Canary fm = SkEncodedImageFormat::kWEBP; 84732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 84832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 84932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 85032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 85132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 85210219fb261606fcc71c607167b28295b4578a10dHal Canary LocalScopedBitmap bitmap(bitmapHandle); 853f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap.valid()) { 854f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 855f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 85632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 857f29ed28c7b878ef28058bc730715d0d32445bc57John Reck std::unique_ptr<SkWStream> strm(CreateJavaOutputStreamAdaptor(env, jstream, jstorage)); 858f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!strm.get()) { 859f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 860f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 86132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86210219fb261606fcc71c607167b28295b4578a10dHal Canary SkBitmap skbitmap; 86310219fb261606fcc71c607167b28295b4578a10dHal Canary bitmap->getSkBitmap(&skbitmap); 86410219fb261606fcc71c607167b28295b4578a10dHal Canary return SkEncodeImage(strm.get(), skbitmap, fm, quality) ? JNI_TRUE : JNI_FALSE; 86532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 86632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { 868f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 869f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap skBitmap; 870f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->getSkBitmap(&skBitmap); 871f29ed28c7b878ef28058bc730715d0d32445bc57John Reck skBitmap.eraseColor(color); 87232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 87332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 87432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { 875f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 87632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->rowBytes()); 87732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 87832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 87932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { 880f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 88115a108550e3d74b406927d85c8e69018761adf49sergeyv if (bitmap->isHardware()) { 88219b4b019169424d62bf3edc40b9560984206cf80sergeyv return GraphicsJNI::hardwareLegacyBitmapConfig(); 88319b4b019169424d62bf3edc40b9560984206cf80sergeyv } 884f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->info().colorType()); 88532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 88632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 88732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { 888f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 889c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return static_cast<jint>(bitmap->getGenerationID()); 89032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 89132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 89257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) { 893f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 894f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().alphaType() == kPremul_SkAlphaType) { 89557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_TRUE; 89657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 89757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_FALSE; 89857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 89957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 90032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { 901f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 902f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return !bitmap->info().isOpaque() ? JNI_TRUE : JNI_FALSE; 90332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 90432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 90557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle, 90657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean hasAlpha, jboolean requestPremul) { 907f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 90857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (hasAlpha) { 9090781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType( 910f29ed28c7b878ef28058bc730715d0d32445bc57John Reck requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); 91132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 9120781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kOpaque_SkAlphaType); 91357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 91457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 91557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 91657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, 91757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean isPremul) { 918f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 919f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap->info().isOpaque()) { 92057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (isPremul) { 9210781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kPremul_SkAlphaType); 92257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } else { 9230781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kUnpremul_SkAlphaType); 92457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 92532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 92632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 92732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 92832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { 929f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 93032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; 93132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 93232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 93332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, 93432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean hasMipMap) { 935f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 93632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setHasHardwareMipMap(hasMipMap); 93732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 93832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 93932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 94032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 94132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 94232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 94332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("-------- unparcel parcel is NULL\n"); 94432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 94532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 94632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 94732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 94832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 949b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const bool isMutable = p->readInt32() != 0; 950b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkColorType colorType = (SkColorType)p->readInt32(); 951b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); 9525acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy const uint32_t colorSpaceSize = p->readUint32(); 9535acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy sk_sp<SkColorSpace> colorSpace; 9545acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy if (kRGBA_F16_SkColorType == colorType) { 9555acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy colorSpace = SkColorSpace::MakeSRGBLinear(); 9565acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } else if (colorSpaceSize > 0) { 9575acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy colorSpace = SkColorSpace::Deserialize(p->readInplace(colorSpaceSize), colorSpaceSize); 9585acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } 959b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int width = p->readInt32(); 960b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int height = p->readInt32(); 961b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int rowBytes = p->readInt32(); 962b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int density = p->readInt32(); 963b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed 964b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (kN32_SkColorType != colorType && 9659505a6552764461c22ce48f1ac13d025d23e1579Romain Guy kRGBA_F16_SkColorType != colorType && 966b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kRGB_565_SkColorType != colorType && 967b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kARGB_4444_SkColorType != colorType && 968b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kIndex_8_SkColorType != colorType && 969b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kAlpha_8_SkColorType != colorType) { 970b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed SkDebugf("Bitmap_createFromParcel unknown colortype: %d\n", colorType); 97132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 97232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 97332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 974ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III std::unique_ptr<SkBitmap> bitmap(new SkBitmap); 9759505a6552764461c22ce48f1ac13d025d23e1579Romain Guy if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType, colorSpace), 9769505a6552764461c22ce48f1ac13d025d23e1579Romain Guy rowBytes)) { 977ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 978ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 97932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 98032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = NULL; 981b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kIndex_8_SkColorType) { 98232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = p->readInt32(); 983ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (count < 0 || count > 256) { 984ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // The data is corrupt, since SkColorTable enforces a value between 0 and 256, 985ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // inclusive. 986ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 987ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 98832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (count > 0) { 98932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = count * sizeof(SkPMColor); 99032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* src = (const SkPMColor*)p->readInplace(size); 991ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (src == NULL) { 992ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 993ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 99432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable = new SkColorTable(src, count); 99532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 99632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 99732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 998a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Read the bitmap blob. 999a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap->getSize(); 1000a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::ReadableBlob blob; 1001a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status = p->readBlob(size, &blob); 1002a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 100332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkSafeUnref(ctable); 1004a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not read bitmap blob."); 100532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 100632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 100732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1008a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the bitmap in place from the ashmem region if possible otherwise copy. 1009c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv sk_sp<Bitmap> nativeBitmap; 10108cee7c17119b204be88860feb812f2374d0de732Riley Andrews if (blob.fd() >= 0 && (blob.isMutable() || !isMutable) && (size >= ASHMEM_BITMAP_MIN_SIZE)) { 1011a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1012a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob " 1013a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 1014a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 1015a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 1016a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1017a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1018a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Dup the file descriptor so we can keep a reference to it after the Parcel 1019a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // is disposed. 1020a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown int dupFd = dup(blob.fd()); 1021a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (dupFd < 0) { 1022211abad3b92b70dd094949c79f67e686c940fa0cErik Wolsheimer ALOGE("Error allocating dup fd. Error:%d", errno); 1023a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1024a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1025a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate dup blob fd."); 1026a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 102739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1028a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1029a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the pixels in place and take ownership of the ashmem region. 1030c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv nativeBitmap = sk_sp<Bitmap>(GraphicsJNI::mapAshmemBitmap(env, bitmap.get(), 1031c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable)); 1032a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1033a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 1034a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown close(dupFd); 1035a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1036a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate ashmem pixel ref."); 1037a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 103839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1039a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1040a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Clear the blob handle, don't release it. 1041a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.clear(); 1042a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1043a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1044a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (blob.fd() >= 0) { 1045a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents of mutable bitmap " 1046a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "from immutable blob (fds %s)", 1047a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1048a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1049a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents from %s blob " 1050a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 1051a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 1052a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 105339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1054a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1055a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1056a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the pixels into a new buffer. 1057c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv nativeBitmap = Bitmap::allocateHeapBitmap(bitmap.get(), ctable); 1058a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1059a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 1060a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1061a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate java pixel ref."); 1062a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 106339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1064a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->lockPixels(); 1065a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(bitmap->getPixels(), blob.data(), size); 1066a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->unlockPixels(); 1067a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1068a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Release the blob handle. 1069a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 107039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1071a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1072c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return createBitmap(env, nativeBitmap.release(), 1073a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); 1074a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown} 107539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 107632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 107732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, 107832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean isMutable, jint density, 107932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject parcel) { 108032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 108132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("------- writeToParcel null parcel\n"); 108232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 108332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 108432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 108532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 1086f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 108739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 1088c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle); 1089c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv bitmapWrapper->getSkBitmap(&bitmap); 109032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 109132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(isMutable); 1092f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.colorType()); 1093f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.alphaType()); 10945acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 10955acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy if (colorSpace != nullptr && bitmap.colorType() != kRGBA_F16_SkColorType) { 10965acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy sk_sp<SkData> data = colorSpace->serialize(); 10975acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy size_t size = data->size(); 10985acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy p->writeUint32(size); 10995acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy if (size > 0) { 11005acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy p->write(data->data(), size); 11015acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } 11025acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } else { 11035acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy p->writeUint32(0); 11045acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy } 1105f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.width()); 1106f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.height()); 1107f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.rowBytes()); 110832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(density); 110932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1110f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap.colorType() == kIndex_8_SkColorType) { 111166ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III // The bitmap needs to be locked to access its color table. 111266ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III SkAutoLockPixels alp(bitmap); 1113f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 111432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ctable != NULL) { 111532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = ctable->count(); 111632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(count); 111732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(p->writeInplace(count * sizeof(SkPMColor)), 111871487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed ctable->readColors(), count * sizeof(SkPMColor)); 111932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 112032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(0); // indicate no ctable 112132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 112232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 112332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1124a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Transfer the underlying ashmem region if we have one and it's immutable. 1125a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status; 1126aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv int fd = bitmapWrapper->bitmap().getAshmemFd(); 1127a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (fd >= 0 && !isMutable && p->allowFds()) { 1128a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1129a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " 1130a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "immutable blob (fds %s)", 1131a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1132a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1133a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1134a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeDupImmutableBlobFileDescriptor(fd); 1135a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 1136a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not write bitmap blob file descriptor."); 113739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews return JNI_FALSE; 113839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1139a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_TRUE; 1140a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 114132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1142a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the bitmap to a new blob. 1143a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bool mutableCopy = isMutable; 1144a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1145a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: copying %s bitmap into new %s blob (fds %s)", 1146a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 1147a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown mutableCopy ? "mutable" : "immutable", 1148a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1149a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1150a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1151a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap.getSize(); 1152a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::WritableBlob blob; 1153a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeBlob(size, mutableCopy, &blob); 1154a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 1155a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not copy bitmap to parcel blob."); 1156a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_FALSE; 115739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1158a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1159a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.lockPixels(); 1160a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown const void* pSrc = bitmap.getPixels(); 1161a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (pSrc == NULL) { 1162a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memset(blob.data(), 0, size); 1163a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1164a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(blob.data(), pSrc, size); 1165a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 1166a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.unlockPixels(); 1167a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1168a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 116932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 117032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 117132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 117232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, 117332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong srcHandle, jlong paintHandle, 117432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray offsetXY) { 1175f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 1176c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(srcHandle)->getSkBitmap(&src); 11776ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle); 117832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkIPoint offset; 1179f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap dst; 11804508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 118132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1182f29ed28c7b878ef28058bc730715d0d32445bc57John Reck src.extractAlpha(&dst, paint, &allocator, &offset); 118332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // If Skia can't allocate pixels for destination bitmap, it resets 118432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // it, that is set its pixels buffer to NULL, and zero width and height. 1185f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (dst.getPixels() == NULL && src.getPixels() != NULL) { 118632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowOOME(env, "failed to allocate pixels for alpha"); 118732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 118832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 118932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) { 119032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int* array = env->GetIntArrayElements(offsetXY, NULL); 119132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[0] = offset.fX; 119232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[1] = offset.fY; 119332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(offsetXY, array, 0); 119432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 119532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1196c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, allocator.getStorageObjAndReset(), 1197f29ed28c7b878ef28058bc730715d0d32445bc57John Reck getPremulBitmapCreateFlags(true)); 119832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 119932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 120032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 120132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1202efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guystatic jboolean Bitmap_isSRGB(JNIEnv* env, jobject, jlong bitmapHandle) { 1203efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy LocalScopedBitmap bitmapHolder(bitmapHandle); 1204efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!bitmapHolder.valid()) return JNI_TRUE; 1205efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1206efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkColorSpace* colorSpace = bitmapHolder->info().colorSpace(); 1207ce217faddb4b40c1b3e698944da1951027080427Romain Guy return GraphicsJNI::isColorSpaceSRGB(colorSpace); 1208efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy} 1209efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1210efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guystatic jboolean Bitmap_getColorSpace(JNIEnv* env, jobject, jlong bitmapHandle, 1211efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy jfloatArray xyzArray, jfloatArray paramsArray) { 1212efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1213efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy LocalScopedBitmap bitmapHolder(bitmapHandle); 1214efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!bitmapHolder.valid()) return JNI_FALSE; 1215efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1216efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkColorSpace* colorSpace = bitmapHolder->info().colorSpace(); 1217efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (colorSpace == nullptr) return JNI_FALSE; 1218efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1219efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor); 1220efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!colorSpace->toXYZD50(&xyzMatrix)) return JNI_FALSE; 1221efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1222efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy jfloat* xyz = env->GetFloatArrayElements(xyzArray, NULL); 1223efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[0] = xyzMatrix.getFloat(0, 0); 1224efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[1] = xyzMatrix.getFloat(1, 0); 1225efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[2] = xyzMatrix.getFloat(2, 0); 1226efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[3] = xyzMatrix.getFloat(0, 1); 1227efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[4] = xyzMatrix.getFloat(1, 1); 1228efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[5] = xyzMatrix.getFloat(2, 1); 1229efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[6] = xyzMatrix.getFloat(0, 2); 1230efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[7] = xyzMatrix.getFloat(1, 2); 1231efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy xyz[8] = xyzMatrix.getFloat(2, 2); 1232efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy env->ReleaseFloatArrayElements(xyzArray, xyz, 0); 1233efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1234efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy SkColorSpaceTransferFn transferParams; 1235efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (!colorSpace->isNumericalTransferFn(&transferParams)) return JNI_FALSE; 1236efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1237efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy jfloat* params = env->GetFloatArrayElements(paramsArray, NULL); 1238efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[0] = transferParams.fA; 1239efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[1] = transferParams.fB; 1240efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[2] = transferParams.fC; 1241efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[3] = transferParams.fD; 1242efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[4] = transferParams.fE; 1243efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[5] = transferParams.fF; 1244efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy params[6] = transferParams.fG; 1245efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy env->ReleaseFloatArrayElements(paramsArray, params, 0); 1246efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1247efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy return JNI_TRUE; 1248efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy} 1249efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 1250efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy/////////////////////////////////////////////////////////////////////////////// 1251efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy 125232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, 125357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y) { 1254f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1255c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1256f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 125732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1258f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 125932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 126032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 126132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1262f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 126332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 126432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 126532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 126632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 126732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor dst[1]; 1268f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(dst, src, 1, bitmap.getColorTable()); 1269ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1270ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 1271d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy if (bitmap.colorType() != kRGBA_F16_SkColorType && 1272d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy !GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 1273ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 1274ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get()); 1275ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0], 1276ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0], 1, 1277ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 1278ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 1279ce217faddb4b40c1b3e698944da1951027080427Romain Guy 128032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(dst[0]); 128132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 128232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 128332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, 128432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 128557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1286f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1287c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1288f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 128932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1290f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 129132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 129232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 129332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1294f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 129532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 129632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 129732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 129832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1299f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 130032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint* dst = env->GetIntArrayElements(pixelArray, NULL); 130132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor* d = (SkColor*)dst + offset; 1302ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1303ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 1304d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy if (bitmap.colorType() == kRGBA_F16_SkColorType || 1305d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 1306ce217faddb4b40c1b3e698944da1951027080427Romain Guy while (--height >= 0) { 1307ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(d, src, width, ctable); 1308ce217faddb4b40c1b3e698944da1951027080427Romain Guy d += stride; 1309ce217faddb4b40c1b3e698944da1951027080427Romain Guy src = (void*)((const char*)src + bitmap.rowBytes()); 1310ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 1311ce217faddb4b40c1b3e698944da1951027080427Romain Guy } else { 1312ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 1313ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get()); 1314ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1315ce217faddb4b40c1b3e698944da1951027080427Romain Guy while (--height >= 0) { 1316ce217faddb4b40c1b3e698944da1951027080427Romain Guy proc(d, src, width, ctable); 1317ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1318ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, d, 1319ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, d, width, 1320ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 1321ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1322ce217faddb4b40c1b3e698944da1951027080427Romain Guy d += stride; 1323ce217faddb4b40c1b3e698944da1951027080427Romain Guy src = (void*)((const char*)src + bitmap.rowBytes()); 1324ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 132532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1326ce217faddb4b40c1b3e698944da1951027080427Romain Guy 132732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(pixelArray, dst, 0); 132832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 132932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 133032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 133132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 133232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, 133357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint colorHandle) { 1334f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1335c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 133632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor color = static_cast<SkColor>(colorHandle); 1337f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1338f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bitmap.getPixels()) { 133932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 134032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 134132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1342f29ed28c7b878ef28058bc730715d0d32445bc57John Reck FromColorProc proc = ChooseFromColorProc(bitmap); 134332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 134432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 134532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 134632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1347ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpace* colorSpace = bitmap.colorSpace(); 1348d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy if (bitmap.colorType() != kRGBA_F16_SkColorType && 1349d70532d123b816e0f2ae482258b4e3af56fcdcb2Romain Guy !GraphicsJNI::isColorSpaceSRGB(colorSpace)) { 1350ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto sRGB = SkColorSpace::MakeSRGB(); 1351ce217faddb4b40c1b3e698944da1951027080427Romain Guy auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace); 1352ce217faddb4b40c1b3e698944da1951027080427Romain Guy xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &color, 1353ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkColorSpaceXform::kBGRA_8888_ColorFormat, &color, 1, 1354ce217faddb4b40c1b3e698944da1951027080427Romain Guy SkAlphaType::kUnpremul_SkAlphaType); 1355ce217faddb4b40c1b3e698944da1951027080427Romain Guy } 1356ce217faddb4b40c1b3e698944da1951027080427Romain Guy 1357f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(bitmap.getAddr(x, y), &color, 1, x, y); 1358f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 135932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 136032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 136132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, 136232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 136357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1364f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1365c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 136632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, pixelArray, offset, stride, 1367f29ed28c7b878ef28058bc730715d0d32445bc57John Reck x, y, width, height, bitmap); 136832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 136932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 137032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, 137132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1372f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1373c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1374f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1375f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getPixels(); 137632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 137732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != src) { 137832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); 137932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 138032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1381f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(abp.pointer(), src, bitmap.getSize()); 138232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 138332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 138432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 138532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, 138632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1387f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1388c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap); 1389f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1390f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* dst = bitmap.getPixels(); 139132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 139232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != dst) { 139332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); 139432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1395f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(dst, abp.pointer(), bitmap.getSize()); 1396f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 139732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 139832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 139932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1400795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craikstatic jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, jlong bm1Handle) { 1401f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm0; 1402f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm1; 14031eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv 14041eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv LocalScopedBitmap bitmap0(bm0Handle); 14051eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv LocalScopedBitmap bitmap1(bm1Handle); 14061eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv 14071eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv // Paying the price for making Hardware Bitmap as Config: 14081eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv // later check for colorType will pass successfully, 14091eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv // because Hardware Config internally may be RGBA8888 or smth like that. 141015a108550e3d74b406927d85c8e69018761adf49sergeyv if (bitmap0->isHardware() != bitmap1->isHardware()) { 14111eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv return JNI_FALSE; 14121eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv } 14131eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv 14141eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv bitmap0->bitmap().getSkBitmap(&bm0); 14151eabed3d14fdc47ac6939cfa98521adcb45bc224sergeyv bitmap1->bitmap().getSkBitmap(&bm1); 1416795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik if (bm0.width() != bm1.width() 1417795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || bm0.height() != bm1.height() 1418795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || bm0.colorType() != bm1.colorType() 1419795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || bm0.alphaType() != bm1.alphaType() 1420795bd0fe93e8bb5214e22cd38aea6a9dc651604bChris Craik || !SkColorSpace::Equals(bm0.colorSpace(), bm1.colorSpace())) { 142132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 142232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 142332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1424f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp0(bm0); 1425f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp1(bm1); 142632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 142732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // if we can't load the pixels, return false 1428f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) { 142932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 143032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 143132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1432f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bm0.colorType() == kIndex_8_SkColorType) { 1433f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct0 = bm0.getColorTable(); 1434f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct1 = bm1.getColorTable(); 143532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == ct0 || NULL == ct1) { 143632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 143732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 143832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ct0->count() != ct1->count()) { 143932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 144032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 144132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 144232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const size_t size = ct0->count() * sizeof(SkPMColor); 144371487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed if (memcmp(ct0->readColors(), ct1->readColors(), size) != 0) { 144432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 144532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 144632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 144732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 144832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now compare each scanline. We can't do the entire buffer at once, 144932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // since we don't care about the pixel values that might extend beyond 145032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the width (since the scanline might be larger than the logical width) 1451f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const int h = bm0.height(); 1452f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const size_t size = bm0.width() * bm0.bytesPerPixel(); 145332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < h; y++) { 145453001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config 145553001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0 145653001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // and bm1 both have pixel data() (have passed NULL == getPixels() check), 145753001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE 145853001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // to warn user those 2 unrecognized config bitmaps may be different. 1459f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm0Addr = bm0.getAddr(0, y); 1460f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm1Addr = bm1.getAddr(0, y); 146153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 146253001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if(bm0Addr == NULL || bm1Addr == NULL) { 146353001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen return JNI_FALSE; 146453001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen } 146553001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 146653001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if (memcmp(bm0Addr, bm1Addr, size) != 0) { 146732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 146832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 146932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 147032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 147132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 147232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 14734387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reckstatic void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) { 14744387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck LocalScopedBitmap bitmapHandle(bitmapPtr); 14754387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck if (!bitmapHandle.valid()) return; 1476ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmapHandle->bitmap()); 14774387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck} 14784387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck 14794508218850faedea95371188da587b6734f5f3dasergeyvstatic jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) { 14804508218850faedea95371188da587b6734f5f3dasergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 14814508218850faedea95371188da587b6734f5f3dasergeyv return static_cast<jint>(bitmapHandle->getAllocationByteCount()); 14824508218850faedea95371188da587b6734f5f3dasergeyv} 14834508218850faedea95371188da587b6734f5f3dasergeyv 14846e3658a63843096058ed444d073fbcd191fd7e1bsergeyvstatic jobject Bitmap_copyPreserveInternalConfig(JNIEnv* env, jobject, jlong bitmapPtr) { 148581f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 148681f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(), 148781f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv "Hardware config is only supported config in Bitmap_nativeCopyPreserveInternalConfig"); 148881f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv Bitmap& hwuiBitmap = bitmapHandle->bitmap(); 148981f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv SkBitmap src; 149081f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv hwuiBitmap.getSkBitmap(&src); 149181f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv 149281f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv SkBitmap result; 149381f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv HeapAllocator allocator; 149481f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv if (!src.copyTo(&result, hwuiBitmap.info().colorType(), &allocator)) { 149581f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv doThrowRE(env, "Could not copy a hardware bitmap."); 149681f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv return NULL; 149781f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv } 1498656117bed2fc1937bcebd615898924ed57c48979sergeyv return createBitmap(env, allocator.getStorageObjAndReset(), getPremulBitmapCreateFlags(false)); 149981f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv} 150081f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv 15010a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyvstatic jobject Bitmap_createHardwareBitmap(JNIEnv* env, jobject, jobject graphicBuffer) { 15020a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer)); 15030a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer); 15040a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv if (!bitmap.get()) { 15050a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv ALOGW("failed to create hardware bitmap from graphic buffer"); 15060a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv return NULL; 15070a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv } 1508656117bed2fc1937bcebd615898924ed57c48979sergeyv return bitmap::createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(false)); 15090a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv} 15100a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv 15116e3658a63843096058ed444d073fbcd191fd7e1bsergeyvstatic jobject Bitmap_createGraphicBufferHandle(JNIEnv* env, jobject, jlong bitmapPtr) { 15126e3658a63843096058ed444d073fbcd191fd7e1bsergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 15136e3658a63843096058ed444d073fbcd191fd7e1bsergeyv LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(), 15146e3658a63843096058ed444d073fbcd191fd7e1bsergeyv "Hardware config is only supported config in Bitmap_getGraphicBuffer"); 15156e3658a63843096058ed444d073fbcd191fd7e1bsergeyv 15166e3658a63843096058ed444d073fbcd191fd7e1bsergeyv Bitmap& hwuiBitmap = bitmapHandle->bitmap(); 15176e3658a63843096058ed444d073fbcd191fd7e1bsergeyv sp<GraphicBuffer> buffer(hwuiBitmap.graphicBuffer()); 15186e3658a63843096058ed444d073fbcd191fd7e1bsergeyv return createJavaGraphicBuffer(env, buffer); 15196e3658a63843096058ed444d073fbcd191fd7e1bsergeyv} 15206e3658a63843096058ed444d073fbcd191fd7e1bsergeyv 152132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 1522c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass make_globalref(JNIEnv* env, const char classname[]) 1523c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1524c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jclass c = env->FindClass(classname); 1525c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(c); 1526c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return (jclass) env->NewGlobalRef(c); 1527c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 1528c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 1529c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz, 1530c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const char fieldname[], const char type[]) 1531c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1532c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jfieldID id = env->GetFieldID(clazz, fieldname, type); 1533c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(id); 1534c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return id; 1535c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 153632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 153776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBitmapMethods[] = { 153832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;", 153932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_creator }, 154032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;", 154132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copy }, 1542721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews { "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;", 1543721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews (void*)Bitmap_copyAshmem }, 1544a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;", 1545a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson (void*)Bitmap_copyAshmemConfig }, 1546775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler { "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer }, 154732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle }, 15484508218850faedea95371188da587b6734f5f3dasergeyv { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure }, 154932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z", 155032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_compress }, 155132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeErase", "(JI)V", (void*)Bitmap_erase }, 155232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes }, 155332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeConfig", "(J)I", (void*)Bitmap_config }, 155432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha }, 155557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeIsPremultiplied", "(J)Z", (void*)Bitmap_isPremultiplied}, 155657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetHasAlpha", "(JZZ)V", (void*)Bitmap_setHasAlpha}, 155757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPremultiplied", "(JZ)V", (void*)Bitmap_setPremultiplied}, 155832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap }, 155932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap }, 156032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreateFromParcel", 156132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;", 156232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_createFromParcel }, 156332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z", 156432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_writeToParcel }, 156532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;", 156632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_extractAlpha }, 156732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId }, 156857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixel", "(JII)I", (void*)Bitmap_getPixel }, 156957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixels", "(J[IIIIIII)V", (void*)Bitmap_getPixels }, 157057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixel", "(JIII)V", (void*)Bitmap_setPixel }, 157157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixels", "(J[IIIIIII)V", (void*)Bitmap_setPixels }, 157232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V", 157332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsToBuffer }, 157432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", 157532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsFromBuffer }, 157632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, 15774387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, 15784508218850faedea95371188da587b6734f5f3dasergeyv { "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount }, 157981f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv { "nativeCopyPreserveInternalConfig", "(J)Landroid/graphics/Bitmap;", 15806e3658a63843096058ed444d073fbcd191fd7e1bsergeyv (void*)Bitmap_copyPreserveInternalConfig }, 15810a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv { "nativeCreateHardwareBitmap", "(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;", 15826e3658a63843096058ed444d073fbcd191fd7e1bsergeyv (void*) Bitmap_createHardwareBitmap }, 15836e3658a63843096058ed444d073fbcd191fd7e1bsergeyv { "nativeCreateGraphicBufferHandle", "(J)Landroid/graphics/GraphicBuffer;", 1584efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy (void*) Bitmap_createGraphicBufferHandle }, 1585efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy { "nativeGetColorSpace", "(J[F[F)Z", (void*)Bitmap_getColorSpace }, 1586efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy { "nativeIsSRGB", "(J)Z", (void*)Bitmap_isSRGB }, 158732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 158832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 158932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikint register_android_graphics_Bitmap(JNIEnv* env) 159032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik{ 1591c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_class = make_globalref(env, "android/graphics/Bitmap"); 1592c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J"); 1593c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V"); 1594c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V"); 1595c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); 1596ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, 1597ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe NELEM(gBitmapMethods)); 15989192d5e8d78b826a665ce048c007e6eaf0f5b003John Reck} 1599