// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "components/image_fetcher/ios/webp_decoder.h"

#import <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/ios/ios_util.h"
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace webp_transcode {
namespace {

class WebpDecoderDelegate : public WebpDecoder::Delegate {
 public:
  WebpDecoderDelegate() : image_([[NSMutableData alloc] init]) {}

  NSData* GetImage() const { return image_; }

  // WebpDecoder::Delegate methods.
  MOCK_METHOD1(OnFinishedDecoding, void(bool success));
  MOCK_METHOD2(SetImageFeatures,
               void(size_t total_size, WebpDecoder::DecodedImageFormat format));
  void OnDataDecoded(NSData* data) override { [image_ appendData:data]; }

 private:
  virtual ~WebpDecoderDelegate() {}

  base::scoped_nsobject<NSMutableData> image_;
};

class WebpDecoderTest : public testing::Test {
 public:
  WebpDecoderTest()
      : delegate_(new WebpDecoderDelegate),
        decoder_(new WebpDecoder(delegate_.get())) {}

  NSData* LoadImage(const base::FilePath& filename) {
    base::FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.AppendASCII("components/test/data/webp_transcode")
               .Append(filename);
    return
        [NSData dataWithContentsOfFile:base::SysUTF8ToNSString(path.value())];
  }

  std::vector<uint8_t>* DecompressData(NSData* data,
                                       WebpDecoder::DecodedImageFormat format) {
    base::ScopedCFTypeRef<CGDataProviderRef> provider(
        CGDataProviderCreateWithCFData((CFDataRef)data));
    base::ScopedCFTypeRef<CGImageRef> image;
    switch (format) {
      case WebpDecoder::JPEG:
        image.reset(CGImageCreateWithJPEGDataProvider(
            provider, nullptr, false, kCGRenderingIntentDefault));
        break;
      case WebpDecoder::PNG:
        image.reset(CGImageCreateWithPNGDataProvider(
            provider, nullptr, false, kCGRenderingIntentDefault));
        break;
      case WebpDecoder::TIFF:
        ADD_FAILURE() << "Data already decompressed";
        return nil;
      case WebpDecoder::DECODED_FORMAT_COUNT:
        ADD_FAILURE() << "Unknown format";
        return nil;
    }
    size_t width = CGImageGetWidth(image);
    size_t height = CGImageGetHeight(image);
    base::ScopedCFTypeRef<CGColorSpaceRef> color_space(
        CGColorSpaceCreateDeviceRGB());
    size_t bytes_per_pixel = 4;
    size_t bytes_per_row = bytes_per_pixel * width;
    size_t bits_per_component = 8;
    std::vector<uint8_t>* result =
        new std::vector<uint8_t>(width * height * bytes_per_pixel, 0);
    base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate(
        &result->front(), width, height, bits_per_component, bytes_per_row,
        color_space, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
    // Check that someting has been written in |result|.
    std::vector<uint8_t> zeroes(width * height * bytes_per_pixel, 0);
    EXPECT_NE(0, memcmp(&result->front(), &zeroes.front(), zeroes.size()))
        << "Decompression failed.";
    return result;
  }

  // Compares data, allowing an averaged absolute difference of 1.
  bool CompareUncompressedData(const uint8_t* ptr_1,
                               const uint8_t* ptr_2,
                               size_t size) {
    uint64_t difference = 0;
    for (size_t i = 0; i < size; ++i) {
      // Casting to int to avoid overflow.
      int error = abs(int(ptr_1[i]) - int(ptr_2[i]));
      EXPECT_GE(difference + error, difference)
          << "Image difference too big (overflow).";
      difference += error;
    }
    double average_difference = double(difference) / double(size);
    DLOG(INFO) << "Average image difference: " << average_difference;
    return average_difference < 1.5;
  }

  bool CheckCompressedImagesEqual(NSData* data_1,
                                  NSData* data_2,
                                  WebpDecoder::DecodedImageFormat format) {
    std::unique_ptr<std::vector<uint8_t>> uncompressed_1(
        DecompressData(data_1, format));
    std::unique_ptr<std::vector<uint8_t>> uncompressed_2(
        DecompressData(data_2, format));
    if (uncompressed_1->size() != uncompressed_2->size()) {
      DLOG(ERROR) << "Image sizes don't match";
      return false;
    }
    return CompareUncompressedData(&uncompressed_1->front(),
                                   &uncompressed_2->front(),
                                   uncompressed_1->size());
  }

  bool CheckTiffImagesEqual(NSData* image_1, NSData* image_2) {
    if ([image_1 length] != [image_2 length]) {
      DLOG(ERROR) << "Image lengths don't match";
      return false;
    }
    // Compare headers.
    const size_t kHeaderSize = WebpDecoder::GetHeaderSize();
    NSData* header_1 = [image_1 subdataWithRange:NSMakeRange(0, kHeaderSize)];
    NSData* header_2 = [image_2 subdataWithRange:NSMakeRange(0, kHeaderSize)];
    if (!header_1 || !header_2)
      return false;
    if (![header_1 isEqualToData:header_2]) {
      DLOG(ERROR) << "Headers don't match.";
      return false;
    }
    return CompareUncompressedData(
        static_cast<const uint8_t*>([image_1 bytes]) + kHeaderSize,
        static_cast<const uint8_t*>([image_2 bytes]) + kHeaderSize,
        [image_1 length] - kHeaderSize);
  }

 protected:
  scoped_refptr<WebpDecoderDelegate> delegate_;
  scoped_refptr<WebpDecoder> decoder_;
};

}  // namespace

TEST_F(WebpDecoderTest, DecodeToJpeg) {
  // Load a WebP image from disk.
  base::scoped_nsobject<NSData> webp_image(
      LoadImage(base::FilePath("test.webp")));
  ASSERT_TRUE(webp_image != nil);
  // Load reference image.
  base::scoped_nsobject<NSData> jpg_image(
      LoadImage(base::FilePath("test.jpg")));
  ASSERT_TRUE(jpg_image != nil);
  // Convert to JPEG.
  EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1);
  EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::JPEG))
      .Times(1);
  decoder_->OnDataReceived(webp_image);
  // Compare to reference image.
  EXPECT_TRUE(CheckCompressedImagesEqual(jpg_image, delegate_->GetImage(),
                                         WebpDecoder::JPEG));
}

TEST_F(WebpDecoderTest, DecodeToPng) {
  // Load a WebP image from disk.
  base::scoped_nsobject<NSData> webp_image(
      LoadImage(base::FilePath("test_alpha.webp")));
  ASSERT_TRUE(webp_image != nil);
  // Load reference image.
  base::scoped_nsobject<NSData> png_image(
      LoadImage(base::FilePath("test_alpha.png")));
  ASSERT_TRUE(png_image != nil);
  // Convert to PNG.
  EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1);
  EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::PNG))
      .Times(1);
  decoder_->OnDataReceived(webp_image);
  // Compare to reference image.
  EXPECT_TRUE(CheckCompressedImagesEqual(png_image, delegate_->GetImage(),
                                         WebpDecoder::PNG));
}

TEST_F(WebpDecoderTest, DecodeToTiff) {
  // Load a WebP image from disk.
  base::scoped_nsobject<NSData> webp_image(
      LoadImage(base::FilePath("test_small.webp")));
  ASSERT_TRUE(webp_image != nil);
  // Load reference image.
  base::scoped_nsobject<NSData> tiff_image(
      LoadImage(base::FilePath("test_small.tiff")));
  ASSERT_TRUE(tiff_image != nil);
  // Convert to TIFF.
  EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1);
  EXPECT_CALL(*delegate_,
              SetImageFeatures([tiff_image length], WebpDecoder::TIFF))
      .Times(1);
  decoder_->OnDataReceived(webp_image);
  // Compare to reference image.
  EXPECT_TRUE(CheckTiffImagesEqual(tiff_image, delegate_->GetImage()));
}

TEST_F(WebpDecoderTest, StreamedDecode) {
  // Load a WebP image from disk.
  base::scoped_nsobject<NSData> webp_image(
      LoadImage(base::FilePath("test.webp")));
  ASSERT_TRUE(webp_image != nil);
  // Load reference image.
  base::scoped_nsobject<NSData> jpg_image(
      LoadImage(base::FilePath("test.jpg")));
  ASSERT_TRUE(jpg_image != nil);
  // Convert to JPEG in chunks.
  EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1);
  EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::JPEG))
      .Times(1);
  const size_t kChunkSize = 10;
  unsigned int num_chunks = 0;
  while ([webp_image length] > kChunkSize) {
    base::scoped_nsobject<NSData> chunk(
        [webp_image subdataWithRange:NSMakeRange(0, kChunkSize)]);
    decoder_->OnDataReceived(chunk);
    webp_image.reset([webp_image
        subdataWithRange:NSMakeRange(kChunkSize,
                                     [webp_image length] - kChunkSize)]);
    ++num_chunks;
  }
  if ([webp_image length] > 0u) {
    decoder_->OnDataReceived(webp_image);
    ++num_chunks;
  }
  ASSERT_GT(num_chunks, 3u) << "Not enough chunks";
  // Compare to reference image.
  EXPECT_TRUE(CheckCompressedImagesEqual(jpg_image, delegate_->GetImage(),
                                         WebpDecoder::JPEG));
}

TEST_F(WebpDecoderTest, InvalidFormat) {
  EXPECT_CALL(*delegate_, OnFinishedDecoding(false)).Times(1);
  const char dummy_image[] = "(>'-')> <('-'<) ^('-')^ <('-'<) (>'-')>";
  base::scoped_nsobject<NSData> data(
      [[NSData alloc] initWithBytes:dummy_image length:arraysize(dummy_image)]);
  decoder_->OnDataReceived(data);
  EXPECT_EQ(0u, [delegate_->GetImage() length]);
}

TEST_F(WebpDecoderTest, DecodeAborted) {
  EXPECT_CALL(*delegate_, OnFinishedDecoding(false)).Times(1);
  decoder_->Stop();
  EXPECT_EQ(0u, [delegate_->GetImage() length]);
}

}  // namespace webp_transcode
