// 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 <android/bitmap.h>

#include "base/android/jni_string.h"
#include "base/bits.h"
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gfx_jni_headers/BitmapHelper_jni.h"

using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaLocalRef;
using base::android::JavaRef;

namespace gfx {
namespace {

int SkColorTypeToBitmapFormat(SkColorType color_type) {
  switch (color_type) {
    case kN32_SkColorType:
      return BITMAP_FORMAT_ARGB_8888;
    case kRGB_565_SkColorType:
      return BITMAP_FORMAT_RGB_565;
    default:
      // A bad format can cause out-of-bounds issues when copying pixels into or
      // out of the java bitmap's pixel buffer.
      CHECK_NE(color_type, color_type);
  }
  return BITMAP_FORMAT_NO_CONFIG;
}

SkColorType BitmapFormatToSkColorType(BitmapFormat bitmap_format) {
  switch (bitmap_format) {
    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:
      CHECK_NE(bitmap_format, bitmap_format);
      return kUnknown_SkColorType;
  }
}

// Wraps a Java bitmap as an SkPixmap. Since the pixmap references the
// underlying pixel data in the Java bitmap directly, it is only valid as long
// as |bitmap| is.
SkPixmap WrapJavaBitmapAsPixmap(const JavaBitmap& bitmap) {
  auto color_type = BitmapFormatToSkColorType(bitmap.format());
  auto image_info =
      SkImageInfo::Make(bitmap.size().width(), bitmap.size().height(),
                        color_type, kPremul_SkAlphaType);
  return SkPixmap(image_info, bitmap.pixels(), bitmap.bytes_per_row());
}

}  // namespace

#define ASSERT_ENUM_EQ(a, b) \
  static_assert(static_cast<int>(a) == static_cast<int>(b), "")

// BitmapFormat has the same values as AndroidBitmapFormat, for simplicitly, so
// that SkColorTypeToBitmapFormat() and the JavaBitmap::format() have the same
// values.
ASSERT_ENUM_EQ(BITMAP_FORMAT_NO_CONFIG, ANDROID_BITMAP_FORMAT_NONE);
ASSERT_ENUM_EQ(BITMAP_FORMAT_ALPHA_8, ANDROID_BITMAP_FORMAT_A_8);
ASSERT_ENUM_EQ(BITMAP_FORMAT_ARGB_4444, ANDROID_BITMAP_FORMAT_RGBA_4444);
ASSERT_ENUM_EQ(BITMAP_FORMAT_ARGB_8888, ANDROID_BITMAP_FORMAT_RGBA_8888);
ASSERT_ENUM_EQ(BITMAP_FORMAT_RGB_565, ANDROID_BITMAP_FORMAT_RGB_565);

JavaBitmap::JavaBitmap(const JavaRef<jobject>& bitmap)
    : bitmap_(bitmap), pixels_(NULL) {
  int err =
      AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_.obj(), &pixels_);
  DCHECK(!err);
  DCHECK(pixels_);

  AndroidBitmapInfo info;
  err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_.obj(), &info);
  DCHECK(!err);
  size_ = gfx::Size(info.width, info.height);
  format_ = static_cast<BitmapFormat>(info.format);
  bytes_per_row_ = info.stride;
  byte_count_ = Java_BitmapHelper_getByteCount(AttachCurrentThread(), bitmap_);
}

JavaBitmap::~JavaBitmap() {
  int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_.obj());
  DCHECK(!err);
}

ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap& skbitmap,
                                                OomBehavior reaction) {
  DCHECK(!skbitmap.isNull());
  DCHECK_GT(skbitmap.width(), 0);
  DCHECK_GT(skbitmap.height(), 0);

  int java_bitmap_format = SkColorTypeToBitmapFormat(skbitmap.colorType());

  ScopedJavaLocalRef<jobject> jbitmap = Java_BitmapHelper_createBitmap(
      AttachCurrentThread(), skbitmap.width(), skbitmap.height(),
      java_bitmap_format, reaction == OomBehavior::kReturnNullOnOom);
  if (!jbitmap) {
    DCHECK_EQ(OomBehavior::kReturnNullOnOom, reaction);
    return jbitmap;
  }

  JavaBitmap dst_lock(jbitmap);
  SkPixmap dst = WrapJavaBitmapAsPixmap(dst_lock);
  skbitmap.readPixels(dst);
  return jbitmap;
}

SkBitmap CreateSkBitmapFromJavaBitmap(const JavaBitmap& jbitmap) {
  DCHECK(!jbitmap.size().IsEmpty());
  DCHECK_GT(jbitmap.bytes_per_row(), 0U);
  DCHECK(jbitmap.pixels());

  // Ensure 4 byte stride alignment since the texture upload code in the
  // compositor relies on this.
  SkPixmap src = WrapJavaBitmapAsPixmap(jbitmap);
  const size_t min_row_bytes = src.info().minRowBytes();
  const size_t row_bytes = base::bits::AlignUp(min_row_bytes, 4u);

  SkBitmap skbitmap;
  skbitmap.allocPixels(src.info(), row_bytes);
  skbitmap.writePixels(src);
  return skbitmap;
}

SkColorType ConvertToSkiaColorType(const JavaRef<jobject>& bitmap_config) {
  BitmapFormat jbitmap_format =
      static_cast<BitmapFormat>(Java_BitmapHelper_getBitmapFormatForConfig(
          AttachCurrentThread(), bitmap_config));
  return BitmapFormatToSkColorType(jbitmap_format);
}

}  //  namespace gfx
