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 "skia/ext/image_operations.h"
     13 #include "third_party/skia/include/core/SkBitmap.h"
     14 #include "ui/gfx/size.h"
     15 
     16 using base::android::AttachCurrentThread;
     17 
     18 namespace gfx {
     19 
     20 JavaBitmap::JavaBitmap(jobject bitmap)
     21     : bitmap_(bitmap),
     22       pixels_(NULL) {
     23   int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_);
     24   DCHECK(!err);
     25   DCHECK(pixels_);
     26 
     27   AndroidBitmapInfo info;
     28   err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info);
     29   DCHECK(!err);
     30   size_ = gfx::Size(info.width, info.height);
     31   format_ = info.format;
     32   stride_ = info.stride;
     33 }
     34 
     35 JavaBitmap::~JavaBitmap() {
     36   int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_);
     37   DCHECK(!err);
     38 }
     39 
     40 // static
     41 bool JavaBitmap::RegisterJavaBitmap(JNIEnv* env) {
     42   return RegisterNativesImpl(env);
     43 }
     44 
     45 static ScopedJavaLocalRef<jobject> CreateJavaBitmap(const gfx::Size& size) {
     46   return Java_BitmapHelper_createBitmap(AttachCurrentThread(),
     47       size.width(), size.height());
     48 }
     49 
     50 ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) {
     51   DCHECK(skbitmap);
     52   DCHECK_EQ(skbitmap->bytesPerPixel(), 4);
     53 
     54   ScopedJavaLocalRef<jobject> jbitmap =
     55       CreateJavaBitmap(gfx::Size(skbitmap->width(), skbitmap->height()));
     56   SkAutoLockPixels src_lock(*skbitmap);
     57   JavaBitmap dst_lock(jbitmap.obj());
     58   void* src_pixels = skbitmap->getPixels();
     59   void* dst_pixels = dst_lock.pixels();
     60   memcpy(dst_pixels, src_pixels, skbitmap->getSize());
     61 
     62   return jbitmap;
     63 }
     64 
     65 SkBitmap CreateSkBitmapFromJavaBitmap(JavaBitmap& jbitmap) {
     66   DCHECK_EQ(jbitmap.format(), ANDROID_BITMAP_FORMAT_RGBA_8888);
     67 
     68   gfx::Size src_size = jbitmap.size();
     69 
     70   SkBitmap skbitmap;
     71   skbitmap.setConfig(SkBitmap::kARGB_8888_Config,
     72                      src_size.width(),
     73                      src_size.height(),
     74                      jbitmap.stride());
     75   skbitmap.allocPixels();
     76   SkAutoLockPixels dst_lock(skbitmap);
     77 
     78   void* src_pixels = jbitmap.pixels();
     79   void* dst_pixels = skbitmap.getPixels();
     80 
     81   memcpy(dst_pixels, src_pixels, skbitmap.getSize());
     82 
     83   return skbitmap;
     84 }
     85 
     86 SkBitmap CreateSkBitmapFromResource(const char* name, gfx::Size size) {
     87   DCHECK(!size.IsEmpty());
     88   JNIEnv* env = AttachCurrentThread();
     89   ScopedJavaLocalRef<jstring> jname(env, env->NewStringUTF(name));
     90   ScopedJavaLocalRef<jobject> jobj(Java_BitmapHelper_decodeDrawableResource(
     91       env, jname.obj(), size.width(), size.height()));
     92   if (jobj.is_null())
     93     return SkBitmap();
     94 
     95   JavaBitmap jbitmap(jobj.obj());
     96   SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(jbitmap);
     97   return skia::ImageOperations::Resize(
     98       bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height());
     99 }
    100 
    101 }  //  namespace gfx
    102