// 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/image_data_decoder.h"

#include <algorithm>
#include <memory>

#include "base/trace_event/trace_event.h"

namespace cobalt {
namespace loader {
namespace image {

namespace {
// Sanity check max size of data buffer.
uint32 kMaxBufferSizeBytes = 4 * 1024 * 1024L;
}  // namespace

ImageDataDecoder::ImageDataDecoder(
    render_tree::ResourceProvider* resource_provider,
    const base::DebuggerHooks& debugger_hooks)
    : resource_provider_(resource_provider),
      debugger_hooks_(debugger_hooks),
      state_(kWaitingForHeader) {
  CalculatePixelFormat();
}

void ImageDataDecoder::DecodeChunk(const uint8* data, size_t size) {
  TRACE_EVENT0("cobalt::loader::image_decoder",
               "ImageDataDecoder::DecodeChunk");
  size_t offset = 0;
  while (offset < size) {
    if (state_ == kError) {
      // Previous chunk causes an error, so there is nothing to do in here.
      return;
    }

    const uint8* input_bytes;
    size_t input_size;

    if (data_buffer_.empty()) {
      // Nothing in |data_buffer_|, so no data append needs to be performed.
      input_bytes = data + offset;
      input_size = size - offset;
      offset += input_size;
    } else {
      DCHECK_GE(kMaxBufferSizeBytes, data_buffer_.size());
      size_t fill_buffer_size =
          std::min(kMaxBufferSizeBytes - data_buffer_.size(), size - offset);

      // Append new data to data_buffer
      data_buffer_.insert(data_buffer_.end(), data + offset,
                          data + offset + fill_buffer_size);

      input_bytes = &data_buffer_[0];
      input_size = data_buffer_.size();
      offset += fill_buffer_size;
    }

    size_t decoded_size = DecodeChunkInternal(input_bytes, input_size);
    if (decoded_size == 0 && offset < size) {
      LOG(ERROR) << "Unable to make progress decoding image.";
      state_ = kError;
      return;
    }

    size_t undecoded_size = input_size - decoded_size;
    if (undecoded_size == 0) {
      // Remove all elements from the data_buffer.
      data_buffer_.clear();
    } else {
      if (data_buffer_.empty()) {
        if (undecoded_size > kMaxBufferSizeBytes) {
          LOG(ERROR) << "Max buffer size too small: " << undecoded_size
                     << "bytes required!";
          state_ = kError;
          return;
        }

        // |data_buffer_| is empty, so assign the undecoded data to it.
        data_buffer_.reserve(undecoded_size);
        data_buffer_.assign(data + offset - undecoded_size, data + offset);
      } else if (decoded_size != 0) {
        // |data_buffer_| is not empty, so erase the decoded data from it.
        data_buffer_.erase(
            data_buffer_.begin(),
            data_buffer_.begin() + static_cast<ptrdiff_t>(decoded_size));
      }
    }
  }
}

scoped_refptr<Image> ImageDataDecoder::FinishAndMaybeReturnImage() {
  TRACE_EVENT0("cobalt::loader::image_decoder",
               "ImageDataDecoder::FinishAndMaybeReturnImage");

  return FinishInternal();
}

std::unique_ptr<render_tree::ImageData> ImageDataDecoder::AllocateImageData(
    const math::Size& size, bool has_alpha) {
  DCHECK(resource_provider_->AlphaFormatSupported(
      render_tree::kAlphaFormatOpaque));
  DCHECK(resource_provider_->AlphaFormatSupported(
      render_tree::kAlphaFormatPremultiplied));
  auto image_data = resource_provider_->AllocateImageData(
      size, pixel_format(),
      has_alpha ? render_tree::kAlphaFormatPremultiplied
                : render_tree::kAlphaFormatOpaque);
  DLOG_IF(ERROR, !image_data) << "Failed to allocate image data ("
                              << size.width() << "x" << size.height() << ").";
  return image_data;
}

scoped_refptr<Image> ImageDataDecoder::CreateStaticImage(
    std::unique_ptr<render_tree::ImageData> image_data) {
  DCHECK(image_data);
  return new StaticImage(
      resource_provider()->CreateImage(std::move(image_data)));
}

void ImageDataDecoder::CalculatePixelFormat() {
  pixel_format_ = render_tree::kPixelFormatRGBA8;
  if (!resource_provider_->PixelFormatSupported(pixel_format_)) {
    pixel_format_ = render_tree::kPixelFormatBGRA8;
  }

  DCHECK(resource_provider_->PixelFormatSupported(pixel_format_));
}

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