1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <android/bitmap.h> 18 19 #pragma GCC diagnostic push 20 #pragma GCC diagnostic ignored "-Wunused-parameter" 21 #include <GraphicsJNI.h> 22 #pragma GCC diagnostic pop 23 24 int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, 25 AndroidBitmapInfo* info) { 26 if (NULL == env || NULL == jbitmap) { 27 return ANDROID_BITMAP_RESULT_BAD_PARAMETER; 28 } 29 30 SkBitmap bm; 31 GraphicsJNI::getSkBitmap(env, jbitmap, &bm); 32 33 if (info) { 34 info->width = bm.width(); 35 info->height = bm.height(); 36 info->stride = bm.rowBytes(); 37 info->flags = 0; 38 39 switch (bm.colorType()) { 40 case kN32_SkColorType: 41 info->format = ANDROID_BITMAP_FORMAT_RGBA_8888; 42 break; 43 case kRGB_565_SkColorType: 44 info->format = ANDROID_BITMAP_FORMAT_RGB_565; 45 break; 46 case kARGB_4444_SkColorType: 47 info->format = ANDROID_BITMAP_FORMAT_RGBA_4444; 48 break; 49 case kAlpha_8_SkColorType: 50 info->format = ANDROID_BITMAP_FORMAT_A_8; 51 break; 52 default: 53 info->format = ANDROID_BITMAP_FORMAT_NONE; 54 break; 55 } 56 } 57 return ANDROID_BITMAP_RESULT_SUCCESS; 58 } 59 60 int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr) { 61 if (NULL == env || NULL == jbitmap) { 62 return ANDROID_BITMAP_RESULT_BAD_PARAMETER; 63 } 64 65 SkPixelRef* pixelRef = GraphicsJNI::refSkPixelRef(env, jbitmap); 66 if (!pixelRef) { 67 return ANDROID_BITMAP_RESULT_JNI_EXCEPTION; 68 } 69 70 pixelRef->lockPixels(); 71 void* addr = pixelRef->pixels(); 72 if (NULL == addr) { 73 pixelRef->unlockPixels(); 74 pixelRef->unref(); 75 return ANDROID_BITMAP_RESULT_ALLOCATION_FAILED; 76 } 77 78 if (addrPtr) { 79 *addrPtr = addr; 80 } 81 return ANDROID_BITMAP_RESULT_SUCCESS; 82 } 83 84 int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) { 85 if (NULL == env || NULL == jbitmap) { 86 return ANDROID_BITMAP_RESULT_BAD_PARAMETER; 87 } 88 89 SkPixelRef* pixelRef = GraphicsJNI::refSkPixelRef(env, jbitmap); 90 if (!pixelRef) { 91 return ANDROID_BITMAP_RESULT_JNI_EXCEPTION; 92 } 93 94 // notifyPixelsChanged() needs be called to apply writes to GL-backed 95 // bitmaps. Note that this will slow down read-only accesses to the 96 // bitmaps, but the NDK methods are primarily intended to be used for 97 // writes. 98 pixelRef->notifyPixelsChanged(); 99 100 pixelRef->unlockPixels(); 101 // Awkward in that we need to double-unref as the call to get the SkPixelRef 102 // did a ref(), so we need to unref() for the local ref and for the previous 103 // AndroidBitmap_lockPixels(). However this keeps GraphicsJNI a bit safer 104 // if others start using it without knowing about android::Bitmap's "fun" 105 // ref counting mechanism(s). 106 pixelRef->unref(); 107 pixelRef->unref(); 108 109 return ANDROID_BITMAP_RESULT_SUCCESS; 110 } 111 112