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