| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 #import "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h" | 5 #import "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h" |
| 6 | 6 |
| 7 #import "base/mac/bind_objc_block.h" | 7 #import "base/mac/bind_objc_block.h" |
| 8 #import "base/mac/scoped_nsobject.h" | |
| 9 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 10 #include "base/task_runner.h" | 9 #include "base/task_runner.h" |
| 11 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
| 12 #import "ios/web/public/image_fetcher/webp_decoder.h" | 11 #import "ios/web/public/image_fetcher/webp_decoder.h" |
| 13 #include "net/http/http_response_headers.h" | 12 #include "net/http/http_response_headers.h" |
| 14 #include "net/http/http_status_code.h" | 13 #include "net/http/http_status_code.h" |
| 15 #include "net/url_request/url_fetcher.h" | 14 #include "net/url_request/url_fetcher.h" |
| 16 #include "url/url_constants.h" | 15 #include "url/url_constants.h" |
| 17 | 16 |
| 18 #if !defined(__has_feature) || !__has_feature(objc_arc) | 17 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 19 #error "This file requires ARC support." | 18 #error "This file requires ARC support." |
| 20 #endif | 19 #endif |
| 21 | 20 |
| 22 #pragma mark - WebpDecoderDelegate | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // TODO(crbug.com/687921): Refactor this. | |
| 27 class WebpDecoderDelegate : public webp_transcode::WebpDecoder::Delegate { | |
| 28 public: | |
| 29 WebpDecoderDelegate() = default; | |
| 30 | |
| 31 NSData* data() const { return decoded_image_; } | |
| 32 | |
| 33 // WebpDecoder::Delegate methods | |
| 34 void OnFinishedDecoding(bool success) override { | |
| 35 if (!success) | |
| 36 decoded_image_ = nil; | |
| 37 } | |
| 38 void SetImageFeatures( | |
| 39 size_t total_size, | |
| 40 webp_transcode::WebpDecoder::DecodedImageFormat format) override { | |
| 41 decoded_image_ = [[NSMutableData alloc] initWithCapacity:total_size]; | |
| 42 } | |
| 43 void OnDataDecoded(NSData* data) override { | |
| 44 DCHECK(decoded_image_); | |
| 45 [decoded_image_ appendData:data]; | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 ~WebpDecoderDelegate() override = default; | |
| 50 NSMutableData* decoded_image_; | |
| 51 | |
| 52 DISALLOW_COPY_AND_ASSIGN(WebpDecoderDelegate); | |
| 53 }; | |
| 54 | |
| 55 // Content-type header for WebP images. | |
| 56 const char kWEBPFirstMagicPattern[] = "RIFF"; | |
| 57 const char kWEBPSecondMagicPattern[] = "WEBP"; | |
| 58 | |
| 59 // Returns a NSData object containing the decoded image. | |
| 60 // Returns nil in case of failure. | |
| 61 NSData* DecodeWebpImage(NSData* webp_image) { | |
| 62 scoped_refptr<WebpDecoderDelegate> delegate(new WebpDecoderDelegate); | |
| 63 scoped_refptr<webp_transcode::WebpDecoder> decoder( | |
| 64 new webp_transcode::WebpDecoder(delegate.get())); | |
| 65 decoder->OnDataReceived(webp_image); | |
| 66 DLOG_IF(ERROR, !delegate->data()) << "WebP image decoding failed."; | |
| 67 return delegate->data(); | |
| 68 } | |
| 69 | |
| 70 } // namespace | |
| 71 | |
| 72 #pragma mark - IOSImageDataFetcherWrapper | 21 #pragma mark - IOSImageDataFetcherWrapper |
| 73 | 22 |
| 74 namespace image_fetcher { | 23 namespace image_fetcher { |
| 75 | 24 |
| 76 IOSImageDataFetcherWrapper::IOSImageDataFetcherWrapper( | 25 IOSImageDataFetcherWrapper::IOSImageDataFetcherWrapper( |
| 77 net::URLRequestContextGetter* url_request_context_getter, | 26 net::URLRequestContextGetter* url_request_context_getter, |
| 78 const scoped_refptr<base::TaskRunner>& task_runner) | 27 const scoped_refptr<base::TaskRunner>& task_runner) |
| 79 : task_runner_(task_runner), | 28 : task_runner_(task_runner), |
| 80 image_data_fetcher_(url_request_context_getter) { | 29 image_data_fetcher_(url_request_context_getter) { |
| 81 DCHECK(task_runner_.get()); | 30 DCHECK(task_runner_.get()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 111 IOSImageDataFetcherWrapper::CallbackForImageDataFetcher( | 60 IOSImageDataFetcherWrapper::CallbackForImageDataFetcher( |
| 112 IOSImageDataFetcherCallback callback) { | 61 IOSImageDataFetcherCallback callback) { |
| 113 scoped_refptr<base::TaskRunner> task_runner = task_runner_; | 62 scoped_refptr<base::TaskRunner> task_runner = task_runner_; |
| 114 | 63 |
| 115 return base::BindBlockArc(^(const std::string& image_data, | 64 return base::BindBlockArc(^(const std::string& image_data, |
| 116 const RequestMetadata& metadata) { | 65 const RequestMetadata& metadata) { |
| 117 // Create a NSData from the returned data and notify the callback. | 66 // Create a NSData from the returned data and notify the callback. |
| 118 NSData* data = | 67 NSData* data = |
| 119 [NSData dataWithBytes:image_data.data() length:image_data.size()]; | 68 [NSData dataWithBytes:image_data.data() length:image_data.size()]; |
| 120 | 69 |
| 121 if (data.length < 12 || | 70 if (!webp_transcode::WebpDecoder::IsWebpImage(image_data)) { |
| 122 image_data.compare(0, 4, kWEBPFirstMagicPattern) != 0 || | |
| 123 image_data.compare(8, 4, kWEBPSecondMagicPattern) != 0) { | |
| 124 callback(data, metadata); | 71 callback(data, metadata); |
| 125 return; | 72 return; |
| 126 } | 73 } |
| 127 | 74 |
| 75 // The image is a webp image. |
| 128 RequestMetadata webp_metadata = metadata; | 76 RequestMetadata webp_metadata = metadata; |
| 129 | 77 |
| 130 // The image is a webp image. | 78 base::PostTaskAndReplyWithResult( |
| 131 base::PostTaskAndReplyWithResult(task_runner.get(), FROM_HERE, | 79 task_runner.get(), FROM_HERE, base::BindBlockArc(^NSData*() { |
| 132 base::Bind(&DecodeWebpImage, data), | 80 return webp_transcode::WebpDecoder::DecodeWebpImage(data); |
| 133 base::BindBlockArc(^(NSData* data) { | 81 }), |
| 134 callback(data, webp_metadata); | 82 base::BindBlockArc(^(NSData* decodedData) { |
| 135 })); | 83 callback(decodedData, webp_metadata); |
| 84 })); |
| 136 }); | 85 }); |
| 137 } | 86 } |
| 138 | 87 |
| 139 } // namespace image_fetcher | 88 } // namespace image_fetcher |
| OLD | NEW |