• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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 #include "chrome/browser/chromeos/login/user_image_loader.h"
6 
7 #include "base/file_path.h"
8 #include "base/file_util.h"
9 #include "base/message_loop.h"
10 #include "chrome/browser/chromeos/login/image_decoder.h"
11 #include "chrome/browser/chromeos/login/helper.h"
12 #include "content/browser/browser_thread.h"
13 #include "skia/ext/image_operations.h"
14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "ui/gfx/codec/png_codec.h"
16 #include "ui/gfx/skbitmap_operations.h"
17 
18 namespace chromeos {
19 
UserImageLoader(Delegate * delegate)20 UserImageLoader::UserImageLoader(Delegate* delegate)
21     : target_message_loop_(NULL),
22       delegate_(delegate) {
23 }
24 
~UserImageLoader()25 UserImageLoader::~UserImageLoader() {
26 }
27 
Start(const std::string & username,const std::string & filename,bool should_save_image)28 void UserImageLoader::Start(const std::string& username,
29                             const std::string& filename,
30                             bool should_save_image) {
31   target_message_loop_ = MessageLoop::current();
32 
33   ImageInfo image_info(username, should_save_image);
34   BrowserThread::PostTask(BrowserThread::FILE,
35                           FROM_HERE,
36                           NewRunnableMethod(this,
37                                             &UserImageLoader::LoadImage,
38                                             filename,
39                                             image_info));
40 }
41 
LoadImage(const std::string & filepath,const ImageInfo & image_info)42 void UserImageLoader::LoadImage(const std::string& filepath,
43                                 const ImageInfo& image_info) {
44   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
45   std::string image_data;
46   file_util::ReadFileToString(FilePath(filepath), &image_data);
47 
48   scoped_refptr<ImageDecoder> image_decoder =
49       new ImageDecoder(this, image_data);
50   image_info_map_.insert(std::make_pair(image_decoder.get(), image_info));
51   image_decoder->Start();
52 }
53 
OnImageDecoded(const ImageDecoder * decoder,const SkBitmap & decoded_image)54 void UserImageLoader::OnImageDecoded(const ImageDecoder* decoder,
55                                      const SkBitmap& decoded_image) {
56   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
57   ImageInfoMap::iterator info_it = image_info_map_.find(decoder);
58   if (info_it == image_info_map_.end()) {
59     NOTREACHED();
60     return;
61   }
62   ImageInfo image_info = info_it->second;
63   SkBitmap final_image = decoded_image;
64   if (image_info.should_save_image) {
65     // Auto crop the image, taking the largest square in the center.
66     // Also make the image smaller to save space and memory.
67     int size = std::min(decoded_image.width(), decoded_image.height());
68     int x = (decoded_image.width() - size) / 2;
69     int y = (decoded_image.height() - size) / 2;
70     SkBitmap cropped_image =
71         SkBitmapOperations::CreateTiledBitmap(decoded_image, x, y, size, size);
72     final_image =
73         skia::ImageOperations::Resize(cropped_image,
74                                       skia::ImageOperations::RESIZE_LANCZOS3,
75                                       login::kUserImageSize,
76                                       login::kUserImageSize);
77   }
78   target_message_loop_->PostTask(FROM_HERE,
79       NewRunnableMethod(this,
80                         &UserImageLoader::NotifyDelegate,
81                         final_image,
82                         image_info));
83   image_info_map_.erase(info_it);
84 }
85 
OnDecodeImageFailed(const ImageDecoder * decoder)86 void UserImageLoader::OnDecodeImageFailed(const ImageDecoder* decoder) {
87   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
88   image_info_map_.erase(decoder);
89 }
90 
NotifyDelegate(const SkBitmap & image,const ImageInfo & image_info)91 void UserImageLoader::NotifyDelegate(const SkBitmap& image,
92                                      const ImageInfo& image_info) {
93   if (delegate_) {
94     delegate_->OnImageLoaded(image_info.username,
95                              image,
96                              image_info.should_save_image);
97   }
98 }
99 
100 }  // namespace chromeos
101