/*
 * Copyright 2013 Google Inc.
 *
 * 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.
 */

// Author: Huibao Lin

#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_message_handler.h"
#include "pagespeed/kernel/base/null_mutex.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/image/image_resizer.h"
#include "pagespeed/kernel/image/jpeg_optimizer.h"
#include "pagespeed/kernel/image/png_optimizer.h"
#include "pagespeed/kernel/image/read_image.h"
#include "pagespeed/kernel/image/test_utils.h"
#include "pagespeed/kernel/image/webp_optimizer.h"

namespace {

// Pixel formats
using net_instaweb::MessageHandler;
using net_instaweb::MockMessageHandler;
using net_instaweb::NullMutex;
using pagespeed::image_compression::PixelFormat;
using pagespeed::image_compression::GRAY_8;
using pagespeed::image_compression::RGB_888;
using pagespeed::image_compression::RGBA_8888;
// Readers and writers
using pagespeed::image_compression::JpegCompressionOptions;
using pagespeed::image_compression::JpegScanlineWriter;
using pagespeed::image_compression::kPngSuiteTestDir;
using pagespeed::image_compression::kPngTestDir;
using pagespeed::image_compression::kResizedTestDir;
using pagespeed::image_compression::PngScanlineReaderRaw;
using pagespeed::image_compression::ReadTestFile;
using pagespeed::image_compression::ScanlineResizer;
using pagespeed::image_compression::ScanlineWriterInterface;
using pagespeed::image_compression::WebpConfiguration;
using pagespeed::image_compression::kMessagePatternPixelFormat;
using pagespeed::image_compression::kMessagePatternStats;
using pagespeed::image_compression::kMessagePatternUnexpectedEOF;
using pagespeed::image_compression::kMessagePatternWritingToWebp;

const size_t kPreserveAspectRatio =
    pagespeed::image_compression::ScanlineResizer::kPreserveAspectRatio;

// Three testing images: GRAY_8, RGB_888, and RGBA_8888.
// Size of these images is 32-by-32 pixels.
const char* kValidImages[] = {
    "basi0g04",
    "basi3p02",
    "basn6a16",
};

// Image of RGBA_8888 format. Size is 128-by-128 pixels.
const char kImagePagespeed[] = "pagespeed-128";
// Same content as pagespeed-128, but resized to 33-by-34 pixels.
const char kImagePageSpeed33x34[] = "pagespeed-33x34";
// Image with 4096-by-2048 pixels.
const char kLarge4096x2048[] = "large";

// Size of the output image [width, height]. The size of the input image
// is 32-by-32. We would like to test resizing ratios of both integers
// and non-integers.
const size_t kOutputSize[][2] = {
    {16, kPreserveAspectRatio},   // Shrink image by 2 times in both directions.
    {kPreserveAspectRatio, 8},    // Shrink image by 4 times in both directions.
    {3, 3},    // Shrink image by 32/3 times in both directions.
    {16, 25},  // Shrink image by [2, 32/25] times.
    {32, 5},   // Shrink image by [1, 32/5] times.
    {3, 32},   // Shrink image by [32/3, 1] times.
    {31, 31},  // Shrink image by [32/31, 32/31] times.
    {32, 32},  // Although the image did not shrink, the algorithm is exercised.
};

const size_t kValidImageCount = arraysize(kValidImages);
const size_t KOutputSizeCount = arraysize(kOutputSize);

class ScanlineResizerTest : public testing::Test {
 public:
  ScanlineResizerTest() :
      message_handler_(new NullMutex),
      reader_(&message_handler_),
      resizer_(&message_handler_),
      scanline_(NULL) {
  }

 protected:
  void InitializeReader(const char* file_name) {
    ASSERT_TRUE(ReadTestFile(kPngSuiteTestDir, file_name, "png",
                             &input_image_));
    ASSERT_TRUE(reader_.Initialize(input_image_.data(), input_image_.length()));
  }

  void ResizeAndValidateImage(const char* file_name, const GoogleString& image);


  MockMessageHandler message_handler_;
  PngScanlineReaderRaw reader_;
  ScanlineResizer resizer_;
  GoogleString input_image_;
  void* scanline_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ScanlineResizerTest);
};

// Read the gold file. Size of the gold file is embedded in its name.
// For example 'testdata/resized/basi0g04_w16_h16.png'.
bool ReadGoldImageToString(const char* file_name,
                           size_t width,
                           size_t height,
                           GoogleString* image_data) {
  GoogleString gold_file_name = StringPrintf("%s_w%d_h%d", file_name,
      static_cast<int>(width), static_cast<int>(height));
  return ReadTestFile(kResizedTestDir, gold_file_name.c_str(), "png",
                      image_data);
}

// Return JPEG writer for Gray_8, or WebP writer for RGB_888 or RGBA_8888.
ScanlineWriterInterface* CreateWriter(PixelFormat pixel_format,
                                      size_t width,
                                      size_t height,
                                      GoogleString* image_data,
                                      GoogleString* file_ext,
                                      MessageHandler* handler) {
  if (pixel_format == GRAY_8) {
    *file_ext = "jpg";
    JpegCompressionOptions jpeg_config;
    jpeg_config.lossy = true;
    jpeg_config.lossy_options.quality = 100;
    return reinterpret_cast<ScanlineWriterInterface*>(
        CreateScanlineWriter(pagespeed::image_compression::IMAGE_JPEG,
                             pixel_format, width, height, &jpeg_config,
                             image_data, handler));
  } else {
    *file_ext = "webp";
    WebpConfiguration webp_config;  // Use lossless by default
    return reinterpret_cast<ScanlineWriterInterface*>(
        CreateScanlineWriter(pagespeed::image_compression::IMAGE_WEBP,
                             pixel_format, width, height, &webp_config,
                             image_data, handler));
  }
}

// Make sure the resized results, include image size, pixel format, and pixel
// values, match the gold data. The gold data has the image size coded in the
// file name. For example, an image resized to 16-by-16 is
// third_party/pagespeed/kernel/image/testdata/resized/basi0g04_w16_h16.png
void ScanlineResizerTest::ResizeAndValidateImage(const char* file_name,
                                                 const GoogleString& image) {
  PngScanlineReaderRaw gold_reader(&message_handler_);
  for (size_t index_size = 0; index_size < KOutputSizeCount; ++index_size) {
    size_t width = kOutputSize[index_size][0];
    size_t height = kOutputSize[index_size][1];
    ASSERT_TRUE(reader_.Initialize(image.data(), image.length()));
    ASSERT_TRUE(resizer_.Initialize(&reader_, width, height));

    if (width == 0) width = height;
    if (height == 0) height = width;
    GoogleString gold_image;
    ASSERT_TRUE(ReadGoldImageToString(file_name, width, height, &gold_image));
    ASSERT_TRUE(gold_reader.Initialize(gold_image.data(), gold_image.length()));

    // Make sure the images sizes and the pixel formats are the same.
    ASSERT_EQ(gold_reader.GetImageWidth(), resizer_.GetImageWidth());
    ASSERT_EQ(gold_reader.GetImageHeight(), resizer_.GetImageHeight());
    ASSERT_EQ(gold_reader.GetPixelFormat(), resizer_.GetPixelFormat());

    while (resizer_.HasMoreScanLines() && gold_reader.HasMoreScanLines()) {
      uint8* resized_scanline = NULL;
      uint8* gold_scanline = NULL;
      ASSERT_TRUE(resizer_.ReadNextScanline(
          reinterpret_cast<void**>(&resized_scanline)));
      ASSERT_TRUE(gold_reader.ReadNextScanline(
          reinterpret_cast<void**>(&gold_scanline)));

      for (size_t i = 0; i < resizer_.GetBytesPerScanline(); ++i) {
        ASSERT_EQ(gold_scanline[i], resized_scanline[i]);
      }
    }

    // Make sure both the resizer and the reader have exhausted scanlines.
    ASSERT_FALSE(resizer_.HasMoreScanLines());
    ASSERT_FALSE(gold_reader.HasMoreScanLines());
  }
}

TEST_F(ScanlineResizerTest, Accuracy) {
  // Test accuracy of resizing for some images in PNG Suite. All images in this
  // suite have 32-by-32 pixels.
  for (size_t index_image = 0; index_image < kValidImageCount; ++index_image) {
    const char* file_name = kValidImages[index_image];
    ASSERT_TRUE(ReadTestFile(kPngSuiteTestDir, file_name, "png",
                             &input_image_));
    ResizeAndValidateImage(file_name, input_image_);
  }

  // Test accuracy of resizing for an image with 33-by-34 pixels.
  ASSERT_TRUE(ReadTestFile(kPngTestDir, kImagePageSpeed33x34, "png",
                           &input_image_));
  ResizeAndValidateImage(kImagePageSpeed33x34, input_image_);
}

// Resize the image and write the result to a JPEG or a WebP image.
TEST_F(ScanlineResizerTest, ResizeAndWrite) {
  message_handler_.AddPatternToSkipPrinting(kMessagePatternPixelFormat);
  message_handler_.AddPatternToSkipPrinting(kMessagePatternStats);
  message_handler_.AddPatternToSkipPrinting(kMessagePatternWritingToWebp);
  for (size_t index_image = 0; index_image < kValidImageCount; ++index_image) {
    const char* file_name = kValidImages[index_image];
    ASSERT_TRUE(ReadTestFile(kPngSuiteTestDir, file_name, "png",
                             &input_image_));

    for (size_t index_size = 0; index_size < KOutputSizeCount; ++index_size) {
      const size_t width = kOutputSize[index_size][0];
      const size_t height = kOutputSize[index_size][1];
      ASSERT_TRUE(reader_.Initialize(input_image_.data(),
                                     input_image_.length()));
      ASSERT_TRUE(resizer_.Initialize(&reader_, width, height));

      GoogleString output_image;
      GoogleString file_ext;
      net_instaweb::scoped_ptr<ScanlineWriterInterface> writer(
         CreateWriter(resizer_.GetPixelFormat(),
                      resizer_.GetImageWidth(),
                      resizer_.GetImageHeight(),
                      &output_image,
                      &file_ext,
                      &message_handler_));

      while (resizer_.HasMoreScanLines()) {
        ASSERT_TRUE(resizer_.ReadNextScanline(&scanline_));
        ASSERT_TRUE(writer->WriteNextScanline(scanline_));
      }

      ASSERT_TRUE(writer->FinalizeWrite());
    }
  }
}

// Both width and height are specified.
TEST_F(ScanlineResizerTest, InitializeWidthHeight) {
  size_t width = 20;
  size_t height = 10;
  InitializeReader(kValidImages[0]);
  ASSERT_TRUE(resizer_.Initialize(&reader_, width, height));
  EXPECT_EQ(width, resizer_.GetImageWidth());
  EXPECT_EQ(height, resizer_.GetImageHeight());
  EXPECT_EQ(reader_.GetPixelFormat(), resizer_.GetPixelFormat());
}

// Only height is specified.
TEST_F(ScanlineResizerTest, InitializeHeight) {
  size_t width = kPreserveAspectRatio;
  size_t height = 10;
  InitializeReader(kValidImages[0]);
  ASSERT_TRUE(resizer_.Initialize(&reader_, width, height));
  EXPECT_EQ(height, resizer_.GetImageWidth());
  EXPECT_EQ(height, resizer_.GetImageHeight());
}

// Only width is specified.
TEST_F(ScanlineResizerTest, InitializeWidth) {
  size_t width = 12;
  size_t height = kPreserveAspectRatio;
  InitializeReader(kValidImages[0]);
  ASSERT_TRUE(resizer_.Initialize(&reader_, width, height));
  EXPECT_EQ(width, resizer_.GetImageWidth());
  EXPECT_EQ(width, resizer_.GetImageHeight());
}

// The resizer is not initialized, so ReadNextScanline returns false.
TEST_F(ScanlineResizerTest, ReadNullScanline) {
#ifndef NDEBUG
  ASSERT_DEATH(resizer_.ReadNextScanline(&scanline_),
               "SCANLINE_RESIZER/SCANLINE_STATUS_INVOCATION_ERROR "
               "null reader or no more scanlines");
#else
  ASSERT_FALSE(resizer_.ReadNextScanline(&scanline_));
#endif
}

// The resizer has only one scanline, so ReadNextScanline returns false
// at the second call.
TEST_F(ScanlineResizerTest, ReadNextScanline) {
  InitializeReader(kValidImages[1]);
  ASSERT_TRUE(resizer_.Initialize(&reader_, 10, 1));
  ASSERT_TRUE(resizer_.ReadNextScanline(&scanline_));
#ifndef NDEBUG
  ASSERT_DEATH(resizer_.ReadNextScanline(&scanline_),
               "SCANLINE_RESIZER/SCANLINE_STATUS_INVOCATION_ERROR "
               "null reader or no more scanlines");
#else
  ASSERT_FALSE(resizer_.ReadNextScanline(&scanline_));
#endif
}

// The original image is truncated. Only 100 bytes are passed to the reader.
// The reader is able decode the image header, but not the pixels.
// The resizer should return false when the reader failes.
TEST_F(ScanlineResizerTest, BadReader) {
  message_handler_.AddPatternToSkipPrinting(kMessagePatternUnexpectedEOF);
  ASSERT_TRUE(ReadTestFile(kPngSuiteTestDir, kValidImages[0], "png",
                           &input_image_));
  ASSERT_TRUE(reader_.Initialize(input_image_.data(), 100));
  ASSERT_TRUE(resizer_.Initialize(&reader_, 10, 20));
  ASSERT_FALSE(resizer_.ReadNextScanline(&scanline_));
}

// The resizer is initialized twice and only a portion of scanlines are readed.
// The resizer should not have any error.
TEST_F(ScanlineResizerTest, PartialRead) {
  InitializeReader(kValidImages[0]);

  ASSERT_TRUE(resizer_.Initialize(&reader_, 10, 20));
  // Read only 1 scanline, although there are 20.
  EXPECT_TRUE(resizer_.ReadNextScanline(&scanline_));

  ASSERT_TRUE(resizer_.Initialize(&reader_, 10, 20));
  // Read only 2 scanlines, although there are 20.
  EXPECT_TRUE(resizer_.ReadNextScanline(&scanline_));
  EXPECT_TRUE(resizer_.ReadNextScanline(&scanline_));
}

// Resize the image by non-integer ratios.
TEST_F(ScanlineResizerTest, ResizeFractionalRatio) {
  const int new_width = 11;
  const int new_height = 19;
  ASSERT_TRUE(ReadTestFile(kPngTestDir, kImagePagespeed, "png", &input_image_));

  ASSERT_TRUE(reader_.Initialize(input_image_.data(), input_image_.length()));
  ASSERT_TRUE(resizer_.Initialize(&reader_, new_width, new_height));

  int num_rows = 0;
  while (resizer_.HasMoreScanLines()) {
    ASSERT_TRUE(resizer_.ReadNextScanline(&scanline_));
    ++num_rows;
  }
  EXPECT_EQ(new_height, num_rows);
}

TEST_F(ScanlineResizerTest, LargeImage) {
  ASSERT_TRUE(ReadTestFile(kPngTestDir, kLarge4096x2048, "png", &input_image_));
  ResizeAndValidateImage(kLarge4096x2048, input_image_);
}

}  // namespace
