// Copyright 2017 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 "third_party/blink/renderer/core/html/canvas/image_element_base.h"

#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/loader/image_loader.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"

namespace blink {

// static
Image::ImageDecodingMode ImageElementBase::ParseImageDecodingMode(
    const AtomicString& async_attr_value) {
  if (async_attr_value.IsNull())
    return Image::kUnspecifiedDecode;

  const auto& value = async_attr_value.LowerASCII();
  if (value == "async")
    return Image::kAsyncDecode;
  if (value == "sync")
    return Image::kSyncDecode;
  return Image::kUnspecifiedDecode;
}

ImageResourceContent* ImageElementBase::CachedImage() const {
  return GetImageLoader().GetContent();
}

const Element& ImageElementBase::GetElement() const {
  return *GetImageLoader().GetElement();
}

bool ImageElementBase::IsSVGSource() const {
  return CachedImage() && IsA<SVGImage>(CachedImage()->GetImage());
}

bool ImageElementBase::IsImageElement() const {
  return CachedImage() && !IsA<SVGImage>(CachedImage()->GetImage());
}

scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas(
    SourceImageStatus* status,
    const FloatSize& default_object_size) {
  ImageResourceContent* image_content = CachedImage();
  if (!GetImageLoader().ImageComplete() || !image_content) {
    *status = kIncompleteSourceImageStatus;
    return nullptr;
  }

  if (image_content->ErrorOccurred()) {
    *status = kUndecodableSourceImageStatus;
    return nullptr;
  }

  scoped_refptr<Image> source_image = image_content->GetImage();
  if (auto* svg_image = DynamicTo<SVGImage>(source_image.get())) {
    UseCounter::Count(GetElement().GetDocument(), WebFeature::kSVGInCanvas2D);
    FloatSize image_size = svg_image->ConcreteObjectSize(default_object_size);
    source_image = SVGImageForContainer::Create(
        svg_image, image_size, 1,
        GetElement().GetDocument().CompleteURL(GetElement().ImageSourceURL()));
  }

  *status = kNormalSourceImageStatus;
  return source_image->ImageForDefaultFrame();
}

bool ImageElementBase::WouldTaintOrigin() const {
  return CachedImage() && !CachedImage()->IsAccessAllowed();
}

FloatSize ImageElementBase::ElementSize(
    const FloatSize& default_object_size,
    const RespectImageOrientationEnum respect_orientation) const {
  ImageResourceContent* image_content = CachedImage();
  if (!image_content || !image_content->HasImage())
    return FloatSize();
  Image* image = image_content->GetImage();
  if (auto* svg_image = DynamicTo<SVGImage>(image))
    return svg_image->ConcreteObjectSize(default_object_size);
  return FloatSize(image->Size(respect_orientation));
}

FloatSize ImageElementBase::DefaultDestinationSize(
    const FloatSize& default_object_size,
    const RespectImageOrientationEnum respect_orientation) const {
  return ElementSize(default_object_size, respect_orientation);
}

bool ImageElementBase::IsAccelerated() const {
  return false;
}

const KURL& ImageElementBase::SourceURL() const {
  return CachedImage()->GetResponse().CurrentRequestUrl();
}

bool ImageElementBase::IsOpaque() const {
  ImageResourceContent* image_content = CachedImage();
  if (!GetImageLoader().ImageComplete() || !image_content)
    return false;
  Image* image = image_content->GetImage();
  return image->CurrentFrameKnownToBeOpaque();
}

IntSize ImageElementBase::BitmapSourceSize() const {
  ImageResourceContent* image = CachedImage();
  if (!image)
    return IntSize();
  // This method is called by ImageBitmap when creating and cropping the image.
  // Return un-oriented size because the cropping must happen before
  // orienting.
  return image->IntrinsicSize(kDoNotRespectImageOrientation);
}

static bool HasDimensionsForImage(SVGImage* svg_image,
                                  base::Optional<IntRect> crop_rect,
                                  const ImageBitmapOptions* options) {
  if (!svg_image->ConcreteObjectSize(FloatSize()).IsEmpty())
    return true;
  if (crop_rect)
    return true;
  if (options->hasResizeWidth() && options->hasResizeHeight())
    return true;
  return false;
}

ScriptPromise ImageElementBase::CreateImageBitmap(
    ScriptState* script_state,
    base::Optional<IntRect> crop_rect,
    const ImageBitmapOptions* options,
    ExceptionState& exception_state) {
  ImageResourceContent* image_content = CachedImage();
  if (!image_content) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "No image can be retrieved from the provided element.");
    return ScriptPromise();
  }
  if (options->hasResizeWidth() && options->resizeWidth() == 0) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "The resize width dimension is equal to 0.");
    return ScriptPromise();
  }
  if (options->hasResizeHeight() && options->resizeHeight() == 0) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "The resize width dimension is equal to 0.");
    return ScriptPromise();
  }
  if (auto* svg_image = DynamicTo<SVGImage>(image_content->GetImage())) {
    if (!HasDimensionsForImage(svg_image, crop_rect, options)) {
      exception_state.ThrowDOMException(
          DOMExceptionCode::kInvalidStateError,
          "The image element contains an SVG image without intrinsic "
          "dimensions, and no resize options or crop region are "
          "specified.");
      return ScriptPromise();
    }
    // The following function only works on SVGImages (as checked above).
    return ImageBitmap::CreateAsync(this, crop_rect, script_state, options);
  }
  return ImageBitmapSource::FulfillImageBitmap(
      script_state, MakeGarbageCollected<ImageBitmap>(this, crop_rect, options),
      exception_state);
}

Image::ImageDecodingMode ImageElementBase::GetDecodingModeForPainting(
    PaintImage::Id new_id) {
  const bool content_transitioned =
      last_painted_image_id_ != PaintImage::kInvalidId &&
      new_id != PaintImage::kInvalidId && last_painted_image_id_ != new_id;
  last_painted_image_id_ = new_id;

  // If the image for the element was transitioned, and no preference has been
  // specified by the author, prefer sync decoding to avoid flickering the
  // element. Async decoding of this image would cause us to display
  // intermediate frames with no image while the decode is in progress which
  // creates a visual flicker in the transition.
  if (content_transitioned &&
      decoding_mode_ == Image::ImageDecodingMode::kUnspecifiedDecode)
    return Image::ImageDecodingMode::kSyncDecode;
  return decoding_mode_;
}

}  // namespace blink
