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