// 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/common/log.h"
#include "starboard/configuration.h"
#include "starboard/linux/shared/decode_target_internal.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) {
  // no-op.
}

boolean SourceManagerFillInputBuffer(j_decompress_ptr 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) {
  return false;
}

void SourceManagerTermSource(j_decompress_ptr 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;
      // All the other decode formats are not supported.
      case kSbDecodeTargetFormat2PlaneYUVNV12:
      case kSbDecodeTargetFormat3PlaneYUVI420:
      case kSbDecodeTargetFormat3Plane10BitYUVI420:
#if SB_API_VERSION >= SB_DECODE_TARGET_FORMAT_YUVI420_COMPACT_API_VERSION
      case kSbDecodeTargetFormat3Plane10BitYUVI420Compact:
#endif  // SB_API_VERSION >= SB_DECODE_TARGET_FORMAT_YUVI420_COMPACT_API_VERSION
      case kSbDecodeTargetFormat1PlaneUYVY:
      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
