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: chrome/browser/chromeos/login/users/avatar/user_image_loader.cc

Issue 2517053004: Use base::RefCountedBytes in user_manager::UserImage (Closed)
Patch Set: remove unnecessary base::move Created 4 years 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
« no previous file with comments | « no previous file | chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/chromeos/login/users/avatar/user_image_loader.h" 5 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 28 matching lines...) Expand all
39 loaded_cb(loaded_cb) {} 39 loaded_cb(loaded_cb) {}
40 ~ImageInfo() {} 40 ~ImageInfo() {}
41 41
42 const base::FilePath file_path; 42 const base::FilePath file_path;
43 const int pixels_per_side; 43 const int pixels_per_side;
44 const ImageDecoder::ImageCodec image_codec; 44 const ImageDecoder::ImageCodec image_codec;
45 const LoadedCallback loaded_cb; 45 const LoadedCallback loaded_cb;
46 }; 46 };
47 47
48 // Crops |image| to the square format and downsizes the image to 48 // Crops |image| to the square format and downsizes the image to
49 // |target_size| in pixels. On success, returns true and stores the cropped 49 // |target_size| in pixels. On success, returns the bytes representation and
50 // image in |bitmap| and the bytes representation in |byytes|. 50 // stores the cropped image in |bitmap|. On failure, returns nullptr.
51 bool CropImage(const SkBitmap& image, 51 scoped_refptr<base::RefCountedBytes> CropImage(const SkBitmap& image,
52 int target_size, 52 int target_size,
53 SkBitmap* bitmap, 53 SkBitmap* bitmap) {
54 user_manager::UserImage::Bytes* bytes) {
55 DCHECK_GT(target_size, 0); 54 DCHECK_GT(target_size, 0);
56 55
57 SkBitmap final_image; 56 SkBitmap final_image;
58 // Auto crop the image, taking the largest square in the center. 57 // Auto crop the image, taking the largest square in the center.
59 int pixels_per_side = std::min(image.width(), image.height()); 58 int pixels_per_side = std::min(image.width(), image.height());
60 int x = (image.width() - pixels_per_side) / 2; 59 int x = (image.width() - pixels_per_side) / 2;
61 int y = (image.height() - pixels_per_side) / 2; 60 int y = (image.height() - pixels_per_side) / 2;
62 SkBitmap cropped_image = SkBitmapOperations::CreateTiledBitmap( 61 SkBitmap cropped_image = SkBitmapOperations::CreateTiledBitmap(
63 image, x, y, pixels_per_side, pixels_per_side); 62 image, x, y, pixels_per_side, pixels_per_side);
64 if (pixels_per_side > target_size) { 63 if (pixels_per_side > target_size) {
65 // Also downsize the image to save space and memory. 64 // Also downsize the image to save space and memory.
66 final_image = skia::ImageOperations::Resize( 65 final_image = skia::ImageOperations::Resize(
67 cropped_image, skia::ImageOperations::RESIZE_LANCZOS3, target_size, 66 cropped_image, skia::ImageOperations::RESIZE_LANCZOS3, target_size,
68 target_size); 67 target_size);
69 } else { 68 } else {
70 final_image = cropped_image; 69 final_image = cropped_image;
71 } 70 }
72 71
73 // Encode the cropped image to web-compatible bytes representation 72 // Encode the cropped image to web-compatible bytes representation
74 std::unique_ptr<user_manager::UserImage::Bytes> encoded = 73 scoped_refptr<base::RefCountedBytes> encoded =
75 user_manager::UserImage::Encode(final_image); 74 user_manager::UserImage::Encode(final_image);
76 if (!encoded) 75 if (encoded)
77 return false; 76 bitmap->swap(final_image);
78 77 return encoded;
79 bitmap->swap(final_image);
80 bytes->swap(*encoded);
81 return true;
82 } 78 }
83 79
84 // Handles the decoded image returned from ImageDecoder through the 80 // Handles the decoded image returned from ImageDecoder through the
85 // ImageRequest interface. 81 // ImageRequest interface.
86 class UserImageRequest : public ImageDecoder::ImageRequest { 82 class UserImageRequest : public ImageDecoder::ImageRequest {
87 public: 83 public:
88 UserImageRequest( 84 UserImageRequest(
89 const ImageInfo& image_info, 85 const ImageInfo& image_info,
90 const std::string& image_data, 86 const std::string& image_data,
91 scoped_refptr<base::SequencedTaskRunner> background_task_runner) 87 scoped_refptr<base::SequencedTaskRunner> background_task_runner)
92 : image_info_(image_info), 88 : image_info_(image_info),
93 image_data_(image_data.begin(), image_data.end()), 89 // TODO(crbug.com/593251): Remove the data copy here.
90 image_data_(new base::RefCountedBytes(
91 reinterpret_cast<const unsigned char*>(image_data.data()),
92 image_data.size())),
94 background_task_runner_(background_task_runner), 93 background_task_runner_(background_task_runner),
95 weak_ptr_factory_(this) {} 94 weak_ptr_factory_(this) {}
96 ~UserImageRequest() override {} 95 ~UserImageRequest() override {}
97 96
98 // ImageDecoder::ImageRequest implementation. 97 // ImageDecoder::ImageRequest implementation.
99 void OnImageDecoded(const SkBitmap& decoded_image) override; 98 void OnImageDecoded(const SkBitmap& decoded_image) override;
100 void OnDecodeImageFailed() override; 99 void OnDecodeImageFailed() override;
101 100
102 // Called after the image is cropped (and downsized) as needed. 101 // Called after the image is cropped (and downsized) as needed.
103 void OnImageCropped(SkBitmap* bitmap, 102 void OnImageCropped(SkBitmap* bitmap,
104 user_manager::UserImage::Bytes* bytes, 103 scoped_refptr<base::RefCountedBytes> bytes);
105 bool succeeded);
106 104
107 // Called after the image is finalized. |image_bytes_regenerated| is true 105 // Called after the image is finalized. |image_bytes_regenerated| is true
108 // if |image_bytes| is regenerated from the cropped image. 106 // if |image_bytes| is regenerated from the cropped image.
109 void OnImageFinalized(const SkBitmap& image, 107 void OnImageFinalized(const SkBitmap& image,
110 const user_manager::UserImage::Bytes& image_bytes, 108 scoped_refptr<base::RefCountedBytes> image_bytes,
111 bool image_bytes_regenerated); 109 bool image_bytes_regenerated);
112 110
113 private: 111 private:
114 const ImageInfo image_info_; 112 const ImageInfo image_info_;
115 const user_manager::UserImage::Bytes image_data_; 113 scoped_refptr<base::RefCountedBytes> image_data_;
116 scoped_refptr<base::SequencedTaskRunner> background_task_runner_; 114 scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
117 115
118 // This should be the last member. 116 // This should be the last member.
119 base::WeakPtrFactory<UserImageRequest> weak_ptr_factory_; 117 base::WeakPtrFactory<UserImageRequest> weak_ptr_factory_;
120 }; 118 };
121 119
122 void UserImageRequest::OnImageDecoded(const SkBitmap& decoded_image) { 120 void UserImageRequest::OnImageDecoded(const SkBitmap& decoded_image) {
123 int target_size = image_info_.pixels_per_side; 121 int target_size = image_info_.pixels_per_side;
124 if (target_size > 0) { 122 if (target_size > 0) {
125 // Cropping an image could be expensive, hence posting to the background 123 // Cropping an image could be expensive, hence posting to the background
126 // thread. 124 // thread.
127 SkBitmap* bitmap = new SkBitmap; 125 SkBitmap* bitmap = new SkBitmap;
128 user_manager::UserImage::Bytes* bytes = new user_manager::UserImage::Bytes;
129 base::PostTaskAndReplyWithResult( 126 base::PostTaskAndReplyWithResult(
130 background_task_runner_.get(), FROM_HERE, 127 background_task_runner_.get(), FROM_HERE,
131 base::Bind(&CropImage, decoded_image, target_size, bitmap, bytes), 128 base::Bind(&CropImage, decoded_image, target_size, bitmap),
132 base::Bind(&UserImageRequest::OnImageCropped, 129 base::Bind(&UserImageRequest::OnImageCropped,
133 weak_ptr_factory_.GetWeakPtr(), base::Owned(bitmap), 130 weak_ptr_factory_.GetWeakPtr(), base::Owned(bitmap)));
134 base::Owned(bytes)));
135 } else { 131 } else {
136 OnImageFinalized(decoded_image, image_data_, 132 OnImageFinalized(decoded_image, image_data_,
137 false /* image_bytes_regenerated */); 133 false /* image_bytes_regenerated */);
138 } 134 }
139 } 135 }
140 136
141 void UserImageRequest::OnImageCropped(SkBitmap* bitmap, 137 void UserImageRequest::OnImageCropped(
142 user_manager::UserImage::Bytes* bytes, 138 SkBitmap* bitmap,
143 bool succeeded) { 139 scoped_refptr<base::RefCountedBytes> bytes) {
144 DCHECK_GT(image_info_.pixels_per_side, 0); 140 DCHECK_GT(image_info_.pixels_per_side, 0);
145 141
146 if (!succeeded) { 142 if (!bytes) {
147 OnDecodeImageFailed(); 143 OnDecodeImageFailed();
148 return; 144 return;
149 } 145 }
150 OnImageFinalized(*bitmap, *bytes, true /* image_bytes_regenerated */); 146 OnImageFinalized(*bitmap, bytes, true /* image_bytes_regenerated */);
151 } 147 }
152 148
153 void UserImageRequest::OnImageFinalized( 149 void UserImageRequest::OnImageFinalized(
154 const SkBitmap& image, 150 const SkBitmap& image,
155 const user_manager::UserImage::Bytes& image_bytes, 151 scoped_refptr<base::RefCountedBytes> image_bytes,
156 bool image_bytes_regenerated) { 152 bool image_bytes_regenerated) {
157 SkBitmap final_image = image; 153 SkBitmap final_image = image;
158 // Make the SkBitmap immutable as we won't modify it. This is important 154 // Make the SkBitmap immutable as we won't modify it. This is important
159 // because otherwise it gets duplicated during painting, wasting memory. 155 // because otherwise it gets duplicated during painting, wasting memory.
160 final_image.setImmutable(); 156 final_image.setImmutable();
161 gfx::ImageSkia final_image_skia = 157 gfx::ImageSkia final_image_skia =
162 gfx::ImageSkia::CreateFrom1xBitmap(final_image); 158 gfx::ImageSkia::CreateFrom1xBitmap(final_image);
163 final_image_skia.MakeThreadSafe(); 159 final_image_skia.MakeThreadSafe();
164 std::unique_ptr<user_manager::UserImage> user_image( 160 std::unique_ptr<user_manager::UserImage> user_image(
165 new user_manager::UserImage(final_image_skia, image_bytes)); 161 new user_manager::UserImage(final_image_skia, image_bytes));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 ImageDecoder::ImageCodec image_codec, 216 ImageDecoder::ImageCodec image_codec,
221 int pixels_per_side, 217 int pixels_per_side,
222 const LoadedCallback& loaded_cb) { 218 const LoadedCallback& loaded_cb) {
223 DecodeImage( 219 DecodeImage(
224 ImageInfo(base::FilePath(), pixels_per_side, image_codec, loaded_cb), 220 ImageInfo(base::FilePath(), pixels_per_side, image_codec, loaded_cb),
225 background_task_runner, data.get(), true /* data_is_ready */); 221 background_task_runner, data.get(), true /* data_is_ready */);
226 } 222 }
227 223
228 } // namespace user_image_loader 224 } // namespace user_image_loader
229 } // namespace chromeos 225 } // namespace chromeos
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698