Home | History | Annotate | Download | only in jni
      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