// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/loader/image/webp_image_decoder.h"

#include <utility>

#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/loader/image/animated_webp_image.h"
#include "starboard/configuration.h"
#include "starboard/memory.h"

namespace cobalt {
namespace loader {
namespace image {

WEBPImageDecoder::WEBPImageDecoder(
    render_tree::ResourceProvider* resource_provider,
    const base::DebuggerHooks& debugger_hooks)
    : ImageDataDecoder(resource_provider, debugger_hooks),
      internal_decoder_(NULL) {
  TRACE_EVENT0("cobalt::loader::image", "WEBPImageDecoder::WEBPImageDecoder()");
  // Initialize the configuration as empty.
  WebPInitDecoderConfig(&config_);
  // Skip the in-loop filtering.
  config_.options.bypass_filtering = 1;
  // Use faster pointwise upsampler.
  config_.options.no_fancy_upsampling = 1;
  // Don't use multi-threaded decoding.
  config_.options.use_threads = 0;
}

WEBPImageDecoder::~WEBPImageDecoder() {
  TRACE_EVENT0("cobalt::loader::image",
               "WEBPImageDecoder::~WEBPImageDecoder()");
  DeleteInternalDecoder();
}

size_t WEBPImageDecoder::DecodeChunkInternal(const uint8* data,
                                             size_t input_byte) {
  TRACE_EVENT0("cobalt::loader::image",
               "WEBPImageDecoder::DecodeChunkInternal()");
  if (state() == kWaitingForHeader) {
    if (!ReadHeader(data, input_byte)) {
      return 0;
    }

    if (config_.input.has_animation) {
      animated_webp_image_ = new AnimatedWebPImage(
          math::Size(config_.input.width, config_.input.height),
          !!config_.input.has_alpha, resource_provider(), debugger_hooks());
    } else {
      decoded_image_data_ = AllocateImageData(
          math::Size(config_.input.width, config_.input.height),
          !!config_.input.has_alpha);
      if (decoded_image_data_ == NULL) {
        return 0;
      }
      if (!CreateInternalDecoder()) {
        return 0;
      }
    }
    set_state(kReadLines);
  }

  if (state() == kReadLines) {
    if (config_.input.has_animation) {
      animated_webp_image_->AppendChunk(data, input_byte);
    } else {
      auto data_to_decode = data;
      auto bytes_to_decode = input_byte;

      // |cached_uncompressed_data_| is non-empty indicates that the last
      // WebPIUpdate() returns VP8_STATUS_SUSPENDED, and we have to concatenate
      // the data before send it to WebPIUpdate() again.  This should rarely
      // happen.
      if (!cached_uncompressed_data_.empty()) {
        cached_uncompressed_data_.insert(
            cached_uncompressed_data_.end(),
            reinterpret_cast<const char*>(data),
            reinterpret_cast<const char*>(data) + input_byte);
        data_to_decode =
            reinterpret_cast<const uint8*>(cached_uncompressed_data_.data());
        bytes_to_decode = cached_uncompressed_data_.size();
      }
      // Send the available data to the decoder without copying. Note that as
      // webp images are mostly used in the form of animated webp, the data sent
      // to DecodeChunkInternal() contains a whole webp image most of the time.
      // Not making an extra copy of the data inside the internal decoder is
      // more optimal in such casts, so WebPIUpdate() is used, instead of
      // WebPIAppend().  The latter makes a copying of the data inside the
      // internal decoder.
      // Returns VP8_STATUS_OK when the image is successfully decoded. Returns
      // VP8_STATUS_SUSPENDED when more data is expected, in such case we have
      // to cache the data already appended as required by WebPIUpdate().
      // Any other return codes indicate an error.
      VP8StatusCode status =
          WebPIUpdate(internal_decoder_, data_to_decode, bytes_to_decode);
      if (status == VP8_STATUS_OK) {
        DCHECK(decoded_image_data_);
        DCHECK(config_.output.u.RGBA.rgba);

        DCHECK_EQ(config_.output.u.RGBA.stride,
                  decoded_image_data_->GetDescriptor().pitch_in_bytes);
        set_state(kDone);
      } else if (status == VP8_STATUS_SUSPENDED) {
        // Only copying the data into |cached_uncompressed_data_| when it is
        // empty, as otherwise the data has already been appended into it before
        // calling WebPIUpdate().
        if (cached_uncompressed_data_.empty()) {
          cached_uncompressed_data_.assign(
              reinterpret_cast<const char*>(data),
              reinterpret_cast<const char*>(data) + input_byte);
        }
      } else {
        DLOG(ERROR) << "WebPIAppend error, status code: " << status;
        DeleteInternalDecoder();
        set_state(kError);
        return 0;
      }
    }
  }

  return input_byte;
}

scoped_refptr<Image> WEBPImageDecoder::FinishInternal() {
  if (config_.input.has_animation) {
    set_state(kDone);
    return animated_webp_image_;
  }
  if (state() != kDone) {
    decoded_image_data_.reset();
    return NULL;
  }
  SB_DCHECK(decoded_image_data_);
  return CreateStaticImage(std::move(decoded_image_data_));
}

bool WEBPImageDecoder::ReadHeader(const uint8* data, size_t size) {
  TRACE_EVENT0("cobalt::loader::image", "WEBPImageDecoder::ReadHeader()");
  // Retrieve features from the bitstream. The *features structure is filled
  // with information gathered from the bitstream.
  // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
  // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
  // features from headers. Returns error in other cases.
  VP8StatusCode status = WebPGetFeatures(data, size, &config_.input);
  if (status == VP8_STATUS_OK) {
    return true;
  } else if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
    // Data is not enough for decoding the header.
    return false;
  } else {
    DLOG(ERROR) << "WebPGetFeatures error, status code: " << status;
    set_state(kError);
    return false;
  }
}

bool WEBPImageDecoder::CreateInternalDecoder() {
  TRACE_EVENT0("cobalt::loader::image",
               "WEBPImageDecoder::CreateInternalDecoder()");
  bool has_alpha = !!config_.input.has_alpha;
  config_.output.colorspace = pixel_format() == render_tree::kPixelFormatRGBA8
                                  ? (has_alpha ? MODE_rgbA : MODE_RGBA)
                                  : (has_alpha ? MODE_bgrA : MODE_BGRA);

  auto image_data_descriptor = decoded_image_data_->GetDescriptor();
  config_.output.u.RGBA.rgba = decoded_image_data_->GetMemory();
  config_.output.u.RGBA.stride = image_data_descriptor.pitch_in_bytes;
  config_.output.u.RGBA.size = image_data_descriptor.pitch_in_bytes *
                               image_data_descriptor.size.height();
  config_.output.is_external_memory = 1;
  // Instantiate a new incremental decoder object with the requested
  // configuration.
  internal_decoder_ = WebPIDecode(NULL, 0, &config_);

  if (internal_decoder_ == NULL) {
    DLOG(WARNING) << "Create internal WEBP decoder failed.";
    set_state(kError);
    return false;
  }
  return true;
}

void WEBPImageDecoder::DeleteInternalDecoder() {
  TRACE_EVENT0("cobalt::loader::image",
               "WEBPImageDecoder::DeleteInternalDecoder()");
  if (internal_decoder_) {
    // Deletes the WebPIDecoder object and associated memory. Must always be
    // called if WebPIDecode succeeded.
    WebPIDelete(internal_decoder_);
    internal_decoder_ = NULL;
    WebPFreeDecBuffer(&config_.output);
  }
}

}  // namespace image
}  // namespace loader
}  // namespace cobalt
