1// Copyright (c) 2012 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.h"
6
7#include "third_party/skia/include/core/SkBitmap.h"
8#include "ui/gfx/codec/jpeg_codec.h"
9
10#include "base/debug/trace_event.h"
11
12namespace chromeos {
13
14namespace {
15
16// Default quality for encoding user images.
17const int kDefaultEncodingQuality = 90;
18
19bool IsAnimatedImage(const UserImage::RawImage& data) {
20  const char kGIFStamp[] = "GIF";
21  const size_t kGIFStampLength = sizeof(kGIFStamp) - 1;
22
23  if (data.size() >= kGIFStampLength &&
24      memcmp(&data[0], kGIFStamp, kGIFStampLength) == 0) {
25    return true;
26  }
27  return false;
28}
29
30bool EncodeImageSkia(const gfx::ImageSkia& image,
31                     std::vector<unsigned char>* output) {
32  TRACE_EVENT2("oobe", "EncodeImageSkia",
33               "width", image.width(), "height", image.height());
34  if (image.isNull())
35    return false;
36  const SkBitmap& bitmap = *image.bitmap();
37  SkAutoLockPixels lock_image(bitmap);
38  return gfx::JPEGCodec::Encode(
39      reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
40      gfx::JPEGCodec::FORMAT_SkBitmap,
41      bitmap.width(),
42      bitmap.height(),
43      bitmap.width() * bitmap.bytesPerPixel(),
44      kDefaultEncodingQuality, output);
45}
46
47}  // namespace
48
49// static
50UserImage UserImage::CreateAndEncode(const gfx::ImageSkia& image) {
51  RawImage raw_image;
52  if (EncodeImageSkia(image, &raw_image)) {
53    UserImage result(image, raw_image);
54    result.MarkAsSafe();
55    return result;
56  }
57  return UserImage(image);
58}
59
60UserImage::UserImage()
61    : has_raw_image_(false),
62      has_animated_image_(false),
63      is_safe_format_(false) {
64}
65
66UserImage::UserImage(const gfx::ImageSkia& image)
67    : image_(image),
68      has_raw_image_(false),
69      has_animated_image_(false),
70      is_safe_format_(false) {
71}
72
73UserImage::UserImage(const gfx::ImageSkia& image,
74                     const RawImage& raw_image)
75    : image_(image),
76      has_raw_image_(false),
77      has_animated_image_(false),
78      is_safe_format_(false) {
79  if (IsAnimatedImage(raw_image)) {
80    has_animated_image_ = true;
81    animated_image_ = raw_image;
82    if (EncodeImageSkia(image_, &raw_image_)) {
83      has_raw_image_ = true;
84      MarkAsSafe();
85    }
86  } else {
87    has_raw_image_ = true;
88    raw_image_ = raw_image;
89  }
90}
91
92UserImage::~UserImage() {}
93
94void UserImage::DiscardRawImage() {
95  RawImage().swap(raw_image_);  // Clear |raw_image_|.
96}
97
98void UserImage::MarkAsSafe() {
99  is_safe_format_ = true;
100}
101
102}  // namespace chromeos
103