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

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: Created 4 years, 1 month 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
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)
achuithb 2016/11/22 21:16:54 Does this early return still make sense? Why not:
satorux1 2016/11/24 02:13:40 good idea. done!
77 return false; 76 return nullptr;
78 77
79 bitmap->swap(final_image); 78 bitmap->swap(final_image);
80 bytes->swap(*encoded); 79 return encoded;
81 return true;
82 } 80 }
83 81
84 // Handles the decoded image returned from ImageDecoder through the 82 // Handles the decoded image returned from ImageDecoder through the
85 // ImageRequest interface. 83 // ImageRequest interface.
86 class UserImageRequest : public ImageDecoder::ImageRequest { 84 class UserImageRequest : public ImageDecoder::ImageRequest {
87 public: 85 public:
88 UserImageRequest( 86 UserImageRequest(
89 const ImageInfo& image_info, 87 const ImageInfo& image_info,
90 const std::string& image_data, 88 const std::string& image_data,
91 scoped_refptr<base::SequencedTaskRunner> background_task_runner) 89 scoped_refptr<base::SequencedTaskRunner> background_task_runner)
92 : image_info_(image_info), 90 : image_info_(image_info),
93 image_data_(image_data.begin(), image_data.end()), 91 // TODO(crbug.com/593251): Remove the data copy here.
92 image_data_(new base::RefCountedBytes(
93 reinterpret_cast<const unsigned char*>(image_data.data()),
94 image_data.size())),
94 background_task_runner_(background_task_runner), 95 background_task_runner_(background_task_runner),
95 weak_ptr_factory_(this) {} 96 weak_ptr_factory_(this) {}
96 ~UserImageRequest() override {} 97 ~UserImageRequest() override {}
97 98
98 // ImageDecoder::ImageRequest implementation. 99 // ImageDecoder::ImageRequest implementation.
99 void OnImageDecoded(const SkBitmap& decoded_image) override; 100 void OnImageDecoded(const SkBitmap& decoded_image) override;
100 void OnDecodeImageFailed() override; 101 void OnDecodeImageFailed() override;
101 102
102 // Called after the image is cropped (and downsized) as needed. 103 // Called after the image is cropped (and downsized) as needed.
103 void OnImageCropped(SkBitmap* bitmap, 104 void OnImageCropped(SkBitmap* bitmap,
104 user_manager::UserImage::Bytes* bytes, 105 scoped_refptr<base::RefCountedBytes> bytes);
105 bool succeeded);
106 106
107 // Called after the image is finalized. |image_bytes_regenerated| is true 107 // Called after the image is finalized. |image_bytes_regenerated| is true
108 // if |image_bytes| is regenerated from the cropped image. 108 // if |image_bytes| is regenerated from the cropped image.
109 void OnImageFinalized(const SkBitmap& image, 109 void OnImageFinalized(const SkBitmap& image,
110 const user_manager::UserImage::Bytes& image_bytes, 110 scoped_refptr<base::RefCountedBytes> image_bytes,
111 bool image_bytes_regenerated); 111 bool image_bytes_regenerated);
112 112
113 private: 113 private:
114 const ImageInfo image_info_; 114 const ImageInfo image_info_;
115 const user_manager::UserImage::Bytes image_data_; 115 scoped_refptr<base::RefCountedBytes> image_data_;
116 scoped_refptr<base::SequencedTaskRunner> background_task_runner_; 116 scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
117 117
118 // This should be the last member. 118 // This should be the last member.
119 base::WeakPtrFactory<UserImageRequest> weak_ptr_factory_; 119 base::WeakPtrFactory<UserImageRequest> weak_ptr_factory_;
120 }; 120 };
121 121
122 void UserImageRequest::OnImageDecoded(const SkBitmap& decoded_image) { 122 void UserImageRequest::OnImageDecoded(const SkBitmap& decoded_image) {
123 int target_size = image_info_.pixels_per_side; 123 int target_size = image_info_.pixels_per_side;
124 if (target_size > 0) { 124 if (target_size > 0) {
125 // Cropping an image could be expensive, hence posting to the background 125 // Cropping an image could be expensive, hence posting to the background
126 // thread. 126 // thread.
127 SkBitmap* bitmap = new SkBitmap; 127 SkBitmap* bitmap = new SkBitmap;
128 user_manager::UserImage::Bytes* bytes = new user_manager::UserImage::Bytes;
129 base::PostTaskAndReplyWithResult( 128 base::PostTaskAndReplyWithResult(
130 background_task_runner_.get(), FROM_HERE, 129 background_task_runner_.get(), FROM_HERE,
131 base::Bind(&CropImage, decoded_image, target_size, bitmap, bytes), 130 base::Bind(&CropImage, decoded_image, target_size, bitmap),
132 base::Bind(&UserImageRequest::OnImageCropped, 131 base::Bind(&UserImageRequest::OnImageCropped,
133 weak_ptr_factory_.GetWeakPtr(), base::Owned(bitmap), 132 weak_ptr_factory_.GetWeakPtr(), base::Owned(bitmap)));
134 base::Owned(bytes)));
135 } else { 133 } else {
136 OnImageFinalized(decoded_image, image_data_, 134 OnImageFinalized(decoded_image, image_data_,
137 false /* image_bytes_regenerated */); 135 false /* image_bytes_regenerated */);
138 } 136 }
139 } 137 }
140 138
141 void UserImageRequest::OnImageCropped(SkBitmap* bitmap, 139 void UserImageRequest::OnImageCropped(
142 user_manager::UserImage::Bytes* bytes, 140 SkBitmap* bitmap,
143 bool succeeded) { 141 scoped_refptr<base::RefCountedBytes> bytes) {
144 DCHECK_GT(image_info_.pixels_per_side, 0); 142 DCHECK_GT(image_info_.pixels_per_side, 0);
145 143
146 if (!succeeded) { 144 if (!bytes) {
147 OnDecodeImageFailed(); 145 OnDecodeImageFailed();
148 return; 146 return;
149 } 147 }
150 OnImageFinalized(*bitmap, *bytes, true /* image_bytes_regenerated */); 148 OnImageFinalized(*bitmap, bytes, true /* image_bytes_regenerated */);
151 } 149 }
152 150
153 void UserImageRequest::OnImageFinalized( 151 void UserImageRequest::OnImageFinalized(
154 const SkBitmap& image, 152 const SkBitmap& image,
155 const user_manager::UserImage::Bytes& image_bytes, 153 scoped_refptr<base::RefCountedBytes> image_bytes,
156 bool image_bytes_regenerated) { 154 bool image_bytes_regenerated) {
157 SkBitmap final_image = image; 155 SkBitmap final_image = image;
158 // Make the SkBitmap immutable as we won't modify it. This is important 156 // Make the SkBitmap immutable as we won't modify it. This is important
159 // because otherwise it gets duplicated during painting, wasting memory. 157 // because otherwise it gets duplicated during painting, wasting memory.
160 final_image.setImmutable(); 158 final_image.setImmutable();
161 gfx::ImageSkia final_image_skia = 159 gfx::ImageSkia final_image_skia =
162 gfx::ImageSkia::CreateFrom1xBitmap(final_image); 160 gfx::ImageSkia::CreateFrom1xBitmap(final_image);
163 final_image_skia.MakeThreadSafe(); 161 final_image_skia.MakeThreadSafe();
164 std::unique_ptr<user_manager::UserImage> user_image( 162 std::unique_ptr<user_manager::UserImage> user_image(
165 new user_manager::UserImage(final_image_skia, image_bytes)); 163 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, 218 ImageDecoder::ImageCodec image_codec,
221 int pixels_per_side, 219 int pixels_per_side,
222 const LoadedCallback& loaded_cb) { 220 const LoadedCallback& loaded_cb) {
223 DecodeImage( 221 DecodeImage(
224 ImageInfo(base::FilePath(), pixels_per_side, image_codec, loaded_cb), 222 ImageInfo(base::FilePath(), pixels_per_side, image_codec, loaded_cb),
225 background_task_runner, data.get(), true /* data_is_ready */); 223 background_task_runner, data.get(), true /* data_is_ready */);
226 } 224 }
227 225
228 } // namespace user_image_loader 226 } // namespace user_image_loader
229 } // namespace chromeos 227 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698