/*
 * 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@google.com (Huibao Lin)
//
// CPU: Intel Sandybridge with HyperThreading (16 cores) dL1:32KB dL2:256KB
// Benchmark              Time(ns)    CPU(ns) Iterations
// -----------------------------------------------------
// BM_ConvertJpegToJpeg   13468318   13264241        100
// BM_ConvertJpegToWebp   85506401   85104136        100
// BM_ConvertPngToPng      2541468    2533139        275
// BM_ConvertPngToWebp     1013797    1010651        693
// BM_ConvertGifToPng     42850766   42661702        100
// BM_ConvertGifToWebp    31759667   31657212        100
// BM_ConvertWebpToWebp   31727731   31491286        100

#include "net/instaweb/rewriter/public/image.h"
#include "pagespeed/kernel/base/benchmark.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_message_handler.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/null_mutex.h"
#include "pagespeed/kernel/base/stdio_file_system.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/image_types.pb.h"
#include "pagespeed/kernel/image/image_util.h"

namespace net_instaweb {

namespace {

const char kTestData[] = "/net/instaweb/rewriter/testdata/";
const char kCuppa[] = "Cuppa.png";
const char kIronChef[] = "IronChef2.gif";
const char kPuzzle[] = "Puzzle.jpg";
const char kScenery[] = "Scenery.webp";

// The original quality of Puzzle.jpg is 97. Rewrite it to a lower
// quality.
const int kNewQuality = 80;

class TestImageRewrite {
 public:
  TestImageRewrite(const char* file_name,
                   net_instaweb::Image::CompressionOptions* options) :
      handler_(new net_instaweb::NullMutex),
      timer_(new net_instaweb::NullMutex, 0),
      options_(options),
      file_name_(file_name) {
  }

  bool Initialize(net_instaweb::ImageType type) {
    expected_output_image_type_ = type;
    GoogleString file_path = StrCat(net_instaweb::GTestSrcDir(), kTestData,
                                    file_name_);
    return file_system_.ReadFile(file_path.c_str(), &contents_,
                                 &handler_);
  }

  void Rewrite() {
    // Reset conversions_attempted. This field is increased each time
    // the image is rewritten, and the image will not be rewritten if
    // this field is greater than the limit.
    options_->conversions_attempted = 0;

    // Rewrite the image.
    net_instaweb::Image* image =
        NewImage(contents_, file_name_, "/NOT-USED",
                 options_, &timer_, &handler_);
    image->Contents();
    EXPECT_EQ(expected_output_image_type_, image->image_type());
    EXPECT_NE(contents_.length(), image->output_size());
  }

 private:
  net_instaweb::StdioFileSystem file_system_;
  net_instaweb::MockMessageHandler handler_;
  net_instaweb::MockTimer timer_;
  net_instaweb::Image::CompressionOptions* options_;
  net_instaweb::ImageType expected_output_image_type_;
  const char* file_name_;
  GoogleString contents_;
};

static void BM_ConvertJpegToJpeg(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.recompress_jpeg = true;
  options.jpeg_quality = kNewQuality;

  TestImageRewrite test_rewrite(kPuzzle, &options);
  ASSERT_TRUE(test_rewrite.Initialize(net_instaweb::IMAGE_JPEG));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertJpegToJpeg);

static void BM_ConvertJpegToWebp(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.preferred_webp = pagespeed::image_compression::WEBP_LOSSY;
  options.convert_jpeg_to_webp = true;
  options.webp_quality = kNewQuality;

  TestImageRewrite test_rewrite(kPuzzle, &options);
  ASSERT_TRUE(test_rewrite.Initialize(net_instaweb::IMAGE_WEBP));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertJpegToWebp);

static void BM_ConvertPngToPng(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.recompress_png = true;

  TestImageRewrite test_rewrite(kCuppa, &options);
  ASSERT_TRUE(test_rewrite.Initialize(net_instaweb::IMAGE_PNG));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertPngToPng);

static void BM_ConvertPngToWebp(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.preferred_webp = pagespeed::image_compression::WEBP_LOSSLESS;
  options.allow_webp_alpha = true;
  options.preserve_lossless = true;

  TestImageRewrite test_rewrite(kCuppa, &options);
  ASSERT_TRUE(test_rewrite.Initialize(
      net_instaweb::IMAGE_WEBP_LOSSLESS_OR_ALPHA));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertPngToWebp);

static void BM_ConvertGifToPng(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.convert_gif_to_png = true;

  TestImageRewrite test_rewrite(kIronChef, &options);
  ASSERT_TRUE(test_rewrite.Initialize(net_instaweb::IMAGE_PNG));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertGifToPng);

// To convert a GIF image to WebP we actually convert the GIF image to PNG,
// and then from PNG to WebpP.
static void BM_ConvertGifToWebp(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.preferred_webp = pagespeed::image_compression::WEBP_LOSSLESS;
  options.allow_webp_alpha = true;
  options.preserve_lossless = true;
  options.convert_gif_to_png = true;

  TestImageRewrite test_rewrite(kIronChef, &options);
  ASSERT_TRUE(test_rewrite.Initialize(
      net_instaweb::IMAGE_WEBP_LOSSLESS_OR_ALPHA));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertGifToWebp);

static void BM_ConvertWebpToWebp(int iters) {
  net_instaweb::Image::CompressionOptions options;
  options.preferred_webp = pagespeed::image_compression::WEBP_LOSSLESS;
  options.recompress_webp = true;
  options.webp_quality = kNewQuality;

  TestImageRewrite test_rewrite(kScenery, &options);
  ASSERT_TRUE(test_rewrite.Initialize(net_instaweb::IMAGE_WEBP));
  for (int i = 0; i < iters; ++i) {
    test_rewrite.Rewrite();
  }
}
BENCHMARK(BM_ConvertWebpToWebp);

}  // namespace

}  // namespace net_instaweb
