Home | History | Annotate | Download | only in login
      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 
     20 UserImageLoader::UserImageLoader(Delegate* delegate)
     21     : target_message_loop_(NULL),
     22       delegate_(delegate) {
     23 }
     24 
     25 UserImageLoader::~UserImageLoader() {
     26 }
     27 
     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 
     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 
     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 
     86 void UserImageLoader::OnDecodeImageFailed(const ImageDecoder* decoder) {
     87   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
     88   image_info_map_.erase(decoder);
     89 }
     90 
     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