// Copyright 2015 Google Inc. 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/debug/trace_event.h"
#include "base/logging.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)
    : ImageDataDecoder(resource_provider),
      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;
}

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");
  UNREFERENCED_PARAMETER(info);
  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) {
  UNREFERENCED_PARAMETER(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");
  UNREFERENCED_PARAMETER(info);
  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_);
  }

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

  if (!AllocateImageData(
          math::Size(static_cast<int>(width), static_cast<int>(height)),
          has_alpha_)) {
    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 = 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 = image_data()->GetMemory() +
                      image_data()->GetDescriptor().pitch_in_bytes * row_index;

  png_bytep pixel = row_buffer;

  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
