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