// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/image/image_platform.h"

#include <stddef.h>
#import <UIKit/UIKit.h>

#include <cmath>
#include <limits>

#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_internal.h"
#include "ui/gfx/image/image_png_rep.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_skia_util_ios.h"

namespace {

// Returns a 16x16 red UIImage to visually show when a UIImage cannot be
// created from PNG data. Logs error as well.
// Caller takes ownership of returned UIImage.
UIImage* CreateErrorUIImage(float scale) {
  LOG(ERROR) << "Unable to decode PNG into UIImage.";
  base::ScopedCFTypeRef<CGColorSpaceRef> color_space(
      CGColorSpaceCreateDeviceRGB());
  base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate(
      nullptr,  // Allow CG to allocate memory.
      16,       // width
      16,       // height
      8,        // bitsPerComponent
      0,        // CG will calculate by default.
      color_space,
      kCGImageAlphaPremultipliedFirst |
          static_cast<CGImageAlphaInfo>(kCGBitmapByteOrder32Host)));
  CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
  CGContextFillRect(context, CGRectMake(0.0, 0.0, 16, 16));
  base::ScopedCFTypeRef<CGImageRef> cg_image(
      CGBitmapContextCreateImage(context));
  return [[UIImage imageWithCGImage:cg_image.get()
                              scale:scale
                        orientation:UIImageOrientationUp] retain];
}

// Converts from ImagePNGRep to UIImage.
UIImage* CreateUIImageFromImagePNGRep(const gfx::ImagePNGRep& image_png_rep) {
  float scale = image_png_rep.scale;
  scoped_refptr<base::RefCountedMemory> png = image_png_rep.raw_data;
  CHECK(png.get());
  NSData* data = [NSData dataWithBytes:png->front() length:png->size()];
  UIImage* image = [[UIImage alloc] initWithData:data scale:scale];
  return image ? image : CreateErrorUIImage(scale);
}

}  // namespace

namespace gfx {

namespace internal {

class ImageRepCocoaTouch final : public ImageRep {
 public:
  explicit ImageRepCocoaTouch(UIImage* image)
      : ImageRep(Image::kImageRepCocoaTouch),
        image_(image, base::scoped_policy::RETAIN) {
    CHECK(image_);
  }

  ImageRepCocoaTouch(const ImageRepCocoaTouch&) = delete;
  ImageRepCocoaTouch& operator=(const ImageRepCocoaTouch&) = delete;

  ~ImageRepCocoaTouch() override { image_.reset(); }

  int Width() const override { return Size().width(); }

  int Height() const override { return Size().height(); }

  gfx::Size Size() const override {
    int width = static_cast<int>(image_.get().size.width);
    int height = static_cast<int>(image_.get().size.height);
    return gfx::Size(width, height);
  }

  UIImage* image() const { return image_; }

 private:
  base::scoped_nsobject<UIImage> image_;
};

const ImageRepCocoaTouch* ImageRep::AsImageRepCocoaTouch() const {
  CHECK_EQ(type_, Image::kImageRepCocoaTouch);
  return reinterpret_cast<const ImageRepCocoaTouch*>(this);
}
ImageRepCocoaTouch* ImageRep::AsImageRepCocoaTouch() {
  return const_cast<ImageRepCocoaTouch*>(
      static_cast<const ImageRep*>(this)->AsImageRepCocoaTouch());
}

scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage(
    UIImage* uiimage) {
  DCHECK(uiimage);
  NSData* data = UIImagePNGRepresentation(uiimage);

  if ([data length] == 0)
    return nullptr;

  scoped_refptr<base::RefCountedBytes> png_bytes(
      new base::RefCountedBytes());
  png_bytes->data().resize([data length]);
  [data getBytes:&png_bytes->data().at(0) length:[data length]];
  return png_bytes;
}

UIImage* UIImageFromPNG(const std::vector<gfx::ImagePNGRep>& image_png_reps) {
  float ideal_scale = ImageSkia::GetMaxSupportedScale();

  if (image_png_reps.empty())
    return CreateErrorUIImage(ideal_scale);

  // Find best match for |ideal_scale|.
  float smallest_diff = std::numeric_limits<float>::max();
  size_t closest_index = 0u;
  for (size_t i = 0; i < image_png_reps.size(); ++i) {
    float scale = image_png_reps[i].scale;
    float diff = std::abs(ideal_scale - scale);
    if (diff < smallest_diff) {
      smallest_diff = diff;
      closest_index = i;
    }
  }

  return
      [CreateUIImageFromImagePNGRep(image_png_reps[closest_index]) autorelease];
}

scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia(
    const ImageSkia* skia) {
  // iOS does not expose libpng, so conversion from ImageSkia to PNG must go
  // through UIImage.
  // TODO(rohitrao): Rewrite the callers of this function to save the UIImage
  // representation in the gfx::Image.  If we're generating it, we might as well
  // hold on to it.
  const gfx::ImageSkiaRep& image_skia_rep = skia->GetRepresentation(1.0f);
  if (image_skia_rep.scale() != 1.0f)
    return nullptr;

  UIImage* image = UIImageFromImageSkiaRep(image_skia_rep);
  return Get1xPNGBytesFromUIImage(image);
}

ImageSkia ImageSkiaFromPNG(
    const std::vector<gfx::ImagePNGRep>& image_png_reps) {
  // iOS does not expose libpng, so conversion from PNG to ImageSkia must go
  // through UIImage.
  ImageSkia image_skia;
  for (const auto& image_png_rep : image_png_reps) {
    base::scoped_nsobject<UIImage> uiimage(
        CreateUIImageFromImagePNGRep(image_png_rep));
    gfx::ImageSkiaRep image_skia_rep =
        ImageSkiaRepOfScaleFromUIImage(uiimage, image_png_rep.scale);
    if (!image_skia_rep.is_null())
      image_skia.AddRepresentation(image_skia_rep);
  }
  return image_skia;
}

UIImage* UIImageOfImageRepCocoaTouch(const ImageRepCocoaTouch* image_rep) {
  return image_rep->image();
}

std::unique_ptr<ImageRep> MakeImageRepCocoaTouch(UIImage* image) {
  return std::make_unique<internal::ImageRepCocoaTouch>(image);
}

}  // namespace internal

Image::Image(UIImage* image) {
  if (image) {
    storage_ = new internal::ImageStorage(Image::kImageRepCocoaTouch);
    AddRepresentation(std::make_unique<internal::ImageRepCocoaTouch>(image));
  }
}

}  // namespace gfx
