Commit f6a37b54 authored by ivankr@chromium.org's avatar ivankr@chromium.org

[cros] Remove redundant PNG enconding in UserImage.

*) PNG enconding removed from UserImage.
*) chrome://userimage/ source understand @<scale> spec now.


BUG=137929


Review URL: https://chromiumcodereview.appspot.com/10831064

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149260 0039d316-1c4b-4281-b951-d872f2087c98
parent 8735169c
...@@ -8,16 +8,11 @@ ...@@ -8,16 +8,11 @@
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/default_user_images.h" #include "chrome/browser/chromeos/login/default_user_images.h"
#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/user_manager.h"
#include "grit/theme_resources.h"
#include "ui/base/resource/resource_bundle.h"
namespace chromeos { namespace chromeos {
namespace { namespace {
// Resource ID of the image to use as stub image.
const int kStubImageResourceID = IDR_PROFILE_PICTURE_LOADING;
// Returns account name portion of an email. // Returns account name portion of an email.
std::string GetUserName(const std::string& email) { std::string GetUserName(const std::string& email) {
std::string::size_type i = email.find('@'); std::string::size_type i = email.find('@');
...@@ -37,8 +32,6 @@ const char kGuestUser[] = ""; ...@@ -37,8 +32,6 @@ const char kGuestUser[] = "";
User::User(const std::string& email) User::User(const std::string& email)
: email_(email), : email_(email),
user_image_(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
kDefaultImageResources[0])),
oauth_token_status_(OAUTH_TOKEN_STATUS_UNKNOWN), oauth_token_status_(OAUTH_TOKEN_STATUS_UNKNOWN),
image_index_(kInvalidImageIndex), image_index_(kInvalidImageIndex),
image_is_stub_(false) { image_is_stub_(false) {
...@@ -61,8 +54,7 @@ void User::SetImageURL(const GURL& image_url) { ...@@ -61,8 +54,7 @@ void User::SetImageURL(const GURL& image_url) {
} }
void User::SetStubImage(int image_index) { void User::SetStubImage(int image_index) {
user_image_.SetImage(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( user_image_ = UserImage();
kStubImageResourceID));
image_index_ = image_index; image_index_ = image_index;
image_is_stub_ = true; image_is_stub_ = true;
} }
......
...@@ -22,6 +22,8 @@ extern const char kDemoUser[]; ...@@ -22,6 +22,8 @@ extern const char kDemoUser[];
// Username for incognito login. // Username for incognito login.
extern const char kGuestUser[]; extern const char kGuestUser[];
extern const int kDefaultImagesCount;
// A class representing information about a previously logged in user. // A class representing information about a previously logged in user.
// Each user has a canonical email (username), returned by |email()| and // Each user has a canonical email (username), returned by |email()| and
// may have a different displayed email (in the raw form as entered by user), // may have a different displayed email (in the raw form as entered by user),
...@@ -64,6 +66,10 @@ class User { ...@@ -64,6 +66,10 @@ class User {
// The image for this user. // The image for this user.
const gfx::ImageSkia& image() const { return user_image_.image(); } const gfx::ImageSkia& image() const { return user_image_.image(); }
bool has_default_image() const {
return image_index_ >= 0 && image_index_ < kDefaultImagesCount;
}
int image_index() const { return image_index_; } int image_index() const { return image_index_; }
bool has_raw_image() const { return user_image_.has_raw_image(); } bool has_raw_image() const { return user_image_.has_raw_image(); }
// Returns raw representation of static user image. // Returns raw representation of static user image.
......
...@@ -23,12 +23,15 @@ bool IsAnimatedImage(const UserImage::RawImage& data) { ...@@ -23,12 +23,15 @@ bool IsAnimatedImage(const UserImage::RawImage& data) {
} // namespace } // namespace
UserImage::UserImage()
: has_raw_image_(false),
has_animated_image_(false) {
}
UserImage::UserImage(const gfx::ImageSkia& image) UserImage::UserImage(const gfx::ImageSkia& image)
: image_(image), : image_(image),
has_raw_image_(false), has_raw_image_(false),
has_animated_image_(false) { has_animated_image_(false) {
if (gfx::PNGCodec::EncodeBGRASkBitmap(image_, false, &raw_image_))
has_raw_image_ = true;
} }
UserImage::UserImage(const gfx::ImageSkia& image, UserImage::UserImage(const gfx::ImageSkia& image,
...@@ -39,25 +42,14 @@ UserImage::UserImage(const gfx::ImageSkia& image, ...@@ -39,25 +42,14 @@ UserImage::UserImage(const gfx::ImageSkia& image,
if (IsAnimatedImage(raw_image)) { if (IsAnimatedImage(raw_image)) {
has_animated_image_ = true; has_animated_image_ = true;
animated_image_ = raw_image; animated_image_ = raw_image;
} if (gfx::PNGCodec::EncodeBGRASkBitmap(image_, false, &raw_image_))
if (gfx::PNGCodec::EncodeBGRASkBitmap(image_, false, &raw_image_)) has_raw_image_ = true;
} else {
has_raw_image_ = true; has_raw_image_ = true;
raw_image_ = raw_image;
}
} }
UserImage::~UserImage() {} UserImage::~UserImage() {}
void UserImage::SetImage(const gfx::ImageSkia& image) {
image_ = image;
if (gfx::PNGCodec::EncodeBGRASkBitmap(image_, false, &raw_image_)) {
has_raw_image_ = true;
} else {
has_raw_image_ = false;
RawImage().swap(raw_image_); // Clear |raw_image_|.
}
has_animated_image_ = false;
if (!animated_image_.empty())
RawImage().swap(animated_image_); // Clear |animated_image_|.
}
} // namespace chromeos } // namespace chromeos
...@@ -12,36 +12,35 @@ ...@@ -12,36 +12,35 @@
namespace chromeos { namespace chromeos {
// Wrapper class for bitmaps and raw images when it's necessary. Could // Wrapper class storing a still image and it's raw representation. Could be
// be used for storing profile images (including animated profile // used for storing profile images (including animated profile images) and user
// images) and user wallpapers. // wallpapers.
class UserImage { class UserImage {
public: public:
// TODO(ivankr): replace with RefCountedMemory to prevent copying.
typedef std::vector<unsigned char> RawImage; typedef std::vector<unsigned char> RawImage;
// Constructs UserImage from bitmap. Should be used where only // Create instance with an empty still frame and no raw data.
// static image is needed (e.g. wallpapers). UserImage();
// Creates a new instance from a given still frame without any raw data.
explicit UserImage(const gfx::ImageSkia& image); explicit UserImage(const gfx::ImageSkia& image);
// Constructs UserImage from raw image and bitmap that should // Creates a new instance from a given still frame and raw representation.
// represent single frame from that one. Can be used for wrapping // |raw_image| can be animated, in which case animated_image() will return the
// animated images. // original |raw_image| and raw_image() will return the encoded representation
// of |image|.
UserImage(const gfx::ImageSkia& image, const RawImage& raw_image); UserImage(const gfx::ImageSkia& image, const RawImage& raw_image);
virtual ~UserImage(); virtual ~UserImage();
// Replaces already stored image to new |image|. Note, that
// |raw_image| and |animated_image| will be reset after that
// operation.
void SetImage(const gfx::ImageSkia& image);
const gfx::ImageSkia& image() const { return image_; } const gfx::ImageSkia& image() const { return image_; }
// Returns true iff |image| argument of constructors or |SetImage| // Optional raw representation of the still image.
// can be encoded as a bitmap.
bool has_raw_image() const { return has_raw_image_; } bool has_raw_image() const { return has_raw_image_; }
const RawImage& raw_image() const { return raw_image_; } const RawImage& raw_image() const { return raw_image_; }
// Returns true iff UserImage is constructed from animated image. // Optional raw representation of the animated image.
bool has_animated_image() const { return has_animated_image_; } bool has_animated_image() const { return has_animated_image_; }
const RawImage& animated_image() const { return animated_image_; } const RawImage& animated_image() const { return animated_image_; }
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include "base/memory/ref_counted_memory.h" #include "base/memory/ref_counted_memory.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/string_split.h" #include "base/string_split.h"
#include "chrome/browser/chromeos/login/default_user_images.h"
#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/ui/webui/web_ui_util.cc"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "googleurl/src/url_parse.h" #include "googleurl/src/url_parse.h"
#include "grit/theme_resources.h" #include "grit/theme_resources.h"
...@@ -21,35 +23,35 @@ namespace { ...@@ -21,35 +23,35 @@ namespace {
// non-animated version of user image should be returned. // non-animated version of user image should be returned.
const char kKeyAnimated[] = "animated"; const char kKeyAnimated[] = "animated";
// Extracts from user image request user email and type of requested // Parses the user image URL, which looks like
// image (animated or non-animated). |path| is an user image request // "chrome://userimage/user@host?key1=value1&...&key_n=value_n@<scale>x",
// and should look like "username@host?key1=value1&...&key_n=value_n". // to user email, optional parameters and scale factor.
// So, "username@host" is stored into |email|. If a query part of void ParseRequest(const GURL& url,
// |path| contains "animated" key, |is_image_animated| is set to true,
// otherwise |is_image_animated| is set to false. Doesn't change
// arguments if email can't be parsed (for instance, in guest mode).
void ParseRequest(const std::string& path,
std::string* email, std::string* email,
bool* is_image_animated) { bool* is_image_animated,
url_parse::Parsed parsed; ui::ScaleFactor* scale_factor) {
url_parse::ParseStandardURL(path.c_str(), path.size(), &parsed); DCHECK(url.is_valid());
if (!parsed.username.is_valid() || !parsed.host.is_valid())
return; *email = url.path();
email->erase(0, 1); // Strip initial slash.
DCHECK(email != NULL);
*email = path.substr(parsed.username.begin, parsed.username.len); // TODO(ivankr): when all chrome://userimage URLs have a valid @<scale>x,
email->append("@"); // remove this and pass |email| instead of |&path| to ParsePathAndScale.
email->append(path.substr(parsed.host.begin, parsed.host.len)); size_t pos = email->find('@');
if (pos != std::string::npos) {
if (!parsed.query.is_valid()) pos = email->find('@', pos + 1);
return; if (pos != std::string::npos)
email->erase(pos);
}
std::string path;
web_ui_util::ParsePathAndScale(url, &path, scale_factor);
url_parse::Component query = parsed.query; std::string url_spec = url.possibly_invalid_spec();
url_parse::Component query = url.parsed_for_possibly_invalid_spec().query;
url_parse::Component key, value; url_parse::Component key, value;
DCHECK(is_image_animated != NULL);
*is_image_animated = false; *is_image_animated = false;
while (ExtractQueryKeyValue(path.c_str(), &query, &key, &value)) { while (ExtractQueryKeyValue(url_spec.c_str(), &query, &key, &value)) {
if (path.substr(key.begin, key.len) == kKeyAnimated) { if (url_spec.substr(key.begin, key.len) == kKeyAnimated) {
*is_image_animated = true; *is_image_animated = true;
break; break;
} }
...@@ -61,22 +63,26 @@ void ParseRequest(const std::string& path, ...@@ -61,22 +63,26 @@ void ParseRequest(const std::string& path,
namespace chromeos { namespace chromeos {
namespace options2 { namespace options2 {
std::vector<unsigned char> UserImageSource::GetUserImage( base::RefCountedMemory* UserImageSource::GetUserImage(
const std::string& email, bool is_image_animated) const { const std::string& email,
bool is_image_animated,
ui::ScaleFactor scale_factor) const {
const chromeos::User* user = chromeos::UserManager::Get()->FindUser(email); const chromeos::User* user = chromeos::UserManager::Get()->FindUser(email);
if (user) { if (user) {
if (user->has_animated_image() && is_image_animated) if (user->has_animated_image() && is_image_animated) {
return user->animated_image(); return new base::RefCountedBytes(user->animated_image());
else if (user->has_raw_image()) } else if (user->has_raw_image()) {
return user->raw_image(); return new base::RefCountedBytes(user->raw_image());
} else if (user->has_default_image()) {
return ResourceBundle::GetSharedInstance().
LoadDataResourceBytes(kDefaultImageResources[user->image_index()],
scale_factor);
} else {
NOTREACHED() << "User with custom image missing raw data";
}
} }
std::vector<unsigned char> user_image; return ResourceBundle::GetSharedInstance().
gfx::PNGCodec::EncodeBGRASkBitmap( LoadDataResourceBytes(IDR_LOGIN_DEFAULT_USER, scale_factor);
*ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
IDR_LOGIN_DEFAULT_USER),
false,
&user_image);
return user_image;
} }
UserImageSource::UserImageSource() UserImageSource::UserImageSource()
...@@ -90,10 +96,11 @@ void UserImageSource::StartDataRequest(const std::string& path, ...@@ -90,10 +96,11 @@ void UserImageSource::StartDataRequest(const std::string& path,
int request_id) { int request_id) {
std::string email; std::string email;
bool is_image_animated = false; bool is_image_animated = false;
ParseRequest(path, &email, &is_image_animated); ui::ScaleFactor scale_factor;
GURL url(chrome::kChromeUIUserImageURL + path);
std::vector<unsigned char> image = GetUserImage(email, is_image_animated); ParseRequest(url, &email, &is_image_animated, &scale_factor);
SendResponse(request_id, new base::RefCountedBytes(image)); SendResponse(request_id,
GetUserImage(email, is_image_animated, scale_factor));
} }
std::string UserImageSource::GetMimeType(const std::string& path) const { std::string UserImageSource::GetMimeType(const std::string& path) const {
...@@ -101,7 +108,10 @@ std::string UserImageSource::GetMimeType(const std::string& path) const { ...@@ -101,7 +108,10 @@ std::string UserImageSource::GetMimeType(const std::string& path) const {
// drag the image they get no extension. // drag the image they get no extension.
std::string email; std::string email;
bool is_image_animated = false; bool is_image_animated = false;
ParseRequest(path, &email, &is_image_animated); ui::ScaleFactor scale_factor;
GURL url(chrome::kChromeUIUserImageURL + path);
ParseRequest(url, &email, &is_image_animated, &scale_factor);
if (is_image_animated) { if (is_image_animated) {
const chromeos::User* user = chromeos::UserManager::Get()->FindUser(email); const chromeos::User* user = chromeos::UserManager::Get()->FindUser(email);
......
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
#include "ui/base/layout.h"
namespace base {
class RefCountedMemory;
}
namespace chromeos { namespace chromeos {
namespace options2 { namespace options2 {
...@@ -31,9 +36,10 @@ class UserImageSource : public ChromeURLDataManager::DataSource { ...@@ -31,9 +36,10 @@ class UserImageSource : public ChromeURLDataManager::DataSource {
// Returns PNG or GIF (when possible and if |is_image_animated| flag // Returns PNG or GIF (when possible and if |is_image_animated| flag
// is true) encoded image for user with specified email. If there's // is true) encoded image for user with specified email. If there's
// no user with such email, returns the default image. // no user with such email, returns the first default image.
std::vector<unsigned char> GetUserImage(const std::string& email, base::RefCountedMemory* GetUserImage(const std::string& email,
bool is_image_animated) const; bool is_image_animated,
ui::ScaleFactor scale_factor) const;
private: private:
virtual ~UserImageSource(); virtual ~UserImageSource();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment