// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/gfx/android/java_bitmap.h" #include #include "base/android/jni_string.h" #include "base/logging.h" #include "jni/BitmapHelper_jni.h" #include "ui/gfx/geometry/size.h" using base::android::AttachCurrentThread; using base::android::ConvertUTF8ToJavaString; namespace gfx { JavaBitmap::JavaBitmap(jobject bitmap) : bitmap_(bitmap), pixels_(NULL) { int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_); DCHECK(!err); DCHECK(pixels_); AndroidBitmapInfo info; err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); DCHECK(!err); size_ = gfx::Size(info.width, info.height); format_ = info.format; stride_ = info.stride; } JavaBitmap::~JavaBitmap() { int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_); DCHECK(!err); } // static bool JavaBitmap::RegisterJavaBitmap(JNIEnv* env) { return RegisterNativesImpl(env); } static int SkColorTypeToBitmapFormat(SkColorType color_type) { switch (color_type) { case kAlpha_8_SkColorType: return BITMAP_FORMAT_ALPHA_8; case kARGB_4444_SkColorType: return BITMAP_FORMAT_ARGB_4444; case kN32_SkColorType: return BITMAP_FORMAT_ARGB_8888; case kRGB_565_SkColorType: return BITMAP_FORMAT_RGB_565; case kUnknown_SkColorType: default: NOTREACHED(); return BITMAP_FORMAT_NO_CONFIG; } } ScopedJavaLocalRef CreateJavaBitmap(int width, int height, SkColorType color_type) { DCHECK_GT(width, 0); DCHECK_GT(height, 0); int java_bitmap_config = SkColorTypeToBitmapFormat(color_type); return Java_BitmapHelper_createBitmap( AttachCurrentThread(), width, height, java_bitmap_config); } ScopedJavaLocalRef ConvertToJavaBitmap(const SkBitmap* skbitmap) { DCHECK(skbitmap); DCHECK(!skbitmap->isNull()); SkColorType color_type = skbitmap->colorType(); DCHECK((color_type == kRGB_565_SkColorType) || (color_type == kN32_SkColorType)); ScopedJavaLocalRef jbitmap = CreateJavaBitmap( skbitmap->width(), skbitmap->height(), color_type); SkAutoLockPixels src_lock(*skbitmap); JavaBitmap dst_lock(jbitmap.obj()); void* src_pixels = skbitmap->getPixels(); void* dst_pixels = dst_lock.pixels(); memcpy(dst_pixels, src_pixels, skbitmap->getSize()); return jbitmap; } SkBitmap CreateSkBitmapFromJavaBitmap(const JavaBitmap& jbitmap) { DCHECK(!jbitmap.size().IsEmpty()); DCHECK_GT(jbitmap.stride(), 0U); DCHECK(jbitmap.pixels()); gfx::Size src_size = jbitmap.size(); SkBitmap skbitmap; switch (jbitmap.format()) { case ANDROID_BITMAP_FORMAT_RGBA_8888: skbitmap.allocPixels(SkImageInfo::MakeN32Premul(src_size.width(), src_size.height()), jbitmap.stride()); break; case ANDROID_BITMAP_FORMAT_A_8: skbitmap.allocPixels(SkImageInfo::MakeA8(src_size.width(), src_size.height()), jbitmap.stride()); break; default: CHECK(false) << "Invalid Java bitmap format: " << jbitmap.format(); break; } const void* src_pixels = jbitmap.pixels(); void* dst_pixels = skbitmap.getPixels(); memcpy(dst_pixels, src_pixels, skbitmap.getSize()); return skbitmap; } SkColorType ConvertToSkiaColorType(jobject bitmap_config) { int jbitmap_config = Java_BitmapHelper_getBitmapFormatForConfig( AttachCurrentThread(), bitmap_config); switch (jbitmap_config) { case BITMAP_FORMAT_ALPHA_8: return kAlpha_8_SkColorType; case BITMAP_FORMAT_ARGB_4444: return kARGB_4444_SkColorType; case BITMAP_FORMAT_ARGB_8888: return kN32_SkColorType; case BITMAP_FORMAT_RGB_565: return kRGB_565_SkColorType; case BITMAP_FORMAT_NO_CONFIG: default: return kUnknown_SkColorType; } } } // namespace gfx