Home | History | Annotate | Download | only in android
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/gfx/android/java_bitmap.h"
      6 
      7 #include <android/bitmap.h>
      8 
      9 #include "base/android/jni_string.h"
     10 #include "base/logging.h"
     11 #include "jni/BitmapHelper_jni.h"
     12 #include "ui/gfx/size.h"
     13 
     14 using base::android::AttachCurrentThread;
     15 using base::android::ConvertUTF8ToJavaString;
     16 
     17 namespace gfx {
     18 
     19 JavaBitmap::JavaBitmap(jobject bitmap)
     20     : bitmap_(bitmap),
     21       pixels_(NULL) {
     22   int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_);
     23   DCHECK(!err);
     24   DCHECK(pixels_);
     25 
     26   AndroidBitmapInfo info;
     27   err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info);
     28   DCHECK(!err);
     29   size_ = gfx::Size(info.width, info.height);
     30   format_ = info.format;
     31   stride_ = info.stride;
     32 }
     33 
     34 JavaBitmap::~JavaBitmap() {
     35   int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_);
     36   DCHECK(!err);
     37 }
     38 
     39 // static
     40 bool JavaBitmap::RegisterJavaBitmap(JNIEnv* env) {
     41   return RegisterNativesImpl(env);
     42 }
     43 
     44 static int SkBitmapConfigToBitmapFormat(SkBitmap::Config bitmap_config) {
     45   switch (bitmap_config) {
     46     case SkBitmap::kA8_Config:
     47       return BITMAP_FORMAT_ALPHA_8;
     48     case SkBitmap::kARGB_4444_Config:
     49       return BITMAP_FORMAT_ARGB_4444;
     50     case SkBitmap::kARGB_8888_Config:
     51       return BITMAP_FORMAT_ARGB_8888;
     52     case SkBitmap::kRGB_565_Config:
     53       return BITMAP_FORMAT_RGB_565;
     54     case SkBitmap::kNo_Config:
     55     default:
     56       NOTREACHED();
     57       return BITMAP_FORMAT_NO_CONFIG;
     58   }
     59 }
     60 
     61 ScopedJavaLocalRef<jobject> CreateJavaBitmap(int width,
     62                                              int height,
     63                                              SkBitmap::Config bitmap_config) {
     64   DCHECK_GT(width, 0);
     65   DCHECK_GT(height, 0);
     66   int java_bitmap_config = SkBitmapConfigToBitmapFormat(bitmap_config);
     67   return Java_BitmapHelper_createBitmap(
     68       AttachCurrentThread(), width, height, java_bitmap_config);
     69 }
     70 
     71 ScopedJavaLocalRef<jobject> CreateJavaBitmapFromAndroidResource(
     72     const char* name,
     73     gfx::Size size) {
     74   DCHECK(name);
     75   DCHECK(!size.IsEmpty());
     76   JNIEnv* env = AttachCurrentThread();
     77   ScopedJavaLocalRef<jstring> jname(ConvertUTF8ToJavaString(env, name));
     78   return Java_BitmapHelper_decodeDrawableResource(
     79       env, jname.obj(), size.width(), size.height());
     80 }
     81 
     82 ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) {
     83   DCHECK(skbitmap);
     84   DCHECK(!skbitmap->isNull());
     85   SkBitmap::Config bitmap_config = skbitmap->config();
     86   DCHECK((bitmap_config == SkBitmap::kRGB_565_Config) ||
     87          (bitmap_config == SkBitmap::kARGB_8888_Config));
     88   ScopedJavaLocalRef<jobject> jbitmap = CreateJavaBitmap(
     89       skbitmap->width(), skbitmap->height(), bitmap_config);
     90   SkAutoLockPixels src_lock(*skbitmap);
     91   JavaBitmap dst_lock(jbitmap.obj());
     92   void* src_pixels = skbitmap->getPixels();
     93   void* dst_pixels = dst_lock.pixels();
     94   memcpy(dst_pixels, src_pixels, skbitmap->getSize());
     95 
     96   return jbitmap;
     97 }
     98 
     99 SkBitmap CreateSkBitmapFromJavaBitmap(const JavaBitmap& jbitmap) {
    100   // TODO(jdduke): Convert to DCHECK's when sufficient data has been capture for
    101   // crbug.com/341406.
    102   CHECK_EQ(jbitmap.format(), ANDROID_BITMAP_FORMAT_RGBA_8888);
    103   CHECK(!jbitmap.size().IsEmpty());
    104   CHECK_GT(jbitmap.stride(), 0U);
    105   CHECK(jbitmap.pixels());
    106 
    107   gfx::Size src_size = jbitmap.size();
    108 
    109   SkBitmap skbitmap;
    110   skbitmap.setConfig(SkBitmap::kARGB_8888_Config,
    111                      src_size.width(),
    112                      src_size.height(),
    113                      jbitmap.stride());
    114   if (!skbitmap.allocPixels()) {
    115     LOG(FATAL) << " Failed to allocate bitmap of size " << src_size.width()
    116                << "x" << src_size.height() << " stride=" << jbitmap.stride();
    117   }
    118   SkAutoLockPixels dst_lock(skbitmap);
    119   const void* src_pixels = jbitmap.pixels();
    120   void* dst_pixels = skbitmap.getPixels();
    121   memcpy(dst_pixels, src_pixels, skbitmap.getSize());
    122 
    123   return skbitmap;
    124 }
    125 
    126 SkBitmap::Config ConvertToSkiaConfig(jobject bitmap_config) {
    127   int jbitmap_config = Java_BitmapHelper_getBitmapFormatForConfig(
    128       AttachCurrentThread(), bitmap_config);
    129   switch (jbitmap_config) {
    130     case BITMAP_FORMAT_ALPHA_8:
    131       return SkBitmap::kA8_Config;
    132     case BITMAP_FORMAT_ARGB_4444:
    133       return SkBitmap::kARGB_4444_Config;
    134     case BITMAP_FORMAT_ARGB_8888:
    135       return SkBitmap::kARGB_8888_Config;
    136     case BITMAP_FORMAT_RGB_565:
    137       return SkBitmap::kRGB_565_Config;
    138     case BITMAP_FORMAT_NO_CONFIG:
    139     default:
    140       return SkBitmap::kNo_Config;
    141   }
    142 }
    143 
    144 }  //  namespace gfx
    145