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.
5 #include "ui/gfx/android/java_bitmap.h"
7 #include <android/bitmap.h>
9 #include "base/android/jni_string.h"
10 #include "base/logging.h"
11 #include "jni/BitmapHelper_jni.h"
12 #include "ui/gfx/size.h"
14 using base::android::AttachCurrentThread
;
15 using base::android::ConvertUTF8ToJavaString
;
19 JavaBitmap::JavaBitmap(jobject bitmap
)
22 int err
= AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_
, &pixels_
);
26 AndroidBitmapInfo info
;
27 err
= AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_
, &info
);
29 size_
= gfx::Size(info
.width
, info
.height
);
30 format_
= info
.format
;
31 stride_
= info
.stride
;
34 JavaBitmap::~JavaBitmap() {
35 int err
= AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_
);
40 bool JavaBitmap::RegisterJavaBitmap(JNIEnv
* env
) {
41 return RegisterNativesImpl(env
);
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
:
57 return BITMAP_FORMAT_NO_CONFIG
;
61 ScopedJavaLocalRef
<jobject
> CreateJavaBitmap(int width
,
63 SkBitmap::Config bitmap_config
) {
66 int java_bitmap_config
= SkBitmapConfigToBitmapFormat(bitmap_config
);
67 return Java_BitmapHelper_createBitmap(
68 AttachCurrentThread(), width
, height
, java_bitmap_config
);
71 ScopedJavaLocalRef
<jobject
> CreateJavaBitmapFromAndroidResource(
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());
82 ScopedJavaLocalRef
<jobject
> ConvertToJavaBitmap(const SkBitmap
* 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());
99 SkBitmap
CreateSkBitmapFromJavaBitmap(const JavaBitmap
& jbitmap
) {
100 // TODO(jdduke): Convert to DCHECK's when sufficient data has been capture for
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());
107 gfx::Size src_size
= jbitmap
.size();
110 skbitmap
.setConfig(SkBitmap::kARGB_8888_Config
,
114 if (!skbitmap
.allocPixels()) {
115 LOG(FATAL
) << " Failed to allocate bitmap of size " << src_size
.width()
116 << "x" << src_size
.height() << " stride=" << jbitmap
.stride();
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());
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
:
140 return SkBitmap::kNo_Config
;