Bitmap.cpp revision c69853c8b72540e5031d28e03cbce5a390c6959f
1f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#define LOG_TAG "Bitmap" 2f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include "Bitmap.h" 3f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkBitmap.h" 532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkPixelRef.h" 632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkImageEncoder.h" 757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III#include "SkImageInfo.h" 832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkColorPriv.h" 932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "GraphicsJNI.h" 1032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkDither.h" 1132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkUnPreMultiply.h" 1232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkStream.h" 1332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <binder/Parcel.h> 1532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_os_Parcel.h" 1632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_util_Binder.h" 1732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_nio_utils.h" 1832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "CreateJavaOutputStreamAdaptor.h" 19f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <Caches.h> 20dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h> 214387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck#include <renderthread/RenderProxy.h> 2232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 23ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h" 24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 2532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <jni.h> 2639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <memory> 2739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <string> 2839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <sys/mman.h> 2939d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <cutils/ashmem.h> 3032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 31a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#define DEBUG_PARCEL 0 328cee7c17119b204be88860feb812f2374d0de732Riley Andrews#define ASHMEM_BITMAP_MIN_SIZE (128 * (1 << 10)) 33a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 34c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass gBitmap_class; 35c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID gBitmap_nativePtr; 36c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_constructorMethodID; 37c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_reinitMethodID; 38c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jmethodID gBitmap_getAllocationByteCountMethodID; 39c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 40f29ed28c7b878ef28058bc730715d0d32445bc57John Recknamespace android { 41f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 42c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvclass Bitmap { 43f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic: 44c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv Bitmap(PixelRef* pixelRef) 45c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv : mPixelRef(pixelRef) { } 46c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 47c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void freePixels() { 48c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mInfo = mPixelRef->info(); 49c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mHasHardwareMipMap = mPixelRef->hasHardwareMipMap(); 50c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mAllocationSize = mPixelRef->getAllocationByteCount(); 51c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mRowBytes = mPixelRef->rowBytes(); 52c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mGenerationId = mPixelRef->getGenerationID(); 53c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mPixelRef.reset(); 54f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 55f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 56c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool valid() { 57c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return !!mPixelRef; 58f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 59f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 60c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv PixelRef* pixelRef() { return mPixelRef.get(); } 61c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 62c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void assertValid() { 63c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LOG_ALWAYS_FATAL_IF(!valid(), "Error, cannot access an invalid/free'd bitmap here!"); 64c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 65c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 66c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void getSkBitmap(SkBitmap* outBitmap) { 67c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 68c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mPixelRef->getSkBitmap(outBitmap); 69c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 700781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck 71c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool hasHardwareMipMap() { 72c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (mPixelRef) { 73c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelRef->hasHardwareMipMap(); 74c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 75f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return mHasHardwareMipMap; 76f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 77f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 78f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void setHasHardwareMipMap(bool hasMipMap) { 79c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 80c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mPixelRef->setHasHardwareMipMap(hasMipMap); 81f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 82f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 83c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv void setAlphaType(SkAlphaType alphaType) { 84c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assertValid(); 85c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mPixelRef->setAlphaType(alphaType); 86f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 87f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 88c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const SkImageInfo& info() { 89c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (mPixelRef) { 90c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelRef->info(); 91c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 92c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mInfo; 93f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 94f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 95c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t getAllocationByteCount() const { 96c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (mPixelRef) { 97c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelRef->getAllocationByteCount(); 98c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 99c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mAllocationSize; 100f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 101f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 102c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t rowBytes() const { 103c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (mPixelRef) { 104c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelRef->rowBytes(); 105c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 106c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mRowBytes; 107c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 108f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 109c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv uint32_t getGenerationID() const { 110c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (mPixelRef) { 111c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelRef->getGenerationID(); 112c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 113c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mGenerationId; 114f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 115c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 116c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv ~Bitmap() { } 117c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 118c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvprivate: 119c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv sk_sp<PixelRef> mPixelRef; 120c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkImageInfo mInfo; 121c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool mHasHardwareMipMap; 122c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t mAllocationSize; 123c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv size_t mRowBytes; 124c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv uint32_t mGenerationId; 125f29ed28c7b878ef28058bc730715d0d32445bc57John Reck}; 126f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 127c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid PixelRef::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) { 128c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (kIndex_8_SkColorType != newInfo.colorType()) { 129c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv ctable = nullptr; 130c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 131c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mRowBytes = rowBytes; 132c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (mColorTable.get() != ctable) { 133c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mColorTable.reset(ctable); 134c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 135c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 136c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // Need to validate the alpha type to filter against the color type 137c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // to prevent things like a non-opaque RGB565 bitmap 138c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkAlphaType alphaType; 139c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType( 140c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv newInfo.colorType(), newInfo.alphaType(), &alphaType), 141c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv "Failed to validate alpha type!"); 142c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 143c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // Dirty hack is dirty 144c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // TODO: Figure something out here, Skia's current design makes this 145c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // really hard to work with. Skia really, really wants immutable objects, 146c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // but with the nested-ref-count hackery going on that's just not 147c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // feasible without going insane trying to figure it out 148c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info()); 149c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv *myInfo = newInfo; 150c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv changeAlphaType(alphaType); 151c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 152c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // Docs say to only call this in the ctor, but we're going to call 153c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // it anyway even if this isn't always the ctor. 154c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // TODO: Fix this too as part of the above TODO 155c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv setPreLocked(getStorage(), mRowBytes, mColorTable.get()); 156c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 157c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 158c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvPixelRef::PixelRef(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) 159c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv : SkPixelRef(info) 160c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv , mPixelStorageType(PixelStorageType::Heap) { 1614508218850faedea95371188da587b6734f5f3dasergeyv mPixelStorage.heap.address = address; 1624508218850faedea95371188da587b6734f5f3dasergeyv mPixelStorage.heap.size = size; 163c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv reconfigure(info, rowBytes, ctable); 164f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 165f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 166c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvPixelRef::PixelRef(void* address, void* context, FreeFunc freeFunc, 167c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) 168c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv : SkPixelRef(info) 169c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv , mPixelStorageType(PixelStorageType::External) { 170f29ed28c7b878ef28058bc730715d0d32445bc57John Reck mPixelStorage.external.address = address; 171f29ed28c7b878ef28058bc730715d0d32445bc57John Reck mPixelStorage.external.context = context; 172f29ed28c7b878ef28058bc730715d0d32445bc57John Reck mPixelStorage.external.freeFunc = freeFunc; 173c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv reconfigure(info, rowBytes, ctable); 174f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 175f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 176c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvPixelRef::PixelRef(void* address, int fd, size_t mappedSize, 177c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) 178c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv : SkPixelRef(info) 179c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv , mPixelStorageType(PixelStorageType::Ashmem) { 18039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews mPixelStorage.ashmem.address = address; 18139d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews mPixelStorage.ashmem.fd = fd; 182003bdee0b6680b8ab0d1fa07451e50e8c3555160John Reck mPixelStorage.ashmem.size = mappedSize; 183c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv reconfigure(info, rowBytes, ctable); 184f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 185f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 186c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvPixelRef::~PixelRef() { 187f29ed28c7b878ef28058bc730715d0d32445bc57John Reck switch (mPixelStorageType) { 188f29ed28c7b878ef28058bc730715d0d32445bc57John Reck case PixelStorageType::External: 189f29ed28c7b878ef28058bc730715d0d32445bc57John Reck mPixelStorage.external.freeFunc(mPixelStorage.external.address, 190f29ed28c7b878ef28058bc730715d0d32445bc57John Reck mPixelStorage.external.context); 191f29ed28c7b878ef28058bc730715d0d32445bc57John Reck break; 19239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews case PixelStorageType::Ashmem: 19339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size); 19439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews close(mPixelStorage.ashmem.fd); 19539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews break; 1964508218850faedea95371188da587b6734f5f3dasergeyv case PixelStorageType::Heap: 1974508218850faedea95371188da587b6734f5f3dasergeyv free(mPixelStorage.heap.address); 198f29ed28c7b878ef28058bc730715d0d32445bc57John Reck break; 199f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 200f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 201f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (android::uirenderer::Caches::hasInstance()) { 202c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID()); 203f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 204f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 205f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 206c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvbool PixelRef::hasHardwareMipMap() const { 207c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mHasHardwareMipMap; 208f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 209f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 210c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid PixelRef::setHasHardwareMipMap(bool hasMipMap) { 211c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv mHasHardwareMipMap = hasMipMap; 212f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 213f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 214c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid* PixelRef::getStorage() const { 215c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv switch (mPixelStorageType) { 216c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv case PixelStorageType::External: 217c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelStorage.external.address; 218c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv case PixelStorageType::Ashmem: 219c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelStorage.ashmem.address; 220c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv case PixelStorageType::Heap: 221c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mPixelStorage.heap.address; 222c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 223c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 224c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 225c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvbool PixelRef::onNewLockPixels(LockRec* rec) { 226c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv rec->fPixels = getStorage(); 227c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv rec->fRowBytes = mRowBytes; 228c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv rec->fColorTable = mColorTable.get(); 229c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return true; 230c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 231c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 232c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvsize_t PixelRef::getAllocatedSizeInBytes() const { 233c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return info().getSafeSize(mRowBytes); 234c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 235c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 236c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvint PixelRef::getAshmemFd() const { 23739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews switch (mPixelStorageType) { 23839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews case PixelStorageType::Ashmem: 23939d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews return mPixelStorage.ashmem.fd; 24039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews default: 24139d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews return -1; 24239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 24339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews} 24439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 245c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvsize_t PixelRef::getAllocationByteCount() const { 2464508218850faedea95371188da587b6734f5f3dasergeyv switch (mPixelStorageType) { 2474508218850faedea95371188da587b6734f5f3dasergeyv case PixelStorageType::Heap: 2484508218850faedea95371188da587b6734f5f3dasergeyv return mPixelStorage.heap.size; 2494508218850faedea95371188da587b6734f5f3dasergeyv default: 2504508218850faedea95371188da587b6734f5f3dasergeyv return rowBytes() * height(); 2514508218850faedea95371188da587b6734f5f3dasergeyv } 2524508218850faedea95371188da587b6734f5f3dasergeyv} 2534508218850faedea95371188da587b6734f5f3dasergeyv 254c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid PixelRef::reconfigure(const SkImageInfo& info) { 2552a94a10bec186d832c2b95675cb6dc27b012c2d0Derek Sollenberger reconfigure(info, info.minRowBytes(), nullptr); 256f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 257f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 258c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid PixelRef::setAlphaType(SkAlphaType alphaType) { 2590781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) { 2600781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck return; 2610781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck } 2620781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck 263c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv changeAlphaType(alphaType); 264f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 265f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 266c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid PixelRef::getSkBitmap(SkBitmap* outBitmap) { 267c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv outBitmap->setInfo(info(), rowBytes()); 268c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv outBitmap->setPixelRef(this); 269c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); 270f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} 271f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 272f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 273f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// Convenience class that does not take a global ref on the pixels, relying 274f29ed28c7b878ef28058bc730715d0d32445bc57John Reck// on the caller already having a local JNI ref 275f29ed28c7b878ef28058bc730715d0d32445bc57John Reckclass LocalScopedBitmap { 276f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic: 277c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit LocalScopedBitmap(jlong bitmapHandle) 278f29ed28c7b878ef28058bc730715d0d32445bc57John Reck : mBitmap(reinterpret_cast<Bitmap*>(bitmapHandle)) {} 279f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 280f29ed28c7b878ef28058bc730715d0d32445bc57John Reck Bitmap* operator->() { 281f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return mBitmap; 282f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 283f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 284f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* pixels() { 285c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return mBitmap->pixelRef()->pixels(); 286f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 287f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 288f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bool valid() { 289f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return mBitmap && mBitmap->valid(); 290f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 291f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 292f29ed28c7b878ef28058bc730715d0d32445bc57John Reckprivate: 293f29ed28c7b878ef28058bc730715d0d32445bc57John Reck Bitmap* mBitmap; 294f29ed28c7b878ef28058bc730715d0d32445bc57John Reck}; 295f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 296c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvnamespace bitmap { 297c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 298c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv// Assert that bitmap's SkAlphaType is consistent with isPremultiplied. 299c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied) { 300c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is 301c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // irrelevant. This just tests to ensure that the SkAlphaType is not 302c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // opposite of isPremultiplied. 303c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isPremultiplied) { 304c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(info.alphaType() != kUnpremul_SkAlphaType); 305c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } else { 306c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(info.alphaType() != kPremul_SkAlphaType); 307c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 308c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 309c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 310c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, 311c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isPremultiplied) 312c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 313c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // The caller needs to have already set the alpha type properly, so the 314c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // native SkBitmap stays in sync with the Java Bitmap. 315c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assert_premultiplied(info, isPremultiplied); 316c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 317c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID, 318c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv info.width(), info.height(), isPremultiplied); 319c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 320c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 321c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvint getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap) 322c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 323c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID); 324c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 325c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 326c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvjobject createBitmap(JNIEnv* env, PixelRef* pixelRef, 327c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, 328c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int density) { 329c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; 330c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied; 331c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // The caller needs to have already set the alpha type properly, so the 332c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv // native SkBitmap stays in sync with the Java Bitmap. 333c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv assert_premultiplied(pixelRef->info(), isPremultiplied); 334c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv Bitmap* bitmap = new Bitmap(pixelRef); 335c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, 336c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv reinterpret_cast<jlong>(bitmap), pixelRef->width(), pixelRef->height(), density, isMutable, 337c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv isPremultiplied, ninePatchChunk, ninePatchInsets); 338c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 339c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (env->ExceptionCheck() != 0) { 340c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv ALOGE("*** Uncaught exception returned from Java call!\n"); 341c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv env->ExceptionDescribe(); 342c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv } 343c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return obj; 344c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 345c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 346c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvvoid toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap) { 347c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LocalScopedBitmap bitmap(bitmapHandle); 348c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->getSkBitmap(outBitmap); 349c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 350c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 351c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvPixelRef* toPixelRef(JNIEnv* env, jobject bitmap) { 352c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(env); 353c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(bitmap); 354c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); 355c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); 356c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv LocalScopedBitmap localBitmap(bitmapHandle); 357c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv localBitmap->assertValid(); 358c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return localBitmap->pixelRef(); 359c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 360c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 361c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace bitmap 362c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 363c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} // namespace android 364c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 365c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android; 366c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvusing namespace android::bitmap; 367c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 36832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 36932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// Conversions to/from SkColor, for get/setPixels, and the create method, which 37032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// is basically like setPixels 37132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 37232054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*FromColorProc)(void* dst, const SkColor src[], int width, 37332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y); 37432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 37532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32(void* dst, const SkColor src[], int width, 37632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 37732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 37832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 37932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 38032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPreMultiplyColor(*src++); 38132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 38232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 38332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 38432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32_Raw(void* dst, const SkColor src[], int width, 38532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 38646d8444631b4b1253a76bfcc78a29d26014d022fDan Albert // Needed to thwart the unreachable code detection from clang. 38746d8444631b4b1253a76bfcc78a29d26014d022fDan Albert static const bool sk_color_ne_zero = SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER; 38846d8444631b4b1253a76bfcc78a29d26014d022fDan Albert 38932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkColor's ordering may be different from SkPMColor 39046d8444631b4b1253a76bfcc78a29d26014d022fDan Albert if (sk_color_ne_zero) { 39132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(dst, src, width * sizeof(SkColor)); 39232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 39332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 39432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 39532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // order isn't same, repack each pixel manually 39632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 39732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 39832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 39932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 40032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 40132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 40232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 40332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 40432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D565(void* dst, const SkColor src[], int width, 40532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 40632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t* d = (uint16_t*)dst; 40732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 40832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_565_SCAN(y); 40932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 41032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 41132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), 41232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_VALUE(x)); 41332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 41432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 41532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 41632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444(void* dst, const SkColor src[], int width, 41732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 41832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 41932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 42032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 42132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 42232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPreMultiplyColor(*src++); 42332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 42432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 42532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 42632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 42732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 42832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444_Raw(void* dst, const SkColor src[], int width, 42932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 43032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 43132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 43232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 43332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 43432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 43532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 43632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied 43732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 43832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 43932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 44032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 44132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 44232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 44332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4446260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void FromColor_DA8(void* dst, const SkColor src[], int width, int x, int y) { 4456260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t* d = (uint8_t*)dst; 4466260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 4476260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik for (int stop = x + width; x < stop; x++) { 4486260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *d++ = SkColorGetA(*src++); 4496260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } 4506260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 4516260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 45232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 45357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) { 45457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (bitmap.colorType()) { 45557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kN32_SkColorType: 45657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D32 : FromColor_D32_Raw; 45757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kARGB_4444_SkColorType: 45857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_D4444 : 45957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III FromColor_D4444_Raw; 46057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kRGB_565_SkColorType: 46132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return FromColor_D565; 4626260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 4636260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return FromColor_DA8; 46432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 46532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 46632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 46732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 46832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 46932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 47032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikbool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride, 47157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III int x, int y, int width, int height, const SkBitmap& dstBitmap) { 47232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(dstBitmap); 47332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik void* dst = dstBitmap.getPixels(); 47457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III FromColorProc proc = ChooseFromColorProc(dstBitmap); 47532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 47632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == dst || NULL == proc) { 47732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return false; 47832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 47932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const jint* array = env->GetIntArrayElements(srcColors, NULL); 48132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkColor* src = (const SkColor*)array + srcOffset; 48232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // reset to to actual choice from caller 48432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = dstBitmap.getAddr(x, y); 48532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now copy/convert each scanline 48632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < height; y++) { 48732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(dst, src, width, x, y); 48832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik src += srcStride; 48932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = (char*)dst + dstBitmap.rowBytes(); 49032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 49132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 49232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dstBitmap.notifyPixelsChanged(); 49332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 49432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), 49532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik JNI_ABORT); 49632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return true; 49732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 49832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 49932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//////////////////// ToColor procs 50032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 50132054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*ToColorProc)(SkColor dst[], const void* src, int width, 50232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*); 50332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 50432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width, 50532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 50632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 50732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 50832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 50932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(*s++); 51032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 51132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 51232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 51332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width, 51432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 51532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 51632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 51732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 51832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 51932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 52032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 52132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 52232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 52332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 52432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width, 52532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 52632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 52732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 52832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 52932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 53032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 53132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 53232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 53332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 53432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width, 53632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 53732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 53832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 53932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 54032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++)); 54132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 54232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 54332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 54432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width, 54532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 54632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 54732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 54832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 54932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 55032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 55132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 55232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 55332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 55432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width, 55632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 55732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 55832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 55932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 56032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 56132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 56232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 56332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 56432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 56532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 56632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S565(SkColor dst[], const void* src, int width, 56732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 56832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 56932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint16_t* s = (const uint16_t*)src; 57032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 57132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t c = *s++; 57232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), 57332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPacked16ToB32(c)); 57432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 57532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 57632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 57832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 57932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 58032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 58171487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 58232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 58332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); 58432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 58532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 58632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 58732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, 58832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 58932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 59032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 59171487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 59232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 59332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 59432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 59532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 59632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 59732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 59832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 59932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, 60032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 60132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 60232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 60371487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed const SkPMColor* colors = ctable->readColors(); 60432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 60532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 60632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 60732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 60832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 60932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 61032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 6116260b22501996d2e7a0323b493ae6c4badb93c28Chris Craikstatic void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) { 6126260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik SkASSERT(width > 0); 6136260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik const uint8_t* s = (const uint8_t*)src; 6146260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik do { 6156260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik uint8_t c = *s++; 6166260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik *dst++ = SkColorSetARGB(c, c, c, c); 6176260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik } while (--width != 0); 6186260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik} 6196260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik 62032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 62157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic ToColorProc ChooseToColorProc(const SkBitmap& src) { 622b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed switch (src.colorType()) { 623b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kN32_SkColorType: 62457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 62557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 62657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Opaque; 62757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 62857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Alpha; 62957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 63057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S32_Raw; 63157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 63257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 63357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 634b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kARGB_4444_SkColorType: 63557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 63657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 63757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Opaque; 63857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 63957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Alpha; 64057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 64157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_S4444_Raw; 64257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 64357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 64457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 645b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kRGB_565_SkColorType: 64632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return ToColor_S565; 647b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kIndex_8_SkColorType: 64832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.getColorTable() == NULL) { 64932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 65032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 65157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III switch (src.alphaType()) { 65257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kOpaque_SkAlphaType: 65357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Opaque; 65457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kPremul_SkAlphaType: 65557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Alpha; 65657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III case kUnpremul_SkAlphaType: 65757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return ToColor_SI8_Raw; 65857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III default: 65957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return NULL; 66057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 6616260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik case kAlpha_8_SkColorType: 6626260b22501996d2e7a0323b493ae6c4badb93c28Chris Craik return ToColor_SA8; 66332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 66432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 66532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 66632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 66732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 66832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 66932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 67032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 67132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 67232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic int getPremulBitmapCreateFlags(bool isMutable) { 673c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int flags = android::bitmap::kBitmapCreateFlag_Premultiplied; 674c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv if (isMutable) flags |= android::bitmap::kBitmapCreateFlag_Mutable; 67532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return flags; 67632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 67732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 67832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 67932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint offset, jint stride, jint width, jint height, 68032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint configHandle, jboolean isMutable) { 6811103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 68232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != jColors) { 68332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t n = env->GetArrayLength(jColors); 68432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (n < SkAbs32(stride) * (size_t)height) { 68532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowAIOOBE(env); 68632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 68732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 68832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 68932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // ARGB_4444 is a deprecated format, convert automatically to 8888 691b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kARGB_4444_SkColorType) { 692b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed colorType = kN32_SkColorType; 69332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 69432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap bitmap; 696b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType)); 69732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 698c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv PixelRef* nativeBitmap = GraphicsJNI::allocateHeapPixelRef(&bitmap, NULL); 699f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!nativeBitmap) { 70032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 70132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 70332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (jColors != NULL) { 70432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, jColors, offset, stride, 70557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 0, 0, width, height, bitmap); 70632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 708c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, nativeBitmap, 709f29ed28c7b878ef28058bc730715d0d32445bc57John Reck getPremulBitmapCreateFlags(isMutable)); 71032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 71132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 71232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, 71332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint dstConfigHandle, jboolean isMutable) { 714f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 715f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src); 7161103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 7174508218850faedea95371188da587b6734f5f3dasergeyv SkBitmap result; 7184508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 71932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 720f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!src.copyTo(&result, dstCT, &allocator)) { 72132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 72232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 723c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv auto pixelRef = allocator.getStorageObjAndReset(); 724c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, pixelRef, getPremulBitmapCreateFlags(isMutable)); 72532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 72632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 727c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic PixelRef* Bitmap_copyAshmemImpl(JNIEnv* env, SkBitmap& src, SkColorType& dstCT) { 728721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews SkBitmap result; 729721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 730721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews AshmemPixelAllocator allocator(env); 731a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson if (!src.copyTo(&result, dstCT, &allocator)) { 732721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return NULL; 733721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews } 734c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv auto pixelRef = allocator.getStorageObjAndReset(); 735c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv pixelRef->setImmutable(); 736c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return pixelRef; 737a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 738a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 739a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) { 740a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 741a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src); 742a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = src.colorType(); 743c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv auto pixelRef = Bitmap_copyAshmemImpl(env, src, dstCT); 744c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jobject ret = createBitmap(env, pixelRef, getPremulBitmapCreateFlags(false)); 745a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson return ret; 746a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson} 747a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson 748a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonstatic jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle) { 749a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkBitmap src; 750a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src); 751a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); 752c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv auto pixelRef = Bitmap_copyAshmemImpl(env, src, dstCT); 753c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jobject ret = createBitmap(env, pixelRef, getPremulBitmapCreateFlags(false)); 754721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews return ret; 755721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews} 756721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews 757775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic void Bitmap_destruct(Bitmap* bitmap) { 758c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv delete bitmap; 75932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 76032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 761775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhlerstatic jlong Bitmap_getNativeFinalizer(JNIEnv*, jobject) { 762775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct)); 763775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler} 764775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler 76532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { 766f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 767f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->freePixels(); 76832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 76932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 77032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 77132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, 7724508218850faedea95371188da587b6734f5f3dasergeyv jint width, jint height, jint configHandle, jboolean requestPremul) { 773f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 774c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->assertValid(); 7751103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); 77617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III 77717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // ARGB_4444 is a deprecated format, convert automatically to 8888 77817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (colorType == kARGB_4444_SkColorType) { 77917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III colorType = kN32_SkColorType; 78017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 7814508218850faedea95371188da587b6734f5f3dasergeyv size_t requestedSize = width * height * SkColorTypeBytesPerPixel(colorType); 7824508218850faedea95371188da587b6734f5f3dasergeyv if (requestedSize > bitmap->getAllocationByteCount()) { 78332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // done in native as there's no way to get BytesPerPixel in Java 78432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowIAE(env, "Bitmap not large enough to support new configuration"); 78532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 78632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 78717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkAlphaType alphaType; 788f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().colorType() != kRGB_565_SkColorType 789f29ed28c7b878ef28058bc730715d0d32445bc57John Reck && bitmap->info().alphaType() == kOpaque_SkAlphaType) { 79017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // If the original bitmap was set to opaque, keep that setting, unless it 79117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // was 565, which is required to be opaque. 79217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = kOpaque_SkAlphaType; 79317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } else { 79417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // Otherwise respect the premultiplied request. 79517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 79617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 797c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv bitmap->pixelRef()->reconfigure(SkImageInfo::Make(width, height, colorType, alphaType)); 79832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 79932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 80032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// These must match the int values in Bitmap.java 80132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikenum JavaEncodeFormat { 80232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kJPEG_JavaEncodeFormat = 0, 80332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kPNG_JavaEncodeFormat = 1, 80432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kWEBP_JavaEncodeFormat = 2 80532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 80632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 80732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, 80832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint format, jint quality, 80932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject jstream, jbyteArray jstorage) { 810f29ed28c7b878ef28058bc730715d0d32445bc57John Reck 811f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 81232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkImageEncoder::Type fm; 81332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 81432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik switch (format) { 81532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kJPEG_JavaEncodeFormat: 81632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kJPEG_Type; 81732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 81832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kPNG_JavaEncodeFormat: 81932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kPNG_Type; 82032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 82132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kWEBP_JavaEncodeFormat: 82232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kWEBP_Type; 82332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 82432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 82532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 82632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 82732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 828f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap.valid()) { 829f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 830f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 83132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 832f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bool success = false; 83332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 834f29ed28c7b878ef28058bc730715d0d32445bc57John Reck std::unique_ptr<SkWStream> strm(CreateJavaOutputStreamAdaptor(env, jstream, jstorage)); 835f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!strm.get()) { 836f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return JNI_FALSE; 837f29ed28c7b878ef28058bc730715d0d32445bc57John Reck } 83832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 839f29ed28c7b878ef28058bc730715d0d32445bc57John Reck std::unique_ptr<SkImageEncoder> encoder(SkImageEncoder::Create(fm)); 840f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (encoder.get()) { 841f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap skbitmap; 842f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->getSkBitmap(&skbitmap); 843f29ed28c7b878ef28058bc730715d0d32445bc57John Reck success = encoder->encodeStream(strm.get(), skbitmap, quality); 84432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 84532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return success ? JNI_TRUE : JNI_FALSE; 84632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 84732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 84832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { 849f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 850f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap skBitmap; 851f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap->getSkBitmap(&skBitmap); 852f29ed28c7b878ef28058bc730715d0d32445bc57John Reck skBitmap.eraseColor(color); 85332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 85432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 85532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { 856f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 85732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->rowBytes()); 85832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 85932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { 861f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 862f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->info().colorType()); 86332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 86432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { 866f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 867c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return static_cast<jint>(bitmap->getGenerationID()); 86832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 86932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 87057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) { 871f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 872f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap->info().alphaType() == kPremul_SkAlphaType) { 87357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_TRUE; 87457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 87557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III return JNI_FALSE; 87657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 87757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 87832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { 879f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 880f29ed28c7b878ef28058bc730715d0d32445bc57John Reck return !bitmap->info().isOpaque() ? JNI_TRUE : JNI_FALSE; 88132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 88232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 88357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle, 88457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean hasAlpha, jboolean requestPremul) { 885f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 88657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (hasAlpha) { 8870781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType( 888f29ed28c7b878ef28058bc730715d0d32445bc57John Reck requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); 88932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 8900781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kOpaque_SkAlphaType); 89157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 89257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III} 89357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III 89457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins IIIstatic void Bitmap_setPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, 89557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jboolean isPremul) { 896f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 897f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (!bitmap->info().isOpaque()) { 89857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III if (isPremul) { 8990781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kPremul_SkAlphaType); 90057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } else { 9010781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck bitmap->setAlphaType(kUnpremul_SkAlphaType); 90257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III } 90332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 90432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 90532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 90632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { 907f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 90832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; 90932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 91032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 91132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, 91232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean hasMipMap) { 913f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 91432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setHasHardwareMipMap(hasMipMap); 91532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 91632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 91732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 91832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 91932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 92032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 92132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("-------- unparcel parcel is NULL\n"); 92232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 92332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 92432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 92532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 92632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 927b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const bool isMutable = p->readInt32() != 0; 928b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkColorType colorType = (SkColorType)p->readInt32(); 929b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); 930b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int width = p->readInt32(); 931b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int height = p->readInt32(); 932b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int rowBytes = p->readInt32(); 933b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int density = p->readInt32(); 934b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed 935b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (kN32_SkColorType != colorType && 936b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kRGB_565_SkColorType != colorType && 937b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kARGB_4444_SkColorType != colorType && 938b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kIndex_8_SkColorType != colorType && 939b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kAlpha_8_SkColorType != colorType) { 940b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed SkDebugf("Bitmap_createFromParcel unknown colortype: %d\n", colorType); 94132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 94232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 94332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 944ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III std::unique_ptr<SkBitmap> bitmap(new SkBitmap); 94532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 946ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes)) { 947ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 948ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 94932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 95032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = NULL; 951b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kIndex_8_SkColorType) { 95232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = p->readInt32(); 953ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (count < 0 || count > 256) { 954ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // The data is corrupt, since SkColorTable enforces a value between 0 and 256, 955ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III // inclusive. 956ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 957ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 95832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (count > 0) { 95932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = count * sizeof(SkPMColor); 96032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* src = (const SkPMColor*)p->readInplace(size); 961ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III if (src == NULL) { 962ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III return NULL; 963ec419e0b731d2aa32f7f570e4021fe18b8be228dLeon Scroggins III } 96432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable = new SkColorTable(src, count); 96532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 96632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 96732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 968a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Read the bitmap blob. 969a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap->getSize(); 970a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::ReadableBlob blob; 971a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status = p->readBlob(size, &blob); 972a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 97332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkSafeUnref(ctable); 974a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not read bitmap blob."); 97532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 97632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 97732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 978a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the bitmap in place from the ashmem region if possible otherwise copy. 979c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv PixelRef* nativeBitmap; 9808cee7c17119b204be88860feb812f2374d0de732Riley Andrews if (blob.fd() >= 0 && (blob.isMutable() || !isMutable) && (size >= ASHMEM_BITMAP_MIN_SIZE)) { 981a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 982a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob " 983a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 984a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 985a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 986a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 987a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 988a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Dup the file descriptor so we can keep a reference to it after the Parcel 989a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // is disposed. 990a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown int dupFd = dup(blob.fd()); 991a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (dupFd < 0) { 992211abad3b92b70dd094949c79f67e686c940fa0cErik Wolsheimer ALOGE("Error allocating dup fd. Error:%d", errno); 993a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 994a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 995a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate dup blob fd."); 996a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 99739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 998a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 999a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Map the pixels in place and take ownership of the ashmem region. 1000a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown nativeBitmap = GraphicsJNI::mapAshmemPixelRef(env, bitmap.get(), 1001003bdee0b6680b8ab0d1fa07451e50e8c3555160John Reck ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable); 1002a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1003a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 1004a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown close(dupFd); 1005a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1006a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate ashmem pixel ref."); 1007a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 100839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1009a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1010a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Clear the blob handle, don't release it. 1011a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.clear(); 1012a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1013a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1014a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (blob.fd() >= 0) { 1015a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents of mutable bitmap " 1016a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "from immutable blob (fds %s)", 1017a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1018a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1019a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.createFromParcel: copied contents from %s blob " 1020a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "(fds %s)", 1021a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.isMutable() ? "mutable" : "immutable", 1022a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 102339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1024a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1025a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1026a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the pixels into a new buffer. 10274508218850faedea95371188da587b6734f5f3dasergeyv nativeBitmap = GraphicsJNI::allocateHeapPixelRef(bitmap.get(), ctable); 1028a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown SkSafeUnref(ctable); 1029a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (!nativeBitmap) { 1030a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 1031a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not allocate java pixel ref."); 1032a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return NULL; 103339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1034a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->lockPixels(); 1035a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(bitmap->getPixels(), blob.data(), size); 1036a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap->unlockPixels(); 1037a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1038a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Release the blob handle. 1039a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 104039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1041a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1042c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, nativeBitmap, 1043a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); 1044a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown} 104539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 104632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 104732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, 104832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean isMutable, jint density, 104932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject parcel) { 105032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 105132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("------- writeToParcel null parcel\n"); 105232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 105332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 105432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 105532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 1056f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 105739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews 1058c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv auto androidBitmap = reinterpret_cast<Bitmap*>(bitmapHandle); 105939d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews androidBitmap->getSkBitmap(&bitmap); 106032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 106132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(isMutable); 1062f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.colorType()); 1063f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.alphaType()); 1064f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.width()); 1065f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.height()); 1066f29ed28c7b878ef28058bc730715d0d32445bc57John Reck p->writeInt32(bitmap.rowBytes()); 106732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(density); 106832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1069f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bitmap.colorType() == kIndex_8_SkColorType) { 107066ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III // The bitmap needs to be locked to access its color table. 107166ce1c3b1a7b5ed3d4d5a9a05a7c133998c9a73eLeon Scroggins III SkAutoLockPixels alp(bitmap); 1072f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 107332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ctable != NULL) { 107432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = ctable->count(); 107532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(count); 107632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(p->writeInplace(count * sizeof(SkPMColor)), 107771487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed ctable->readColors(), count * sizeof(SkPMColor)); 107832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 107932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(0); // indicate no ctable 108032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 108132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 108232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1083a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Transfer the underlying ashmem region if we have one and it's immutable. 1084a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::status_t status; 1085c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv int fd = androidBitmap->pixelRef()->getAshmemFd(); 1086a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (fd >= 0 && !isMutable && p->allowFds()) { 1087a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1088a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " 1089a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown "immutable blob (fds %s)", 1090a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1091a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1092a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1093a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeDupImmutableBlobFileDescriptor(fd); 1094a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 1095a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not write bitmap blob file descriptor."); 109639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews return JNI_FALSE; 109739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1098a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_TRUE; 1099a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 110032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1101a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown // Copy the bitmap to a new blob. 1102a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bool mutableCopy = isMutable; 1103a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#if DEBUG_PARCEL 1104a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown ALOGD("Bitmap.writeToParcel: copying %s bitmap into new %s blob (fds %s)", 1105a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown isMutable ? "mutable" : "immutable", 1106a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown mutableCopy ? "mutable" : "immutable", 1107a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown p->allowFds() ? "allowed" : "forbidden"); 1108a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown#endif 1109a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1110a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown size_t size = bitmap.getSize(); 1111a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown android::Parcel::WritableBlob blob; 1112a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown status = p->writeBlob(size, mutableCopy, &blob); 1113a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (status) { 1114a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown doThrowRE(env, "Could not copy bitmap to parcel blob."); 1115a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown return JNI_FALSE; 111639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews } 1117a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1118a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.lockPixels(); 1119a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown const void* pSrc = bitmap.getPixels(); 1120a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown if (pSrc == NULL) { 1121a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memset(blob.data(), 0, size); 1122a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } else { 1123a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown memcpy(blob.data(), pSrc, size); 1124a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown } 1125a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown bitmap.unlockPixels(); 1126a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown 1127a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown blob.release(); 112832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 112932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 113032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 113132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, 113232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong srcHandle, jlong paintHandle, 113332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray offsetXY) { 1134f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap src; 1135f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src); 11366ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle); 113732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkIPoint offset; 1138f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap dst; 11394508218850faedea95371188da587b6734f5f3dasergeyv HeapAllocator allocator; 114032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1141f29ed28c7b878ef28058bc730715d0d32445bc57John Reck src.extractAlpha(&dst, paint, &allocator, &offset); 114232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // If Skia can't allocate pixels for destination bitmap, it resets 114332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // it, that is set its pixels buffer to NULL, and zero width and height. 1144f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (dst.getPixels() == NULL && src.getPixels() != NULL) { 114532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowOOME(env, "failed to allocate pixels for alpha"); 114632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 114732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 114832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) { 114932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int* array = env->GetIntArrayElements(offsetXY, NULL); 115032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[0] = offset.fX; 115132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[1] = offset.fY; 115232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(offsetXY, array, 0); 115332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 115432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1155c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return createBitmap(env, allocator.getStorageObjAndReset(), 1156f29ed28c7b878ef28058bc730715d0d32445bc57John Reck getPremulBitmapCreateFlags(true)); 115732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 115832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 115932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 116032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 116132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, 116257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y) { 1163f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1164f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); 1165f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 116632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1167f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 116832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 116932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 117032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1171f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 117232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 117332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 117432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 117532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 117632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor dst[1]; 1177f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(dst, src, 1, bitmap.getColorTable()); 117832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(dst[0]); 117932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 118032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 118132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, 118232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 118357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1184f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1185f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); 1186f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 118732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1188f29ed28c7b878ef28058bc730715d0d32445bc57John Reck ToColorProc proc = ChooseToColorProc(bitmap); 118932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 119032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 119132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 1192f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getAddr(x, y); 119332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 119432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 119532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 119632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1197f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ctable = bitmap.getColorTable(); 119832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint* dst = env->GetIntArrayElements(pixelArray, NULL); 119932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor* d = (SkColor*)dst + offset; 120032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik while (--height >= 0) { 120132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(d, src, width, ctable); 120232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik d += stride; 1203f29ed28c7b878ef28058bc730715d0d32445bc57John Reck src = (void*)((const char*)src + bitmap.rowBytes()); 120432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 120532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(pixelArray, dst, 0); 120632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 120732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 120832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 120932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 121032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, 121157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint colorHandle) { 1212f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1213f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); 121432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor color = static_cast<SkColor>(colorHandle); 1215f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1216f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bitmap.getPixels()) { 121732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 121832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 121932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1220f29ed28c7b878ef28058bc730715d0d32445bc57John Reck FromColorProc proc = ChooseFromColorProc(bitmap); 122132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 122232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 122332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 122432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1225f29ed28c7b878ef28058bc730715d0d32445bc57John Reck proc(bitmap.getAddr(x, y), &color, 1, x, y); 1226f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 122732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 122832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 122932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, 123032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 123157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III jint x, jint y, jint width, jint height) { 1232f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1233f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); 123432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, pixelArray, offset, stride, 1235f29ed28c7b878ef28058bc730715d0d32445bc57John Reck x, y, width, height, bitmap); 123632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 123732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 123832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, 123932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1240f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1241f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); 1242f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1243f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const void* src = bitmap.getPixels(); 124432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 124532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != src) { 124632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); 124732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 124832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1249f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(abp.pointer(), src, bitmap.getSize()); 125032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 125132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 125232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 125332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, 125432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 1255f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bitmap; 1256f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); 1257f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp(bitmap); 1258f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void* dst = bitmap.getPixels(); 125932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 126032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != dst) { 126132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); 126232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 1263f29ed28c7b878ef28058bc730715d0d32445bc57John Reck memcpy(dst, abp.pointer(), bitmap.getSize()); 1264f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bitmap.notifyPixelsChanged(); 126532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 126632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 126732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 126832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, 126932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bm1Handle) { 1270f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm0; 1271f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkBitmap bm1; 1272f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bm0Handle)->getSkBitmap(&bm0); 1273f29ed28c7b878ef28058bc730715d0d32445bc57John Reck reinterpret_cast<Bitmap*>(bm1Handle)->getSkBitmap(&bm1); 1274f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bm0.width() != bm1.width() || 1275f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bm0.height() != bm1.height() || 1276f29ed28c7b878ef28058bc730715d0d32445bc57John Reck bm0.colorType() != bm1.colorType()) { 127732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 127832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 127932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1280f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp0(bm0); 1281f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkAutoLockPixels alp1(bm1); 128232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 128332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // if we can't load the pixels, return false 1284f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) { 128532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 128632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 128732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1288f29ed28c7b878ef28058bc730715d0d32445bc57John Reck if (bm0.colorType() == kIndex_8_SkColorType) { 1289f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct0 = bm0.getColorTable(); 1290f29ed28c7b878ef28058bc730715d0d32445bc57John Reck SkColorTable* ct1 = bm1.getColorTable(); 129132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == ct0 || NULL == ct1) { 129232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 129332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 129432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ct0->count() != ct1->count()) { 129532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 129632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 129732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 129832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const size_t size = ct0->count() * sizeof(SkPMColor); 129971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed if (memcmp(ct0->readColors(), ct1->readColors(), size) != 0) { 130032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 130132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 130232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 130332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 130432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now compare each scanline. We can't do the entire buffer at once, 130532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // since we don't care about the pixel values that might extend beyond 130632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the width (since the scanline might be larger than the logical width) 1307f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const int h = bm0.height(); 1308f29ed28c7b878ef28058bc730715d0d32445bc57John Reck const size_t size = bm0.width() * bm0.bytesPerPixel(); 130932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < h; y++) { 131053001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config 131153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0 131253001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // and bm1 both have pixel data() (have passed NULL == getPixels() check), 131353001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE 131453001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen // to warn user those 2 unrecognized config bitmaps may be different. 1315f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm0Addr = bm0.getAddr(0, y); 1316f29ed28c7b878ef28058bc730715d0d32445bc57John Reck void *bm1Addr = bm1.getAddr(0, y); 131753001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 131853001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if(bm0Addr == NULL || bm1Addr == NULL) { 131953001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen return JNI_FALSE; 132053001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen } 132153001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen 132253001ca3a629c0069f4fdac44f7711ad4a0c395ahenry.uh_chen if (memcmp(bm0Addr, bm1Addr, size) != 0) { 132332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 132432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 132532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 132632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 132732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 132832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1329c6e2e8ff474ae44bab5b9eb665851118abd27b68John Reckstatic jlong Bitmap_refPixelRef(JNIEnv* env, jobject, jlong bitmapHandle) { 1330f29ed28c7b878ef28058bc730715d0d32445bc57John Reck LocalScopedBitmap bitmap(bitmapHandle); 1331c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkPixelRef* pixelRef = bitmap->pixelRef(); 1332c6e2e8ff474ae44bab5b9eb665851118abd27b68John Reck SkSafeRef(pixelRef); 1333c6e2e8ff474ae44bab5b9eb665851118abd27b68John Reck return reinterpret_cast<jlong>(pixelRef); 1334c6e2e8ff474ae44bab5b9eb665851118abd27b68John Reck} 1335c6e2e8ff474ae44bab5b9eb665851118abd27b68John Reck 13364387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reckstatic void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) { 13374387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck LocalScopedBitmap bitmapHandle(bitmapPtr); 13384387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck if (!bitmapHandle.valid()) return; 13394387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck SkBitmap bitmap; 13404387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck bitmapHandle->getSkBitmap(&bitmap); 13414387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmap); 13424387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck} 13434387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck 13444508218850faedea95371188da587b6734f5f3dasergeyvstatic jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) { 13454508218850faedea95371188da587b6734f5f3dasergeyv LocalScopedBitmap bitmapHandle(bitmapPtr); 13464508218850faedea95371188da587b6734f5f3dasergeyv return static_cast<jint>(bitmapHandle->getAllocationByteCount()); 13474508218850faedea95371188da587b6734f5f3dasergeyv} 13484508218850faedea95371188da587b6734f5f3dasergeyv 134932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 1350c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jclass make_globalref(JNIEnv* env, const char classname[]) 1351c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1352c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jclass c = env->FindClass(classname); 1353c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(c); 1354c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return (jclass) env->NewGlobalRef(c); 1355c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 1356c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv 1357c69853c8b72540e5031d28e03cbce5a390c6959fsergeyvstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz, 1358c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv const char fieldname[], const char type[]) 1359c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv{ 1360c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv jfieldID id = env->GetFieldID(clazz, fieldname, type); 1361c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv SkASSERT(id); 1362c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv return id; 1363c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv} 136432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 136576f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBitmapMethods[] = { 136632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;", 136732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_creator }, 136832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;", 136932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copy }, 1370721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews { "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;", 1371721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews (void*)Bitmap_copyAshmem }, 1372a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;", 1373a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson (void*)Bitmap_copyAshmemConfig }, 1374775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler { "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer }, 137532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle }, 13764508218850faedea95371188da587b6734f5f3dasergeyv { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure }, 137732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z", 137832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_compress }, 137932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeErase", "(JI)V", (void*)Bitmap_erase }, 138032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes }, 138132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeConfig", "(J)I", (void*)Bitmap_config }, 138232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha }, 138357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeIsPremultiplied", "(J)Z", (void*)Bitmap_isPremultiplied}, 138457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetHasAlpha", "(JZZ)V", (void*)Bitmap_setHasAlpha}, 138557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPremultiplied", "(JZ)V", (void*)Bitmap_setPremultiplied}, 138632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap }, 138732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap }, 138832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreateFromParcel", 138932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;", 139032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_createFromParcel }, 139132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z", 139232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_writeToParcel }, 139332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;", 139432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_extractAlpha }, 139532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId }, 139657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixel", "(JII)I", (void*)Bitmap_getPixel }, 139757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeGetPixels", "(J[IIIIIII)V", (void*)Bitmap_getPixels }, 139857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixel", "(JIII)V", (void*)Bitmap_setPixel }, 139957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III { "nativeSetPixels", "(J[IIIIIII)V", (void*)Bitmap_setPixels }, 140032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V", 140132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsToBuffer }, 140232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", 140332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsFromBuffer }, 140432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, 1405c6e2e8ff474ae44bab5b9eb665851118abd27b68John Reck { "nativeRefPixelRef", "(J)J", (void*)Bitmap_refPixelRef }, 14064387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, 14074508218850faedea95371188da587b6734f5f3dasergeyv { "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount }, 140832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 140932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 141032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikint register_android_graphics_Bitmap(JNIEnv* env) 141132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik{ 1412c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_class = make_globalref(env, "android/graphics/Bitmap"); 1413c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J"); 1414c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V"); 1415c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V"); 1416c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); 1417ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, 1418ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe NELEM(gBitmapMethods)); 1419c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv}