diff options
Diffstat (limited to 'ios')
-rw-r--r-- | ios/chrome/DEPS | 1 | ||||
-rw-r--r-- | ios/chrome/browser/net/image_fetcher.mm | 9 | ||||
-rw-r--r-- | ios/chrome/ios_chrome.gyp | 1 | ||||
-rw-r--r-- | ios/ios_tests_unit.gyp | 18 | ||||
-rw-r--r-- | ios/web/ios_web.gyp | 16 | ||||
-rw-r--r-- | ios/web/public/webp_decoder.h | 83 | ||||
-rw-r--r-- | ios/web/public/webp_decoder.mm | 251 | ||||
-rw-r--r-- | ios/web/public/webp_decoder_unittest.mm | 263 | ||||
-rw-r--r-- | ios/web/test/data/test.jpg | bin | 84820 -> 0 bytes | |||
-rw-r--r-- | ios/web/test/data/test.webp | bin | 30320 -> 0 bytes | |||
-rw-r--r-- | ios/web/test/data/test_alpha.png | bin | 175667 -> 0 bytes | |||
-rw-r--r-- | ios/web/test/data/test_alpha.webp | bin | 92312 -> 0 bytes | |||
-rw-r--r-- | ios/web/test/data/test_small.tiff | bin | 4306 -> 0 bytes | |||
-rw-r--r-- | ios/web/test/data/test_small.webp | bin | 724 -> 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 Binary files differdeleted file mode 100644 index 182a14a..0000000 --- a/ios/web/test/data/test.jpg +++ /dev/null diff --git a/ios/web/test/data/test.webp b/ios/web/test/data/test.webp Binary files differdeleted file mode 100644 index 122741b..0000000 --- a/ios/web/test/data/test.webp +++ /dev/null diff --git a/ios/web/test/data/test_alpha.png b/ios/web/test/data/test_alpha.png Binary files differdeleted file mode 100644 index 2de1a48..0000000 --- a/ios/web/test/data/test_alpha.png +++ /dev/null diff --git a/ios/web/test/data/test_alpha.webp b/ios/web/test/data/test_alpha.webp Binary files differdeleted file mode 100644 index ba39447..0000000 --- a/ios/web/test/data/test_alpha.webp +++ /dev/null diff --git a/ios/web/test/data/test_small.tiff b/ios/web/test/data/test_small.tiff Binary files differdeleted file mode 100644 index 8f1986d..0000000 --- a/ios/web/test/data/test_small.tiff +++ /dev/null diff --git a/ios/web/test/data/test_small.webp b/ios/web/test/data/test_small.webp Binary files differdeleted file mode 100644 index 5447184..0000000 --- a/ios/web/test/data/test_small.webp +++ /dev/null |