Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: components/image_fetcher/ios/ios_image_data_fetcher.mm

Issue 2652893005: Create the IOSImageDataFetcher (Closed)
Patch Set: Address comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "components/image_fetcher/ios/ios_image_data_fetcher.h"
6
7 #import "base/mac/bind_objc_block.h"
8 #import "base/mac/scoped_nsobject.h"
9 #include "base/memory/ptr_util.h"
10 #include "base/task_runner.h"
11 #include "base/task_runner_util.h"
12 #import "components/image_fetcher/image_data_fetcher.h"
13 #import "ios/web/public/image_fetcher/webp_decoder.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/http/http_status_code.h"
16 #include "net/url_request/url_fetcher.h"
17 #include "url/url_constants.h"
18
19 #if !defined(__has_feature) || !__has_feature(objc_arc)
20 #error "This file requires ARC support."
21 #endif
22
23 #pragma mark - WebpDecoderDelegate
24
25 namespace {
26
27 class WebpDecoderDelegate : public webp_transcode::WebpDecoder::Delegate {
28 public:
29 NSData* data() const { return decoded_image_; }
30
31 // WebpDecoder::Delegate methods
32 void OnFinishedDecoding(bool success) override {
33 if (!success)
34 decoded_image_.reset();
35 }
36 void SetImageFeatures(
37 size_t total_size,
38 webp_transcode::WebpDecoder::DecodedImageFormat format) override {
39 decoded_image_.reset([[NSMutableData alloc] initWithCapacity:total_size]);
40 }
41 void OnDataDecoded(NSData* data) override {
42 DCHECK(decoded_image_);
43 [decoded_image_ appendData:data];
44 }
45
46 private:
47 ~WebpDecoderDelegate() override {}
48 base::scoped_nsobject<NSMutableData> decoded_image_;
49 };
50
51 // Content-type header for WebP images.
52 static const char kWEBPMimeType[] = "image/webp";
53
54 // Returns a NSData object containing the decoded image.
55 // Returns nil in case of failure.
56 NSData* DecodeWebpImage(NSData* webp_image) {
57 scoped_refptr<WebpDecoderDelegate> delegate(new WebpDecoderDelegate);
58 scoped_refptr<webp_transcode::WebpDecoder> decoder(
59 new webp_transcode::WebpDecoder(delegate.get()));
60 decoder->OnDataReceived(webp_image);
61 DLOG_IF(ERROR, !delegate->data()) << "WebP image decoding failed.";
62 return base::scoped_nsobject<NSData>(delegate->data());
63 }
64
65 } // namespace
66
67 #pragma mark - IOSImageDataFetcher
68
69 namespace image_fetcher {
70
71 IOSImageDataFetcher::IOSImageDataFetcher(
72 net::URLRequestContextGetter* url_request_context_getter,
73 const scoped_refptr<base::TaskRunner>& task_runner)
74 : task_runner_(task_runner) {
75 DCHECK(task_runner_.get());
76 image_data_fetcher_ =
77 base::MakeUnique<ImageDataFetcher>(url_request_context_getter);
78 }
79
80 IOSImageDataFetcher::~IOSImageDataFetcher() {}
81
82 void IOSImageDataFetcher::FetchImageDataWebpDecoded(
83 const GURL& image_url,
84 IOSImageDataFetcherCallback callback) {
85 DCHECK(callback);
86 if (!callback)
87 return;
88
89 scoped_refptr<base::TaskRunner> task_runner = task_runner_;
90 ImageDataFetcher::ImageDataFetcherCallback local_callback =
91 base::BindBlockArc(^(const std::string& image_data,
92 const net::URLFetcher* source) {
93 // Make sure the request was successful. For "data" requests, the
94 // response code has no meaning, because there is no actual server (data
95 // is encoded directly in the URL). In that case, set the response code
96 // to 200 (OK).
97 const GURL& original_url = source->GetOriginalURL();
98 const int http_response_code = original_url.SchemeIs(url::kDataScheme)
99 ? net::HTTP_OK
100 : source->GetResponseCode();
101 if (http_response_code != net::HTTP_OK) {
102 callback(http_response_code, nil);
103 return;
104 }
105
106 // Create a NSData from the returned data and notify the callback.
107 NSData* data =
108 [NSData dataWithBytes:image_data.data() length:image_data.size()];
109
110 if (source->GetResponseHeaders()) {
111 std::string mime_type;
112 source->GetResponseHeaders()->GetMimeType(&mime_type);
113 if (mime_type == kWEBPMimeType) {
114 base::PostTaskAndReplyWithResult(
115 task_runner.get(), FROM_HERE,
116 base::Bind(&DecodeWebpImage, data),
117 base::BindBlockArc(^(NSData* decodedData) {
118 callback(http_response_code, decodedData);
119 }));
120 return;
121 }
122 }
123 callback(http_response_code, data);
124 });
125 image_data_fetcher_->FetchImageData(image_url, local_callback);
126 }
127
128 void IOSImageDataFetcher::SetDataUseServiceName(
129 DataUseServiceName data_use_service_name) {
130 image_data_fetcher_->SetDataUseServiceName(data_use_service_name);
131 }
132
133 } // namespace image_fetcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698