| Index: ios/chrome/browser/webp_transcode/webp_decoder_unittest.mm
|
| diff --git a/ios/chrome/browser/webp_transcode/webp_decoder_unittest.mm b/ios/chrome/browser/webp_transcode/webp_decoder_unittest.mm
|
| deleted file mode 100644
|
| index e7b67f7da910b0be592815eea126361c67a9419e..0000000000000000000000000000000000000000
|
| --- a/ios/chrome/browser/webp_transcode/webp_decoder_unittest.mm
|
| +++ /dev/null
|
| @@ -1,296 +0,0 @@
|
| -// 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.
|
| -
|
| -#include "ios/chrome/browser/webp_transcode/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"
|
| -#include "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("ios/chrome/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) {
|
| -// TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235
|
| -#if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR
|
| - if (base::ios::IsRunningOnIOS9OrLater())
|
| - return;
|
| -#endif
|
| - // 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) {
|
| -// TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235
|
| -#if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR
|
| - if (base::ios::IsRunningOnIOS9OrLater())
|
| - return;
|
| -#endif
|
| - // 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) {
|
| -// TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235
|
| -#if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR
|
| - if (base::ios::IsRunningOnIOS9OrLater())
|
| - return;
|
| -#endif
|
| - // 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) {
|
| -// TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235
|
| -#if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR
|
| - if (base::ios::IsRunningOnIOS9OrLater())
|
| - return;
|
| -#endif
|
| - // 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
|
|
|