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

#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/console_log.h"
#include "nb/memory_scope.h"

namespace cobalt {
namespace loader {
namespace image {

namespace {

// Gamma constants.
const double kMaxGamma = 21474.83;
const double kDefaultGamma = 2.2;
const double kInverseGamma = 0.45455;

// Protect against large PNGs. See Mozilla's bug #251381 for more info.
const uint32 kMaxPNGSize = 1000000UL;

// Use fix point multiplier instead of integer division or floating point math.
// This multipler produces exactly the same result for all values in range 0 -
// 255.
const uint32 kFixPointOffset = 24;
const uint32 kFixPointShifted = 1U << kFixPointOffset;
const uint32 kFixPointMultiplier =
    static_cast<uint32>(1.0 / 255.0 * kFixPointShifted) + 1;

// Multiplies unsigned value by fixpoint value and converts back to unsigned.
uint32 FixPointUnsignedMultiply(uint32 fixed, uint32 alpha) {
  return (fixed * alpha * kFixPointMultiplier) >> kFixPointOffset;
}

// Call back functions from libpng
// static
void DecodingFailed(png_structp png, png_const_charp) {
  DLOG(WARNING) << "Decoding failed.";
  longjmp(png->jmpbuf, 1);
}

// static
void DecodingWarning(png_structp png, png_const_charp warning_msg) {
  DLOG(WARNING) << "Decoding warning message: " << warning_msg;
  // Mozilla did this, so we will too.
  // Convert a tRNS warning to be an error (see
  // http://bugzilla.mozilla.org/show_bug.cgi?id=251381 )
  if (!strncmp(warning_msg, "Missing PLTE before tRNS", 24)) {
    png_error(png, warning_msg);
  }
}

}  // namespace

PNGImageDecoder::PNGImageDecoder(
    render_tree::ResourceProvider* resource_provider,
    const base::DebuggerHooks& debugger_hooks)
    : ImageDataDecoder(resource_provider, debugger_hooks),
      png_(NULL),
      info_(NULL),
      has_alpha_(false),
      interlace_buffer_(0) {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image", "PNGImageDecoder::PNGImageDecoder()");

  png_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, DecodingFailed,
                                DecodingWarning);
  info_ = png_create_info_struct(png_);
  png_set_progressive_read_fn(png_, this, HeaderAvailable, RowAvailable,
                              DecodeDone);
}

size_t PNGImageDecoder::DecodeChunkInternal(const uint8* data, size_t size) {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image",
               "PNGImageDecoder::DecodeChunkInternal()");
  // 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(png_->jmpbuf)) {
    // image data is empty.
    DLOG(WARNING) << "Decoder encounters an error.";
    set_state(kError);
    return 0;
  }
MSVC_POP_WARNING();

  png_process_data(png_, info_, const_cast<png_bytep>(data), size);

  // All the data is decoded by libpng internally.
  return size;
}

scoped_refptr<Image> PNGImageDecoder::FinishInternal() {
  if (state() != kDone) {
    decoded_image_data_.reset();
    return NULL;
  }
  SB_DCHECK(decoded_image_data_);
  return CreateStaticImage(std::move(decoded_image_data_));
}

PNGImageDecoder::~PNGImageDecoder() {
  TRACE_EVENT0("cobalt::loader::image", "PNGImageDecoder::~PNGImageDecoder()");
  // Both are created at the same time. So they should be both zero
  // or both non-zero. Use && here to be safer.
  if (png_ && info_) {
    // png_destroy_read_struct() frees the memory associated with the read
    // png_struct struct that holds information from the given PNG file, the
    // associated png_info struct for holding the image information and png_info
    // struct for holding the information at end of the given PNG file.
    png_destroy_read_struct(&png_, &info_, 0);
  }

  delete[] interlace_buffer_;
  interlace_buffer_ = 0;
  info_ = NULL;
  png_ = NULL;
}

// Called when we have obtained the header information (including the size).
// static
void PNGImageDecoder::HeaderAvailable(png_structp png, png_infop info) {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image", "PNGImageDecoder::~PNGImageDecoder()");
  PNGImageDecoder* decoder =
      static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png));
  decoder->HeaderAvailableCallback();
}

// Called when a row is ready.
// static
void PNGImageDecoder::RowAvailable(png_structp png, png_bytep row_buffer,
                                   png_uint_32 row_index, int interlace_pass) {
  PNGImageDecoder* decoder =
      static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png));
  decoder->RowAvailableCallback(row_buffer, row_index);
}

// Called when decoding is done.
// static
void PNGImageDecoder::DecodeDone(png_structp png, png_infop info) {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image", "PNGImageDecoder::DecodeDone()");

  PNGImageDecoder* decoder =
      static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png));
  decoder->DecodeDoneCallback();
}

void PNGImageDecoder::HeaderAvailableCallback() {
  TRACK_MEMORY_SCOPE("Rendering");
  TRACE_EVENT0("cobalt::loader::image",
               "PNGImageDecoder::HeaderAvailableCallback()");
  DCHECK_EQ(state(), kWaitingForHeader);

  png_uint_32 width = png_get_image_width(png_, info_);
  png_uint_32 height = png_get_image_height(png_, info_);

  // Protect against large images.
  if (width > kMaxPNGSize || height > kMaxPNGSize) {
    DLOG(WARNING) << "Large PNG with width: " << width
                  << ", height: " << height;
    set_state(kError);
    longjmp(png_->jmpbuf, 1);
    return;
  }

  // A valid PNG image must contain an IHDR chunk, one or more IDAT chunks,
  // and an IEND chunk.
  int bit_depth;
  int color_type;
  int interlace_type;
  int compression_type;
  int filter_type;
  png_get_IHDR(png_, info_, &width, &height, &bit_depth, &color_type,
               &interlace_type, &compression_type, &filter_type);

  // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA.
  if (color_type == PNG_COLOR_TYPE_PALETTE ||
      (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)) {
    png_set_expand(png_);
  }

  png_bytep trns = 0;
  int trns_count = 0;
  if (png_get_valid(png_, info_, PNG_INFO_tRNS)) {
    png_get_tRNS(png_, info_, &trns, &trns_count, 0);
    png_set_expand(png_);
  }

  if (bit_depth == 16) {
    png_set_strip_16(png_);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(png_);
  }

  // Deal with gamma and keep it under our control.
  double gamma;
  if (png_get_gAMA(png_, info_, &gamma)) {
    if (gamma <= 0.0 || gamma > kMaxGamma) {
      gamma = kInverseGamma;
      png_set_gAMA(png_, info_, gamma);
    }
    png_set_gamma(png_, kDefaultGamma, gamma);
  } else {
    png_set_gamma(png_, kDefaultGamma, kInverseGamma);
  }

  if (interlace_type == PNG_INTERLACE_ADAM7) {
    // Notify libpng to send us rows for interlaced pngs.
    png_set_interlace_handling(png_);
    CLOG(WARNING, debugger_hooks()) << "Interlaced PNGs are not displayed "
                                       "properly in older versions of Cobalt";
  }

  // Updates |info_| to reflect any transformations that have been requested.
  // For example, rowbytes will be updated to handle expansion of an interlaced
  // image with png_read_update_info().
  png_read_update_info(png_, info_);
  int channels = png_get_channels(png_, info_);
  DCHECK(channels == 3 || channels == 4);

  has_alpha_ = (channels == 4);

  if (interlace_type == PNG_INTERLACE_ADAM7) {
    size_t size = channels * width * height;
    interlace_buffer_ = new png_byte[size];
    if (!interlace_buffer_) {
      DLOG(WARNING) << "Allocate interlace buffer failed.";
      set_state(kError);
      longjmp(png_->jmpbuf, 1);
      return;
    }
  }

  decoded_image_data_ = AllocateImageData(
      math::Size(static_cast<int>(width), static_cast<int>(height)),
      has_alpha_);
  if (!decoded_image_data_) {
    set_state(kError);
    longjmp(png_->jmpbuf, 1);
    return;
  }

  set_state(kReadLines);
}

// Responsible for swizzeling and alpha-premultiplying a row of pixels.
template <bool has_alpha, int r, int g, int b, int a>
void FillRow(int width, uint8* dest, png_bytep source) {
  const int color_channels = has_alpha ? 4 : 3;
  for (int x = 0; x < width; ++x, dest += 4, source += color_channels) {
    uint32 alpha = static_cast<uint32>(has_alpha ? source[3] : 255);

    dest[r] = static_cast<uint8>(
        has_alpha ? FixPointUnsignedMultiply(source[0], alpha) : source[0]);
    dest[g] = static_cast<uint8>(
        has_alpha ? FixPointUnsignedMultiply(source[1], alpha) : source[1]);
    dest[b] = static_cast<uint8>(
        has_alpha ? FixPointUnsignedMultiply(source[2], alpha) : source[2]);
    dest[a] = static_cast<uint8>(alpha);
  }
}

// This function is called for every row in the image.  If the image is
// interlacing, and you turned on the interlace handler, this function will be
// called for every row in every pass. Some of these rows will not be changed
// from the previous pass.
void PNGImageDecoder::RowAvailableCallback(png_bytep row_buffer,
                                           png_uint_32 row_index) {
  TRACK_MEMORY_SCOPE("Rendering");
  DCHECK_EQ(state(), kReadLines);

  // Nothing to do if the row is unchanged, or the row is outside
  // the image bounds: libpng may send extra rows, ignore them to
  // make our lives easier.
  if (!row_buffer) {
    return;
  }

  int color_channels = has_alpha_ ? 4 : 3;
  png_bytep row = row_buffer;

  int width = decoded_image_data_->GetDescriptor().size.width();
  // For non-NUll rows of interlaced images during progressive read,
  // png_progressive_combine_row() shall combine the data for the current row
  // with the previously processed row data.
  if (interlace_buffer_) {
    row = interlace_buffer_ + (row_index * color_channels * width);
    png_progressive_combine_row(png_, row, row_buffer);
  }

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

  png_bytep pixel = row;

  switch (pixel_format()) {
    case render_tree::kPixelFormatRGBA8: {
      if (has_alpha_) {
        FillRow<true, 0, 1, 2, 3>(width, pixel_data, pixel);
      } else {
        FillRow<false, 0, 1, 2, 3>(width, pixel_data, pixel);
      }
    } break;
    case render_tree::kPixelFormatBGRA8: {
      if (has_alpha_) {
        FillRow<true, 2, 1, 0, 3>(width, pixel_data, pixel);
      } else {
        FillRow<false, 2, 1, 0, 3>(width, pixel_data, pixel);
      }
    } break;
    case render_tree::kPixelFormatUYVY:
    case render_tree::kPixelFormatY8:
    case render_tree::kPixelFormatU8:
    case render_tree::kPixelFormatV8:
    case render_tree::kPixelFormatUV8:
    case render_tree::kPixelFormatInvalid: {
      NOTREACHED();
    } break;
  }
}

void PNGImageDecoder::DecodeDoneCallback() { set_state(kDone); }

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