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

Side by Side Diff: chrome/browser/chromeos/login/users/avatar/user_image_loader.cc

Issue 931993002: Make image_decoder a Leaky LazyInstance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a few comments Created 5 years, 9 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
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
(...skipping 13 matching lines...) Expand all
24 int pixels_per_side, 24 int pixels_per_side,
25 const LoadedCallback& loaded_cb) 25 const LoadedCallback& loaded_cb)
26 : file_path(file_path), 26 : file_path(file_path),
27 pixels_per_side(pixels_per_side), 27 pixels_per_side(pixels_per_side),
28 loaded_cb(loaded_cb) { 28 loaded_cb(loaded_cb) {
29 } 29 }
30 30
31 UserImageLoader::ImageInfo::~ImageInfo() { 31 UserImageLoader::ImageInfo::~ImageInfo() {
32 } 32 }
33 33
34 UserImageLoader::UserImageRequest::UserImageRequest(
35 const ImageInfo& image_info,
36 const std::string& image_data,
37 UserImageLoader* user_image_loader)
38 : ImageRequest(user_image_loader->background_task_runner_),
39 image_info_(image_info),
40 image_data_(image_data.begin(), image_data.end()),
41 user_image_loader_(user_image_loader) {
42 }
43
44 UserImageLoader::UserImageRequest::~UserImageRequest() {
45 }
46
34 UserImageLoader::UserImageLoader( 47 UserImageLoader::UserImageLoader(
35 ImageDecoder::ImageCodec image_codec, 48 ImageDecoder::ImageCodec image_codec,
36 scoped_refptr<base::SequencedTaskRunner> background_task_runner) 49 scoped_refptr<base::SequencedTaskRunner> background_task_runner)
37 : foreground_task_runner_(base::MessageLoopProxy::current()), 50 : foreground_task_runner_(base::MessageLoopProxy::current()),
38 background_task_runner_(background_task_runner), 51 background_task_runner_(background_task_runner),
39 image_codec_(image_codec) { 52 image_codec_(image_codec) {
40 } 53 }
41 54
42 UserImageLoader::~UserImageLoader() { 55 UserImageLoader::~UserImageLoader() {
43 } 56 }
(...skipping 28 matching lines...) Expand all
72 85
73 // In case ReadFileToString() fails, |data| is empty and DecodeImage() calls 86 // In case ReadFileToString() fails, |data| is empty and DecodeImage() calls
74 // back to OnDecodeImageFailed(). 87 // back to OnDecodeImageFailed().
75 DecodeImage(data.Pass(), image_info); 88 DecodeImage(data.Pass(), image_info);
76 } 89 }
77 90
78 void UserImageLoader::DecodeImage(const scoped_ptr<std::string> data, 91 void UserImageLoader::DecodeImage(const scoped_ptr<std::string> data,
79 const ImageInfo& image_info) { 92 const ImageInfo& image_info) {
80 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 93 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
81 94
82 scoped_refptr<ImageDecoder> image_decoder = 95 UserImageRequest* image_request =
83 new ImageDecoder(this, *data, image_codec_); 96 new UserImageRequest(image_info, *data, this);
84 image_info_map_.insert(std::make_pair(image_decoder.get(), image_info)); 97 ImageDecoder::StartWithOptions(image_request, *data, image_codec_, false);
85 image_decoder->Start(background_task_runner_);
86 } 98 }
87 99
88 void UserImageLoader::OnImageDecoded(const ImageDecoder* decoder, 100 void UserImageLoader::UserImageRequest::OnImageDecoded(
89 const SkBitmap& decoded_image) { 101 const SkBitmap& decoded_image) {
90 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 102 DCHECK(task_runner()->RunsTasksOnCurrentThread());
91 103
92 ImageInfoMap::iterator it = image_info_map_.find(decoder); 104 const int target_size = image_info_.pixels_per_side;
93 if (it == image_info_map_.end()) {
94 NOTREACHED();
95 return;
96 }
97 const std::string file_path = it->second.file_path;
98 const int target_size = it->second.pixels_per_side;
99 const LoadedCallback loaded_cb = it->second.loaded_cb;
100 image_info_map_.erase(it);
101
102 SkBitmap final_image = decoded_image; 105 SkBitmap final_image = decoded_image;
103 106
104 if (target_size > 0) { 107 if (target_size > 0) {
105 // Auto crop the image, taking the largest square in the center. 108 // Auto crop the image, taking the largest square in the center.
106 int pixels_per_side = 109 int pixels_per_side =
107 std::min(decoded_image.width(), decoded_image.height()); 110 std::min(decoded_image.width(), decoded_image.height());
108 int x = (decoded_image.width() - pixels_per_side) / 2; 111 int x = (decoded_image.width() - pixels_per_side) / 2;
109 int y = (decoded_image.height() - pixels_per_side) / 2; 112 int y = (decoded_image.height() - pixels_per_side) / 2;
110 SkBitmap cropped_image = SkBitmapOperations::CreateTiledBitmap( 113 SkBitmap cropped_image = SkBitmapOperations::CreateTiledBitmap(
111 decoded_image, x, y, pixels_per_side, pixels_per_side); 114 decoded_image, x, y, pixels_per_side, pixels_per_side);
112 if (pixels_per_side > target_size) { 115 if (pixels_per_side > target_size) {
113 // Also downsize the image to save space and memory. 116 // Also downsize the image to save space and memory.
114 final_image = 117 final_image =
115 skia::ImageOperations::Resize(cropped_image, 118 skia::ImageOperations::Resize(cropped_image,
116 skia::ImageOperations::RESIZE_LANCZOS3, 119 skia::ImageOperations::RESIZE_LANCZOS3,
117 target_size, 120 target_size,
118 target_size); 121 target_size);
119 } else { 122 } else {
120 final_image = cropped_image; 123 final_image = cropped_image;
121 } 124 }
122 } 125 }
123 // Make the SkBitmap immutable as we won't modify it. This is important 126 // Make the SkBitmap immutable as we won't modify it. This is important
124 // because otherwise it gets duplicated during painting, wasting memory. 127 // because otherwise it gets duplicated during painting, wasting memory.
125 final_image.setImmutable(); 128 final_image.setImmutable();
126 gfx::ImageSkia final_image_skia = 129 gfx::ImageSkia final_image_skia =
127 gfx::ImageSkia::CreateFrom1xBitmap(final_image); 130 gfx::ImageSkia::CreateFrom1xBitmap(final_image);
128 final_image_skia.MakeThreadSafe(); 131 final_image_skia.MakeThreadSafe();
129 user_manager::UserImage user_image(final_image_skia, 132 user_manager::UserImage user_image(final_image_skia, image_data_);
130 decoder->get_image_data()); 133 user_image.set_file_path(image_info_.file_path);
131 user_image.set_file_path(file_path); 134 if (user_image_loader_->image_codec_ == ImageDecoder::ROBUST_JPEG_CODEC)
132 if (image_codec_ == ImageDecoder::ROBUST_JPEG_CODEC)
133 user_image.MarkAsSafe(); 135 user_image.MarkAsSafe();
134 foreground_task_runner_->PostTask(FROM_HERE, 136 user_image_loader_->foreground_task_runner_->PostTask(
135 base::Bind(loaded_cb, user_image)); 137 FROM_HERE, base::Bind(image_info_.loaded_cb, user_image));
138 delete this;
136 } 139 }
137 140
138 void UserImageLoader::OnDecodeImageFailed(const ImageDecoder* decoder) { 141 void UserImageLoader::UserImageRequest::OnDecodeImageFailed() {
139 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 142 DCHECK(task_runner()->RunsTasksOnCurrentThread());
140 143 user_image_loader_->foreground_task_runner_->PostTask(
141 ImageInfoMap::iterator it = image_info_map_.find(decoder); 144 FROM_HERE, base::Bind(image_info_.loaded_cb, user_manager::UserImage()));
142 if (it == image_info_map_.end()) { 145 delete this;
143 NOTREACHED();
144 return;
145 }
146 const LoadedCallback loaded_cb = it->second.loaded_cb;
147 image_info_map_.erase(it);
148
149 foreground_task_runner_->PostTask(
150 FROM_HERE, base::Bind(loaded_cb, user_manager::UserImage()));
151 } 146 }
152 147
153 } // namespace chromeos 148 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698