| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ios/chrome/browser/webp_transcode/webp_decoder.h" | 5 #include "ios/chrome/browser/webp_transcode/webp_decoder.h" |
| 6 | 6 |
| 7 #import <CoreGraphics/CoreGraphics.h> | 7 #import <CoreGraphics/CoreGraphics.h> |
| 8 #import <Foundation/Foundation.h> | 8 #import <Foundation/Foundation.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| 11 | 11 |
| 12 #include <memory> | 12 #include <memory> |
| 13 | 13 |
| 14 #include "base/base_paths.h" | 14 #include "base/base_paths.h" |
| 15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/ios/ios_util.h" | 16 #include "base/ios/ios_util.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/mac/scoped_cftyperef.h" | 18 #include "base/mac/scoped_cftyperef.h" |
| 19 #include "base/mac/scoped_nsobject.h" | 19 #include "base/mac/scoped_nsobject.h" |
| 20 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "base/memory/ref_counted.h" | 21 #include "base/memory/ref_counted.h" |
| 22 #include "base/path_service.h" | 22 #include "base/path_service.h" |
| 23 #include "base/strings/sys_string_conversions.h" | 23 #include "base/strings/sys_string_conversions.h" |
| 24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
| 25 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 27 |
| 28 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 29 #error "This file requires ARC support." |
| 30 #endif |
| 31 |
| 28 namespace webp_transcode { | 32 namespace webp_transcode { |
| 29 namespace { | 33 namespace { |
| 30 | 34 |
| 31 class WebpDecoderDelegate : public WebpDecoder::Delegate { | 35 class WebpDecoderDelegate : public WebpDecoder::Delegate { |
| 32 public: | 36 public: |
| 33 WebpDecoderDelegate() : image_([[NSMutableData alloc] init]) {} | 37 WebpDecoderDelegate() : image_([[NSMutableData alloc] init]) {} |
| 34 | 38 |
| 35 NSData* GetImage() const { return image_; } | 39 NSData* GetImage() const { return image_; } |
| 36 | 40 |
| 37 // WebpDecoder::Delegate methods. | 41 // WebpDecoder::Delegate methods. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } // namespace | 168 } // namespace |
| 165 | 169 |
| 166 TEST_F(WebpDecoderTest, DecodeToJpeg) { | 170 TEST_F(WebpDecoderTest, DecodeToJpeg) { |
| 167 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 | 171 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 |
| 168 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR | 172 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR |
| 169 if (base::ios::IsRunningOnIOS9OrLater()) | 173 if (base::ios::IsRunningOnIOS9OrLater()) |
| 170 return; | 174 return; |
| 171 #endif | 175 #endif |
| 172 // Load a WebP image from disk. | 176 // Load a WebP image from disk. |
| 173 base::scoped_nsobject<NSData> webp_image( | 177 base::scoped_nsobject<NSData> webp_image( |
| 174 [LoadImage(base::FilePath("test.webp")) retain]); | 178 LoadImage(base::FilePath("test.webp"))); |
| 175 ASSERT_TRUE(webp_image != nil); | 179 ASSERT_TRUE(webp_image != nil); |
| 176 // Load reference image. | 180 // Load reference image. |
| 177 base::scoped_nsobject<NSData> jpg_image( | 181 base::scoped_nsobject<NSData> jpg_image( |
| 178 [LoadImage(base::FilePath("test.jpg")) retain]); | 182 LoadImage(base::FilePath("test.jpg"))); |
| 179 ASSERT_TRUE(jpg_image != nil); | 183 ASSERT_TRUE(jpg_image != nil); |
| 180 // Convert to JPEG. | 184 // Convert to JPEG. |
| 181 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); | 185 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); |
| 182 EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::JPEG)) | 186 EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::JPEG)) |
| 183 .Times(1); | 187 .Times(1); |
| 184 decoder_->OnDataReceived(webp_image); | 188 decoder_->OnDataReceived(webp_image); |
| 185 // Compare to reference image. | 189 // Compare to reference image. |
| 186 EXPECT_TRUE(CheckCompressedImagesEqual(jpg_image, delegate_->GetImage(), | 190 EXPECT_TRUE(CheckCompressedImagesEqual(jpg_image, delegate_->GetImage(), |
| 187 WebpDecoder::JPEG)); | 191 WebpDecoder::JPEG)); |
| 188 } | 192 } |
| 189 | 193 |
| 190 TEST_F(WebpDecoderTest, DecodeToPng) { | 194 TEST_F(WebpDecoderTest, DecodeToPng) { |
| 191 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 | 195 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 |
| 192 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR | 196 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR |
| 193 if (base::ios::IsRunningOnIOS9OrLater()) | 197 if (base::ios::IsRunningOnIOS9OrLater()) |
| 194 return; | 198 return; |
| 195 #endif | 199 #endif |
| 196 // Load a WebP image from disk. | 200 // Load a WebP image from disk. |
| 197 base::scoped_nsobject<NSData> webp_image( | 201 base::scoped_nsobject<NSData> webp_image( |
| 198 [LoadImage(base::FilePath("test_alpha.webp")) retain]); | 202 LoadImage(base::FilePath("test_alpha.webp"))); |
| 199 ASSERT_TRUE(webp_image != nil); | 203 ASSERT_TRUE(webp_image != nil); |
| 200 // Load reference image. | 204 // Load reference image. |
| 201 base::scoped_nsobject<NSData> png_image( | 205 base::scoped_nsobject<NSData> png_image( |
| 202 [LoadImage(base::FilePath("test_alpha.png")) retain]); | 206 LoadImage(base::FilePath("test_alpha.png"))); |
| 203 ASSERT_TRUE(png_image != nil); | 207 ASSERT_TRUE(png_image != nil); |
| 204 // Convert to PNG. | 208 // Convert to PNG. |
| 205 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); | 209 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); |
| 206 EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::PNG)) | 210 EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::PNG)) |
| 207 .Times(1); | 211 .Times(1); |
| 208 decoder_->OnDataReceived(webp_image); | 212 decoder_->OnDataReceived(webp_image); |
| 209 // Compare to reference image. | 213 // Compare to reference image. |
| 210 EXPECT_TRUE(CheckCompressedImagesEqual(png_image, delegate_->GetImage(), | 214 EXPECT_TRUE(CheckCompressedImagesEqual(png_image, delegate_->GetImage(), |
| 211 WebpDecoder::PNG)); | 215 WebpDecoder::PNG)); |
| 212 } | 216 } |
| 213 | 217 |
| 214 TEST_F(WebpDecoderTest, DecodeToTiff) { | 218 TEST_F(WebpDecoderTest, DecodeToTiff) { |
| 215 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 | 219 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 |
| 216 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR | 220 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR |
| 217 if (base::ios::IsRunningOnIOS9OrLater()) | 221 if (base::ios::IsRunningOnIOS9OrLater()) |
| 218 return; | 222 return; |
| 219 #endif | 223 #endif |
| 220 // Load a WebP image from disk. | 224 // Load a WebP image from disk. |
| 221 base::scoped_nsobject<NSData> webp_image( | 225 base::scoped_nsobject<NSData> webp_image( |
| 222 [LoadImage(base::FilePath("test_small.webp")) retain]); | 226 LoadImage(base::FilePath("test_small.webp"))); |
| 223 ASSERT_TRUE(webp_image != nil); | 227 ASSERT_TRUE(webp_image != nil); |
| 224 // Load reference image. | 228 // Load reference image. |
| 225 base::scoped_nsobject<NSData> tiff_image( | 229 base::scoped_nsobject<NSData> tiff_image( |
| 226 [LoadImage(base::FilePath("test_small.tiff")) retain]); | 230 LoadImage(base::FilePath("test_small.tiff"))); |
| 227 ASSERT_TRUE(tiff_image != nil); | 231 ASSERT_TRUE(tiff_image != nil); |
| 228 // Convert to TIFF. | 232 // Convert to TIFF. |
| 229 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); | 233 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); |
| 230 EXPECT_CALL(*delegate_, | 234 EXPECT_CALL(*delegate_, |
| 231 SetImageFeatures([tiff_image length], WebpDecoder::TIFF)) | 235 SetImageFeatures([tiff_image length], WebpDecoder::TIFF)) |
| 232 .Times(1); | 236 .Times(1); |
| 233 decoder_->OnDataReceived(webp_image); | 237 decoder_->OnDataReceived(webp_image); |
| 234 // Compare to reference image. | 238 // Compare to reference image. |
| 235 EXPECT_TRUE(CheckTiffImagesEqual(tiff_image, delegate_->GetImage())); | 239 EXPECT_TRUE(CheckTiffImagesEqual(tiff_image, delegate_->GetImage())); |
| 236 } | 240 } |
| 237 | 241 |
| 238 TEST_F(WebpDecoderTest, StreamedDecode) { | 242 TEST_F(WebpDecoderTest, StreamedDecode) { |
| 239 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 | 243 // TODO(droger): This test fails on iOS 9 x64 devices. http://crbug.com/523235 |
| 240 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR | 244 #if defined(OS_IOS) && defined(ARCH_CPU_ARM64) && !TARGET_IPHONE_SIMULATOR |
| 241 if (base::ios::IsRunningOnIOS9OrLater()) | 245 if (base::ios::IsRunningOnIOS9OrLater()) |
| 242 return; | 246 return; |
| 243 #endif | 247 #endif |
| 244 // Load a WebP image from disk. | 248 // Load a WebP image from disk. |
| 245 base::scoped_nsobject<NSData> webp_image( | 249 base::scoped_nsobject<NSData> webp_image( |
| 246 [LoadImage(base::FilePath("test.webp")) retain]); | 250 LoadImage(base::FilePath("test.webp"))); |
| 247 ASSERT_TRUE(webp_image != nil); | 251 ASSERT_TRUE(webp_image != nil); |
| 248 // Load reference image. | 252 // Load reference image. |
| 249 base::scoped_nsobject<NSData> jpg_image( | 253 base::scoped_nsobject<NSData> jpg_image( |
| 250 [LoadImage(base::FilePath("test.jpg")) retain]); | 254 LoadImage(base::FilePath("test.jpg"))); |
| 251 ASSERT_TRUE(jpg_image != nil); | 255 ASSERT_TRUE(jpg_image != nil); |
| 252 // Convert to JPEG in chunks. | 256 // Convert to JPEG in chunks. |
| 253 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); | 257 EXPECT_CALL(*delegate_, OnFinishedDecoding(true)).Times(1); |
| 254 EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::JPEG)) | 258 EXPECT_CALL(*delegate_, SetImageFeatures(testing::_, WebpDecoder::JPEG)) |
| 255 .Times(1); | 259 .Times(1); |
| 256 const size_t kChunkSize = 10; | 260 const size_t kChunkSize = 10; |
| 257 unsigned int num_chunks = 0; | 261 unsigned int num_chunks = 0; |
| 258 while ([webp_image length] > kChunkSize) { | 262 while ([webp_image length] > kChunkSize) { |
| 259 base::scoped_nsobject<NSData> chunk( | 263 base::scoped_nsobject<NSData> chunk( |
| 260 [[webp_image subdataWithRange:NSMakeRange(0, kChunkSize)] retain]); | 264 [webp_image subdataWithRange:NSMakeRange(0, kChunkSize)]); |
| 261 decoder_->OnDataReceived(chunk); | 265 decoder_->OnDataReceived(chunk); |
| 262 webp_image.reset([[webp_image | 266 webp_image.reset([webp_image |
| 263 subdataWithRange:NSMakeRange(kChunkSize, [webp_image length] - | 267 subdataWithRange:NSMakeRange(kChunkSize, |
| 264 kChunkSize)] retain]); | 268 [webp_image length] - kChunkSize)]); |
| 265 ++num_chunks; | 269 ++num_chunks; |
| 266 } | 270 } |
| 267 if ([webp_image length] > 0u) { | 271 if ([webp_image length] > 0u) { |
| 268 decoder_->OnDataReceived(webp_image); | 272 decoder_->OnDataReceived(webp_image); |
| 269 ++num_chunks; | 273 ++num_chunks; |
| 270 } | 274 } |
| 271 ASSERT_GT(num_chunks, 3u) << "Not enough chunks"; | 275 ASSERT_GT(num_chunks, 3u) << "Not enough chunks"; |
| 272 // Compare to reference image. | 276 // Compare to reference image. |
| 273 EXPECT_TRUE(CheckCompressedImagesEqual(jpg_image, delegate_->GetImage(), | 277 EXPECT_TRUE(CheckCompressedImagesEqual(jpg_image, delegate_->GetImage(), |
| 274 WebpDecoder::JPEG)); | 278 WebpDecoder::JPEG)); |
| 275 } | 279 } |
| 276 | 280 |
| 277 TEST_F(WebpDecoderTest, InvalidFormat) { | 281 TEST_F(WebpDecoderTest, InvalidFormat) { |
| 278 EXPECT_CALL(*delegate_, OnFinishedDecoding(false)).Times(1); | 282 EXPECT_CALL(*delegate_, OnFinishedDecoding(false)).Times(1); |
| 279 const char dummy_image[] = "(>'-')> <('-'<) ^('-')^ <('-'<) (>'-')>"; | 283 const char dummy_image[] = "(>'-')> <('-'<) ^('-')^ <('-'<) (>'-')>"; |
| 280 base::scoped_nsobject<NSData> data( | 284 base::scoped_nsobject<NSData> data( |
| 281 [[NSData alloc] initWithBytes:dummy_image length:arraysize(dummy_image)]); | 285 [[NSData alloc] initWithBytes:dummy_image length:arraysize(dummy_image)]); |
| 282 decoder_->OnDataReceived(data); | 286 decoder_->OnDataReceived(data); |
| 283 EXPECT_EQ(0u, [delegate_->GetImage() length]); | 287 EXPECT_EQ(0u, [delegate_->GetImage() length]); |
| 284 } | 288 } |
| 285 | 289 |
| 286 TEST_F(WebpDecoderTest, DecodeAborted) { | 290 TEST_F(WebpDecoderTest, DecodeAborted) { |
| 287 EXPECT_CALL(*delegate_, OnFinishedDecoding(false)).Times(1); | 291 EXPECT_CALL(*delegate_, OnFinishedDecoding(false)).Times(1); |
| 288 decoder_->Stop(); | 292 decoder_->Stop(); |
| 289 EXPECT_EQ(0u, [delegate_->GetImage() length]); | 293 EXPECT_EQ(0u, [delegate_->GetImage() length]); |
| 290 } | 294 } |
| 291 | 295 |
| 292 } // namespace webp_transcode | 296 } // namespace webp_transcode |
| OLD | NEW |