// Copyright 2016 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/nplb/blitter_pixel_tests/image.h"

#include <math.h>
#include <vector>

#include "starboard/blitter.h"
#include "starboard/file.h"
#include "starboard/log.h"
#include "third_party/libpng/png.h"

#if SB_HAS(BLITTER)

namespace starboard {
namespace nplb {
namespace blitter_pixel_tests {

Image::Image(SbBlitterSurface surface) {
  SbBlitterSurfaceInfo surface_info;
  SB_CHECK(SbBlitterGetSurfaceInfo(surface, &surface_info));
  width_ = surface_info.width;
  height_ = surface_info.height;

  pixel_data_ = new uint8_t[width_ * height_ * 4];
  SB_CHECK(SbBlitterDownloadSurfacePixels(
      surface, kSbBlitterPixelDataFormatRGBA8, width_ * 4, pixel_data_));
}

Image::Image(uint8_t* passed_pixel_data, int width, int height) {
  pixel_data_ = passed_pixel_data;
  width_ = width;
  height_ = height;
}

namespace {
// Helper function for reading PNG files.
void PNGReadPlatformFile(png_structp png,
                         png_bytep buffer,
                         png_size_t buffer_size) {
  // Casting between two pointer types.
  SbFile in_file = reinterpret_cast<SbFile>(png_get_io_ptr(png));

  int bytes_to_read = buffer_size;
  char* current_read_pos = reinterpret_cast<char*>(buffer);
  while (bytes_to_read > 0) {
    int bytes_read = SbFileRead(in_file, current_read_pos, bytes_to_read);
    SB_CHECK(bytes_read > 0);
    bytes_to_read -= bytes_read;
    current_read_pos += bytes_read;
  }
}

}  // namespace

Image::Image(const std::string& png_path) {
  // Much of this PNG loading code is based on a section from the libpng manual:
  // http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3
  SbFile in_file = OpenFileForReading(png_path);
  if (!SbFileIsValid(in_file)) {
    SB_DLOG(ERROR) << "Error opening file for reading: " << png_path;
    SB_NOTREACHED();
  }

  uint8_t header[8];
  int bytes_to_read = sizeof(header);
  char* current_read_pos = reinterpret_cast<char*>(header);
  while (bytes_to_read > 0) {
    int bytes_read = SbFileRead(in_file, current_read_pos, bytes_to_read);
    SB_CHECK(bytes_read > 0);
    bytes_to_read -= bytes_read;
    current_read_pos += bytes_read;
  }

  SB_CHECK(!png_sig_cmp(header, 0, 8)) << "Invalid PNG header.";

  // Set up a libpng context for reading images.
  png_structp png =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  SB_CHECK(png);

  // Create a structure to contain metadata about the image.
  png_infop png_metadata = png_create_info_struct(png);
  SB_DCHECK(png_metadata);

  // libpng expects to longjump to png->jmpbuf if it encounters an error.
  // According to longjmp's documentation, this implies that stack unwinding
  // will occur in that case, though C++ objects with non-trivial destructors
  // will not be called.  This is fine though, since we abort upon errors here.
  // If alternative behavior is desired, custom error and warning handler
  // functions can be passed into the png_create_read_struct() call above.
  if (setjmp(png->jmpbuf)) {
    SB_NOTREACHED() << "libpng encountered an error during encoding.";
  }

  // Set up for file i/o.
  png_set_read_fn(png, reinterpret_cast<void*>(in_file), &PNGReadPlatformFile);
  // Tell png we already read 8 bytes.
  png_set_sig_bytes(png, 8);
  // Read the image info.
  png_read_info(png, png_metadata);

  // Transform PNGs into a canonical RGBA form, in order to simplify the process
  // of reading png files of varying formats.  Of course, if we would like to
  // maintain data in formats other than RGBA, this logic should be adjusted.
  {
    if (png_get_bit_depth(png, png_metadata) == 16) {
      png_set_strip_16(png);
    }

    png_byte color = png_get_color_type(png, png_metadata);

    if (color == PNG_COLOR_TYPE_GRAY &&
        png_get_bit_depth(png, png_metadata) < 8) {
      png_set_expand_gray_1_2_4_to_8(png);
    }

    // Convert from grayscale or palette to color.
    if (!(color & PNG_COLOR_MASK_COLOR)) {
      png_set_gray_to_rgb(png);
    } else if (color == PNG_COLOR_TYPE_PALETTE) {
      png_set_palette_to_rgb(png);
    }

    // Add an alpha channel if missing.
    if (!(color & PNG_COLOR_MASK_ALPHA)) {
      png_set_add_alpha(png, 0xff /* opaque */, PNG_FILLER_AFTER);
    }
  }

  // End transformations. Get the updated info, and then verify.
  png_read_update_info(png, png_metadata);
  SB_DCHECK(png_get_color_type(png, png_metadata) == PNG_COLOR_TYPE_RGBA);
  SB_DCHECK(png_get_bit_depth(png, png_metadata) == 8);

  width_ = png_get_image_width(png, png_metadata);
  height_ = png_get_image_height(png, png_metadata);

  int pitch_in_bytes = width_ * 4;

  pixel_data_ = new uint8_t[height_ * pitch_in_bytes];
  std::vector<png_bytep> rows(height_);
  for (int i = 0; i < height_; ++i) {
    rows[i] = pixel_data_ + i * pitch_in_bytes;
  }
  png_read_image(png, &rows[0]);

  // Time to clean up.  First create a structure to read image metadata (like
  // comments) from the end of the png file, then read the remaining data in
  // the png file, and then finally release our context and close the file.
  png_infop end = png_create_info_struct(png);
  SB_DCHECK(end);

  // Read the end data in the png file.
  png_read_end(png, end);

  // Release our png reading context and associated info structs.
  png_destroy_read_struct(&png, &png_metadata, &end);

  SB_CHECK(SbFileClose(in_file));
}

Image::~Image() {
  delete[] pixel_data_;
}

bool Image::CanOpenFile(const std::string& path) {
  SbFile in_file = OpenFileForReading(path);
  if (!SbFileIsValid(in_file)) {
    return false;
  }
  SB_CHECK(SbFileClose(in_file));
  return true;
}

Image Image::Diff(const Image& other,
                  int pixel_test_value_fuzz,
                  bool* is_same) const {
  SB_DCHECK(pixel_test_value_fuzz >= 0);

  // Image dimensions involved in the diff must match each other.
  if (width_ != other.width_ || height_ != other.height_) {
    SB_LOG(ERROR) << "Test images have different dimensions.";
    SB_NOTREACHED();
  }

  *is_same = true;

  int num_pixels = width_ * height_;
  int num_bytes = num_pixels * 4;
  // Setup our destination diff image data that will eventually be returned.
  uint8_t* diff_pixel_data = new uint8_t[num_bytes];

  for (int i = 0; i < num_pixels; ++i) {
    int byte_offset = i * 4;
    bool components_differ = false;
    // Iterate through each color component and for each one test it to see if
    // it differs by more than |pixel_test_value_fuzz|.
    for (int c = 0; c < 4; ++c) {
      int index = byte_offset + c;
      int diff = pixel_data_[index] - other.pixel_data_[index];
      components_differ |= (diff < 0 ? -diff > pixel_test_value_fuzz
                                     : diff > pixel_test_value_fuzz);
    }

    // Mark the corresponding pixel in the diff image appropriately, depending
    // on the results of the test.

    if (components_differ) {
      // Mark differing pixels as opaque red.
      diff_pixel_data[byte_offset + 0] = 255;
      diff_pixel_data[byte_offset + 1] = 0;
      diff_pixel_data[byte_offset + 2] = 0;
      diff_pixel_data[byte_offset + 3] = 255;
      *is_same = false;
    } else {
      // Mark matching pixels as transparent white.
      diff_pixel_data[byte_offset + 0] = 255;
      diff_pixel_data[byte_offset + 1] = 255;
      diff_pixel_data[byte_offset + 2] = 255;
      diff_pixel_data[byte_offset + 3] = 0;
    }
  }

  return Image(diff_pixel_data, width_, height_);
}

Image Image::GaussianBlur(float sigma) const {
  SB_DCHECK(sigma >= 0);
  // While it is typical to set the window size to 3 times the standard
  // deviation because most of the Gaussian function fits within that range,
  // we use 2 here to increase performance.  We thus contain 95% of the
  // function's mass versus 99.7% if we used 3 times.
  int kernel_radius = static_cast<int>(sigma * 2.0f);
  int kernel_size = 1 + 2 * kernel_radius;
  int kernel_center = kernel_radius;

  // Allocate space for our small Gaussian kernel image.
  float* kernel = new float[kernel_size * kernel_size];

  // Compute the kernel image.  Go through each pixel of the kernel image and
  // calculate the value of the Gaussian function with |sigma| at that point.
  // We assume that the center of the image is located at
  // (|kernel_center|, |kernel_center|).
  float kernel_total = 0.0f;
  for (int y = 0; y < kernel_size; ++y) {
    for (int x = 0; x < kernel_size; ++x) {
      int diff_x = x - kernel_center;
      int diff_y = y - kernel_center;
      float distance_sq = diff_x * diff_x + diff_y * diff_y;
      int kernel_index = y * kernel_size + x;

      float kernel_value =
          (sigma == 0 ? 1 : exp(-distance_sq / (2 * sigma * sigma)));

      kernel[kernel_index] = kernel_value;
      kernel_total += kernel_value;
    }
  }
  // Normalize the function so that its volume is 1.
  for (int i = 0; i < kernel_size * kernel_size; ++i) {
    kernel[i] /= kernel_total;
  }

  // Allocate pixel data for our blurred results image.
  uint8_t* blur_pixel_data = new uint8_t[width_ * height_ * 4];

  // Setup some constants that will be accessed from the tight loop coming up.
  const uint8_t* pixel_data_end = pixel_data_ + width_ * height_ * 4;
  const int skip_row_bytes = width_ * 4 - kernel_size * 4;

  // Now convolve our Gaussian kernel over the |pixel_data_| and put the results
  // into |blur_pixel_data|.
  uint8_t* cur_dest = blur_pixel_data;
  for (int y = 0; y < height_; ++y) {
    for (int x = 0; x < width_; ++x) {
      // We keep intermediate convolution results as a float to maintain
      // precision until we're done accumulating values from the convolution
      // window.
      float cur_pixel[4];
      for (int i = 0; i < 4; ++i) {
        cur_pixel[i] = 0.0f;
      }

      // Setup pointers into the kernel image and the source image that we will
      // increment as we visit each pixel of the kernel image.
      float* kernel_value = kernel;
      int source_start_y = y - kernel_center;
      int source_start_x = x - kernel_center;
      const uint8_t* cur_src =
          pixel_data_ + (source_start_y * width_ + source_start_x) * 4;

      // Iterate over the kernel image.
      for (int k_y = 0; k_y < kernel_size; ++k_y, cur_src += skip_row_bytes) {
        for (int k_x = 0; k_x < kernel_size;
             ++k_x, cur_src += 4, ++kernel_value) {
          // Do not accumulate anything for source pixels that are outside of
          // the source image.  This implies that the edges of the destination
          // image will always have some transparency.
          if ((cur_src < pixel_data_) | (cur_src >= pixel_data_end)) {
            continue;
          }
          // Accumulate the destination value.
          for (int i = 0; i < 4; ++i) {
            cur_pixel[i] += *kernel_value * cur_src[i];
          }
        }
      }
      // Finally save the computed value to the destination image memory.
      for (int i = 0; i < 4; ++i) {
        cur_dest[i] = static_cast<uint8_t>(
            (cur_pixel[i] > 255.0f ? 255.0f : cur_pixel[i]) + 0.5f);
      }
      cur_dest += 4;
    }
  }

  delete[] kernel;

  return Image(blur_pixel_data, width_, height_);
}

namespace {
// Write PNG data to a vector to simplify memory management.
typedef std::vector<png_byte> PNGByteVector;

void PNGWriteFunction(png_structp png_ptr, png_bytep data, png_size_t length) {
  PNGByteVector* out_buffer =
      reinterpret_cast<PNGByteVector*>(png_get_io_ptr(png_ptr));
  // Append the data to the array using pointers to the beginning and end of the
  // buffer as the first and last iterators.
  out_buffer->insert(out_buffer->end(), data, data + length);
}
}  // namespace

void Image::WriteToPNG(const std::string& png_path) const {
  // Initialize png library and headers for writing.
  png_structp png =
      png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  SB_DCHECK(png);
  png_infop info = png_create_info_struct(png);
  SB_DCHECK(info);

  // if error encountered png will call longjmp(), so we set up a setjmp() here
  // with a failed assert to indicate an error in one of the png functions.
  if (setjmp(png->jmpbuf)) {
    png_destroy_write_struct(&png, &info);
    SB_NOTREACHED() << "libpng encountered an error during encoding.";
  }

  // Structure into which png data will be written.
  PNGByteVector png_buffer;

  // Set the write callback. Don't set the flush function, since there's no
  // need for buffered IO when writing to memory.
  png_set_write_fn(png, &png_buffer, &PNGWriteFunction, NULL);

  // Stuff and then write png header.
  png_set_IHDR(png, info, width_, height_,
               8,  // 8 bits per color channel.
               PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
               PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  png_write_info(png, info);

  // Write image bytes, row by row.
  png_bytep row = static_cast<png_bytep>(pixel_data_);
  for (int i = 0; i < height_; ++i) {
    png_write_row(png, row);
    row += width_ * 4;
  }

  png_write_end(png, NULL);
  png_destroy_write_struct(&png, &info);

  size_t num_bytes = png_buffer.size() * sizeof(PNGByteVector::value_type);

  SbFile out_file = SbFileOpen(png_path.c_str(),
                               kSbFileWrite | kSbFileCreateAlways, NULL, NULL);
  if (!SbFileIsValid(out_file)) {
    SB_DLOG(ERROR) << "Error opening file for writing: " << png_path;
    SB_NOTREACHED();
  }

  int bytes_remaining = num_bytes;
  char* data_pointer = reinterpret_cast<char*>(&(png_buffer[0]));
  while (bytes_remaining > 0) {
    int bytes_written = SbFileWrite(out_file, data_pointer, bytes_remaining);
    if (bytes_written == -1) {
      SB_LOG(ERROR) << "Error writing encoded image data to PNG file: "
                    << png_path;
      SB_NOTREACHED();
    }
    bytes_remaining -= bytes_written;
    data_pointer += bytes_written;
    SB_DCHECK(bytes_remaining >= 0);
  }

  SB_CHECK(SbFileClose(out_file));
}

SbFile Image::OpenFileForReading(const std::string& path) {
  return SbFileOpen(path.c_str(), kSbFileRead | kSbFileOpenOnly, NULL, NULL);
}

}  // namespace blitter_pixel_tests
}  // namespace nplb
}  // namespace starboard

#endif  // SB_HAS(BLITTER)
