// Copyright 2018 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 "starboard/shared/libjpeg/jpeg_image_decoder.h"

#include <setjmp.h>

#include <algorithm>
#include <vector>

#include "starboard/configuration.h"
#include "starboard/linux/shared/decode_target_internal.h"
#include "starboard/log.h"

// Inhibit C++ name-mangling for libjpeg functions.
extern "C" {
#include "third_party/libjpeg/jpeglib.h"
#include "third_party/libjpeg/jpegint.h"
}

namespace starboard {
namespace shared {
namespace libjpeg {

namespace {

JDIMENSION kInvalidHeight = 0xFFFFFF;

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;
}

bool ReadHeader(jpeg_decompress_struct* info) {
  if (jpeg_read_header(info, true) != JPEG_HEADER_OK) {
    return false;
  }

  return true;
}

bool StartDecompress(jpeg_decompress_struct* info) {
  // jpeg_has_multiple_scans() returns TRUE if the incoming image file has more
  // than one scan.
  info->buffered_image = jpeg_has_multiple_scans(info);

  // TODO: switch libjpeg version to support JCS_RGBA_8888 output.
  info->out_color_space = JCS_RGB;

  // Compute output image dimensions
  jpeg_calc_output_dimensions(info);

  if (!jpeg_start_decompress(info)) {
    SB_LOG(WARNING) << "Start decompressor failed.";
    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_t* 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 ReadLines(jpeg_decompress_struct* info,
               SbDecodeTargetFormat decode_target_format,
               uint8_t* image_data) {
  // 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_t* pixel_data = image_data + info->image_width * 4 * row_index;

    JSAMPLE* sample_buffer = *buffer;
    switch (decode_target_format) {
      case kSbDecodeTargetFormat1PlaneRGBA:
        FillRow<0, 1, 2, 3>(static_cast<int>(info->image_width), pixel_data,
                            sample_buffer);
        break;
      case kSbDecodeTargetFormat1PlaneBGRA:
        FillRow<2, 1, 0, 3>(static_cast<int>(info->image_width), pixel_data,
                            sample_buffer);
        break;
      case kSbDecodeTargetFormat2PlaneYUVNV12:
      case kSbDecodeTargetFormat3PlaneYUVI420:
#if SB_API_VERSION >= 10
      case kSbDecodeTargetFormat3Plane10BitYUVI420:
#endif  // SB_API_VERSION >= 10
#if SB_API_VERSION >= 6
      case kSbDecodeTargetFormat1PlaneUYVY:
#endif  // SB_API_VERSION >= 6
      case kSbDecodeTargetFormatInvalid:
        SB_NOTREACHED();
        break;
    }
  }

  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 DecodeProgressiveJPEG(jpeg_decompress_struct* info,
                           SbDecodeTargetFormat decode_target_format,
                           uint8_t* image_data) {
  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(info, decode_target_format, image_data)) {
      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.
      SB_DCHECK(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;
}

}  // namespace

SbDecodeTarget Decode(SbDecodeTargetGraphicsContextProvider* context_provider,
                      SbDecodeTargetFormat decode_target_format,
                      const uint8_t* data,
                      size_t input_byte) {
  jpeg_decompress_struct info = {};
  jpeg_source_mgr source_manager = {};
  jpeg_error_mgr error_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;

  // |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.
  // warning C4611: interaction between '_setjmp' and C++ object destruction is
  // non-portable.
  if (setjmp(jump_buffer)) {
    // image data is empty.
    SB_DLOG(WARNING) << "Decoder encounters an error.";
    return kSbDecodeTargetInvalid;
  }

  // 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 (!ReadHeader(&info)) {
    // Data is not enough for decoding the header.
    return kSbDecodeTargetInvalid;
  }

  if (!StartDecompress(&info)) {
    return kSbDecodeTargetInvalid;
  }

  std::vector<uint8_t> decoded_data(info.image_width * info.image_height * 4);

  if (info.buffered_image) {  // Progressive JPEG.
    if (!DecodeProgressiveJPEG(&info, decode_target_format,
                               decoded_data.data())) {
      return kSbDecodeTargetInvalid;
    }
  } else if (!ReadLines(&info, decode_target_format,
                        decoded_data.data())) {  // Baseline sequential JPEG.
    return kSbDecodeTargetInvalid;
  }

  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.
    SB_DLOG(WARNING) << "Data source requests suspension of the decompressor.";
  }

  auto width = info.image_width;
  auto height = info.image_height;
  jpeg_destroy_decompress(&info);

  return DecodeTargetCreate(context_provider, decoded_data.data(), width,
                            height, decode_target_format);
}

}  // namespace libjpeg
}  // namespace shared
}  // namespace starboard
