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/logging.h"
     10 #include "jni/BitmapHelper_jni.h"
     11 #include "skia/ext/image_operations.h"
     12 #include "third_party/skia/include/core/SkBitmap.h"
     13 #include "ui/gfx/size.h"
     14 
     15 using base::android::AttachCurrentThread;
     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 ui::RegisterNativesImpl(env);
     42 }
     43 
     44 static ScopedJavaLocalRef<jobject> CreateJavaBitmap(const gfx::Size& size) {
     45   return ui::Java_BitmapHelper_createBitmap(AttachCurrentThread(),
     46       size.width(), size.height());
     47 }
     48 
     49 ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) {
     50   DCHECK(skbitmap);
     51   DCHECK_EQ(skbitmap->bytesPerPixel(), 4);
     52 
     53   ScopedJavaLocalRef<jobject> jbitmap =
     54       CreateJavaBitmap(gfx::Size(skbitmap->width(), skbitmap->height()));
     55   SkAutoLockPixels src_lock(*skbitmap);
     56   JavaBitmap dst_lock(jbitmap.obj());
     57   void* src_pixels = skbitmap->getPixels();
     58   void* dst_pixels = dst_lock.pixels();
     59   memcpy(dst_pixels, src_pixels, skbitmap->getSize());
     60 
     61   return jbitmap;
     62 }
     63 
     64 static ScopedJavaLocalRef<jobject> CreateJavaBitmapFromResource(
     65     const char* name, gfx::Size requested_size) {
     66   JNIEnv* env = AttachCurrentThread();
     67   ScopedJavaLocalRef<jstring> jname(env, env->NewStringUTF(name));
     68   return ui::Java_BitmapHelper_decodeDrawableResource(env,
     69                                                       jname.obj(),
     70                                                       requested_size.width(),
     71                                                       requested_size.height());
     72 }
     73 
     74 static SkBitmap ConvertToSkBitmap(ScopedJavaLocalRef<jobject> jbitmap) {
     75   if (jbitmap.is_null())
     76     return SkBitmap();
     77 
     78   JavaBitmap src_lock(jbitmap.obj());
     79   DCHECK_EQ(src_lock.format(), ANDROID_BITMAP_FORMAT_RGBA_8888);
     80 
     81   gfx::Size src_size = src_lock.size();
     82 
     83   SkBitmap skbitmap;
     84   skbitmap.setConfig(SkBitmap::kARGB_8888_Config,
     85       src_size.width(), src_size.height(), src_lock.stride());
     86   skbitmap.allocPixels();
     87   SkAutoLockPixels dst_lock(skbitmap);
     88 
     89   void* src_pixels = src_lock.pixels();
     90   void* dst_pixels = skbitmap.getPixels();
     91 
     92   memcpy(dst_pixels, src_pixels, skbitmap.getSize());
     93 
     94   return skbitmap;
     95 }
     96 
     97 SkBitmap CreateSkBitmapFromResource(const char* name, gfx::Size size) {
     98   DCHECK(!size.IsEmpty());
     99   SkBitmap bitmap =
    100       ConvertToSkBitmap(CreateJavaBitmapFromResource(name, size));
    101   if (bitmap.isNull())
    102     return bitmap;
    103   return skia::ImageOperations::Resize(bitmap,
    104                                        skia::ImageOperations::RESIZE_GOOD,
    105                                        size.width(), size.height());
    106 }
    107 
    108 }  //  namespace gfx
    109