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" 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "skia/ext/image_operations.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::AttachCurrentThread; 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using base::android::ConvertUTF8ToJavaString; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaBitmap::JavaBitmap(jobject bitmap) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bitmap_(bitmap), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixels_(NULL) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!err); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pixels_); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AndroidBitmapInfo info; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!err); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = gfx::Size(info.width, info.height); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format_ = info.format; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stride_ = info.stride; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaBitmap::~JavaBitmap() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!err); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool JavaBitmap::RegisterJavaBitmap(JNIEnv* env) { 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return RegisterNativesImpl(env); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic int SkColorTypeToBitmapFormat(SkColorType color_type) { 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (color_type) { 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case kAlpha_8_SkColorType: 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_ALPHA_8; 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case kARGB_4444_SkColorType: 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_ARGB_4444; 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case kN32_SkColorType: 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_ARGB_8888; 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case kRGB_565_SkColorType: 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_RGB_565; 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case kUnknown_SkColorType: 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BITMAP_FORMAT_NO_CONFIG; 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ScopedJavaLocalRef<jobject> CreateJavaBitmap(int width, 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int height, 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkColorType color_type) { 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_GT(width, 0); 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_GT(height, 0); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int java_bitmap_config = SkColorTypeToBitmapFormat(color_type); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return Java_BitmapHelper_createBitmap( 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AttachCurrentThread(), width, height, java_bitmap_config); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(skbitmap); 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(!skbitmap->isNull()); 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkColorType color_type = skbitmap->colorType(); 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK((color_type == kRGB_565_SkColorType) || 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (color_type == kN32_SkColorType)); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedJavaLocalRef<jobject> jbitmap = CreateJavaBitmap( 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch skbitmap->width(), skbitmap->height(), color_type); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkAutoLockPixels src_lock(*skbitmap); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JavaBitmap dst_lock(jbitmap.obj()); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* src_pixels = skbitmap->getPixels(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dst_pixels = dst_lock.pixels(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dst_pixels, src_pixels, skbitmap->getSize()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return jbitmap; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SkBitmap CreateSkBitmapFromAndroidResource(const char* name, gfx::Size size) { 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(name); 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(!size.IsEmpty()); 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ScopedJavaLocalRef<jstring> jname(ConvertUTF8ToJavaString(env, name)); 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::android::ScopedJavaLocalRef<jobject> jobj = 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Java_BitmapHelper_decodeDrawableResource( 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) env, jname.obj(), size.width(), size.height()); 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (jobj.is_null()) 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return SkBitmap(); 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jobj.obj())); 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (bitmap.isNull()) 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return bitmap; 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return skia::ImageOperations::Resize( 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height()); 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 109effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSkBitmap CreateSkBitmapFromJavaBitmap(const JavaBitmap& jbitmap) { 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(jdduke): Convert to DCHECK's when sufficient data has been capture for 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // crbug.com/341406. 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(jbitmap.format(), ANDROID_BITMAP_FORMAT_RGBA_8888); 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(!jbitmap.size().IsEmpty()); 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(jbitmap.stride(), 0U); 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(jbitmap.pixels()); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Size src_size = jbitmap.size(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap skbitmap; 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci skbitmap.allocPixels(SkImageInfo::MakeN32Premul(src_size.width(), 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci src_size.height()), 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jbitmap.stride()); 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const void* src_pixels = jbitmap.pixels(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dst_pixels = skbitmap.getPixels(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dst_pixels, src_pixels, skbitmap.getSize()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skbitmap; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSkColorType ConvertToSkiaColorType(jobject bitmap_config) { 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int jbitmap_config = Java_BitmapHelper_getBitmapFormatForConfig( 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AttachCurrentThread(), bitmap_config); 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (jbitmap_config) { 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_ALPHA_8: 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return kAlpha_8_SkColorType; 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_ARGB_4444: 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return kARGB_4444_SkColorType; 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_ARGB_8888: 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return kN32_SkColorType; 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_RGB_565: 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return kRGB_565_SkColorType; 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case BITMAP_FORMAT_NO_CONFIG: 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return kUnknown_SkColorType; 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 149