summaryrefslogtreecommitdiffstats
path: root/ios
diff options
context:
space:
mode:
Diffstat (limited to 'ios')
-rw-r--r--ios/chrome/DEPS1
-rw-r--r--ios/chrome/browser/net/image_fetcher.mm9
-rw-r--r--ios/chrome/ios_chrome.gyp1
-rw-r--r--ios/ios_tests_unit.gyp18
-rw-r--r--ios/web/ios_web.gyp16
-rw-r--r--ios/web/public/webp_decoder.h83
-rw-r--r--ios/web/public/webp_decoder.mm251
-rw-r--r--ios/web/public/webp_decoder_unittest.mm263
-rw-r--r--ios/web/test/data/test.jpgbin84820 -> 0 bytes
-rw-r--r--ios/web/test/data/test.webpbin30320 -> 0 bytes
-rw-r--r--ios/web/test/data/test_alpha.pngbin175667 -> 0 bytes
-rw-r--r--ios/web/test/data/test_alpha.webpbin92312 -> 0 bytes
-rw-r--r--ios/web/test/data/test_small.tiffbin4306 -> 0 bytes
-rw-r--r--ios/web/test/data/test_small.webpbin724 -> 0 bytes
14 files changed, 7 insertions, 635 deletions
diff --git a/ios/chrome/DEPS b/ios/chrome/DEPS
index fb23515..e6bb4b0 100644
--- a/ios/chrome/DEPS
+++ b/ios/chrome/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+components/leveldb_proto",
"+components/suggestions",
"+components/translate/core",
+ "+components/webp_transcode",
"+ios/public/provider/chrome",
"+ios/web/public",
"+net",
diff --git a/ios/chrome/browser/net/image_fetcher.mm b/ios/chrome/browser/net/image_fetcher.mm
index bff9639..2d45c01 100644
--- a/ios/chrome/browser/net/image_fetcher.mm
+++ b/ios/chrome/browser/net/image_fetcher.mm
@@ -10,8 +10,8 @@
#include "base/location.h"
#include "base/mac/scoped_nsobject.h"
#include "base/task_runner.h"
+#include "components/webp_transcode/webp_decoder.h"
#include "ios/web/public/web_thread.h"
-#include "ios/web/public/webp_decoder.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
@@ -19,7 +19,7 @@
namespace {
-class WebpDecoderDelegate : public web::WebpDecoder::Delegate {
+class WebpDecoderDelegate : public webp_transcode::WebpDecoder::Delegate {
public:
NSData* data() const { return decoded_image_; }
@@ -30,7 +30,7 @@ class WebpDecoderDelegate : public web::WebpDecoder::Delegate {
}
void SetImageFeatures(
size_t total_size,
- web::WebpDecoder::DecodedImageFormat format) override {
+ webp_transcode::WebpDecoder::DecodedImageFormat format) override {
decoded_image_.reset([[NSMutableData alloc] initWithCapacity:total_size]);
}
void OnDataDecoded(NSData* data) override {
@@ -50,7 +50,8 @@ static const char kWEBPMimeType[] = "image/webp";
base::scoped_nsobject<NSData> DecodeWebpImage(
const base::scoped_nsobject<NSData>& webp_image) {
scoped_refptr<WebpDecoderDelegate> delegate(new WebpDecoderDelegate);
- scoped_refptr<web::WebpDecoder> decoder(new web::WebpDecoder(delegate.get()));
+ scoped_refptr<webp_transcode::WebpDecoder> decoder(
+ new webp_transcode::WebpDecoder(delegate.get()));
decoder->OnDataReceived(webp_image);
DLOG_IF(ERROR, !delegate->data()) << "WebP image decoding failed.";
return base::scoped_nsobject<NSData>([delegate->data() retain]);
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index 0174556..fe3e2db 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -21,6 +21,7 @@
'../../components/components.gyp:leveldb_proto',
'../../components/components.gyp:suggestions',
'../../components/components.gyp:translate_core_browser',
+ '../../components/components.gyp:webp_transcode',
'../../net/net.gyp:net',
'../../skia/skia.gyp:skia',
'../../url/url.gyp:url_lib',
diff --git a/ios/ios_tests_unit.gyp b/ios/ios_tests_unit.gyp
index 64da0d6..3d33685 100644
--- a/ios/ios_tests_unit.gyp
+++ b/ios/ios_tests_unit.gyp
@@ -22,27 +22,9 @@
'sources': [
'web/browser_state_unittest.cc',
'web/navigation/navigation_item_impl_unittest.mm',
- 'web/public/webp_decoder_unittest.mm',
'web/string_util_unittest.cc',
'web/url_scheme_util_unittest.mm',
],
- 'actions': [
- {
- 'action_name': 'copy_test_data',
- 'variables': {
- 'test_data_files': [
- 'web/test/data/test.jpg',
- 'web/test/data/test.webp',
- 'web/test/data/test_alpha.webp',
- 'web/test/data/test_alpha.png',
- 'web/test/data/test_small.tiff',
- 'web/test/data/test_small.webp',
- ],
- 'test_data_prefix': 'ios',
- },
- 'includes': [ '../build/copy_test_data_ios.gypi' ],
- },
- ],
},
],
}
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp
index d256398..72833e8 100644
--- a/ios/web/ios_web.gyp
+++ b/ios/web/ios_web.gyp
@@ -14,7 +14,6 @@
'../..',
],
'dependencies': [
- 'webp_decoder',
'../../base/base.gyp:base',
'../../content/content.gyp:content_browser',
'../../net/net.gyp:net',
@@ -88,21 +87,6 @@
],
},
{
- 'target_name': 'webp_decoder',
- 'type': 'static_library',
- 'include_dirs': [
- '../..',
- ],
- 'dependencies': [
- '../../base/base.gyp:base',
- '../../third_party/libwebp/libwebp.gyp:libwebp_dec',
- ],
- 'sources': [
- 'public/webp_decoder.h',
- 'public/webp_decoder.mm',
- ],
- },
- {
'target_name': 'test_support_ios_web',
'type': 'static_library',
'dependencies': [
diff --git a/ios/web/public/webp_decoder.h b/ios/web/public/webp_decoder.h
deleted file mode 100644
index 8700718..0000000
--- a/ios/web/public/webp_decoder.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef IOS_WEB_PUBLIC_WEBP_DECODER_H_
-#define IOS_WEB_PUBLIC_WEBP_DECODER_H_
-
-#include "base/mac/scoped_nsobject.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "third_party/libwebp/webp/decode.h"
-
-@class NSData;
-
-namespace web {
-
-// Decodes a WebP image into either JPEG, PNG or uncompressed TIFF.
-class WebpDecoder : public base::RefCountedThreadSafe<WebpDecoder> {
- public:
- // Format of the decoded image.
- // This enum is used for UMA reporting, keep it in sync with the histogram
- // definition.
- enum DecodedImageFormat {
- JPEG = 1,
- PNG,
- TIFF,
- DECODED_FORMAT_COUNT
- };
-
- class Delegate : public base::RefCountedThreadSafe<WebpDecoder::Delegate> {
- public:
- virtual void OnFinishedDecoding(bool success) = 0;
- virtual void SetImageFeatures(size_t total_size, // In bytes.
- DecodedImageFormat format) = 0;
- virtual void OnDataDecoded(NSData* data) = 0;
-
- protected:
- friend class base::RefCountedThreadSafe<WebpDecoder::Delegate>;
- virtual ~Delegate() {}
- };
-
- explicit WebpDecoder(WebpDecoder::Delegate* delegate);
-
- // For tests.
- static size_t GetHeaderSize();
-
- // Main entry point.
- void OnDataReceived(const base::scoped_nsobject<NSData>& data);
-
- // Stops the decoding.
- void Stop();
-
- private:
- struct WebPIDecoderDeleter {
- inline void operator()(WebPIDecoder* ptr) const { WebPIDelete(ptr); }
- };
-
- enum State {
- READING_FEATURES,
- READING_DATA,
- DONE
- };
-
- friend class base::RefCountedThreadSafe<WebpDecoder>;
- virtual ~WebpDecoder();
-
- // Implements WebP image decoding state machine steps.
- void DoReadFeatures(NSData* data);
- void DoReadData(NSData* data);
- bool DoSendData();
-
- scoped_refptr<WebpDecoder::Delegate> delegate_;
- WebPDecoderConfig config_;
- WebpDecoder::State state_;
- scoped_ptr<WebPIDecoder, WebPIDecoderDeleter> incremental_decoder_;
- base::scoped_nsobject<NSData> output_buffer_;
- base::scoped_nsobject<NSMutableData> features_;
- int has_alpha_;
-};
-
-} // namespace web
-
-#endif // IOS_WEB_PUBLIC_WEBP_DECODER_H_
diff --git a/ios/web/public/webp_decoder.mm b/ios/web/public/webp_decoder.mm
deleted file mode 100644
index 3ac1cda..0000000
--- a/ios/web/public/webp_decoder.mm
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2013 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/web/public/webp_decoder.h"
-
-#import <Foundation/Foundation.h>
-#import <UIKit/UIKit.h>
-
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-
-namespace {
-
-const uint8_t kNumIfdEntries = 15;
-const unsigned int kExtraDataSize = 16;
-// 10b for signature/header + n * 12b entries + 4b for IFD terminator:
-const unsigned int kExtraDataOffset = 10 + 12 * kNumIfdEntries + 4;
-const unsigned int kHeaderSize = kExtraDataOffset + kExtraDataSize;
-const int kRecompressionThreshold = 64 * 64; // Threshold in pixels.
-const CGFloat kJpegQuality = 0.85;
-
-// Adapted from libwebp example dwebp.c.
-void PutLE16(uint8_t* const dst, uint32_t value) {
- dst[0] = (value >> 0) & 0xff;
- dst[1] = (value >> 8) & 0xff;
-}
-
-void PutLE32(uint8_t* const dst, uint32_t value) {
- PutLE16(dst + 0, (value >> 0) & 0xffff);
- PutLE16(dst + 2, (value >> 16) & 0xffff);
-}
-
-void WriteTiffHeader(uint8_t* dst,
- int width,
- int height,
- int bytes_per_px,
- bool has_alpha) {
- // For non-alpha case, we omit tag 0x152 (ExtraSamples).
- const uint8_t num_ifd_entries = has_alpha ? kNumIfdEntries
- : kNumIfdEntries - 1;
- uint8_t tiff_header[kHeaderSize] = {
- 0x49, 0x49, 0x2a, 0x00, // little endian signature
- 8, 0, 0, 0, // offset to the unique IFD that follows
- // IFD (offset = 8). Entries must be written in increasing tag order.
- num_ifd_entries, 0, // Number of entries in the IFD (12 bytes each).
- 0x00, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 10: Width (TBD)
- 0x01, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 22: Height (TBD)
- 0x02, 0x01, 3, 0, bytes_per_px, 0, 0, 0, // 34: BitsPerSample: 8888
- kExtraDataOffset + 0, 0, 0, 0,
- 0x03, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 46: Compression: none
- 0x06, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 58: Photometric: RGB
- 0x11, 0x01, 4, 0, 1, 0, 0, 0, // 70: Strips offset:
- kHeaderSize, 0, 0, 0, // data follows header
- 0x12, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 82: Orientation: topleft
- 0x15, 0x01, 3, 0, 1, 0, 0, 0, // 94: SamplesPerPixels
- bytes_per_px, 0, 0, 0,
- 0x16, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 106: Rows per strip (TBD)
- 0x17, 0x01, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 118: StripByteCount (TBD)
- 0x1a, 0x01, 5, 0, 1, 0, 0, 0, // 130: X-resolution
- kExtraDataOffset + 8, 0, 0, 0,
- 0x1b, 0x01, 5, 0, 1, 0, 0, 0, // 142: Y-resolution
- kExtraDataOffset + 8, 0, 0, 0,
- 0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
- 0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
- 0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
- 0, 0, 0, 0, // 190: IFD terminator
- // kExtraDataOffset:
- 8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
- 72, 0, 0, 0, 1, 0, 0, 0 // 72 pixels/inch, for X/Y-resolution
- };
-
- // Fill placeholders in IFD:
- PutLE32(tiff_header + 10 + 8, width);
- PutLE32(tiff_header + 22 + 8, height);
- PutLE32(tiff_header + 106 + 8, height);
- PutLE32(tiff_header + 118 + 8, width * bytes_per_px * height);
- if (!has_alpha)
- PutLE32(tiff_header + 178, 0);
-
- memcpy(dst, tiff_header, kHeaderSize);
-}
-
-} // namespace
-
-namespace web {
-
-// static
-size_t WebpDecoder::GetHeaderSize() {
- return kHeaderSize;
-}
-
-WebpDecoder::WebpDecoder(WebpDecoder::Delegate* delegate)
- : delegate_(delegate), state_(READING_FEATURES), has_alpha_(0) {
- DCHECK(delegate_.get());
- const bool rv = WebPInitDecoderConfig(&config_);
- DCHECK(rv);
-}
-
-WebpDecoder::~WebpDecoder() {
- WebPFreeDecBuffer(&config_.output);
-}
-
-void WebpDecoder::OnDataReceived(const base::scoped_nsobject<NSData>& data) {
- DCHECK(data);
- switch (state_) {
- case READING_FEATURES:
- DoReadFeatures(data);
- break;
- case READING_DATA:
- DoReadData(data);
- break;
- case DONE:
- DLOG(WARNING) << "Received WebP data but decoding is finished. Ignoring.";
- break;
- }
-}
-
-void WebpDecoder::Stop() {
- if (state_ != DONE) {
- state_ = DONE;
- DLOG(WARNING) << "Unexpected end of WebP data.";
- delegate_->OnFinishedDecoding(false);
- }
-}
-
-void WebpDecoder::DoReadFeatures(NSData* data) {
- DCHECK_EQ(READING_FEATURES, state_);
- DCHECK(data);
- if (features_)
- [features_ appendData:data];
- else
- features_.reset([[NSMutableData alloc] initWithData:data]);
- VP8StatusCode status =
- WebPGetFeatures(static_cast<const uint8_t*>([features_ bytes]),
- [features_ length], &config_.input);
- switch (status) {
- case VP8_STATUS_OK: {
- has_alpha_ = config_.input.has_alpha;
- const uint32_t width = config_.input.width;
- const uint32_t height = config_.input.height;
- const size_t bytes_per_px = has_alpha_ ? 4 : 3;
- const int stride = bytes_per_px * width;
- const size_t image_data_size = stride * height;
- const size_t total_size = image_data_size + kHeaderSize;
- // Force pre-multiplied alpha.
- config_.output.colorspace = has_alpha_ ? MODE_rgbA : MODE_RGB;
- config_.output.u.RGBA.stride = stride;
- // Create the output buffer.
- config_.output.u.RGBA.size = image_data_size;
- uint8_t* dst = static_cast<uint8_t*>(malloc(total_size));
- if (!dst) {
- DLOG(ERROR) << "Could not allocate WebP decoding buffer (size = "
- << total_size << ").";
- delegate_->OnFinishedDecoding(false);
- state_ = DONE;
- break;
- }
- WriteTiffHeader(dst, width, height, bytes_per_px, has_alpha_);
- output_buffer_.reset([[NSData alloc] initWithBytesNoCopy:dst
- length:total_size
- freeWhenDone:YES]);
- config_.output.is_external_memory = 1;
- config_.output.u.RGBA.rgba = dst + kHeaderSize;
- // Start decoding.
- state_ = READING_DATA;
- incremental_decoder_.reset(WebPINewDecoder(&config_.output));
- DoReadData(features_);
- features_.reset();
- break;
- }
- case VP8_STATUS_NOT_ENOUGH_DATA:
- // Do nothing.
- break;
- default:
- DLOG(ERROR) << "Error in WebP image features.";
- delegate_->OnFinishedDecoding(false);
- state_ = DONE;
- break;
- }
-}
-
-void WebpDecoder::DoReadData(NSData* data) {
- DCHECK_EQ(READING_DATA, state_);
- DCHECK(incremental_decoder_);
- DCHECK(data);
- VP8StatusCode status = WebPIAppend(incremental_decoder_.get(),
- static_cast<const uint8_t*>([data bytes]),
- [data length]);
- switch (status) {
- case VP8_STATUS_SUSPENDED:
- // Do nothing: re-compression to JPEG or PNG cannot be done incrementally.
- // Wait for the whole image to be decoded.
- break;
- case VP8_STATUS_OK: {
- bool rv = DoSendData();
- DLOG_IF(ERROR, !rv) << "Error in WebP image conversion.";
- state_ = DONE;
- delegate_->OnFinishedDecoding(rv);
- break;
- }
- default:
- DLOG(ERROR) << "Error in WebP image decoding.";
- delegate_->OnFinishedDecoding(false);
- state_ = DONE;
- break;
- }
-}
-
-bool WebpDecoder::DoSendData() {
- DCHECK_EQ(READING_DATA, state_);
- int width, height;
- uint8_t* data_ptr =
- WebPIDecGetRGB(incremental_decoder_.get(), NULL, &width, &height, NULL);
- if (!data_ptr)
- return false;
- DCHECK_EQ(static_cast<const uint8_t*>([output_buffer_ bytes]) + kHeaderSize,
- data_ptr);
- base::scoped_nsobject<NSData> result_data;
- // When the WebP image is larger than |kRecompressionThreshold| it is
- // compressed to JPEG or PNG. Otherwise, the uncompressed TIFF is used.
- DecodedImageFormat format = TIFF;
- if (width * height > kRecompressionThreshold) {
- base::scoped_nsobject<UIImage> tiff_image(
- [[UIImage alloc] initWithData:output_buffer_]);
- if (!tiff_image)
- return false;
- // Compress to PNG if the image is transparent, JPEG otherwise.
- // TODO(droger): Use PNG instead of JPEG if the WebP image is lossless.
- if (has_alpha_) {
- result_data.reset([UIImagePNGRepresentation(tiff_image) retain]);
- format = PNG;
- } else {
- result_data.reset(
- [UIImageJPEGRepresentation(tiff_image, kJpegQuality) retain]);
- format = JPEG;
- }
- if (!result_data)
- return false;
- } else {
- result_data.reset([output_buffer_ retain]);
- }
- UMA_HISTOGRAM_ENUMERATION(
- "WebP.DecodedImageFormat", format, DECODED_FORMAT_COUNT);
- delegate_->SetImageFeatures([result_data length], format);
- delegate_->OnDataDecoded(result_data);
- output_buffer_.reset();
- return true;
-}
-
-} // namespace web
diff --git a/ios/web/public/webp_decoder_unittest.mm b/ios/web/public/webp_decoder_unittest.mm
deleted file mode 100644
index 40d20a1..0000000
--- a/ios/web/public/webp_decoder_unittest.mm
+++ /dev/null
@@ -1,263 +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/web/public/webp_decoder.h"
-
-#import <CoreGraphics/CoreGraphics.h>
-#import <Foundation/Foundation.h>
-
-#include "base/base_paths.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/memory/ref_counted.h"
-#include "base/path_service.h"
-#include "base/strings/sys_string_conversions.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace web {
-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));
- virtual void OnDataDecoded(NSData* data) { [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/web/test/data").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, NULL, false, kCGRenderingIntentDefault));
- break;
- case WebpDecoder::PNG:
- image.reset(CGImageCreateWithPNGDataProvider(
- provider, NULL, 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) {
- scoped_ptr<std::vector<uint8_t> > uncompressed_1(
- DecompressData(data_1, format));
- scoped_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")) retain]);
- ASSERT_TRUE(webp_image != nil);
- // Load reference image.
- base::scoped_nsobject<NSData> jpg_image(
- [LoadImage(base::FilePath("test.jpg")) retain]);
- 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")) retain]);
- ASSERT_TRUE(webp_image != nil);
- // Load reference image.
- base::scoped_nsobject<NSData> png_image(
- [LoadImage(base::FilePath("test_alpha.png")) retain]);
- 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")) retain]);
- ASSERT_TRUE(webp_image != nil);
- // Load reference image.
- base::scoped_nsobject<NSData> tiff_image(
- [LoadImage(base::FilePath("test_small.tiff")) retain]);
- 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")) retain]);
- ASSERT_TRUE(webp_image != nil);
- // Load reference image.
- base::scoped_nsobject<NSData> jpg_image(
- [LoadImage(base::FilePath("test.jpg")) retain]);
- 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)] retain]);
- decoder_->OnDataReceived(chunk);
- webp_image.reset([[webp_image subdataWithRange:NSMakeRange(
- kChunkSize, [webp_image length] - kChunkSize)] retain]);
- ++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 web
diff --git a/ios/web/test/data/test.jpg b/ios/web/test/data/test.jpg
deleted file mode 100644
index 182a14a..0000000
--- a/ios/web/test/data/test.jpg
+++ /dev/null
Binary files differ
diff --git a/ios/web/test/data/test.webp b/ios/web/test/data/test.webp
deleted file mode 100644
index 122741b..0000000
--- a/ios/web/test/data/test.webp
+++ /dev/null
Binary files differ
diff --git a/ios/web/test/data/test_alpha.png b/ios/web/test/data/test_alpha.png
deleted file mode 100644
index 2de1a48..0000000
--- a/ios/web/test/data/test_alpha.png
+++ /dev/null
Binary files differ
diff --git a/ios/web/test/data/test_alpha.webp b/ios/web/test/data/test_alpha.webp
deleted file mode 100644
index ba39447..0000000
--- a/ios/web/test/data/test_alpha.webp
+++ /dev/null
Binary files differ
diff --git a/ios/web/test/data/test_small.tiff b/ios/web/test/data/test_small.tiff
deleted file mode 100644
index 8f1986d..0000000
--- a/ios/web/test/data/test_small.tiff
+++ /dev/null
Binary files differ
diff --git a/ios/web/test/data/test_small.webp b/ios/web/test/data/test_small.webp
deleted file mode 100644
index 5447184..0000000
--- a/ios/web/test/data/test_small.webp
+++ /dev/null
Binary files differ