15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/android/java_bitmap.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <android/bitmap.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/android/jni_string.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jni/BitmapHelper_jni.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::AttachCurrentThread; 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using base::android::ConvertUTF8ToJavaString; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaBitmap::JavaBitmap(jobject bitmap) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bitmap_(bitmap), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixels_(NULL) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!err); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pixels_); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AndroidBitmapInfo info; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!err); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = gfx::Size(info.width, info.height); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format_ = info.format; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stride_ = info.stride; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaBitmap::~JavaBitmap() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!err); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool JavaBitmap::RegisterJavaBitmap(JNIEnv* env) { 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return RegisterNativesImpl(env); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static int SkBitmapConfigToBitmapFormat(SkBitmap::Config bitmap_config) { 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (bitmap_config) { 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case SkBitmap::kA8_Config: 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_ALPHA_8; 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case SkBitmap::kARGB_4444_Config: 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_ARGB_4444; 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case SkBitmap::kARGB_8888_Config: 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_ARGB_8888; 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case SkBitmap::kRGB_565_Config: 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_RGB_565; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case SkBitmap::kNo_Config: 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_NO_CONFIG; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ScopedJavaLocalRef<jobject> CreateJavaBitmap(int width, 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int height, 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SkBitmap::Config bitmap_config) { 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_GT(width, 0); 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_GT(height, 0); 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int java_bitmap_config = SkBitmapConfigToBitmapFormat(bitmap_config); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return Java_BitmapHelper_createBitmap( 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AttachCurrentThread(), width, height, java_bitmap_config); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochScopedJavaLocalRef<jobject> CreateJavaBitmapFromAndroidResource( 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const char* name, 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch gfx::Size size) { 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(name); 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(!size.IsEmpty()); 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch JNIEnv* env = AttachCurrentThread(); 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ScopedJavaLocalRef<jstring> jname(ConvertUTF8ToJavaString(env, name)); 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Java_BitmapHelper_decodeDrawableResource( 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch env, jname.obj(), size.width(), size.height()); 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(skbitmap); 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(!skbitmap->isNull()); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SkBitmap::Config bitmap_config = skbitmap->config(); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK((bitmap_config == SkBitmap::kRGB_565_Config) || 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (bitmap_config == SkBitmap::kARGB_8888_Config)); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedJavaLocalRef<jobject> jbitmap = CreateJavaBitmap( 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skbitmap->width(), skbitmap->height(), bitmap_config); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkAutoLockPixels src_lock(*skbitmap); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JavaBitmap dst_lock(jbitmap.obj()); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* src_pixels = skbitmap->getPixels(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dst_pixels = dst_lock.pixels(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dst_pixels, src_pixels, skbitmap->getSize()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return jbitmap; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSkBitmap CreateSkBitmapFromJavaBitmap(const JavaBitmap& jbitmap) { 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(jdduke): Convert to DCHECK's when sufficient data has been capture for 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // crbug.com/341406. 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(jbitmap.format(), ANDROID_BITMAP_FORMAT_RGBA_8888); 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(!jbitmap.size().IsEmpty()); 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(jbitmap.stride(), 0U); 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(jbitmap.pixels()); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Size src_size = jbitmap.size(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap skbitmap; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) src_size.width(), 11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) src_size.height(), 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jbitmap.stride()); 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!skbitmap.allocPixels()) { 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LOG(FATAL) << " Failed to allocate bitmap of size " << src_size.width() 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << "x" << src_size.height() << " stride=" << jbitmap.stride(); 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkAutoLockPixels dst_lock(skbitmap); 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const void* src_pixels = jbitmap.pixels(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dst_pixels = skbitmap.getPixels(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dst_pixels, src_pixels, skbitmap.getSize()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skbitmap; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SkBitmap::Config ConvertToSkiaConfig(jobject bitmap_config) { 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int jbitmap_config = Java_BitmapHelper_getBitmapFormatForConfig( 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AttachCurrentThread(), bitmap_config); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (jbitmap_config) { 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_ALPHA_8: 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SkBitmap::kA8_Config; 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_ARGB_4444: 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SkBitmap::kARGB_4444_Config; 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_ARGB_8888: 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SkBitmap::kARGB_8888_Config; 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_RGB_565: 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SkBitmap::kRGB_565_Config; 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_NO_CONFIG: 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SkBitmap::kNo_Config; 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 145