// Copyright 2015 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/jpeg_image_decoder.h"

#include <algorithm>

#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "nb/memory_scope.h"
#include "third_party/libjpeg/jpegint.h"

namespace cobalt {
namespace loader {
namespace image {

namespace {

const JDIMENSION kInvalidHeight = 0xFFFFFF;
const JDIMENSION kDctScaleSize = 8;

JDIMENSION AlignUp(JDIMENSION value, JDIMENSION alignment) {
  return (value + alignment - 1) / alignment * alignment;
}

bool CanDecodeIntoYUV(const jpeg_decompress_struct& decompress_info) {
  auto comp_infos = decompress_info.cur_comp_info;

  // Only images encoded to YCbCr in three planes are supported.
  if (decompress_info.jpeg_color_space != JCS_YCbCr ||
      decompress_info.comps_in_scan != 3) {
    return false;
  }

  // Ensure that it is either YUV 420 or YUV 444.
  bool is_yuv_420 =
      comp_infos[0]->h_samp_factor == 2 && comp_infos[0]->v_samp_factor == 2 &&
      comp_infos[1]->h_samp_factor == 1 && comp_infos[1]->v_samp_factor == 1 &&
      comp_infos[2]->h_samp_factor == 1 && comp_infos[2]->v_samp_factor == 1 &&
      decompress_info.max_h_samp_factor == 2 &&
      decompress_info.max_v_samp_factor == 2;
  bool is_yuv_444 =
      comp_infos[0]->h_samp_factor == 1 && comp_infos[0]->v_samp_factor == 1 &&
      comp_infos[1]->h_samp_factor == 1 && comp_infos[1]->v_samp_factor == 1 &&
      comp_infos[2]->h_samp_factor == 1 && comp_infos[2]->v_samp_factor == 1 &&
      decompress_info.max_h_samp_factor == 1 &&
      decompress_info.max_v_samp_factor == 1;
  if (!is_yuv_420 && !is_yuv_444) {
    return false;
  }

  // The dimension of the image may not be a multiple of the sample factors,
  // this can happen when the sample factors are not 1.  In such case the
  // mapping of the u/v plane won't be even, because the mapping of the last
  // vertical line on the u/v plane will be different than the other vertical
  // lines.  Our renderer cannot handle this properly so we return false in this
  // case.
  if (decompress_info.image_width % decompress_info.max_h_samp_factor != 0 ||
      decompress_info.image_height % decompress_info.max_v_samp_factor != 0) {
    return false;
  }

  // Ensure that the DCT block size is expected.
  return comp_infos[0]->DCT_scaled_size == kDctScaleSize &&
         comp_infos[1]->DCT_scaled_size == kDctScaleSize &&
         comp_infos[2]->DCT_scaled_size == kDctScaleSize;
}

void ErrorManagerExit(j_common_ptr common_ptr) {
  // Returns the control to the setjmp point. The buffer which is filled by a
  // previous call to setjmp that contains information to store the environment
  // to that point.
  jmp_buf* buffer = static_cast<jmp_buf*>(common_ptr->client_data);
  longjmp(*buffer, 1);
}

void SourceManagerInitSource(j_decompress_ptr decompress_ptr) {
  SB_UNREFERENCED_PARAMETER(decompress_ptr);
  // no-op.
}

boolean SourceManagerFillInputBuffer(j_decompress_ptr decompress_ptr) {
  SB_UNREFERENCED_PARAMETER(decompress_ptr);
  // Normally, this function is called when we need to read more of the encoded
  // buffer into memory and a return false indicates that we have no data to
  // supply yet, but in our case, the encoded buffer is always in memory, so
  // this should never get called unless there is an error, in which case we
  // return false to indicate that.
  return false;
}

boolean SourceManagerResyncToRestart(j_decompress_ptr decompress_ptr,
                                     int desired) {
  SB_UNREFERENCED_PARAMETER(decompress_ptr);
  SB_UNREFERENCED_PARAMETER(desired);
  return false;
}

void SourceManagerTermSource(j_decompress_ptr decompress_ptr) {
  SB_UNREFERENCED_PARAMETER(decompress_ptr);
  // no-op.
}

void SourceManagerSkipInputData(j_decompress_ptr decompress_ptr,
                                long num_bytes) {  // NOLINT(runtime/int)
  // Since all our data that is required to be decoded should be in the buffer
  // already, trying to skip beyond it means that there is some kind of error or
  // corrupt input data. We acknowledge these error cases by setting
  // |bytes_in_buffer| to 0 which will result in a call to
  // SourceManagerFillInputBuffer() which will return false to indicate that an
  // error has occurred.
  size_t bytes_to_skip = std::min(decompress_ptr->src->bytes_in_buffer,
                                  static_cast<size_t>(num_bytes));
  decompress_ptr->src->bytes_in_buffer -= bytes_to_skip;
  decompress_ptr->src->next_input_byte += bytes_to_skip;
}

}  // namespace

JPEGImageDecoder::JPEGImageDecoder(
    render_tree::ResourceProvider* resource_provider,
    bool allow_image_decoding_to_multi_plane)
    : ImageDataDecoder(resource_provider),
      allow_image_decoding_to_multi_plane_(
          allow_image_decoding_to_multi_plane) {
  TRACE_EVENT0("cobalt::loader::image", "JPEGImageDecoder::JPEGImageDecoder()");
  TRACK_MEMORY_SCOPE("Rendering");
  memset(&info_, 0, sizeof(info_));
  memset(&source_manager_, 0, sizeof(source_manager_));

  info_.err = jpeg_std_error(&error_manager_);
  error_manager_.error_exit = &ErrorManagerExit;

  // Allocate and initialize JPEG decompression object.
  jpeg_create_decompress(&info_);

  info_.src = &source_manager_;

  // Set up callback functions.
  // Even some of them are no-op, we have to set them up for jpeg lib.
  source_manager_.init_source = SourceManagerInitSource;
  source_manager_.fill_input_buffer = SourceManagerFillInputBuffer;
  source_manager_.skip_input_data = SourceManagerSkipInputData;
  source_manager_.resync_to_restart = SourceManagerResyncToRestart;
  source_manager_.term_source = SourceManagerTermSource;
}

JPEGImageDecoder::~JPEGImageDecoder() {
  // Deallocate a JPEG decompression object.
  jpeg_destroy_decompress(&info_);
}

size_t JPEGImageDecoder::DecodeChunkInternal(const uint8* data,
                                             size_t input_byte) {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image",
               "JPEGImageDecoder::DecodeChunkInternal()");
  // |client_data| is available for use by application.
  jmp_buf jump_buffer;
  info_.client_data = &jump_buffer;

  // int setjmp(jmp_buf env) saves the current environment (ths program state),
  // at some point of program execution, into a platform-specific data
  // structure (jmp_buf) that can be used at some later point of program
  // execution by longjmp to restore the program state to that saved by setjmp
  // into jmp_buf. This process can be imagined to be a "jump" back to the point
  // of program execution where setjmp saved the environment. The return value
  // from setjmp indicates whether control reached that point normally or from a
  // call to longjmp. If the return is from a direct invocation, setjmp returns
  // 0. If the return is from a call to longjmp, setjmp returns a nonzero value.
  MSVC_PUSH_DISABLE_WARNING(4611);
  // warning C4611: interaction between '_setjmp' and C++ object destruction is
  // non-portable.
  if (setjmp(jump_buffer)) {
    // image data is empty.
    DLOG(WARNING) << "Decoder encounters an error.";
    set_state(kError);
    return 0;
  }
  MSVC_POP_WARNING();

  // Next byte to read from buffer.
  info_.src->next_input_byte = reinterpret_cast<const JOCTET*>(data);
  // Number of bytes remaining in buffer.
  info_.src->bytes_in_buffer = input_byte;

  if (state() == kWaitingForHeader) {
    if (!ReadHeader()) {
      // Data is not enough for decoding the header.
      return 0;
    }

    if (!StartDecompress()) {
      return 0;
    }
    set_state(kReadLines);
  }

  if (state() == kReadLines) {
    if (info_.buffered_image) {  // Progressive JPEG.
      if (!DecodeProgressiveJPEG()) {
        // The size of undecoded bytes is info_.src->bytes_in_buffer.
        return input_byte - info_.src->bytes_in_buffer;
      }
    } else if (!ReadLines()) {  // Baseline sequential JPEG.
      // The size of undecoded bytes is info_.src->bytes_in_buffer.
      return input_byte - info_.src->bytes_in_buffer;
    }

    if (!jpeg_finish_decompress(&info_)) {
      // In this case, we did read all the rows, so we don't really have to
      // treat this as an error.
      DLOG(WARNING) << "Data source requests suspension of the decompressor.";
    }
    set_state(kDone);
  }

  return input_byte;
}

scoped_refptr<Image> JPEGImageDecoder::FinishInternal() {
  if (state() != kDone) {
    decoded_image_data_.reset();
    raw_image_memory_.reset();
    return NULL;
  }

  SB_DCHECK(output_format_ != kOutputFormatInvalid);

  if (output_format_ == kOutputFormatRGBA ||
      output_format_ == kOutputFormatBGRA) {
    SB_DCHECK(decoded_image_data_);
    return CreateStaticImage(std::move(decoded_image_data_));
  }

  SB_DCHECK(output_format_ == kOutputFormatYUV);
  SB_DCHECK(raw_image_memory_);

  render_tree::MultiPlaneImageDataDescriptor descriptor(
      render_tree::kMultiPlaneImageFormatYUV3PlaneBT601FullRange);

  auto uv_plane_width = y_plane_width_ / h_sample_factor_;
  auto uv_plane_height = y_plane_height_ / v_sample_factor_;
  auto y_plane_size = y_plane_width_ * y_plane_height_;
  auto uv_plane_size = uv_plane_width * uv_plane_height;

  math::Size plane_size(info_.image_width, info_.image_height);
  descriptor.AddPlane(
      0, render_tree::ImageDataDescriptor(
             plane_size, render_tree::kPixelFormatY8,
             render_tree::kAlphaFormatPremultiplied, y_plane_width_));

  plane_size.SetSize(plane_size.width() / h_sample_factor_,
                     plane_size.height() / v_sample_factor_);
  descriptor.AddPlane(y_plane_size, render_tree::ImageDataDescriptor(
                                        plane_size, render_tree::kPixelFormatU8,
                                        render_tree::kAlphaFormatPremultiplied,
                                        uv_plane_width));
  descriptor.AddPlane(
      y_plane_size + uv_plane_size,
      render_tree::ImageDataDescriptor(plane_size, render_tree::kPixelFormatV8,
                                       render_tree::kAlphaFormatPremultiplied,
                                       uv_plane_width));

  auto image = resource_provider()->CreateMultiPlaneImageFromRawMemory(
      std::move(raw_image_memory_), descriptor);
  SB_DCHECK(image);
  return new StaticImage(image);
}

bool JPEGImageDecoder::ReadHeader() {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image", "JPEGImageDecoder::ReadHeader()");
  if (jpeg_read_header(&info_, true) == JPEG_SUSPENDED) {
    // Since |jpeg_read_header| doesn't have enough data, go back to the state
    // before reading the header.
    info_.global_state = DSTATE_START;
    return false;
  }

  if (allow_image_decoding_to_multi_plane_ && CanDecodeIntoYUV(info_)) {
    output_format_ = kOutputFormatYUV;
  } else if (pixel_format() == render_tree::kPixelFormatRGBA8) {
    output_format_ = kOutputFormatRGBA;
  } else if (pixel_format() == render_tree::kPixelFormatBGRA8) {
    output_format_ = kOutputFormatBGRA;
  } else {
    NOTREACHED() << "Unsupported pixel format: " << pixel_format();
  }
  if (output_format_ == kOutputFormatYUV) {
    info_.out_color_space = JCS_YCbCr;
    // Enable raw data output to avoid any copying.
    info_.raw_data_out = TRUE;

    auto y_info = info_.cur_comp_info[0];
    h_sample_factor_ = y_info->h_samp_factor;
    v_sample_factor_ = y_info->v_samp_factor;
    y_plane_width_ = AlignUp(y_info->width_in_blocks,
                             static_cast<JDIMENSION>(y_info->h_samp_factor)) *
                     kDctScaleSize;
    y_plane_height_ = AlignUp(y_info->height_in_blocks,
                              static_cast<JDIMENSION>(y_info->v_samp_factor)) *
                      kDctScaleSize;

    // Raw read mode requires that the output data is aligned to dct block size.
    auto aligned_size = math::Size(static_cast<int>(y_plane_width_),
                                   static_cast<int>(y_plane_height_));
    auto y_plane_size_in_bytes = aligned_size.width() * aligned_size.height();
    auto uv_plane_size_in_bytes =
        y_plane_size_in_bytes / h_sample_factor_ / v_sample_factor_;
    raw_image_memory_ = resource_provider()->AllocateRawImageMemory(
        y_plane_size_in_bytes + uv_plane_size_in_bytes * 2, sizeof(void*));
    return raw_image_memory_ != NULL;
  }
  // TODO: switch libjpeg version to support JCS_RGBA_8888 output.
  info_.out_color_space = JCS_RGB;

  decoded_image_data_ =
      AllocateImageData(math::Size(static_cast<int>(info_.image_width),
                                   static_cast<int>(info_.image_height)),
                        false);
  return decoded_image_data_ != NULL;
}

bool JPEGImageDecoder::StartDecompress() {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image", "JPEGImageDecoder::StartDecompress()");
  // jpeg_has_multiple_scans() returns TRUE if the incoming image file has more
  // than one scan.
  info_.buffered_image = jpeg_has_multiple_scans(&info_);

  // Compute output image dimensions
  jpeg_calc_output_dimensions(&info_);

  if (!jpeg_start_decompress(&info_)) {
    LOG(WARNING) << "Start decompressor failed.";
    set_state(kError);
    return false;
  }

  return true;
}

// A baseline sequential JPEG is stored as one top-to-bottom scan of the image.
// Progressive JPEG divides the file into a series of scans. It is starting with
// a very low quality image, and then following scans gradually improve the
// quality.
// TODO: support displaying the low resolution image while decoding the
// progressive JPEG.
bool JPEGImageDecoder::DecodeProgressiveJPEG() {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image",
               "JPEGImageDecoder::DecodeProgressiveJPEG()");
  int status;
  do {
    // |jpeg_consume_input| decodes the input data as it arrives.
    status = jpeg_consume_input(&info_);
  } while (status == JPEG_REACHED_SOS || status == JPEG_ROW_COMPLETED ||
           status == JPEG_SCAN_COMPLETED);

  while (info_.output_scanline == kInvalidHeight ||
         info_.output_scanline <= info_.output_height) {
    if (info_.output_scanline == 0) {
      // Initialize for an output pass in buffered-image mode.
      // The |input_scan_number| indicates the scan of the image to be
      // processed.
      if (!jpeg_start_output(&info_, info_.input_scan_number)) {
        // Decompression is suspended.
        return false;
      }
    }

    if (info_.output_scanline == kInvalidHeight) {
      // Recover from the previous set flag.
      info_.output_scanline = 0;
    }

    if (!ReadLines()) {
      if (info_.output_scanline == 0) {
        // Data is not enough for one line scan, so flag the |output_scanline|
        // to make sure that we don't call |jpeg_start_output| multiple times
        // for the same scan.
        info_.output_scanline = kInvalidHeight;
      }
      return false;
    }

    if (info_.output_scanline >= info_.output_height) {
      // Finish up after an output pass in buffered-image mode.
      if (!jpeg_finish_output(&info_)) {
        // Decompression is suspended due to
        // input_scan_number <= output_scan_number and EOI is not reached.
        // The suspension will be recovered when more data are coming.
        return false;
      }

      // The output scan number is the notional scan being processed by the
      // output side. The decompressor will not allow output scan number to get
      // ahead of input scan number.
      DCHECK_GE(info_.input_scan_number, info_.output_scan_number);
      // This scan pass is done, so reset the output scanline.
      info_.output_scanline = 0;
      if (info_.input_scan_number == info_.output_scan_number) {
        // No more scan needed at this point.
        break;
      }
    }
  }

  // |jpeg_input_complete| tests for the end of image.
  if (!jpeg_input_complete(&info_)) {
    return false;
  }

  return true;
}

// Responsible for swizzeling and alpha-premultiplying a row of pixels.
template <int r, int g, int b, int a>
void FillRow(int width, uint8* dest, JSAMPLE* source) {
  for (int x = 0; x < width; ++x, source += 3, dest += 4) {
    dest[r] = source[0];
    dest[g] = source[1];
    dest[b] = source[2];
    dest[a] = 0xFF;
  }
}

bool JPEGImageDecoder::ReadYUVLines() {
  DCHECK(output_format_ == kOutputFormatYUV);
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image", "JPEGImageDecoder::ReadYUVLines()");

  while (info_.output_scanline < info_.output_height) {
    JSAMPROW y[kDctScaleSize * 2], u[kDctScaleSize], v[kDctScaleSize];
    JSAMPARRAY planes[3] = {y, u, v};

    auto offset = info_.output_scanline * y_plane_width_;
    auto y_plane_size = y_plane_width_ * y_plane_height_;
    auto uv_plane_size = y_plane_size / (h_sample_factor_ * v_sample_factor_);

    uint8* y_plane_addr = raw_image_memory_->GetMemory() + offset;
    uint8* u_plane_addr = raw_image_memory_->GetMemory() + y_plane_size +
                          offset / (h_sample_factor_ * v_sample_factor_);
    uint8* v_plane_addr = raw_image_memory_->GetMemory() + y_plane_size +
                          uv_plane_size +
                          offset / (h_sample_factor_ * v_sample_factor_);
    for (JDIMENSION i = 0; i < kDctScaleSize * v_sample_factor_; ++i) {
      y[i] = y_plane_addr + y_plane_width_ * i;
    }
    for (JDIMENSION i = 0; i < kDctScaleSize; ++i) {
      u[i] = u_plane_addr + y_plane_width_ / h_sample_factor_ * i;
      v[i] = v_plane_addr + y_plane_width_ / h_sample_factor_ * i;
    }
    auto size =
        jpeg_read_raw_data(&info_, planes, kDctScaleSize * v_sample_factor_);
    if (size != kDctScaleSize * v_sample_factor_) {
      return false;
    }
  }

  return true;
}

bool JPEGImageDecoder::ReadRgbaOrGbraLines() {
  DCHECK(output_format_ == kOutputFormatRGBA ||
         output_format_ == kOutputFormatBGRA);

  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image",
               "JPEGImageDecoder::ReadRgbaOrGbraLines()");

  // Creation of 2-D sample arrays which is for one row.
  // See the comments in jmemmgr.c.
  JSAMPARRAY buffer = (*info_.mem->alloc_sarray)(
      (j_common_ptr)&info_, JPOOL_IMAGE, info_.output_width * 4, 1);

  while (info_.output_scanline < info_.output_height) {
    // |info_.output_scanline| would be increased 1 after reading one row.
    int row_index = static_cast<int>(info_.output_scanline);

    // jpeg_read_scanlines() returns up to the maximum number of scanlines of
    // decompressed image data. This may be less than the number requested in
    // cases such as bottom of image, data source suspension, and operating
    // modes that emit multiple scanlines at a time. Image data should be
    // returned in top-to-bottom scanline order.
    // TODO: Investigate the performance improvements by processing
    // multiple pixel rows. It may have performance advantage to use values
    // larger than 1. For example, JPEG images often use 4:2:0 downsampling, and
    // in that case libjpeg needs to make an additional copy of half the image
    // pixels(see merged_2v_upsample()).
    if (jpeg_read_scanlines(&info_, buffer, 1) != 1) {
      return false;
    }

    // Write the decoded row pixels to image data.
    uint8* pixel_data =
        decoded_image_data_->GetMemory() +
        decoded_image_data_->GetDescriptor().pitch_in_bytes * row_index;

    JSAMPLE* sample_buffer = *buffer;
    switch (output_format_) {
      case kOutputFormatRGBA: {
        FillRow<0, 1, 2, 3>(static_cast<int>(info_.output_width), pixel_data,
                            sample_buffer);
      } break;
      case kOutputFormatBGRA: {
        FillRow<2, 1, 0, 3>(static_cast<int>(info_.output_width), pixel_data,
                            sample_buffer);
      } break;
      case kOutputFormatInvalid:
      case kOutputFormatYUV: {
        NOTREACHED();
      } break;
    }
  }

  return true;
}

bool JPEGImageDecoder::ReadLines() {
  return output_format_ == kOutputFormatYUV ? ReadYUVLines()
                                            : ReadRgbaOrGbraLines();
}

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